prevent server call when Text and Value are the same

4 posts, 0 answers
  1. evyatar
    evyatar avatar
    2 posts
    Member since:
    Nov 2016

    Posted 20 Nov 2016 Link to this post

    I have a server side service that returns json that looks like [{appID:"11"},{appID:"22"}]

    In this case the text and values are the same.

    When I am doing a call to "value" function I see that a data is fetched from the server.

    var combobox = $("#combobox").data("kendoComboBox");

    combobox.value("11");

    Why a call to server is required in case that the text and value are the same?

    Is there a way to set the value without a need to fetch data from the server?

     

    thanks,

    Evyatar

  2. Dimiter Topalov
    Admin
    Dimiter Topalov avatar
    578 posts

    Posted 22 Nov 2016 Link to this post

    Hi Evyatar,

    As described in the API reference for the value() method of the Kendo UI ComboBox, a request will be triggered under the following circumstances:

    1) The widget is not bound (autoBind: false, and no user actions that would trigger binding have been performed yet)

    2) A filter has been applied

    http://docs.telerik.com/kendo-ui/api/javascript/ui/combobox#methods-value

    You can avoid the request by calling the value() method only when the value to be set is different than the current one, e.g.:

    var cb = $('#combobox').data('kendoComboBox');
    ...
    if(cb.text() !== '11'){
      cb.value('11');
    }

    Regards,
    Dimiter Topalov
    Telerik by Progress
    Kendo UI is ready for Visual Studio 2017 RC! Learn more.
  3. evyatar
    evyatar avatar
    2 posts
    Member since:
    Nov 2016

    Posted 01 Dec 2016 in reply to Dimiter Topalov Link to this post

    Hi Dimiter

    I don't understand what is the different between cb.value('11') to cb.text('11')

    In the code sample I use only cb.text and its looks ok 

    <!DOCTYPE html>
    <html>
    <head>
        <base href="//demos.telerik.com/kendo-ui/grid/angular">
        <style>html { font-size: 14px; font-family: Arial, Helvetica, sans-serif; }</style>
        <title></title>
        <link rel="stylesheet" href="//kendo.cdn.telerik.com/2016.3.1118/styles/kendo.common-material.min.css" />
        <link rel="stylesheet" href="//kendo.cdn.telerik.com/2016.3.1118/styles/kendo.material.min.css" />
        <link rel="stylesheet" href="//kendo.cdn.telerik.com/2016.3.1118/styles/kendo.material.mobile.min.css" />
        <script src="//kendo.cdn.telerik.com/2016.3.1118/js/jquery.min.js"></script>
        <script src="//kendo.cdn.telerik.com/2016.3.1118/js/angular.min.js"></script>
        <script src="//kendo.cdn.telerik.com/2016.3.1118/js/kendo.all.min.js"></script>
    </head>
    <body>
    <div id="example" ng-app="KendoDemos">
        <div ng-controller="MyCtrl">
            <kendo-grid options="mainGridOptions" k-on-edit="onGridCellEdit(kendoEvent)" k-on-change="onGridChange({ selected: selected,data: data  })">
            </kendo-grid>
            <form>
                <vf-combobox vf-service="https://portal/api/privateApplications/deduplication"
                              vf-value-field="appID"
                              vf-text-field="appID"
                              ng-model="vfCurrentGridRow.appID"
                /> <br>
            </form>
            <p>
                {{vfCurrentGridRow | json}}
            </p>
        </div>
    </div>
    <style>
        .contact-info-form {
            list-style-type: none;
            margin: 30px 0;
            padding: 0;
        }
        .contact-info-form li {
            margin: 10px 0;
        }
        .contact-info-form label {
            display: inline-block;
            width: 100px;
            text-align: right;
            font-weight: bold;
        }
    </style>
    <script>
        Combobox.$inject = ['$http'];
        function Combobox($http) {
            function ComboboxFactory(element, updateModel, vfTextField, vfValueField, vfWhere ,service, initValue){
                var vm = this;
                vm.updateModel = updateModel;
                vm.setValue = setValue;
                vm.getValue = getValue;
                vm.setText = setText;
                vm.enable = enable;
                var combobox = init();
                function setValue(value){
                    combobox.value(value);
                }
                function getValue(){
                    combobox.value();
                }
                function setText(value){
                    combobox.text(value);
                }
                function enable(value){
                    combobox.enable(value);
                }
                function init(){
                    var model = { id: vfTextField, fields: {} };
                    model.fields[vfTextField] ={editable: false, nullable: true};
                    model.fields[vfValueField] ={editable: false, nullable: true};
                    var ddlDataSource = new kendo.data.DataSource({
                        autoSync: true,
                        serverFiltering: true,
                        pageSize : 20,
                        serverPaging : true,
                        schema: {
                            model: model,
                            total: function (response) {
                                return vm.count;
                            },
                            parse: function (data, type) {
                                if (data.data.entities) {
                                    vm.count = data.metadata.count;
                                    return data.data.entities;
                                } else {
                                    vm.count = 1;
                                    return data.data;
                                }
                            }
                        },
                        transport: {
                            parameterMap: function (data, type) {
                                debugger;
                                console.dir(data);
                                var field;
                                var value;
                                try {
                                    field = data.filter.filters[0].field;
                                    value = data.filter.filters[0].value;
                                }
                                catch(err) {
                                    //value = ngModelController.$viewValue;
                                    //field = $scope.vfValueField;
                                }
                                var result="";
                                if (field && value){
                                    result= field+"="+encodeURIComponent("%"+value+"%")
                                }
                                if (vfWhere){
                                    var where = vfWhere({row:{}});
                                    if (where){
                                        if (where.field && where.value){
                                            result+= where.field+"="+encodeURIComponent(where.value)
                                        }
                                    }
                                }
                                return result;
                            },
                            read:{
                                url: function (data) {
                                    var resultUrl = service;
                                    return resultUrl;
                                },
                                dataType: 'json',
                                complete: function (jqXHR, textStatus) {
                                }
                            },
                        },
                        error: function (e) {
                            if (e.xhr.status == 401) {
                                window.location = "/";
                                return;
                            }
                            if (e.xhr.status == 403) {
                                return;
                            }
                        }
                    });
                    var coptions = {
                        autoBind: false,
                        placeholder: "Select an Item",
                        filter: 'contains',
                        suggest: false,
                        delay: 0,
                        minLength: 1,
                        dataSource: ddlDataSource,
                        dataTextField: vfTextField,
                        dataValueField: vfValueField,
                        valuePrimitive: true,
                        change: function(kendoEvent) {
                            var value = this.value();
                            // Use the value of the widget
                            updateModel(value);
                        },
                        dataBound: function (e) {
                            if (angular.isDefined(initValue) && initValue){
                                e.sender.text(initValue);
                            }
                        },
                    }
                    var template = '<input data-text-field="'+vfTextField+'" data-value-field="'+vfValueField+'" data-bind="value:'+vfValueField+'" />'
                    var el = angular.element(template);
                    //var combobox = element.append(el).kendoComboBox(coptions).data("kendoComboBox");
                    var combobox = el.appendTo(element).kendoComboBox(coptions).data("kendoComboBox");
                    return combobox;
                }
                return vm;
            }
            return ComboboxFactory;
        }
        function vfCombobox() {
            var directive = {
                scope: {
                    'vfService': '@',
                    'vfTextField': '@',
                    'vfValueField': '@',
                    'vfWhere': '&',
                    value: '=ngModel'
                },
                require: 'ngModel',
                restrict     : 'EA',
                controller   : controller,
                controllerAs : 'vm',
                link         : link,
                bindToController: true
            };
            return directive;
        }
        controller.$inject = ['$scope', '$rootScope' ,'Combobox'];
        function controller($scope, $rootScope, Combobox ) {
            this.Combobox = Combobox;
        }
        function link($scope, element, attrs, ctrl) {
            var ngModelController = ctrl;
            $scope.combobox = new $scope.vm.Combobox(element,
                function(value){
                    ngModelController.$setViewValue(value);
                },
                $scope.vm.vfTextField,
                $scope.vm.vfValueField,
                $scope.vm.vfWhere,
                $scope.vm.vfService
            );
            ngModelController.$render = function() {
                console.log("$render")
                var value = ngModelController.$viewValue;
                if (value!="" && value) {
                   $scope.combobox.setText(value);
                }
            };
        }
        angular.module("KendoDemos", [ "kendo.directives" ])
            .factory('Combobox', Combobox)
            .directive('vfCombobox', vfCombobox)
            .controller("MyCtrl", function($scope, Combobox){
                var vm = $scope;
                $scope.vfCurrentGridRow = $scope.vfCurrentGridRow || {};
                $scope.onGridChange = function (changeData) {
                    //$scope.vfCurrentGridRow = changeData.data;
                }
                $scope.onGridCellEdit = function (changeData) {
                    $scope.vfCurrentGridRow = changeData.model;
                }
                $scope.changeRowEnd = function (model) {
                    //$scope.vfCurrentGridRow = model;
                }
                var model = { id: "guid", fields: {} };
                model.fields["appID"] ={editable: true, nullable: true};
                model.fields["appVersion"] ={editable: true, nullable: true};
                model.fields["status"] ={editable: true, nullable: true};
                model.fields["type"] ={editable: true, nullable: true};
                model.fields["value"] ={editable: true, nullable: true};
                $scope.mainGridOptions = {
                    editable:true,
                    dataSource: {
                        transport: {
                            read:{
                                url: function (data) {
                                    var resultUrl = "https://portal/api/activationStates?&limit=5&offset=0";
                                    return resultUrl;
                                },
                                dataType: 'json',
                                complete: function (jqXHR, textStatus) {
                                }
                            }
                        },
                        schema: {
                            model: model,
                            total: function (response) {
                                return vm.count;
                            },
                            parse: function (data, type) {
                                if (data.data.entities) {
                                    vm.count = data.metadata.count;
                                    return data.data.entities;
                                } else {
                                    vm.count = 1;
                                    return data.data;
                                }
                            }
                        },
                        pageSize: 5,
                        serverPaging: true,
                        serverSorting: true
                    },
                    sortable: true,
                    pageable: true,
                    toolbar: ["create"],
                    columns: [{
                        field: "appID",
                        title: "appID",
                        width: "120px",
                        editor : function (container, options) {
                            $scope.cb = $scope.cb || {};
                            $scope.cb[options.field] = new Combobox(container,
                                function(value){
                                    $scope.$apply(function(){
                                        $scope.vfCurrentGridRow[options.field] = value;
                                    });
                                },
                                "appID",
                                "appID",
                                null,
                                "https://portal/api/privateApplications/deduplication"
                            );
                        }
                    }]
                };
            })
    </script>
    </body>
    </html>
  4. Dimiter Topalov
    Admin
    Dimiter Topalov avatar
    578 posts

    Posted 05 Dec 2016 Link to this post

    Hello Evyatar,

    The difference between the text() and value() methods is that when the widget is still not bound, the former will just update the selected text, and the widget will stay unbound:

    http://docs.telerik.com/kendo-ui/api/javascript/ui/combobox#methods-text

    ... while the value() method will trigger a data service call, as described in its API reference:

    http://docs.telerik.com/kendo-ui/api/javascript/ui/combobox#methods-value

    Regards,
    Dimiter Topalov
    Telerik by Progress
    Kendo UI is ready for Visual Studio 2017 RC! Learn more.
Back to Top