MVVM, remote templates and numeric textbox

4 posts, 1 answers
  1. Dorian
    Dorian avatar
    21 posts
    Member since:
    Nov 2013

    Posted 25 Mar 2014 Link to this post

    Hello!

    I'm having a problem considering binding min-max values of numeric textbox using kendo.data.ObservableObject or any attributes, etc.

    But before we dwell further on the problem here is my code:

    javascript: 
    001.var tab;
    002.var layout;
    003.var currnetInstances = 0;
    004.var mainWin = { "showTabs": true };
    005. 
    006.$(document).ready(function () {
    007.    tab = $("#tabstrip").kendoTabStrip({
    008.        animation: false
    009.    }).data("kendoTabStrip");
    010. 
    011.    $("#butt").kendoButton({
    012.        icon: "add",
    013.        click: function (e) {
    014.            openForm("myForm", "form-template-one", "Form: Ime in Priimek")
    015.        }
    016.    });
    017. 
    018.    $("#butt2").kendoButton({
    019.        icon: "add",
    020.        click: function (e) {
    021.            if (mainWin.showTabs == true) {
    022.                mainWin.showTabs = false;
    023.                $("#butt").val("Odpri v oknu");
    024.                 
    025.            }
    026.            else if (mainWin.showTabs == false) {
    027.                mainWin.showTabs = true;
    028.                $("#butt").val("Dodaj tab");
    029.            }
    030.             
    031.        }
    032.    });
    033.});
    034. 
    035.templateLoader.loadExtTemplate("views/templates.html");
    036. 
    037. 
    038. 
    039.function openForm(formId, formTemplateId, formName) {
    040.    var template = kendo.template($("#" + formTemplateId).html(), { useWithBlock: false });
    041.     
    042.    displayForm(formId, formTemplateId, formName, template);
    043.}
    044. 
    045.function displayForm(formId, formTemplateId, formName) {
    046.    ++currnetInstances;
    047. 
    048.    formId = formId + "_" + currnetInstances;
    049. 
    050.    if (mainWin.showTabs == true) {
    051.        tab.append(
    052.            {
    053.                text: formName,
    054.                encoded: false,                             // Allows use of HTML for item text
    055.                content: "<div id='" + formId + "'></div>"
    056.            }
    057.        );
    058. 
    059.        tab.activateTab($("#tabstrip .k-last"));
    060.    }
    061.    else if (mainWin.showTabs == false) {
    062.        $(document.body).prepend("<div id='" + formId + "'></div>");
    063.        var win = $("#" + formId).kendoWindow({
    064.            animation: false,
    065.            width: 400,
    066.            height:400,
    067.            title: formName,
    068.            visible: false
    069.        }).data("kendoWindow");
    070. 
    071.        win.center();
    072.        win.open();
    073.    }
    074. 
    075.    if (typeof(layout == "undefined")) {
    076.        layout = new kendo.Layout(formTemplateId);
    077.    }
    078. 
    079.    var formModel = new kendo.data.ObservableObject({
    080.        id1: "k-textbox",
    081.        id2: "k-textbox",
    082.        id3: "k-textbox",
    083.        labelValue1: "ime",
    084.        labelValue2: "priimek",
    085.        labelValue3: "ime in priimek",
    086.        value1: "",
    087.        value2: "",
    088.        combined: function (e) {
    089.            return this.get("value1") + " " + this.get("value2");
    090.        },
    091.        numericBG: function (e) {
    092.            return "green";
    093.        },
    094.        numericVal: -2,
    095.        knumeric_class: function (e) {
    096.            if (parseInt(this.get("numericVal")) < 0) {
    097.                return "numeric_negative"
    098.            }
    099.            else {
    100.                return "numeric_positive"
    101.            }
    102.        },
    103.        numChange: function (e) {
    104.            this.knumeric_class();
    105.        },
    106.        num: function () { return 15;}
    107.    })
    108.     
    109.    formModel.bind("change", function (e) {
    110.        var varia = formModel.toJSON();
    111.        console.log(varia);
    112.    });
    113. 
    114.    layout.render("#" + formId);
    115. 
    116.    kendo.bind($("#" + formId), formModel);
    117.}

    templates html:
    01.<script type="text/x-kendoui-template" id="form-template-one" data-use-with-blocks="false">
    02.    <div class='form'>
    03.        <label style='display:inline-block;width:160px;line-height:30px;' data-bind='attr: {for: id1}, text: labelValue1'"></label><br />
    04.        <input class='' data-bind="attr: {class: id1}, value: value1">
    05.        <br /><br />
    06. 
    07.        <label style='display:inline-block;width:160px;line-height:30px;' data-bind='attr: {for: id2}, text: labelValue2'"></label><br />
    08.        <input class='' data-bind="attr: {class: id2}, value: value2">
    09.        <br /><br />
    10. 
    11.        <label style='display:inline-block;width:160px;line-height:30px;' data-bind='attr: {for: id3}, text: labelValue3'"></label><br />
    12.        <input class='' data-bind="attr: {class: id3}, value: combined" ><br />
    13.         
    14.        <div data-bind="attr: {class: knumeric_class}">
    15.            <label style='display:inline-block;width:160px;line-height:30px;'  data-bind='attr: {for: id3}, text: labelValue3'"></label><br />
    16.             
    17.            <input data-role="numerictextbox" data-bind="value: numericVal"  data-spinners="false" style='text-indent:-5px;'>
    18.             
    19.        </div>
    20.    </div>
    21.</script>

    As seen from the examples I load my template from a remote file, then I use layout to write it to DOM in its proper place.
    Now the problem is that I cant use the # based syntax in the template as it's simply not executing (not event the alerts, console log or anything else) and I would need to use the kendo.data.observableobject to bind the appropriate data into widgets since the templates should be reusable, everything else is of course set through the observable which in turn is generated on per case basis.

    So to clarify my question again: how to bind numeric textbox values for min and max (and possibly attr which it actively refuses to do so) using remote templates and the observableobject.
  2. Petyo
    Admin
    Petyo avatar
    2438 posts

    Posted 27 Mar 2014 Link to this post

    Hello Dorian,

    you are raising a valid concern here - the view/layout templates should support # based expressions - this is in our pipeline. A workaround I may suggest is to use the source: this binding approach to enable them - please check this jsbin for more details.

    Regards,
    Petyo
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  3. Kendo UI is VS 2017 Ready
  4. Dorian
    Dorian avatar
    21 posts
    Member since:
    Nov 2013

    Posted 27 Mar 2014 in reply to Petyo Link to this post

    Resolved the issue somewhat by extending the widget: 
    kendo.data.binders.widget.max = kendo.data.Binder.extend({
                init: function (widget, bindings, options) {
                    //call the base constructor
                    kendo.data.Binder.fn.init.call(this, widget.element[0], bindings, options);
                },
                refresh: function () {
                    var that = this,
                    value = that.bindings["max"].get(); //get the value from the View-Model
                    $(that.element).data("kendoRcgNumeric").max(value); //update the widget
                }
    });

    Now with this resolved in a manner that works for us I have yet another question.
    How do I trigger the widget methods when using pure MVVM approach (no javascript declaration of the widgets).

    For example I would like to trigger the focus method of some chosen numeric textbox in a form created and displayed via MVVM approach (using no selectors, no javascript widget invocation, etc.). Is it even possible to access that?
  5. Answer
    Petyo
    Admin
    Petyo avatar
    2438 posts

    Posted 28 Mar 2014 Link to this post

    Hi Dorian,

    Your custom binding approach is a feasible one - in fact, it is quite a "clean" one.

    Regarding your second question - the view model object should serve as an abstraction over the data presented in the view, so that the rest of your code should not bother with the specifics of the DOM structure or the widgets.

    I am not sure that the widget methods should be abstracted by the view model object, though - its primary purpose would be abstract and maintain the two way bindings over a given data structure. Focusing a form field or displaying a certain item should be handled by a controller in response to a certain event (user interaction or network event, for example).

    Thus being said, any method abstraction may be implemented with a custom binding on top of it, in a similar manner to the one you have posted below.

    Regards,
    Petyo
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
Back to Top
Kendo UI is VS 2017 Ready