angular-ui / ui-grid

UI Grid: an Angular Data Grid
http://ui-grid.info
MIT License
5.39k stars 2.47k forks source link

Page selector with external pagination should not reload page with every keystroke #2518

Open bayy opened 9 years ago

bayy commented 9 years ago

Version: ui-grid - v3.0.0-RC.18-d9b2314 - 2015-01-06

screen shot 2015-01-08 at 1 41 01 pm

I have useExternalPagination set to true. With the current implementation, if I want to go to page 123, when I input 2 after 1, the page 12 is loaded, and then I can type in 3, which loads page 123.

I also have difficulty in loading page 23 directly, because I cannot just delete 1 and then put in 23 without triggering page reload. I have to go through reloading of page 1, 12, 2, and 23 to get to page 23.

Basically the problem is that the page should not be reloaded with every keystroke.

PaulL1 commented 9 years ago

@brianchance: any thoughts on this?

brianchance commented 9 years ago

Could use ngModelOptions and debounce, but that is a 1.3 only feature. Could supply your own pager template with it on if using 1.3.

Otherwise, I guess you would need to tab off, but that behavior may not be expected or use a custom directive to implement the debounce.

bayy commented 9 years ago

Maybe, a new button such as 'Go'/'Goto Page' can be added, and only when this button is clicked with a valid input number, the new page will be loaded. This may be better than the debounce solution, since with debounce with a timeout value, it is still possible that the page reload happens before the customer finishes entering the number.

Just a suggestion.

brianchance commented 9 years ago

This pager panel has an ng-model-options for debounce (250), add to an app.run. You will need the latest unstable release that merged paging and pagination. You could also use the ng-model-option updateOn: 'blur' so it updates when they tab off.

$templateCache.put('ui-grid/pagination',
  "<div class=\"ui-grid-pager-panel\" ui-grid-pager ng-show=\"grid.options.enablePaginationControls\"><div class=\"ui-grid-pager-container\"><div class=\"ui-grid-pager-control\"><button type=\"button\" ng-click=\"paginationApi.seek(1)\" ng-disabled=\"cantPageBackward()\"><div class=\"first-triangle\"><div class=\"first-bar\"></div></div></button> <button type=\"button\" ng-click=\"paginationApi.previousPage()\" ng-disabled=\"cantPageBackward()\"><div class=\"first-triangle prev-triangle\"></div></button> <input type=\"number\" ng-model=\"grid.options.paginationCurrentPage\" min=\"1\" ng-model-options=\"{ debounce: 250 }\" max=\"{{ paginationApi.getTotalPages() }}\" required> <span class=\"ui-grid-pager-max-pages-number\" ng-show=\"paginationApi.getTotalPages() > 0\">/ {{ paginationApi.getTotalPages() }}</span> <button type=\"button\" ng-click=\"paginationApi.nextPage()\" ng-disabled=\"cantPageForward()\"><div class=\"last-triangle next-triangle\"></div></button> <button type=\"button\" ng-click=\"paginationApi.seek(paginationApi.getTotalPages())\" ng-disabled=\"cantPageToLast()\"><div class=\"last-triangle\"><div class=\"last-bar\"></div></div></button></div><div class=\"ui-grid-pager-row-count-picker\"><select ng-model=\"grid.options.paginationPageSize\" ng-options=\"o as o for o in grid.options.paginationPageSizes\"></select><span class=\"ui-grid-pager-row-count-label\">&nbsp;{{sizesLabel}}</span></div></div><div class=\"ui-grid-pager-count-container\"><div class=\"ui-grid-pager-count\"><span ng-show=\"grid.options.totalItems > 0\">{{showingLow}} - {{showingHigh}} of {{grid.options.totalItems}} {{totalItemsLabel}}</span></div></div></div>"
);

If you wanted to add a button, bind the text box to a temporary model (say grid.options.tempPaginationCurrentPage), then use the paginationApi.seek(page) function in the onclick of the button, passing the temporary value.

npoirey commented 7 years ago

Another possibility until an option is added is doing something like that, less likely to break in my opinion. This update the grid on blur or "enter" keypress.

In an app.run

 //update the template cache so that we can trigger the pagination change only on enter or blur
 function updateGridPaginationTemplate(){
   var paginationTemplate = $templateCache.get('ui-grid/pagination');
   $templateCache.put('ui-grid/pagination',
     paginationTemplate.replace('class="ui-grid-pager-control-input"', 'class="ui-grid-pager-control- input" update-on-enter ng-model-options="{updateOn: \'blur\'}"'));
 }

and somewhere in your app declare the directive to update on enter:

angular.module('app').directive('updateOnEnter', function() {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attrs, ctrl) {
            element.bind("keyup", function(ev) {
                if (ev.keyCode == 13) {
                    ctrl.$commitViewValue();
                    scope.$apply(ctrl.$setTouched);
                }
            });
        }
    }
});