Search code examples
jqueryjquery-uiknockout.jsbreezewijmo

dropdown not updating view when value in viewmodel changes


I have the following in my view:

 <div id="tbAddress" class="row">
    <div class="span12">
        <div class="row">
            <div class="span1">&nbsp;</div>
            <div class="span11">
                <h2>Mailing Address</h2>
            </div>
        </div>
        <div class="row">
            <div class="span1">&nbsp;</div>
            <div class="span2">Address</div>
            <div class="span9">
                <input type="text" data-bind="value: MailingAddress1 " />
            </div>
        </div>
        <div class="row">
            <div class="span1">&nbsp;</div>
            <div class="span2">Address 2</div>
            <div class="span9">
                <input type="text" data-bind="value: MailingAddress2 " />
            </div>
        </div>
        <div class="row">
            <div class="span1">&nbsp;</div>
            <div class="span2">City</div>
            <div class="span9">
                <input type="text" data-bind="value: MailingCity " />
            </div>
        </div>
        <div class="row">
            <div class="span1">&nbsp;</div>
            <div class="span2">State</div>
            <div class="span3">
                 <select data-bind="value: MailingState">
                    <option value="AL">Alabama</option>
                    <option value="AK">Alaska</option>
                    <option value="AZ">Arizona</option>
                    <option value="AR">Arkansas</option>
                    <option value="CA">California</option>
                    <option value="CO">Colorado</option>
                    <option value="CT">Connecticut</option>
                    <option value="DE">Delaware</option>
                    <option value="DC">Dist of Columbia</option>
                    <option value="FL">Florida</option>
                    <option value="GA">Georgia</option>
                    <option value="HI">Hawaii</option>
                    <option value="ID">Idaho</option>
                    <option value="IL">Illinois</option>
                    <option value="IN">Indiana</option>
                    <option value="IA">Iowa</option>
                    <option value="KS">Kansas</option>
                    <option value="KY">Kentucky</option>
                    <option value="LA">Louisiana</option>
                    <option value="ME">Maine</option>
                    <option value="MD">Maryland</option>
                    <option value="MA">Massachusetts</option>
                    <option value="MI">Michigan</option>
                    <option value="MN">Minnesota</option>
                    <option value="MS">Mississippi</option>
                    <option value="MO">Missouri</option>
                    <option value="MT">Montana</option>
                    <option value="NE">Nebraska</option>
                    <option value="NV">Nevada</option>
                    <option value="NH">New Hampshire</option>
                    <option value="NJ">New Jersey</option>
                    <option value="NM">New Mexico</option>
                    <option value="NY">New York</option>
                    <option value="NC">North Carolina</option>
                    <option value="ND">North Dakota</option>
                    <option value="OH">Ohio</option>
                    <option value="OK">Oklahoma</option>
                    <option value="OR">Oregon</option>
                    <option value="PA">Pennsylvania</option>
                    <option value="RI">Rhode Island</option>
                    <option value="SC">South Carolina</option>
                    <option value="SD">South Dakota</option>
                    <option value="TN">Tennessee</option>
                    <option value="TX">Texas</option>
                    <option value="UT">Utah</option>
                    <option value="VT">Vermont</option>
                    <option value="VA">Virginia</option>
                    <option value="WA">Washington</option>
                    <option value="WV">West Virginia</option>
                    <option value="WI">Wisconsin</option>
                    <option value="WY">Wyoming</option>
                </select>
            </div>
            <div class="span1">&nbsp;</div>
            <div class="span2">Zip Code</div>
            <div class="span3">
                <input type="text" data-bind="value: MailingZIP " />
            </div>
        </div>
        <div class="row">
            <div class="span1">&nbsp;</div>
            <div class="span2">Phone</div>
            <div class="span3">
                <input type="text" data-bind="value: Phone " />
            </div>
            <div class="span1">&nbsp;</div>
            <div class="span2">Fax</div>
            <div class="span3">
                <input type="text" data-bind="value: Fax " />
            </div>
        </div>
        <div class="row">
            <div class="span1">&nbsp;</div>
            <div class="span2">Email</div>
            <div class="span9">
                <input type="text" data-bind="value: Email " />
            </div>
        </div>
        <div class="row">
            <div class="span1">&nbsp;</div>
            <div class="span2">Website</div>
            <div class="span9">
                <input type="text" data-bind="value: Website " />
            </div>
        </div>
        <div class="row">
            <div class="span1">&nbsp;</div>
            <div class="span7">
                <h2>Physical Address</h2>
            </div>
            <div class="span4">
                <button type="submit" data-bind="click: $parent.sameAsMailingAddressClicked">Physical Address Same as Mailing</button>
            </div>
        </div>
        <div class="row">
            <div class="span1">&nbsp;</div>
            <div class="span2">Address</div>
            <div class="span9">
                <input type="text" data-bind="value: PhysicalAddress1 " />
            </div>
        </div>
        <div class="row">
            <div class="span1">&nbsp;</div>
            <div class="span2">Address 2</div>
            <div class="span9">
                <input type="text" data-bind="value: PhysicalAddress2 " />
            </div>
        </div>
        <div class="row">
            <div class="span1">&nbsp;</div>
            <div class="span2">City</div>
            <div class="span9">
                <input type="text" data-bind="value: PhysicalCity " />
            </div>
        </div>
        <div class="row">
            <div class="span1">&nbsp;</div>
            <div class="span2">State</div>
            <div class="span3">
                <select data-bind="value: PhysicalState">
                    <option value="AL">Alabama</option>
                    <option value="AK">Alaska</option>
                    <option value="AZ">Arizona</option>
                    <option value="AR">Arkansas</option>
                    <option value="CA">California</option>
                    <option value="CO">Colorado</option>
                    <option value="CT">Connecticut</option>
                    <option value="DE">Delaware</option>
                    <option value="DC">Dist of Columbia</option>
                    <option value="FL">Florida</option>
                    <option value="GA">Georgia</option>
                    <option value="HI">Hawaii</option>
                    <option value="ID">Idaho</option>
                    <option value="IL">Illinois</option>
                    <option value="IN">Indiana</option>
                    <option value="IA">Iowa</option>
                    <option value="KS">Kansas</option>
                    <option value="KY">Kentucky</option>
                    <option value="LA">Louisiana</option>
                    <option value="ME">Maine</option>
                    <option value="MD">Maryland</option>
                    <option value="MA">Massachusetts</option>
                    <option value="MI">Michigan</option>
                    <option value="MN">Minnesota</option>
                    <option value="MS">Mississippi</option>
                    <option value="MO">Missouri</option>
                    <option value="MT">Montana</option>
                    <option value="NE">Nebraska</option>
                    <option value="NV">Nevada</option>
                    <option value="NH">New Hampshire</option>
                    <option value="NJ">New Jersey</option>
                    <option value="NM">New Mexico</option>
                    <option value="NY">New York</option>
                    <option value="NC">North Carolina</option>
                    <option value="ND">North Dakota</option>
                    <option value="OH">Ohio</option>
                    <option value="OK">Oklahoma</option>
                    <option value="OR">Oregon</option>
                    <option value="PA">Pennsylvania</option>
                    <option value="RI">Rhode Island</option>
                    <option value="SC">South Carolina</option>
                    <option value="SD">South Dakota</option>
                    <option value="TN">Tennessee</option>
                    <option value="TX">Texas</option>
                    <option value="UT">Utah</option>
                    <option value="VT">Vermont</option>
                    <option value="VA">Virginia</option>
                    <option value="WA">Washington</option>
                    <option value="WV">West Virginia</option>
                    <option value="WI">Wisconsin</option>
                    <option value="WY">Wyoming</option>
                </select>
            </div>
            <div class="span1">&nbsp;</div>
            <div class="span2">Zip Code</div>
            <div class="span3">
                <input type="text" data-bind="value: PhysicalZIP " />
            </div>
        </div>
    </div>
</div>

The button Same As Mailing then calls this function in my viewmodel

function doSameMailing(){

    var ap = self.activePermit();

    ap.PhysicalAddress1(ap.MailingAddress1());
    ap.PhysicalAddress2(ap.MailingAddress2());
    ap.PhysicalCity(ap.MailingCity());
    ap.PhysicalState(ap.MailingState());
    ap.PhysicalZIP(ap.MailingZIP());

}

In the viewAttached handler, I have the following code to make the inputs and select statement utilize the wijmo controls.

 $('select').wijcombobox();
 $(':text').wijtextbox();

I want to copy the mailing address into the Physical Address fields, this works for all but the PhysicalState field. If I check the viewmodel, the Physical State value is changed in the viewmodel but the view does not update the value in the select. If I hit the save button the PhysicalState field gets saved with the proper value.

I am using the following:

  • wijmo professional 2013.v1.2
  • durandal
  • breeze
  • jquery 1.90.1
  • jqueryui 1.10.2
  • knockout 2.2.1

Solution

  • The problem you're running into is because the wijmo combobox hides the select and renders its own html. The supported way to set the dropdown value is to use the plugin's option method, like so:

    $("#physicalStatesSelect").wijcombobox("option", "selectedValue", "TN")
    

    In order to make this work seamlessly using knockout, you'll need to create a custom binding and use that to manage the plugin.

    Here's a simple example of a binding that you could use:

    ko.bindingHandlers.wijmocombobox = {
        init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
            //create the element
            $(element).wijcombobox();
        },
        update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
            //update logic
            var selectedValue = ko.utils.unwrapObservable(valueAccessor());
            $(element).wijcombobox("option", "selectedValue", selectedValue)
        }
    };
    

    With that binding your html looks like this:

    <select data-bind="wijmocombobox: PhysicalState">
        <option value="AL">Alabama</option>
        <option value="AK">Alaska</option>
        <option value="AZ">Arizona</option>
        ...
    </select>
    

    Notice that the wijcombobox is getting created in the init, so you should remove the current call to $('select').wijcombobox();

    In order to get your PhysicalState view model property updated from the control, it may be necessary to set up an event handler inside your binding's 'init' method. This handler can listen for changes in the element, and manually set the PhysicalState value with the selectedValue from wijmocombobox. Something like:

    var selectedValueObservable = valueAccessor();
    var newValue = $(element).wijcombobox("option", "selectedValue");
    selectedValueObservable(newValue);