c# - select change event fires during binding -


i'm building multi-step form using knockoutjs in asp.net mvc 5 application.

the problem is, during binding, change event dropdown firing. similar issue reported here.

i have tried suggested in post above, event still firing twice.

 <div class="row">             <div class="col-md-4">                 <div class="form-group">                     @html.labelfor(model => model.step1.country, new { @class = "control-label" })                     @html.dropdownlistfor(model => model.step1.country, model.step1.countries, new { @class = "select-country", @style = "width: 100%;", data_bind = "value: model.step1.country" })                 </div>             </div>             <div class="col-md-4">                 <div class="form-group">                     @html.labelfor(model => model.step1.state, new { @class = "control-label" })                     @html.dropdownlistfor(model => model.step1.state, model.step1.states, new { @style = "width: 100%;", data_bind = "value: model.step1.state" })                 </div>             </div>             <div class="col-md-4">                 <div class="form-group">                     @html.labelfor(model => model.step1.city, new { @class = "control-label" })                     @html.textboxfor(model => model.step1.city, new { maxlength = "50", @class = "form-control", data_bind = "value: model.step1.city" })                 </div>             </div>         </div> 

wizard plugin:

(function ($) { $.fn.wizard = function (options) {      //set form of current wizard     var $form = $("#" + options.formid);      var viewmodel = function (d, m) {         var self = this;          self.model = ko.mapping.fromjs(d, m);          self.model.generalerrors = ko.computed(function () {             return ko.utils.arrayfilter(self.model.errors(), function (item) {                 return !!item.membername;             });         });          self.model.step1.country.subscribe(function (value) {             alert(value);             console.log(value);         });          self.selectionchanged = function (element) {          }      }      var vm = new viewmodel(options.model, options.mapping);      ko.applybindings(vm, this[0]);      vm.updateonchange = true;      return this;     }; }(jquery));   <script type="text/javascript">     $(function () {         $("#wizardwrapper").wizard({             formid: "wizardform",             model: @(html.raw(json.encode(model))),             url: "/datacollection/@httpcontext.current.request.requestcontext.routedata.values["controller"].tostring()/",             mapping: {                 create: function (options){                     var m = ko.mapping.fromjs(options.data);                     return m;                 }             }         });     }); </script> 

does know how can fix this?

thanks user3297291,

thanks, adding valueallowunset stopped event firing when binding , fires when selection made.

however, 1 problem,the event fires again during postback when save click. event triggered again by

 ko.mapping.fromjs(data, self.model); 

in ajax post below.

save event:

            self.next = function (element) {             var validator = $(element).closest("form").validate();              if ($(element).closest("form").valid()) {                $.ajax({                     url: options.url + action,                     type: 'post',                     datatype: 'json',                     contenttype: 'application/json',                     data: ko.tojson(self.model),                     success: function (data) {                         self.updateonchange = false;                         ko.mapping.fromjs(data, self.model);                         self.updateonchange = true;                     },                     error: function (jqxhr, textstatus, errorthrown) {                      }                 });             } else {                 validator.focusinvalid();             }         } 

button:

<input data-bind="event: { click: next.bind($data, $element) }" type="submit" class="btn btn-default btn-prev btn-sky" value="next" /> 

update:

in order fix issue subscription triggering again after country updated, used solution few changes.

self.dirty = ko.observable(false);         self.selectedcountry = ko.observable();          self.dirtycalculations = ko.computed(function () {             var value = self.model.step1.country();              if (value == self.selectedcountry()) {                 self.selectedcountry(null);                 self.dirty(false);             } else {                 self.selectedcountry(value);                 self.dirty(true);             }         });  self.model.step1.country.subscribe(function (value) {             if (value != undefined && self.dirty()) {                 $.ajax({                     url: options.url + "getstate",                     type: 'post',                     datatype: 'json',                     contenttype: 'application/json',                     data: ko.tojson(self.model),                     traditional: true,                     success: function (data) {                         self.updateonchange = false;                         ko.mapping.fromjs(data, self.model);                         self.updateonchange = true;                     }                 });             } else {                 self.resetdirtyflag();             }         }); 

simple answer: (mis?)use valueallowunset binding.

var vm = function(initial) {    this.selection = ko.observable(initial);    this.updatecount = ko.observable(0);      this.selection.subscribe(function() {      this.updatecount(this.updatecount() + 1);    }, this);      }    ko.applybindings(new vm(1), document.queryselector(".example1"));  ko.applybindings(new vm(2), document.queryselector(".example2"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>  <div class="example1">    <h1>with valueallowunset</h1>    <select name="" id="" data-bind="value: selection, valueallowunset: true">      <option value="0">0</option>      <option value="1">1</option>      <option value="2">2</option>    </select>    <div>      updates: <span data-bind="text: updatecount"></span>    </div>  </div>    <div class="example2">    <h1>without valueallowunset</h1>    <select name="" id="" data-bind="value: selection">      <option value="0">0</option>      <option value="1">1</option>      <option value="2">2</option>    </select>    <div>      updates: <span data-bind="text: updatecount"></span>    </div>  </div>

alternative solution: i'd suggest use options binding render options via knockout instead of mvc. makes bit easier debug client side. might personal preference.


Comments

Popular posts from this blog

Ansible - ERROR! the field 'hosts' is required but was not set -

customize file_field button ruby on rails -

SoapUI on windows 10 - high DPI/4K scaling issue -