Angularjs- adding/removing dynamic html elements (dropdown)
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
msreekm
Updated on April 16, 2020Comments
-
msreekm about 4 years
here is my code- http://plnkr.co/edit/oTWXbLIKOxoGTd4U0goD?p=preview
why is the days
dropdown
does not data bind withscope.demoDays
, it is always empty?is this the correct way to add
dropdown
dynamically? If user adds 5 dropdown, how to get the results , willng-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>
-
Saghir A. Khatri about 10 yearsplease post code here, instead of referring to other sites. Thx
-
msreekm about 10 yearscopied js and html here. It is much easier to see JS code running in plnkr.
-
Anthony Chu about 10 yearsThis change will make the dropdowns show up, but they are basically redrawn whenever the fields array changes and all selected values are lost.
-
markstewie about 10 yearsYeah, there is definitely a better way of going about it. But this makes it work.
-
msreekm about 10 yearsThanks for the explanation and simplifying the code !
-
msreekm about 10 yearsj.wittwer's answer keep's the selected values,thanks for the response.