0

I have a server side template(ZPT) where in I am populating a select box as:

<select id="state">
  <option value="">----</option>
  <option tal:repeat="state states" tal:attributes="value state/code" tal:content="state/desc"></option>
</select>

I want to add some dynamic stuff to the select box using angularjs and I am writing an angular directive which can initialize the model on the select box. Previously I was setting the initial value of my ng-model using $scope.state = document.getElementById('state').value but I was advised that DOM manipulation should be done in a directive and not in controller.

So now I'm trying to write this directive which will be common for all the HTML tags rendered by the template and adding special case for select tags.

.directive('initModelFromServer', function() {
return {
   restrict: 'A',
   require: 'ngModel',
   link : function(scope, elm, attr, ngModelCtrl) {
       if (attr.type === 'text'){
           ngModelCtrl.$setViewValue(elm.val());
       }
       var tagName = elm[0].nodeName;
       if (tagName === 'SELECT'){
           ngModelCtrl.$setViewValue(elm[0].children(elm[0].selectedIndex));
       }
   }
};

and then applying the directive to my tags as:

<select id="state" ng-model="state" init-model-from-server>
  <option value="">----</option>
  <option tal:repeat="state states" tal:attributes="value state/code" tal:content="state/desc"></option>
</select>

The problem is when I do elm[0].selectedIndex when I find the select tag it's always set as 0. I've tried other approaches by finding the children of select and finding selected attribute on an option but haven't been able to achieve the same functionality.

I don't want to send a json object from my server side template and assign it to angular variables because then it would be more data to be passed to the client. I would rather want a directive which can initialize model directly using DOM manipulation in the link method for all sort of HTML tags rendered by the server.

Thanks in advance!

bazzinga
  • 165
  • 1
  • 5
  • 16
  • What is `tal:repeat`? Is that rendered with JavaScript? If so then your directive might be running before whatever `tal:repeat` is and thus there would only be one option in the select element (hence the `selectedIndex == 0`) – jraede May 21 '14 at 22:43
  • tal:repeat is a Zope page templates tag which is generating multiple option nodes and is rendered by the server itself. – bazzinga May 21 '14 at 22:52
  • Can you post an example of the content that Angular is seeing after it's rendered by the server? – jraede May 21 '14 at 23:13
  • I copied this from the page source: – bazzinga May 21 '14 at 23:29
  • Does looping through all children and checking for the `selected` attribute yield a different result than using `selectedIndex`? – jraede May 21 '14 at 23:33
  • Can you post an example of how to do that? – bazzinga May 21 '14 at 23:36
  • Fiddle: http://jsfiddle.net/AhYtu/ – jraede May 21 '14 at 23:39
  • I tried that using angular's jqlite API and the selected flag is true only for the option. – bazzinga May 21 '14 at 23:53
  • OK then why don't you use that instead of selectedIndex? – jraede May 21 '14 at 23:55
  • Sorry I should've clarified above, the selected flag is true only for the first option '----'. – bazzinga May 21 '14 at 23:56
  • Just to add here when I select an option the ng-model does get the selected value it's just the initial value of the selected option isn't getting assigned to ng-model. – bazzinga May 22 '14 at 00:03
  • Also, when I add the same directive to input elements their ng-models get initialized correctly. I'm wondering if it's a browser issue or the order in which the directive is compiled. – bazzinga May 22 '14 at 00:07
  • I just tried removing the directive from select tag and instead tried to initialize $scope.state = document.getElementById("state").value and it worked by showing the selected value in select so I'm wondering there is something wrong with the way the directive is supposed to work with select tags. Any help would be much appreciated! – bazzinga May 22 '14 at 01:26
  • I was able to get the model to initialize for the select box by using the directive provided in http://stackoverflow.com/questions/13769732/angular-js-init-ng-model-from-default-values/17823590#17823590. Thanks for the help @jraede – bazzinga May 22 '14 at 20:17

0 Answers0