how to populate an observable array from two different arrays in knockout.js -


within app have section allows users add filter search criteria filter observable array contains 3 drop down menus , input fields manually adding values. 2 of drop down menus static, third populated based upon selected items located elsewhere in page. having trouble in binding between 2 array's. have drop downs populating cannot figure out how pass value selectedattributes() array inserted in attribure property of filter list

html

<input type="button" value="add filter" title="add filter" data-bind="click: $root.addfilter, enable: myfilters().length < 10" /> <table>  <tbody data-bind="foreach: myfilters">   <tr>   <td>     <!-- ko with: $root.iqreport -->     <select data-bind="options: selectedattributes(), optionstext: function(selectedattributes){ return selectedattributes.namehierarchy() + '.' + selectedattributes.labelname() },  optionscaption:'select field...'">     </select>     <!-- /ko -->   </td>   <td>     <select data-bind="options: $root.filteroperators, value:operator, optionstext: 'operatorname'">     </select>   </td>   <td>     <input data-bind="value: criteria1" />   </td>   <td>     <input data-bind="value: criteria2" />   </td>   <td>     <select data-bind="options: $root.joinoperators, value:joinoperator, optionstext: 'joinname'">     </select>  </td>  <td>     <a class="attributelink" data-bind="click: $root.removefilter">remove</a>  </td>  </tr> 

knockoutjs

function filterlist(joiningoperator, attributehierarchy, attributeidhierarchy, operator, filtercriteria, filtercriteriarange) {     var self = this;      self.joinoperator = ko.observable(joiningoperator);     self.attribute = ko.observable(attributehierarchy);     self.attributeid = ko.observable(attributeidhierarchy);     self.operator = ko.observable(operator);     self.criteria1 = ko.observable(filtercriteria);     self.criteria2 = ko.observable(filtercriteriarange); }   var viewmodel function(){          //non-editable operators         self.filteroperators = [         { operatorname: "equals", operatorvalue: "=" },         { operatorname: "greater than", operatorvalue: ">" },         { operatorname: "greater or equal to", operatorvalue: ">=" },         { operatorname: "less than", operatorvalue: "<" },         { operatorname: "less or equal to", operatorvalue: "<=" },         { operatorname: "not equal to", operatorvalue: "<>" },         { operatorname: "not less than", operatorvalue: "!>" },         { operatorname: "not greater than", operatorvalue: "!<" },         { operatorname: "between", operatorvalue: "between" },         { operatorname: "like", operatorvalue: "like" }         ];          //non-editable joins         self.joinoperators = [         {joinname: "and"},         {joinname: "or"}         ];           //define filter collection         self.myfilters = ko.observablearray([]);           //add new filter row         self.addfilter = function () {             self.myfilters.push(new filterlist(self.joinoperators[0], "", "", self.filteroperators[0], "", ""));         };          filterlist.attribute.subscribe(function () {          }, filterlist);           self.removefilter = function (row) {             self.myfilters.remove(row);         }; } 

the collection iqreports populated array independent of myfilters[] hence virtual binding in html.

what learn when user selects value selected attributes drop down how go having value populate/update observable property self.attribute of myfilters

update

the iqreports collection observable array consisting of additional observable arrays.this created server side, , passed client. selectedattributes class contains following properties

public class reportentity     {         public int entityid { get; set;          public string name { get; set; }         public string iconpath { get; set; }         public list<reportattribute> primaryattributes { get; set; }         public list<reportattribute> secondaryattributes { get; set; }         public list<reportassociatedentity> associatedentities { get; set; }         public string hierarchy { get; set; }         public string namehierarchy { get; set; }         public reportentity()          {             // initialize attributes lists.             primaryattributes = new list<reportattribute>();             secondaryattributes = new list<reportattribute>();              // initialize associated entities list.             associatedentities = new list<reportassociatedentity>();         }     }   public class reportattribute     {         public string fieldname { get; set; }         public string labelname { get; set; }         public bool isprimary { get; set; }         public int position { get; set; }         public bool isselected { get; set; }         public bool issortedby { get; set; }         public int sortposition { get; set; }         public bool sortascending { get; set; }         public bool isgroupedby { get; set; }         public string namehierarchy { get; set; }         public string hierarchy { get; set; }         public reportattribute() { }     } 

once in client can navigate values using firebug in manner self.iqreport().selectedattributes()[0]().fieldname think reference getting lost because have nested inside of observable array (myfilters) why have virtual binding wrapped around section pertains iqreports. removing statement breaks foreach because cannot resolve property selectedattributes() trying explicitly path using $root not work resulting in none of drop downs being populated. firebug @ point state cannot find property selectedattributes().

the workaround introduced move iqreports reference out of foreach instead have in html

<!-- ko with: $root.iqreport -->      <select data-bind="options: selectedattributes(), value: $root.selecteditem,  optionstext: function(selectedattributes){ return selectedattributes.namehierarchy() + '.' + selectedattributes.labelname() },  optionscaption:'select field...'">       </select> <!-- /ko --> <input type="button" value="add filter" title="add filter" data-bind="click: $root.addfilter, enable: myfilters().length < 10" /> <!--<pre data-bind="text: ko.tojson(iqreport, null, 2)"></pre>--> <table>      <tbody data-bind="foreach: myfilters">        <tr>           <td>           <b><span data-bind="text: filterattribute" /></b>           </td>           <td>            <select data-bind="options: $root.filteroperators, value:operator, optionstext: 'operatorname'">            </select>           </td>            <td>              <input data-bind="value: criteria1" />            </td>            <td>              <input data-bind="value: criteria2" />            </td>            <td>              <select data-bind="options: $root.joinoperators, value:joinoperator, optionstext: 'joinname'">              </select>            </td>            <td>             <a class="attributelink" data-bind="click: $root.removefilter">remove</a>             </td>      </tr>     </tbody> </table> 

then within view model added new observable , setup mapping table follows

 self.selecteditem = ko.observable();    //define filter collection  self.myfilters = ko.observablearray([]);   //add new filter row //here navigated individual field properties using selecteditem object self.addfilter = function () {             self.myfilters.push(new filterlist(self.joinoperators[0], self.selecteditem().namehierarchy() + "." + self.selecteditem().fieldname(), "", self.filteroperators[0], "", ""));         }; 

while not initial preferred approach provide workaround. using virtual binding allowed me populate select element never able pass value of select myfilters.attribute() observable. suspect due foreach have no idea how work around it

-cheers

use value binding , bind self.attribute, , remove with binding value binding can find self.attribute.

so instead of this:

<!-- ko with: $root.iqreport -->     <select data-bind="         options: selectedattributes(),          optionstext: function(selectedattributes){              return selectedattributes.namehierarchy() + '.' + selectedattributes.labelname() },         optionscaption:'select  field...'     ">     </select> <!-- /ko --> 

do this:

<select data-bind="     options: $root.iqreport.selectedattributes(),      optionstext: function(selectedattributes){          return selectedattributes.namehierarchy() + '.' + selectedattributes.labelname()      },       optionscaption:'select field...',     value: attribute  "> 

Comments

Popular posts from this blog

SPSS keyboard combination alters encoding -

Add new record to the table by click on the button in Microsoft Access -

javascript - jQuery .height() return 0 when visible but non-0 when hidden -