[SOLVED] Example Smart Select with Virtual List

I have been trying to create a Smart Select with a very large number of items downloaded via JSON, and looking for a good example on how to do this. The following is my best attempt:

> $$.getJSON(siteURL.concat('items'),function(data){
>         var virtualList = myApp.virtualList('.smart-select select#listItems',{items: data});
> });
<li>
   <a href="#" 
      class="item-link smart-select"
      data-searchbar="true"
      data-searchbar-placeholder="Search Items"
      data-virtual-list = "true"
      data-back-on-select ="true"
      >
      <select class = "virtual-list" id="listItems">
      </select>    
      <div class="item-content">
         <div class="item-inner"> 
              <div class="item-title">Items</div>
              <div class="item-after" id="disp-items"></div>
          </div>  
       </div>
      </a> 
 </li>

No, you don’t have to init VL, just put all options inside as before and add data-virtual-list=true. Virtual list will be created automatically on smart select page on open

Question: Why does Smart Select (with 599 items) loaded via Javascript using smartSelectAddOption end up having such a long delay (6 seconds) when selecting any item in the list?

I made some progress in isolating the issue:

Given I do this in HTML for smart select:

<li> <a href="#" class="item-link smart-select"  data-virtual-list = "true" > 
<select id="listItems"> 
       <!-- javascript options go here -->
</select> 
<div class="item-content"> 
     <div class="item-inner"> 
           <div class="item-title">Items</div> 
      </div> 
 </div> 

`

I implement the smart select with a long list (599 items), which I create in javascript by converting from an array of items that I downloaded via JSON to options in the smart select using the myApp.smartSelectAddOption() method. The problem is it takes about 6 seconds from when I select an item until it actually appears as a selected item in the list view. If I fill all the options manually in the html (instead of using smartSelectAddOption) it works very quickly as I would expect.

So using the smartSelectAddOption method causes it to be very slow and I do not know why?

Note that I call the smartSelectAddOption method after the page is loaded; it is inside myApp.onPageInit(){}

This is specifically how I call the myApp.smartSelectAddOption(), I call this function as part of the $$.getJSON() where I am downloading my items list from the server:

function generateOptions(options, cssClass) {
    //this function is used to generate options selections dynamically
    for (var i in options) {
        optionValue= options[i];
         myApp.smartSelectAddOption(
            cssClass, 
            '<option value="'+ optionValue + '">' + options[i] + '</option>'
        );
    }
>    
> }

I thought I solved this by moving the related processes that create the smartSelect list dynamically via JSON to be inside myApp.onPageBeforeInit(), but this turned out not to be the case…

Just idea
Don’t use smartSelect with amount of data. it’s really slow - gets data from server (step 1), create select element (fill options array, I remember this operation was not optimized in v1.x) (step 2), create a popup page with data from options array (step 3) to select item(s).

Make an emulation for smartselect - open a popup with VL filled your data and close it by user’s interaction (close or select item).

1 Like

Thank you for the idea @adasoft !

What I found out since is this:

If I create my smart select option list dynamically using MyApp.smartSelectAddOption(), the resulting list is extremely slow: with 700 items it takes about 6 seconds from when I click on an item until it finally responds. However, if I build my own option list directly using the following code (but still in a smart select so taking advantage of everything else already done in the smart select routines), the response is quite fast. I did not look under the hood to understand what is different about MyApp.smartSelectAddOption() that would make it so slow, or if what I am doing will end up with a problem later, but thus far it is working great as a solution to this problem!

My HTML:

        <li><a href="#" 
                class="item-link smart-select"
                data-open-in = "picker"
                data-virtual-list = "true"
                data-searchbar ="true"
                data-searchbar-placeholder="Search accounts"
            >
                     
            <select id="accounts" name="Accounts">
                <option value=""></option>    //IMPORTANT TO INCLUDE THIS LINE!
                <!-- javascript smart select items go here -->
            </select>   
            <div class="item-content">
              <div class="item-inner"> 
                <div class="item-title">Patron</div>
              </div>  
            </div></a> 
        </li>

Note in the HTML I found that it was important to include the one option line noted above, otherwise options selected do not transfer to the form (I do not know why, but this made it work).

My javascript dynamically creating the option list:

$$.getJSON(siteURL.concat('patrons'),function(data){
    patrons = data;   //gets used later
    for (var i in patrons) {
        var patron = patrons[i];
        accountItems.push(patron.AccountName);  //accountItems is a simple array of account names.
    }
    cssClass = '#accounts';
    for (var i in accountItems) {
       $$(cssClass).append('<option value ="'+ accountItems[i] + '">' + accountItems[i] + ' </option>');
    } 
});

it REBUILD options array EVERY TIME with new element added.

a bit speed up your code

$$.getJSON(siteURL.concat('patrons'),function(data){
    patrons = data;   //gets used later
    var html = "";
    for (var i in patrons) {
        var patron = patrons[i];
        accountItems.push(patron.AccountName);  //accountItems is a simple array of account names.
        html += "<option value ="'+ patron.AccountName + '">' + patron.AccountName + ' </option>'";
    }
    cssClass = '#accounts'; //??? move to $$()

    $$(cssClass).append(html);

});
2 Likes

@adasoft Thank you so much! This totally makes sense! Great help, thank you! The reason I had cssClass defined is I was moving the routine to its own function where I would pass in the array and class/id – this was leftover from when I was doing that and now that is optimized will create that again.