2

I'm trying to generate dynamic form based on the key of document fields and using ng-if attribute in AngularJS.

Ex:

- If field name is "name|string" then populate textfield
- If field name is "name|select" then populate dropdownlist
- If field name is "name|datepicker" then populate datepicker

Following is the code:

<div class="form-group" ng-repeat="(index, formVal) in providerModelData"  ng-if="!$first">                    
        <label>{{mySplit(index,0) | uppercase}}</label>
        <div ng-if="!mySplit(index,1)">
            <input type="text" class="form-control" ng-model="providerModelData[index]">
        </div>
        <div ng-if="mySplit(index,1) == 'datepicker'">
            <input type="text" class="form-control" ng-model="providerModelData[index]">            
        </div>
                <div ng-if="mySplit(index,1) == 'select'">                        
        <select class="form-control" ng-init="getDropdownData(index,colName)" ng-options="dropdown._id for dropdown in dropdownData[colName]">                
            <option value="">Select</option>
        </select>
    </div>
    </div>

controller:

$scope.mySplit = function(string, nb) {
            var array = string.split('|');
            return array[nb];
        }

textfields are working fine and populating data but I'm facing issue while populating dropdown fields.

Example: I've two dropdown fields in my mongodb document i.e. city|select and state|select

I'm trying to use ng-options to call function by passing index and colName (document name) to populate dropdownlist but its not working.

Following is the code:

    $scope.dropdownData = {};
        $scope.getDropdownData = function (query, colName) {
            $http.get('/getdropdowndata/', {
                params: {
                    query: query,
                    colName: colName
                }
            }).success(function (response) {

                $scope.dropdownData[colName] = response;                    

            });
        };

Express:

router.route('/').get(function (req, res) {    
    var url_parts = url.parse(req.url, true);
    var query = url_parts.query;
    console.log(query.query);
    db.collection(query.colName).aggregate([{
        "$group":{
            "_id":"$"+query.query
            }
        }],function (err, docs) {        
        console.log(docs);
        res.json(docs);
    });
});

Initially I tried calling function in ng-repeat but it was going into infine loop. Then later I tried ng-init options but it only calls or initialize once which is not working in my case. Here I need to call function dynamically and based on that I want to populate dropdown for different fields.

Any help would be appreciated.

4
  • The problem is with "dropdown._id for dropdown in getDropdownData(index,colName)". getDropdownData is a function, not a collection. You need to save the result of that function call to a scope variable, and use that variable for the ng-options Commented Apr 3, 2016 at 12:21
  • How can I use $scope variable in angular expression? Bcoz I'm calling function from my view not from controller Commented Apr 3, 2016 at 12:40
  • Can you provide a JSBin or Codepen with your code , what happens when you hard code the response of server I. getDropDownApi without sending a request and accepting it from server ?? Commented Apr 3, 2016 at 13:46
  • If you could provide the structure of response from the server and internals of providerModelData with each of the request and response structure it will be helpful..? Commented Apr 3, 2016 at 14:07

3 Answers 3

1

Your view is completely messed up as far I see it you are missing

ng-model

for your select input.

Your JSON is improper its missing , before {'id_':'Arizona'}

Try to get response in your controller and push it to array and make use of that array in your View :

$scope.getDropdownData=function(query, colName){                    
$http.get('/getdropdowndata/', {
    params: {
        query: query,
         colName:colName
    }
  }).success(function (response) {
      var returnArray = [];
      alert(JSON.stringify(response));
      angular.ForEach(response,function(option){
      //parse response and push it to returnArray
        returnArray.push(option);
     });
       return returnArray;
  });
}

View :

   <div class="form-group">
     <select class="form-control" ng-model="selection" ng-options="dropdown._id for dropdown in  getDropDownData()">
     <option value="">Select</option>
    </select>
  </div>

Here is the link to Codepen .

Sign up to request clarification or add additional context in comments.

14 Comments

yes , but can you provide a sample of what you're getting from the server and does the above solution work ??
I've tried @yarons solution but its not populating data in dropdown list
This is what I'm getting from server [ { _id: 'LA' }, { _id: 'LA' }, { _id: 'Denver' }, { _id: 'LR' } ] [ { _id: 'Arizona' } { _id: 'California' }, { _id: 'Arizona' } ]
this is a invalid json missing comma before { _id: 'Arizona' } ??
Its getting generated from mongodb/express
|
1

Consider the following solution:
In your controller, set up a variable for the dropdown data:

$scope.dropdownData = {};

Then change your getDropdownData function to:

$scope.getDropdownData=function(query, colName){                    
    $http.get('/getdropdowndata/', {
        params: {
            query: query,
            colName:colName
        }
    }).success(function (response) {
        alert(JSON.stringify(response));
        $scope.dropdownData[colName] = response; // This will put data into our html file
    });
}

And the HTML for your dropdown case should be:

<div ng-if="mySplit(index,1) == 'select'">                                    
    <select class="form-control" ng-init="getDropdownData(index,colName)" ng-options="dropdown._id for dropdown in dropdownData[colName]">
        <option value="">Select</option>
    </select>
</div>

I used the notorious ngInit to make the call from getting data for the server. Perhaps there's a better way that I didn't consider. But in any case, the idea is to make the call to the server, and save the data in a way that you can fetch it easily from the view.

Edit

I don't know why, but for some reason this solution doesn't work with ng-options. It does, however, work when using it like this:

<select class="form-control" ng-init="getDropdownData(index,colName)">
    <option value="">Select</option>
    <option ng-repeat="dropdown in dropdownData[colName]" value="dropdown._id">{{dropdown._id}}</option>
</select>

See a simple example here.

13 Comments

I tried this but not working. dropdown not populating data
have you tried debugging your angular code to verify the the getDropdownData function is being called?
Yes function is getting called and returns object but not populating data in dropdownlist
In my answer, I initialized $scope.dropdownData with an empty object {}. You initialized yours with an empty array.
This is my array for city: [ { _id: 'LA' }, { _id: 'LA' }, { _id: 'Denver' }, { _id: 'LR' } ] and this for state [ { _id: 'Arizona' } { _id: 'California' }, { _id: 'Arizona' } ]. Is array format correct?
|
0

Finally I solved it myself. Thanks @Rishab777 and @yarons for guiding me.

Here's the view code:

    <div ng-if="mySplit(index, 1) == 'select'">                     
        <select class="form-control">                
            <option value="">Select</option>
            <option ng-model="providerModelData[index]" ng-selected="providerModelData[index]" ng-repeat="dropdown in dropdownData[index]" value="{{dropdown._id}}">{{dropdown._id}}</option>
        </select>
    </div>

and controller:

        $scope.showModal = false;
        $scope.toggleModal = function (colId, colName) {
            $http.get('/collectiondata/' + colId + '/collectionName/' + colName).success(function (response) {
                $scope.colName = colName;
                $scope.colId = colId;

                for (var key in response) {
                    if (response.hasOwnProperty(key)) {
                        if ($scope.mySplit(key, 1) === 'select') {                                
                            $scope.getDropdownData(key, colName);     
                        }
                    }
                }

                $scope.providerModelData = response;
                $scope.showModal = !$scope.showModal;
            });
        };

        $scope.dropdownData = {};

        $scope.getDropdownData = function (query, colName) {
            $http.get('/getdropdowndata/', {
                params: {
                    query: query,
                    colName: colName
                }
            }).success(function (response) {                    
                $scope.dropdownData[query] = response;
            });
        };

Now the issue is ng-selected="providerModelData[index]" is not working and its showing last item as selected only.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.