msreekm
msreekm

Reputation: 309

Angularjs- adding/removing dynamic html elements (dropdown)

here is my code- http://plnkr.co/edit/oTWXbLIKOxoGTd4U0goD?p=preview

  1. why is the days dropdown does not data bind with scope.demoDays, it is always empty?

  2. is this the correct way to add dropdown dynamically? If user adds 5 dropdown, how to get the results , will ng-model="selectedDay" create an array of selection? any suggestions?

Thank you

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope, $compile) {

  var counter = 0;
  $scope.fields = [];

  $scope.days =['Day','Sun','Mon','Tue','Wed','Thu','Fri','Sat'];

    $scope.addField = function() {          
     $scope.fields.push({name:"test " + counter++});
    };
});



app.directive('demoDisplay', function($compile){
    return {
    scope:{
        demoDisplay:"=", //import referenced model to our directives scope
        demoDays:"="
      },
     link:function (scope, elem, attr, ctrl) 
      {
        scope.$watch('demoDisplay', function(){ // watch for when model changes

          elem.html("") //remove all elements

          angular.forEach(scope.demoDisplay, function(d){ //iterate list
              var s = scope.$new(); //create a new scope
              angular.extend(s,d); //copy data onto it
              console.log(scope.demoDays);

              var template = '<label class="item item-input"><div class="style-select"><select ng-model="selectedDay" ng-options="day for day in scope.demoDays"></select><br></div></label>';
              elem.append($compile(template)(s)); // compile template & append
          });
        }, true) //look deep into object
      }
    }
})

html

<button ng-click="addField()">Add Field</button>

<div demo-display="fields" demo-days="days"></div>

Upvotes: 0

Views: 22138

Answers (2)

j.wittwer
j.wittwer

Reputation: 9497

There is no need for $watch in your link function - you have already established two-way binding by specifying = on your scope property. And you can use a plain template, without having to compile.

templateUrl: 'template.html',

where template.html is:

<label class="item item-input">
  <div class="style-select">
    <select ng-model="demoDisplay.selection" ng-options="day for day in demoDays"></select>
    <br>
  </div>
</label>

Notice that the select is bound to demoDisplay.selection, which will be created on each field and be accessible on the parent scope via two-way binding. Also, note that within ng-options, I changed scope.demoDays to just demoDays. In a directive's template you only need to use the property's name to access a scope value.

You can use the directive inside ng-repeat to create additional fields when the button is clicked:

<div ng-repeat="field in data.fields">
  <div demo-display="field" demo-days="days"></div>
</div>

Here is a working plunker: http://plnkr.co/edit/pOY0l18W7wEbfSU7DKw2?p=preview

Upvotes: 9

markstewie
markstewie

Reputation: 9587

Any easy fix to get it working.

In your var template you have scope.demoDays.

Simply change this to demoDays. You are already in this scope so using it again isn't necessary.

Upvotes: 0

Related Questions