Telerik Forums
Kendo UI for jQuery Forum
0 answers
129 views

I have this field in my kendo grid column :

field: "tauxAcquisEntree",
template: '#if (tauxAcquisEntree === 0){#'
                    + '<div class="text-right">#= tauxAcquisEntree #</div>'
                    + '# }else if (tauxAcquisEntree > 1 ){#'
                    + '<div class="d-flex justify-content-end"><div class="input-group d-flex flex-nowrap percent-input"> <input id="fraisent" name="fraisent" value="#= tauxAcquisEntree #" max="4"   class="form-control text-center"  min="1" type="number" step=1 pattern="[0-9]$" autocomplete="off"   /> </div></div>'
                    + '# }else{#'
                    + '<div id="fraisOne" name="fraisOne" class="d-flex justify-content-end"><div class="input-group d-flex flex-nowrap percent-input"> <input value="#= tauxAcquisEntree #" class="form-control text-center" max="1" min="1"  type ="number" pattern="[0-1]$" autocomplete="off" readonly  /> </div></div>'
                    + '# }#'
                ,

I have a condition when i get the field "tauxAcquisEntree" from the "database"  if it's equal to "1" the input type number becomes readonly.

The problem is when the user changes the value of the input type number in the front and it's equal to "1" the template condition gets triggered which is a behavior that i don't want to happen.

To summarize how can i get the if condition in the template to be applied only if the value if from backend or the database (and not what the user typed) ?

youssef
Top achievements
Rank 1
 updated question on 28 Jun 2023
0 answers
47 views

I'm using template binding to display a list of users.   For each user, we have a yes/no radio button and a drop down.  The options available in the drop down are dependent on the radio button.  If the user picks "yes" in the radio, we give them 4 options in the drop down, if they select no, we give them 2 options.

I created a view model that contains an array of users and for each user I have an array of the available options for the drop down. 

ex. viewModel= [{UserId: 1, RBValue: true, DropDownId: 3, DropDownOpts: [1,2,3,4]}, {UserId: 2, RBValue: false, DropDownId:1, DropDownOpts: [1,2]};

And then in my template I have a select  as such:

<select source: DropDownOpts, value: DropDownId"></select

When the radio is updated, I modify the DropDOwnOpts for that item.   

When the page loads, it works fine.   The appropriate options appear in the dropdown list, but when I modify the DropDownOpts in the viewmodel, I can see the update in the console, but the options do not change.

Am I missing something obvious here?  Or is this not possible (I'm sure I can do it via js, but would rather not).

Thanks for any help.

Scott
Top achievements
Rank 1
 asked on 27 Apr 2023
0 answers
100 views

When using the MVVM value binding with the DropDownTree, pressing the X button to clear the selection does not clear the bound field in the viewmodel.  If the DropDownTree is configured with valuePrimitive=true, then the VM bound field is completely unchanged  If the DropDownTree is configured with valuePrimitive=false, then the VM bound field is set to the string value of the prior selection's ID.

So my present workaround is to use valuePrimitive=false and if the VM bound field ends up being a string instead of an object, then treat it as null instead.  This adds a bunch of extra and ugly code to my app - is there any way to get the widget to simply set the bound VM field to null when the user clicks the X?

Bill
Top achievements
Rank 1
 updated question on 25 Nov 2022
0 answers
104 views

I'm specifically working with the scheduler, however I believe this applies to any MVVM items.

When double click an event in the scheduler, my editor template is rendered and Kendo binds this to the event being edited. This happens for "free" as I do not do this. Consider this element:

<div data-container-for="title">
   <input type="text" data-role="textbox" name="title" required="required" data-bind="value:title" />
</div>

The binding to title works perfectly fine and I see my value.

Next, my event has a CategoryId which tags the event and what it is. This is a property I have added. Let me point out that if I replace title above with CategoryId, the integer value of the category displays. So this value is known and part of the bound object. However, I am using a very custom templated dropdown for this.

<div data-container-for="CategoryId">
   <input id="CategoryId" data-bind="value: CategoryId, source: categoriesDataSource" data-role="dropdownlist" data-auto-width="true"
          data-header-template="categorySearchHeaderTemplate" data-template="categorySearchTemplate" data-text-field="Description"
          data-value-field="Id" data-auto-bind="false" />
</div>

Hopefully this makes sense. My categories have an Id and a Description. There is a list of them. The event has a CategoryId which holds the value of what category is selected. However this element has its own datasource! Note the data-bind.

// This datasource is created and then kendo.bind() is called to bind to my dropdown
var categoriesViewModel = kendo.observable({
   categoriesDataSource: new kendo.data.DataSource({
      data: jsonSerializedCategories
   })
});

This drop down works perfectly fine for templates and for the elements in it. See screenshot below. But the value binding does not work. This is obviously because I had to set my own datasource on it. The value is not found in that datasource; it's in the one Kendo generated and applied to the popup. What is the proper way to set this up? The value is in one datasource and the elements here are in the other one I created.

Paul
Top achievements
Rank 1
Iron
Iron
Veteran
 updated question on 17 Oct 2022
0 answers
456 views
Hi,

If you want to add formatting and parsing to kendo you have to override text binding in the framework. Add data-format and data-parser attribute bound element. The data-parser attribute is not required and will only be used if data-format attribute is present. So far I had no problem using it.
PS: data-parser attributes is only needed when underlying data is stored as string(s) apposed to native form. 

<li class="text-center" data-bind="text:date" data-format="MMM-yy" data-parser="date"><b></b></li>
<li> </li>
<li><a href="\#" data-bind="text:salary"></a></li>
<li><a href="\#" data-bind="text:overtime" data-format="N2"></a></li>

(function (f, define) {
    define(["kendo"], f);
})(function () {
 
    (function ($, undefined) {
 
        var kendo = window.kendo,
            binders = kendo.data.binders,
            Binder = kendo.data.Binder,
            toString = kendo.toString;
 
        var parsers = {
            "number": function (value) {
                return kendo.parseFloat(value);
            },
 
            "date": function (value) {
                return kendo.parseDate(value);
            },
 
            "boolean": function (value) {
                if (typeof value === "string") {
                    return value.toLowerCase() === "true";
                }
                return value != null ? !!value : value;
            },
 
            "string": function (value) {
                return value != null ? (value + "") : value;
            },
 
            "default": function (value) {
                return value;
            }
        };
 
        binders.text = Binder.extend({
            init: function (element, bindings, options) {
                //call the base constructor
                Binder.fn.init.call(this, element, bindings, options);
                this.jelement = $(element);
                this.format = this.jelement.attr("data-format");
                this.parser = parsers[this.jelement.attr("data-parser") || "default"];
            },
            refresh: function () {
                var text = this.bindings.text.get();
                if (text === null) {
                    text = "";
                }
                else if (this.format) {
                    text = toString(this.parser(text), this.format);
                }
                this.jelement.text(text);
            }
        });
 
    })(window.kendo.jQuery);
 
    return window.kendo;
}, typeof define == 'function' && define.amd ? define : function (_, f) { f(); });

Maxim
Top achievements
Rank 1
 asked on 29 Apr 2014
0 answers
88 views
I'm creating this thread as a way of soliciting ideas for getting the best performance I can out of the kendo MVVM framework (speed is King!).

One of the major problems I've encountered with this and other MVVM frameworks is that using dependent /calculated observable objects and functions can really slow down the client GUI. This is in part because of some rather verbose permissions and model states that are generally required in an "enterprise" HTML5/JavaScript. application. If a particular function on the observable references multiple values on the view model (using get), this can cause useless and extraneous executions of that function caused by other processes updating and changing the values on the model. The two best examples of this are loading the model with AJAX, and clearing the model; these two operations cause every single model value to change, which causes a lot of useless multiple executions and updates of calculated fields.

What suggestions might everyone have for increasing the performance of kendo MVVM?


Keith
Top achievements
Rank 1
 asked on 14 Mar 2014
0 answers
53 views
My controls are widgets, so if I define my template in the markup it appears twice on the page...

Is there a way with the MVVM that I can move the template out to my JS and still bind it?...like a data-bind="template: markup, source: data" or something?

Steve
sitefinitysteve
Top achievements
Rank 2
Iron
Veteran
 asked on 19 Nov 2012
0 answers
100 views
I was looking for a PRISM like InteractionRequest to use modal dialogs with Kendo UI MVVM. I could not find one and ended up creating one. I'll share it here as it would be great if it could be improved on or even adopted in the framework. It's usage is as follows:
<div style="display: none;"
    data-role="window"
    data-bind='interactionRequest: { path: editOpportunityInteractionRequest, template: editOpportunityTemplate }'
    data-title="Edit"
    data-modal="true"
    data-visible="false">
</div>
I created a custom binding called interactionRequest. You bind it to an InterationRequest object in your view model and you need to provide the id of a template that will be rendered in the window. An InteractionRequest has a raise method that you pass a view model to be bound to the window and returns a promise that will be resolved when a result is set on the view model. I'm using TypeScript for this.
import App = module("./DataContext");
import Interactivity = module("./InteractionRequest");
import Models = module("./Models");
import ViewModels = module("./EditOpportunityViewModel");
 
export class OpportunitiesViewModel extends kendo.data.ObservableObject {
 
    editOpportunityInteractionRequest = new Interactivity.InteractionRequest();
    dataContext: App.DataContext;
 
    constructor (dataContext: App.DataContext) {
        super();
        this.set("dataContext", dataContext);
    }
 
    onCustomCreate(e: JQueryEventObject) {
        e.preventDefault();
        var opportunity = new Models.Opportunity();
        this.dataContext.opportunities.insert(0, opportunity);
        var viewModel = new ViewModels.EditOpportunityViewModel(opportunity, this.dataContext);
        this.editOpportunityInteractionRequest.raise(viewModel).done((viewModel: ViewModels.EditOpportunityViewModel) => {
            if (!viewModel.result) {
                this.dataContext.opportunities.remove(viewModel.opportunity);
            }
        });
    }
 
    onCustomEdit(e: JQueryEventObject) {
        e.preventDefault();
        var opportunity = <Models.IOpportunityModel>e.data;
        var viewModel = new ViewModels.EditOpportunityViewModel(opportunity, this.dataContext);
        this.editOpportunityInteractionRequest.raise(viewModel).done(viewModel => {
            if (!viewModel.result) {
                this.dataContext.cancelChanges();
            }
        });
    }
}


The InteractionRequest itself is very simple:
/// <reference path="..\lib\jquery.d.ts"/>
/// <reference path="..\lib\kendo.web.d.ts"/>
 
export class InteractionRequest extends kendo.data.ObservableObject {
    promise: JQueryPromise;
     
    raise(viewModel: { result: any; }) {
        this.trigger("raise", viewModel);
        return this.promise;
    }
}
The raise method expects that the raise event it triggers is handled by the interactionRequest custom binding that will set the promise on the InteractionRequest so that it may be returned by the raise method.

This is the custom binding code (which is still in JavaScript)
kendo.data.binders.widget.interactionRequest = kendo.data.Binder.extend({
    init: function (element, bindings, options) {
        kendo.data.Binder.fn.init.call(this, element, bindings, options);
        var that = this,
            binding = bindings.interactionRequest;
        that.template = kendo.template($("#" + binding.path.template).html());
        that.resultHandler = function (e) {
            if (e.field === "result") {
                that.element.close();
            }
        };
        that.closeHandler = function () {
            that.viewModel.unbind("change", that.resultHandler);
            var widget = that.element,
                container = widget.element.find(".k-edit-form-container");
            kendo.destroy(container);
            that.deferred.resolve(that.viewModel);
        };
        that.element.bind("close", that.closeHandler);
    },
    refresh: function (attribute) {
        var that = this,
            binding = that.bindings.interactionRequest,
            source = binding.source.get(binding.path.path);
        if (that.previousSource) {
            that.previousSource.unbind("change", that.raiseHandler);
        }
        that.raiseHandler = function (e) {           
            that.deferred = new $.Deferred();
            source.promise = that.deferred.promise();
            if (e instanceof kendo.data.ObservableObject) {
                that.viewModel = e;
            } else {
                that.viewModel = kendo.observable(e);
            }
            that.viewModel.bind("change", that.resultHandler);
            var widget = that.element;
            widget.content('<div class="k-edit-form-container"></div');
            var container = widget.element.find(".k-edit-form-container");
            container.html(that.template(that.viewModel));
            that.viewModel.validator = container.kendoValidator().data("kendoValidator");
            kendo.bind(container, that.viewModel);
            widget.center().open();           
        };
        source.bind("raise", that.raiseHandler);
        that.previousSource = source;
    },
    destroy: function () {
        var that = this,
            binding = that.bindings.interactionRequest,
            source = binding.source.get(binding.path);
        that.element.unbind("close", that.closeHandler);
        if (that.raiseHandler) {
            source.unbind("raise", that.raiseHandler);
        }
    }
});

It will open the window when the InteractionRequest triggers its raise event. It will bind the view model passed to the raise method of the InteractionRequest to the template rendered in the window. When a result is set on this view model, the window is closed and the deferred is resolved. In my case I set the result to true when an update button is clicked and to false when a cancel button is clicked.
import App = module("./DataContext");
import Models = module("./Models");
 
export class EditOpportunityViewModel extends kendo.data.ObservableObject {
 
    result: bool;
    validator: kendo.ui.Validator;
 
    constructor (public opportunity: Models.IOpportunityModel, public dataContext: App.DataContext) {
        super();       
    }
 
    update(e: JQueryEventObject) {
        e.preventDefault();
 
        if (!this.validator.validate()) {
            return;
        }
 
        this.dataContext.sync().done(() => {
            this.set("result", true);
        });       
    }
 
    cancel(e: JQueryEventObject) {
        e.preventDefault();
        this.set("result", false);
    }
}


I specifically think the custom binding could be improved with regards to the specification of the template to be rendered in the window. Preferably I set a custom data-template option on the div, but this does not currently get  passed into the custom binding. I will also need to figure out how to trigger validation on the dialog before I set the dialog result to true. 
EDIT: added validation
Remco
Top achievements
Rank 1
 asked on 13 Nov 2012
0 answers
17 views
See attached...any idea what that would happen?

It's not a calculated property...I can browse to it in the firebug DOM tab and see it's value is 4

sitefinitysteve
Top achievements
Rank 2
Iron
Veteran
 asked on 25 Oct 2012
0 answers
35 views
Hello
when my data source fill from controller by default select one value fordeopdownlist and i set null for value of deopdownlist i dot want select any value.

$(document).ready(function () {
 
        var baseAddress = window.parent.document.location + "Home/";
        var viewModel = kendo.observable({
            userDataSource: new kendo.data.DataSource({
                transport: {
                    read: {
                        url: baseAddress + "GetUsers",
                        dataType: "json",
                    }
                }
            }),
            SelectedRole: null,
            SelectedUser: null,
            accessValue: null,
            Roles: [],
            Accesses: [],
 
        });

Mohammad
Top achievements
Rank 1
 asked on 14 Oct 2012
Narrow your results
Selected tags
Tags
+? more
Top users last month
Mark
Top achievements
Rank 1
Yurii
Top achievements
Rank 1
Leland
Top achievements
Rank 2
Iron
Iron
Iron
Hon
Top achievements
Rank 1
Iron
Deltaohm
Top achievements
Rank 3
Bronze
Iron
Iron
Want to show your ninja superpower to fellow developers?
Top users last month
Mark
Top achievements
Rank 1
Yurii
Top achievements
Rank 1
Leland
Top achievements
Rank 2
Iron
Iron
Iron
Hon
Top achievements
Rank 1
Iron
Deltaohm
Top achievements
Rank 3
Bronze
Iron
Iron
Want to show your ninja superpower to fellow developers?
Want to show your ninja superpower to fellow developers?