BorisMoore / jsviews

Interactive data-driven views, MVVM and MVP, built on top of JsRender templates
http://www.jsviews.com/#jsviews
MIT License
856 stars 130 forks source link

linking of selected value on select element does not work correctly with all jquery versions #444

Closed johan-ohrn closed 4 years ago

johan-ohrn commented 4 years ago

I've found an issue where linking of selected value of a select element does not work. I believe it's a bug in jsviews and that it's a coincidence that it's working with some versions of jquery.

See the following fiddles: jquery 1.9.1 (work) jquery 1.12.4 (does not work)

I have the following viewmodel:

var vm = {
    arr: [],
  selectedValue: '0',
  onChange: function() {console.log('change')}
};

and this is the template:

    <select data-link='{:selectedValue:} {on "change" onChange}'>
      {^{for arr}}
      <option value='{{:value}}'>{{:text}}</option>
      {{/for}}
    </select>

I observably refresh vm.arr like so:

  $.observable(vm.arr).refresh([
    {value:'0', text:'t1'},
    {value:'1', text:'t2'},
  ]);

I'm expecting that the first item in the drop down should become selected and it does with jquery version 1.9.1. With version 1.12.4 it does not work however. I found that the following callback in jsviews.js (line 5945) is executed:

        $elem.on("jsv-domchange", function() {
            // If the options have changed dynamically under the select, we need to refresh the data-linked selection, using the new options
            if (!arguments[3].refresh) { // eventArgs.refresh !== true - so a refresh action will only set the selection once
                var source = linkCtx.fn(view.data, view, $sub);
                $elem.val(linkCtx.convert || linkCtx.convertBack ? $sub._cnvt(linkCtx.convert, view, source) : source);
            }
        });

The if statement is entered twice, once for each data-link expression: {:selectedValue:} and {on "change" onChange} source is evaluated to "0" for the {:selectedValue:} expression and for the {on "change" onChange} expression it looks like source is evaluated to an array of one tag object. So effectively this is the code that's executed in the callback function: $elem.val("0") and $elem.val([{view:... tmpl:... content:... params:...}]). The last call seems fishy and jquery 1.12.4 responds by unselecting all option elements.

BorisMoore commented 4 years ago

Thanks for reporting this, Johan. Yes I see the issue, and am looking at a probable fix in the coming days.

BorisMoore commented 4 years ago

Hi Johan. I have included a fix for this issue in the update that I uploaded to here: https://github.com/BorisMoore/jsviews/issues/442#issuecomment-586102978.

So that update should fix https://github.com/BorisMoore/jsviews/issues/442, https://github.com/BorisMoore/jsviews/issues/444 and https://github.com/BorisMoore/jsviews/issues/440.

Let me know if it works for you.

johan-ohrn commented 4 years ago

I can confirm that this work. Thanks!

BorisMoore commented 4 years ago

Thanks for verifying. I'll close this issue once we publish the update...

BorisMoore commented 4 years ago

Fixed in v1.0.6