Display dropdown on table data cell in html using angularjs

Viewed 4064

I am trying to populate rows in my html table based on my angularjs response. My aim is to make one of my table data cell in a drop down format.

Requirements:

  • The drop down will have three values (A, B and C).
  • The initial value should be the value obtained in my angularjs response.
  • The other values of the dropdown should be the remaining values that is not obtained in the response.

In detail:

I have this table row:

<tbody>
   <tr valign="middle" st-select-row="row" st-select-mode="multiple" ng-repeat="row in display_republish_records" id="{{row.botMainId}}">
      <td><select class="custom-select" style="margin-left:0px" ng-model="botId" ng-options="choice.name for choice in botIds"></select></td>
      <td ng-bind="row.botSet"></td>
      <td ng-bind="row.botNumber"></td>
   </tr>
</tbody>

And, I have the response data in this format:

0: {botMainId: "A", botSet: "HK64604", botNumber: "786443174705883702", $$hashKey: "object:27"}
1: {botMainId: "A", botSet: "HK65825", botNumber: "595143174706013402", $$hashKey: "object:28"}
2: {botMainId: "A", botSet: "HK67383", botNumber: "281943174706142702", $$hashKey: "object:29"}
3: {botMainId: "B", botSet: "HK72557", botNumber: "922443174706654102", $$hashKey: "object:30"}
4: {botMainId: "B", botSet: "HK73332", botNumber: "724243174706716502", $$hashKey: "object:31"}
5: {botMainId: "A", botSet: "HK74025", botNumber: "379943174706764502", $$hashKey: "object:32"}
6: {botMainId: "A", botSet: "HK74694", botNumber: "825843174706807002", $$hashKey: "object:33"}
7: {botMainId: "C", botSet: "HK74819", botNumber: "563543174706827202", $$hashKey: "object:34"}
8: {botMainId: "C", botSet: "HK75964", botNumber: "423643174706902802", $$hashKey: "object:35"}
9: {botMainId: "B", botSet: "HK76384", botNumber: "678043174706923902", $$hashKey: "object:36"}

From this data, the dropdown on the first row, second row and third dow should hold the inital value as A and then B, C as the other dropdown values.

The fourth and fifth row should hold B as the initial value and C and A as the other dropdown values and so on.

Now, my js of what I've tried so far:

$http({
                                    'url' : '/myURL',
                                    'method' : 'POST',
                                    'headers' : {
                                        'Content-Type' : 'application/json'
                                    }
                                }).then(function(response) {
                                    console.log(response.data);
                                    var arrayLength = response.data.length;
                                    for (var i = 0; i < arrayLength; i++) {
                                       /* console.log(response.data[i].botMainId);*/
                                        var botRuleCode1 = null;
                                        var botRuleCode2 = null;
                                        var botRuleCode3 = null;
                                        if (response.data[i].botMainId == 'A'){
                                            botRuleCode1 = 'A';
                                            botRuleCode2 = 'B';
                                            botRuleCode3 = 'C';
                                        } else if (response.data[i].botMainId == 'B'){
                                            botRuleCode1 = 'B';
                                            botRuleCode2 = 'A';
                                            botRuleCode3 = 'C';
                                        } else {
                                            botRuleCode1 = 'C';
                                            botRuleCode2 = 'B';
                                            botRuleCode3 = 'A';
                                        }
                                        $scope.botIds = [ {
                                            id : botRuleCode1,
                                            name : botRuleCode1
                                        }, {
                                            id : botRuleCode2,
                                            name : botRuleCode2
                                        }, {
                                            id : botRuleCode3,
                                            name : botRuleCode3
                                        }];

                                        $scope.botId = $scope.botIds[0];
                                    }
                                    $scope.botData = response.data;

                                    $window.scrollTo(0, 0);

                                })

This script will take the last value of the for is set for all the dropdowns, making a common dropdown value for all the rows.

Can someone help on how could I change this code?

3 Answers

The problem with your code is that you are using the same ngModel botId for each row in your repeater.

It would be better to have a different object to store the selection value per each item, so you can fill it right after your data is returned from the API call. Something like this illustrates the described approach:

angular.module("myApp", [])
    .constant('POSSIBLE_OPTIONS', ['A', 'B', 'C'])
    .controller("MyController", ['POSSIBLE_OPTIONS', function (POSSIBLE_OPTIONS) {
        var ctrl = this;

        ctrl.display_republish_records = [
            {botMainId: "A", botSet: "HK64604", botNumber: "786443174705883702"},
            {botMainId: "A", botSet: "HK65825", botNumber: "595143174706013402"},
            {botMainId: "A", botSet: "HK67383", botNumber: "281943174706142702"},
            {botMainId: "B", botSet: "HK72557", botNumber: "922443174706654102"},
            {botMainId: "B", botSet: "HK73332", botNumber: "724243174706716502"},
            {botMainId: "A", botSet: "HK74025", botNumber: "379943174706764502"},
            {botMainId: "A", botSet: "HK74694", botNumber: "825843174706807002"},
            {botMainId: "C", botSet: "HK74819", botNumber: "563543174706827202"},
            {botMainId: "C", botSet: "HK75964", botNumber: "423643174706902802"},
            {botMainId: "B", botSet: "HK76384", botNumber: "678043174706923902"}
        ];

        ctrl.posibbleOptions = getUniqueValuesV2(ctrl.display_republish_records, 'botMainId')
            .map(optionsMapper);

        ctrl.posibbleOptionsFromConstant = POSSIBLE_OPTIONS
            .map(optionsMapper);

        ctrl.selectionModel = {};

        angular.forEach(ctrl.display_republish_records, function (bot) {
            ctrl.selectionModel[bot.botNumber] = ctrl.posibbleOptions.filter(function (opt) {
                return opt.id === bot.botMainId;
            })[0];
        });

        function optionsMapper(id) {
            return {
                id: id,
                name: id
            }
        }


        function getUniqueValues(array, prop) {
            return [...new Set(array.map(item => item[prop]))];
        }
        
        function getUniqueValuesV2(array, prop) {
          return array.map(function(item) {
                      return item[prop];
                    }).filter(function(item, i, ar){ 
                      return ar.indexOf(item) === i;  
                    });
        }

    }]);
pre {
    max-width: 100%;
    word-break: break-word;
    white-space: pre-wrap;
}
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.7/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyController as $ctrl">
    <hr/>

    <table>

        <tr valign="middle" st-select-row="row" st-select-mode="multiple"
            ng-repeat="row in $ctrl.display_republish_records track by row.botNumber"
            ng-attr-id="{{::row.botMainId}}-{{::row.botNumber}}">
            <td>
                <select class="custom-select" style="margin-left:0px" ng-model="$ctrl.selectionModel[row.botNumber]"
                        ng-options="choice.name for choice in $ctrl.posibbleOptions track by choice.id">
                    <option value="" hidden readonly="" ng-hide="true"></option>
                </select>
            </td>
            <td ng-bind="row.botSet"></td>
            <td ng-bind="row.botNumber"></td>
        </tr>

    </table>


    <hr/>

    <h3>Debug info:</h3>

    <code>
        <pre>{{$ctrl.posibbleOptionsFromConstant}}</pre>
    </code>
    <hr/>

    <code>
        <pre>{{$ctrl.posibbleOptions}}</pre>
    </code>
    <hr/>

    <code>
        <pre>{{$ctrl.selectionModel}}</pre>
    </code>

</div>

Hello I have an example create for this case but i hope it helps.

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js"></script>
    <script type="text/javascript">
        var app = angular.module('MyApp', [])
        app.controller('MyController', function ($scope, $window) {
            $scope.Customers = [
                { Name: "John Hammond", Country: "United States" },
                { Name: "Mudassar Khan", Country: "India" },
                { Name: "Suzanne Mathews", Country: "France" },
                { Name: "Robert Schidner", Country: "Russia" }
               ];
            $scope.GetDetails = function () {
                var details = '';
                $('[id*=tblCustomers] tr:not(:has(th))').each(function (index, item) {
                    var name = $scope.Customers[index].Name;
                    var country = $scope.Customers[index].Country;
                    var selected = $(item).find('[id*=ddlYesNo] option:selected').val()
                    details += "Name: " + name + "\nCountry: " + country + "\nAction: " + selected + "\n\n";
                });
                $window.alert(details);
            };
        });
    </script>
</head>
<body>
    <div ng-app="MyApp" ng-controller="MyController">
        <table id="tblCustomers" cellpadding="0" cellspacing="0">
            <tr>
                <th>
                    Name
                </th>
                <th>
                    Country
                </th>
                <th>
                    Action
                </th>
            </tr>
            <tbody ng-repeat="m in Customers">
                <tr>
                    <td>
                        {{m.Name}}
                    </td>
                    <td>
                        {{m.Country}}
                    </td>
                    <td>
                        <select id="ddlYesNo">
                            <option value="">Select</option>
                            <option value="Yes">Yes</option>
                            <option value="No">No</option>
                        </select>
                    </td>
                </tr>
            </tbody>
        </table>
        <br />
        <input type="button" value="Get Details" ng-click="GetDetails()" />
    </div>
</body>
</html>

  1. This is JS for showing listing with drop down in it

    incidentDataList = [{IncidentId:1,Name:'Test',Description:'Test',AssignedUser: 'demo', IncidentStatus: 'Open'},{IncidentId:1,Name:'Test',Description:'Test',AssignedUser: 'demo', IncidentStatus: 'Resolved'}];
    $scope.updateStatus = function (incidentData,index) {
     const headers = {
         'content-type': 'application/json',
         'Access-Control-Allow-Origin': '*',
         'Access-Control-Allow-Methods': 'GET,POST,OPTIONS,DELETE,PUT',
         'Access-Control-Allow-Credentials': 'true'
     };
     $scope.showerror = false;
     $scope.alert.error = "";
     $scope.showsuccess = false;
     $scope.alert.success = "";
     incidentData.IncidentStatus = $scope.incidentDataList[index].IncidentStatus;
     $http.put('/updateIncident', JSON.stringify(incidentData),{ 'headers': headers }).then(function (response) {
         if (response.data)
         {    $scope.showsuccess = true;
              $scope.alert.success = "Status " + incidentData.IncidentStatus +" updated successfully ";
              $scope.incidentData = {};
         }
     }, function (response) {
         if (response.data)
         {    
             $scope.showerror = true;
             $scope.alert.error = "Error while updating " + $scope.incidentData.Name;
         }
     });
    

    }

  2. This is you HTML code, write this select code inside list

    <select ng-change="updateStatus(data,$index)" ng-model="incidentDataList[$index].IncidentStatus" class="form-control" ng-options="x for x in IncidentStatusList" aria-describedby="IncidentStatus" placeholder="Incident Status">
    
Select Incident Status
Related