Search bar For Kendo ui Grid (Kendo ui builder, Kuib designer) How to Avoid duplicate values in Database - Forum - Kendo UI Builder by Progress: OpenEdge Edition - Progress Community

Search bar For Kendo ui Grid (Kendo ui builder, Kuib designer) How to Avoid duplicate values in Database

 Forum

Search bar For Kendo ui Grid (Kendo ui builder, Kuib designer) How to Avoid duplicate values in Database

This question is answered

Hello all, i would like to add Search bar to my Grid, which will search in all row, i know how to do it with separate columns but do not wish to have 20 search bar on every column, is it possible to migrate that bar and make one above the grid which will work for everything.

is it possible to avoid duplicate entries in grid? for example name, if user enters name of the column which allready exists she/he have to get error message that such "firm" with such name allready exists.

i'm working with Kuib 1.1 and Openedge 11.6

sorry that i did not provided any code example, im completly enw in this and will much appricate any support from you.

Sincerely: giorgi

Verified Answer
  • Hello,

    It looks like the validator is not called when clicking "Update" to save the row.

    The validator is called when switching fields but not when saving.

    Is this the behavior that you are seeing?

    I would need to check with the Kendo UI team to know if there is an option that ensures that validator is called on save.

    We might need to handle this issue via Technical Support.

    Here is a possible workaround.

    The idea of the workaround is to override the Edit/Update button to call validate().

    I preferred to override the existing Edit/Update button instead of creating my own. In that way, I am preserving the behavior  of switching of the button.

    Perhaps, it might be better to create your own button using code like the following:

        $scope.grid0.options.columns[3].command[0] = {text: "Edit", click: validateRow };

    The workaround uses a function called "bindEvent" to simplify the logic of using $scope.$watch() to watch for when the buttons become available so we can bind a new function to the click event.

    This is a very specific case.

    As mentioned in a previous post. It might be better to wrap this code into a function and move it (along with the support functions) to another .js file so that you can update this functionality with ease in the future. If you have a different implementation.

    Please let me know how it goes.

    Thanks.

    P.S.: As a bonus, the code also includes, in a comment, a sample code to display a field using a drop down list within the grid.

                   onShow: function ($scope, customData) {

                       var that = this;

                       this.scope = $scope;

    /*                    

                       //$scope.grid0.options.editable = true;

                       $scope.grid0.options.columns[2].editor = function (container, options) {

                           angular.element('<input required data-text-field="RepName" data-value-field="SalesRep" data-bind="value:SalesRep"/>')

                               .appendTo(container)

                               .kendoDropDownList({

                                   autoBind: true,

                   dataSource: $scope._$ds.SalesrepDS.options

                               });

                       };

    */

                       function bindEvent(repeat, selector, event, override, fn) {

                           var cancelWatch = $scope.$watch(function () {

                               return angular.element(selector).length;

                           }, function (length, oldValue) {

                               if (length > 0) {

                                   var elements = angular.element(selector);

                                   if (override) {

                                       elements.off(event);

                                   }

                                   elements.on(event, fn);

                                   if (!repeat) {

                                       cancelWatch();

                                   }

                               }

                           });

                       }

                       function validateRow(e) {

                           var gridElement = angular.element("#grid0"),

                               validator = gridElement.data("kendoValidator");

                           e.preventDefault();

                           e.stopPropagation();

                           if (validator.validate()) {

                               gridElement.data("kendoGrid").saveRow();

                           }

                       }

                       $scope.grid0.options.columns[1].editor = function (container, options) {

                           angular.element('<input required name="Name" data-bind="value:Name" style="color:black"/>').appendTo(container);

                       };

                       $scope.$on('kendoWidgetCreated', function (event, widget) {

                           var gridElement = angular.element("#grid0");

                           if (event.targetScope.vm.widget === widget) {

                               bindEvent(false, ".k-grid-add", "click", false, function () {

                                   bindEvent(false, ".k-grid-update", "click", true, validateRow);

                               });

                               bindEvent(true, ".k-grid-edit", "click", false, function () {

                                   bindEvent(false, ".k-grid-update", "click", true, validateRow);

                               });

                               gridElement.kendoValidator({

                                   messages: {

                                       Name: "A record with the specified Name already exists"

                                   },

                                   rules: {

                                       Name: function (input) {

                                           if (input.is("[Name]") && input.val() !== "") {

                                               var dataSource = new kendo.data.DataSource({});

                                               dataSource.data(gridElement.data("kendoGrid").dataSource.data());

                                               dataSource.filter({field: "Name", operator: "equals", value: input.val()});

                                               return dataSource.view().length <= 1;

                                           }

                                           return true;

                                       }

                                   }

                               });

                           }

                       });

                   },

All Replies
  • Hello Giorgi,

    For the Search bar question, you might want to check the grid-external-filtering sample.

    Source code: github.com/.../kendo-ui-builder-samples

    Demo: oemobiledemo.progress.com/.../grid-external-filtering

    Regarding avoiding duplicate entries in the grid.

    A possible way is to use the support in the OpenEdge backend / Business Entity.

    When a new record is saved, the request goes to the server which then can validate whether the record is a duplicate and return the error.

    Are you using a pre-defined template or the Blank view option?

    I hope this helps,

    Edsel

  • thanks a lot egarcia for your answer, i will check the provided link, yes i am using blank view, managed to use combobox as search box, and it works, but could not find anything abour duplicate values in grid. thanks again for your time and effort and sorry for late feedback

  • i would like to avoid duplicate values on client side,

  • Hello Giorgi,

    There may be multiple ways to validate for duplicates.

    Here is a sample code for a view created using the Blank view option.

    Considering that you may need to use this logic in several views, it might be useful to wrap this code into a function (or a class) and put it in a separate JavaScript file. Also, if you need to adjust the logic in the future, then it would be easier since you would only update it in one place.

    The general idea is to use the kendoValidator() and specify a rule.

    Optionally, you can also use an editor for the field if you want to use the "required" option.

    To validate for duplicate records, you can use data() to get an array with the local data and create a new DataSource so that you can use the filter() method and query how many records match the specified field.

    I hope this helps,

    Edsel

                   onShow: function ($scope, customData) {

                       var that = this;

                       this.scope = $scope;

                       ...

    //                    $scope.grid0.options.columns[1].editor = function (container, options) {

    //                        angular.element('<input required name="Name" data-bind="value:Name" style="color:black"/>').appendTo(container);

    //                    };

                       $scope.$on('kendoWidgetCreated', function (event, widget) {

                           if (event.targetScope.vm.widget === widget) {

                               angular.element("#grid0").kendoValidator({

                                   messages: {

                                       Name: "A record with the specified Name already exists"

                                   },

                                   rules: {

                                       Name: function (input) {

                                           if (input.is("[Name]") && input.val() !== "") {

                                               var dataSource = new kendo.data.DataSource({});

                                               dataSource.data(angular.element("#grid0").data("kendoGrid").dataSource.data());

                                               dataSource.filter({field: "Name", operator: "equals", value: input.val()});

                                               return dataSource.view().length <= 1;

                                           }

                                           return true;

                                       }

                                   }

                               });

                           }

                       });

                      ...

                   },

  • Followed your advice, but i'm still able to enter duplicate value in Name field, when i uncommented

    //                    $scope.grid0.options.columns[1].editor = function (container, options) {

    //                        angular.element('<input required name="Name" data-bind="value:Name" style="color:black"/>').appendTo(container);

    //      

    this part of code ADD new record button has been disabled. started to enter information automaticaly without information, empty field.

  • Hello,

    It looks like the validator is not called when clicking "Update" to save the row.

    The validator is called when switching fields but not when saving.

    Is this the behavior that you are seeing?

    I would need to check with the Kendo UI team to know if there is an option that ensures that validator is called on save.

    We might need to handle this issue via Technical Support.

    Here is a possible workaround.

    The idea of the workaround is to override the Edit/Update button to call validate().

    I preferred to override the existing Edit/Update button instead of creating my own. In that way, I am preserving the behavior  of switching of the button.

    Perhaps, it might be better to create your own button using code like the following:

        $scope.grid0.options.columns[3].command[0] = {text: "Edit", click: validateRow };

    The workaround uses a function called "bindEvent" to simplify the logic of using $scope.$watch() to watch for when the buttons become available so we can bind a new function to the click event.

    This is a very specific case.

    As mentioned in a previous post. It might be better to wrap this code into a function and move it (along with the support functions) to another .js file so that you can update this functionality with ease in the future. If you have a different implementation.

    Please let me know how it goes.

    Thanks.

    P.S.: As a bonus, the code also includes, in a comment, a sample code to display a field using a drop down list within the grid.

                   onShow: function ($scope, customData) {

                       var that = this;

                       this.scope = $scope;

    /*                    

                       //$scope.grid0.options.editable = true;

                       $scope.grid0.options.columns[2].editor = function (container, options) {

                           angular.element('<input required data-text-field="RepName" data-value-field="SalesRep" data-bind="value:SalesRep"/>')

                               .appendTo(container)

                               .kendoDropDownList({

                                   autoBind: true,

                   dataSource: $scope._$ds.SalesrepDS.options

                               });

                       };

    */

                       function bindEvent(repeat, selector, event, override, fn) {

                           var cancelWatch = $scope.$watch(function () {

                               return angular.element(selector).length;

                           }, function (length, oldValue) {

                               if (length > 0) {

                                   var elements = angular.element(selector);

                                   if (override) {

                                       elements.off(event);

                                   }

                                   elements.on(event, fn);

                                   if (!repeat) {

                                       cancelWatch();

                                   }

                               }

                           });

                       }

                       function validateRow(e) {

                           var gridElement = angular.element("#grid0"),

                               validator = gridElement.data("kendoValidator");

                           e.preventDefault();

                           e.stopPropagation();

                           if (validator.validate()) {

                               gridElement.data("kendoGrid").saveRow();

                           }

                       }

                       $scope.grid0.options.columns[1].editor = function (container, options) {

                           angular.element('<input required name="Name" data-bind="value:Name" style="color:black"/>').appendTo(container);

                       };

                       $scope.$on('kendoWidgetCreated', function (event, widget) {

                           var gridElement = angular.element("#grid0");

                           if (event.targetScope.vm.widget === widget) {

                               bindEvent(false, ".k-grid-add", "click", false, function () {

                                   bindEvent(false, ".k-grid-update", "click", true, validateRow);

                               });

                               bindEvent(true, ".k-grid-edit", "click", false, function () {

                                   bindEvent(false, ".k-grid-update", "click", true, validateRow);

                               });

                               gridElement.kendoValidator({

                                   messages: {

                                       Name: "A record with the specified Name already exists"

                                   },

                                   rules: {

                                       Name: function (input) {

                                           if (input.is("[Name]") && input.val() !== "") {

                                               var dataSource = new kendo.data.DataSource({});

                                               dataSource.data(gridElement.data("kendoGrid").dataSource.data());

                                               dataSource.filter({field: "Name", operator: "equals", value: input.val()});

                                               return dataSource.view().length <= 1;

                                           }

                                           return true;

                                       }

                                   }

                               });

                           }

                       });

                   },

  • sorry for late answer, thanks alot for your time and support, finally it is working

  • one more question, does this code need any html