public inbox for [email protected]  
help / color / mirror / Atom feed
From: Aditya Toshniwal <[email protected]>
To: pgadmin-hackers <[email protected]>
Cc: Akshay Joshi <[email protected]>
Subject: Re: [pgAdmin][RM5038] Select2 enhancement - Load items on demand (scroll)
Date: Fri, 3 Jan 2020 15:13:04 +0530
Message-ID: <CAM9w-_nU8m_LbFaCvLzYnrepM+Y1RGbAT8xQaMucWxm=3cuaNg@mail.gmail.com> (raw)
In-Reply-To: <CANxoLDcumo3DLJbVuz_dFXFdStS+AtPqUdCZA_kJ9=6K8qBZfg@mail.gmail.com>
References: <CAM9w-_nEN_PK4Mn+9hyLz-ZC2MGp1XGDjx-1L0J=TCQOOUfxBQ@mail.gmail.com>
	<CANxoLDcumo3DLJbVuz_dFXFdStS+AtPqUdCZA_kJ9=6K8qBZfg@mail.gmail.com>

Hi Hackers,

The previous patch broke the tags and tokenizer options of select2. Turned
out, with the change of data adapter we also need to configure adapters for
tags, tokenizer and others.
Attached is the patch to set those to the default available in select2.
I've also renamed onDemandLoad to showOnScroll to avoid confusion as we are
showing the already present data on scroll and not loading the data on
demand from ajax.

Kindly review.

On Wed, Jan 1, 2020 at 11:25 AM Akshay Joshi <[email protected]>
wrote:

> Thanks, patch applied.
>
> On Tue, Dec 24, 2019 at 1:01 PM Aditya Toshniwal <
> [email protected]> wrote:
>
>> Hi Hackers,
>>
>> Attached is the patch to enhance select2 used in pgAdmin. The select2
>> dropdown will show only a few items when opened initially. On scrolling it
>> will show others. Searching will work as before. This will reduce the
>> number of DOM nodes on page.
>> Note that, individual controls can disable the behaviour if desired by
>> passing onDemandLoad:false for select2 options. It is enabled by default.
>>
>> Kindly review.
>>
>> --
>> Thanks and Regards,
>> Aditya Toshniwal
>> pgAdmin Hacker | Sr. Software Engineer | EnterpriseDB India | Pune
>> "Don't Complain about Heat, Plant a TREE"
>>
>
>
> --
> *Thanks & Regards*
> *Akshay Joshi*
>
> *Sr. Software Architect*
> *EnterpriseDB Software India Private Limited*
> *Mobile: +91 976-788-8246*
>


-- 
Thanks and Regards,
Aditya Toshniwal
pgAdmin Hacker | Sr. Software Engineer | EnterpriseDB India | Pune
"Don't Complain about Heat, Plant a TREE"


Attachments:

  [application/octet-stream] RM5038.part2.patch (8.1K, 3-RM5038.part2.patch)
  download | inline diff:
diff --git a/web/pgadmin/browser/static/js/node.ui.js b/web/pgadmin/browser/static/js/node.ui.js
index 6e5060791..23c0d9195 100644
--- a/web/pgadmin/browser/static/js/node.ui.js
+++ b/web/pgadmin/browser/static/js/node.ui.js
@@ -93,57 +93,6 @@ define([
     );
   });
 
-  /* Define on demand loading of dropdown items.
-   * This also requires ajax option of select2 to be set.
-   * The trick is, ajax: {} will also work even if you're actually not
-   * using ajax.
-   */
-  $.fn.select2.amd.define('select2/onDemandDataAdapter', [
-    'select2/utils',
-    'select2/data/select',
-  ], function (Utils, SelectAdapter) {
-
-    function onDemandDataAdapter ($element, options) {
-      this.$element = $element;
-      this.options = options;
-    }
-    Utils.Extend(onDemandDataAdapter, SelectAdapter);
-    onDemandDataAdapter.prototype.query = function (params, callback) {
-      var data = [];
-      var self = this;
-      if (!params.page) {
-        params.page = 1;
-      }
-      var pageSize = 20;
-
-      var $options = this.$element.children();
-      $options.each(function () {
-        var $option = $(this);
-
-        if (!$option.is('option') && !$option.is('optgroup')) {
-          return;
-        }
-
-        var option = self.item($option);
-
-        var matches = self.matches(params, option);
-
-        if (matches !== null) {
-          data.push(matches);
-        }
-      });
-
-      callback({
-        results: data.slice((params.page - 1) * pageSize, params.page * pageSize),
-        pagination: {
-          more: data.length >= params.page * pageSize,
-        },
-      });
-    };
-
-    return onDemandDataAdapter;
-  });
-
   /*
    * NodeAjaxOptionsControl
    *   This control will fetch the options required to render the select
diff --git a/web/pgadmin/static/js/backform.pgadmin.js b/web/pgadmin/static/js/backform.pgadmin.js
index c53be832c..867d0a681 100644
--- a/web/pgadmin/static/js/backform.pgadmin.js
+++ b/web/pgadmin/static/js/backform.pgadmin.js
@@ -10,10 +10,10 @@
 define([
   'sources/gettext', 'underscore', 'jquery',
   'backbone', 'backform', 'backgrid', 'codemirror', 'sources/sqleditor_utils',
-  'sources/keyboard_shortcuts', 'sources/window',
+  'sources/keyboard_shortcuts', 'sources/window', 'sources/select2/configure_show_on_scroll',
   'spectrum', 'pgadmin.backgrid', 'select2', 'bootstrap.toggle',
 ], function(gettext, _, $, Backbone, Backform, Backgrid, CodeMirror,
-  SqlEditorUtils, keyboardShortcuts, pgWindow) {
+  SqlEditorUtils, keyboardShortcuts, pgWindow, configure_show_on_scroll) {
 
   var pgAdmin = (window.pgAdmin = window.pgAdmin || {}),
     pgBrowser = pgAdmin.Browser;
@@ -2190,7 +2190,7 @@ define([
         emptyOptions: false,
         preserveSelectionOrder: false,
         isDropdownParent: false,
-        onDemandLoad: true,
+        showOnScroll: true,
       });
 
       // Evaluate the disabled, visible, and required option
@@ -2249,15 +2249,8 @@ define([
         select2Opts.data = data.rawValue;
       }
 
-      /* Set the pgadmin adapter for on demand load.
-       * Setting empty ajax option will enable infinite scrolling.
-       */
-      if(select2Opts.onDemandLoad) {
-        select2Opts.dataAdapter = $.fn.select2.amd.require('select2/onDemandDataAdapter');
-        if(_.isUndefined(select2Opts.ajax)) {
-          select2Opts.ajax = {};
-        }
-      }
+      /* Configure show on scroll if required */
+      select2Opts = configure_show_on_scroll.default(select2Opts);
 
       this.$sel = this.$el.find('select').select2(select2Opts);
 
diff --git a/web/pgadmin/static/js/backgrid.pgadmin.js b/web/pgadmin/static/js/backgrid.pgadmin.js
index 2f0a8a018..7e8f9648f 100644
--- a/web/pgadmin/static/js/backgrid.pgadmin.js
+++ b/web/pgadmin/static/js/backgrid.pgadmin.js
@@ -9,11 +9,11 @@
 
 define([
   'sources/gettext', 'underscore', 'jquery', 'backbone', 'backform', 'backgrid', 'alertify',
-  'moment', 'bignumber', 'sources/utils', 'sources/keyboard_shortcuts',
+  'moment', 'bignumber', 'sources/utils', 'sources/keyboard_shortcuts', 'sources/select2/configure_show_on_scroll',
   'bootstrap.datetimepicker', 'backgrid.filter', 'bootstrap.toggle',
 ], function(
   gettext, _, $, Backbone, Backform, Backgrid, Alertify, moment, BigNumber,
-  commonUtils, keyboardShortcuts
+  commonUtils, keyboardShortcuts, configure_show_on_scroll
 ) {
   /*
    * Add mechanism in backgrid to render different types of cells in
@@ -883,7 +883,7 @@ define([
         select2_opts = _.extend({
           openOnEnter: false,
           multiple: false,
-          onDemandLoad: true,
+          showOnScroll: true,
         }, self.defaults.select2,
         (col.select2 || {})
         ),
@@ -944,12 +944,9 @@ define([
         select2_opts['placeholder'] = '';
       }
 
-      if(select2_opts.onDemandLoad) {
-        select2_opts.dataAdapter = $.fn.select2.amd.require('select2/onDemandDataAdapter');
-        if(_.isUndefined(select2_opts.ajax)) {
-          select2_opts.ajax = {};
-        }
-      }
+      /* Configure show on scroll if required */
+      select2_opts = configure_show_on_scroll.default(select2_opts);
+
       // Initialize select2 control.
       this.$sel = this.$select.select2(select2_opts);
 
diff --git a/web/pgadmin/static/js/select2/configure_show_on_scroll.js b/web/pgadmin/static/js/select2/configure_show_on_scroll.js
new file mode 100644
index 000000000..ca2e8139f
--- /dev/null
+++ b/web/pgadmin/static/js/select2/configure_show_on_scroll.js
@@ -0,0 +1,97 @@
+import 'select2';
+import $ from 'jquery';
+import _ from 'underscore';
+
+export default function (options) {
+  if(options.showOnScroll) {
+    let Utils = $.fn.select2.amd.require('select2/utils');
+
+    /* Define on scroll showing of dropdown items.
+     * This also requires ajax option of select2 to be set.
+     * The trick is, ajax: {} will also work even if you're actually not
+     * using ajax.
+     */
+    let ScrollDataAdapter = function ($element, options) {
+      ScrollDataAdapter.__super__.constructor.call(this, $element, options);
+    };
+
+    if(options.data) {
+      Utils.Extend(ScrollDataAdapter, $.fn.select2.amd.require('select2/data/array'));
+    } else {
+      Utils.Extend(ScrollDataAdapter, $.fn.select2.amd.require('select2/data/select'));
+    }
+
+    ScrollDataAdapter.prototype.query = function (params, callback) {
+      var data = [];
+      var self = this;
+      if (!params.page) {
+        params.page = 1;
+      }
+      var pageSize = 20;
+
+      var $options = this.$element.children();
+      $options.each(function () {
+        var $option = $(this);
+
+        if (!$option.is('option') && !$option.is('optgroup')) {
+          return;
+        }
+
+        var option = self.item($option);
+
+        var matches = self.matches(params, option);
+
+        if (matches !== null) {
+          data.push(matches);
+        }
+      });
+
+      callback({
+        results: data.slice((params.page - 1) * pageSize, params.page * pageSize),
+        pagination: {
+          more: data.length >= params.page * pageSize,
+        },
+      });
+    };
+
+    if (options.minimumInputLength > 0) {
+      ScrollDataAdapter = Utils.Decorate(
+        ScrollDataAdapter,
+        $.fn.select2.amd.require('select2/data/minimumInputLength')
+      );
+    }
+
+    if (options.maximumInputLength > 0) {
+      ScrollDataAdapter = Utils.Decorate(
+        ScrollDataAdapter,
+        $.fn.select2.amd.require('select2/data/maximumInputLength')
+      );
+    }
+
+    if (options.maximumSelectionLength > 0) {
+      ScrollDataAdapter = Utils.Decorate(
+        ScrollDataAdapter,
+        $.fn.select2.amd.require('select2/data/maximumSelectionLength')
+      );
+    }
+
+    if (options.tags) {
+      ScrollDataAdapter = Utils.Decorate(ScrollDataAdapter, $.fn.select2.amd.require('select2/data/tags'));
+    }
+
+    if (options.tokenSeparators != null || options.tokenizer != null) {
+      ScrollDataAdapter = Utils.Decorate(
+        ScrollDataAdapter,
+        $.fn.select2.amd.require('select2/data/tokenizer')
+      );
+    }
+
+    options.dataAdapter = ScrollDataAdapter;
+
+    /* Setting empty ajax option will enable infinite scrolling. */
+    if(_.isUndefined(options.ajax)) {
+      options.ajax = {};
+    }
+  }
+  return options;
+}


view thread (6+ messages)  latest in thread

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected], [email protected]
  Subject: Re: [pgAdmin][RM5038] Select2 enhancement - Load items on demand (scroll)
  In-Reply-To: <CAM9w-_nU8m_LbFaCvLzYnrepM+Y1RGbAT8xQaMucWxm=3cuaNg@mail.gmail.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox