Booster
Booster

Reputation: 140

Dynamic HTML Element Binding Using Kendo

Here is the scenario I'm currently in: I have three HTML elements. A textbox called shipToAddress, another textbox called deliverToAddress and a checkbox called sameAsShipToAddress.

I then have a kendo view model behind the scenes that contains a variable called address which will hold a string of an address ex: "123 Main Street".

When the page first loads, the shipToAddress element data-binds to the kendo view model's address variable ex: "123 Main Street". The deliverToAddress has no data-bind what so ever when the page initially loads. However once the sameAsShipToAddress checked box gets checked, I want to add a data-bind attribute to the deliverToAddress so it too will look at the kendo view model's address variable.

Here is the HTML:

<input id="shipToAddress" 
       data-bind="value: address" />

<input type="checkbox" 
       id="deliverSameAsShipTo" 
       value="deliverSameAsShipTo"
       data-bind="checked: sameAsShipToAddress,
                  events: { click: differentDeliveryAddress }" />

<input id="deliverToAddress" />

And here is the backend Kendo View Model:

var _vm = kendo.observable({
    address: "",
    sameAsShipToAddress: false,

    differentDeliveryAddress() {
        if (!this.sameAsShipToAddress)
            $("#deliverToAddress").attr("data-bind", "value: address");
        else
            $("#deliverToAddress").removeAttr("data-bind");
    }


});

Can this be done? I feel like I'm close with the following code but currently the deliverToAddress' value property is not getting set. Do I need to some how refresh the deliverToAddress element's attributes?

Upvotes: 2

Views: 1807

Answers (1)

keenthinker
keenthinker

Reputation: 7830

Your code works correctly and you are very close to the final solution. Instead of setting the value of the bound field, set the "binding definition" as the property value:

$("#deliverToAddress").attr("data-bind", "value: address");

The ViewModel is already bidirectionally bound, so rebind the model and the binding will work in both directions.

After adding the property (and thus binding to the address field of the ViewModel) you need to set also the value of the deliverToAddress field. After that the binding resp. unbinding (set the value to empty string here) works correctly - you can see using the browser DOM explorer, that the attribute is added - change the address text and click the test button - deliverToAddress changes too.

I have created an example in the Telerik Dojo.

The view model code looks like this (I have added a button to test the behaviour):

$(document).ready(function(){
    var vm = kendo.observable({
                                                address: "",
                                                sameAsShipToAddress: false
    });
    kendo.bind(document.body, vm);
    //
    $("#setDeliverAddressButton").kendoButton({
    click: function(e) {
            console.log(vm.sameAsShipToAddress);
            if (vm.sameAsShipToAddress) {
                $("#deliverToAddress").attr("data-bind", "value: address");
                $("#deliverToAddress").val(vm.address);
            }
            else {
                $("#deliverToAddress").removeAttr("data-bind");
                $("#deliverToAddress").val("");
            }
        }
    });
  $("#triggerChangeButton").kendoButton({
    click: function(e) {
      kendo.bind(document.body, vm);
    }
  });
});

The HTML:

<input id="shipToAddress" data-bind="value: address" />

<input type="checkbox" 
           id="deliverSameAsShipTo" 
           value="deliverSameAsShipTo"
           data-bind="checked: sameAsShipToAddress" />

<input id="deliverToAddress" />
<button role="button" id="setDeliverAddressButton">set deliver address</button>

bidirectional update

Another option (or even you need to do this always) is to trigger the change programatically as described in this discussion: How to update the ViewModel after programatic changes.

Upvotes: 3

Related Questions