This is a migrated thread and some comments may be shown as answers.

prevent server call when Text and Value are the same

3 Answers 152 Views
ComboBox
This is a migrated thread and some comments may be shown as answers.
evyatar
Top achievements
Rank 1
evyatar asked on 20 Nov 2016, 10:17 AM

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

3 Answers, 1 is accepted

Sort by
0
Dimiter Topalov
Telerik team
answered on 22 Nov 2016, 09:57 AM
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.
0
evyatar
Top achievements
Rank 1
answered on 01 Dec 2016, 12:59 PM
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>
0
Dimiter Topalov
Telerik team
answered on 05 Dec 2016, 11:29 AM
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.
Tags
ComboBox
Asked by
evyatar
Top achievements
Rank 1
Answers by
Dimiter Topalov
Telerik team
evyatar
Top achievements
Rank 1
Share this question
or