Any code snippets for better lookup field auto-complete?

  • 1
  • Question
  • Updated 3 years ago
Boss' Complaint: "Adding line items [to an invoice] takes too long because I have to click each item name after I start typing it in."

Problem: Skuid's lookup fields are slow (understandable) and don't perform any sort of useful auto-completion.

What I'd like to be able to do: If you type an entire record name into the lookup field and tab to the next field, it retains that record name just as if you had clicked on it.

Can anyone provide pointers on how to achieve this?
Photo of Charles Zink

Charles Zink

  • 388 Points 250 badge 2x thumb

Posted 3 years ago

  • 1
Photo of Moshe Karmel

Moshe Karmel, Champion

  • 8,646 Points 5k badge 2x thumb
I had the same issue and would love to collaborate on a snippet of sorts!
I assumed that if Zach and the pros hadn't fixed it, then it must be impossible...
https://community.skuidify.com/skuid/topics/lookup_fields_need_to_be_clicked_on
Photo of Charles Zink

Charles Zink

  • 388 Points 250 badge 2x thumb
Ouch, that issue has been open for a long time! I was hoping there was some sort of custom Javascript work-around that I hadn't been able to find yet. Unfortunately I'm incredibly busy with other areas of integration that I haven't had much time to learn the Skuid APIs.
Photo of Irvin Waldman

Irvin Waldman, Champion

  • 9,006 Points 5k badge 2x thumb
Can any of your lookup fields be changed to render as picklists?
Photo of Charles Zink

Charles Zink

  • 388 Points 250 badge 2x thumb
Unfortunately not. It's a list of 100's of inventory codes.
Photo of Moshe Karmel

Moshe Karmel, Champion

  • 8,646 Points 5k badge 2x thumb
After getting inspired by Charles that anything is possible, I decided to put a quick concept together. I am using jQuery's "focusout" event to update the field with the value that was selected at the time that focus was lost. Since I don't get how skuid gets the salesforce Id from the name string, I had to query a model in order to get the actual Id but in theory it can be a lot simpler. It only seems to work once (I haven't quite finished yet) but here's what I got.

<code>

<skuidpage unsavedchangeswarning="" showsidebar="true" showheader="true">   <models>
      <model id="Contact" limit="1" query="false" createrowifnonefound="true" sobject="Contact" doclone="" type="">
         <fields>
            <field id="AccountId"/>
            <field id="Account.Name"/>
         </fields>
         <conditions/>
         <actions/>
      </model>
      <model id="Account" limit="1" query="false" createrowifnonefound="false" sobject="Account" doclone="" type="">
         <fields>
            <field id="Id"/>
            <field id="Name"/>
         </fields>
         <conditions>
            <condition type="fieldvalue" value="" enclosevalueinquotes="true" field="Name" state="filterableoff" inactive="true" name="Name"/>
         </conditions>
         <actions/>
      </model>
   </models>
   <components>
      <basicfieldeditor showheader="true" showsavecancel="true" model="Contact" buttonposition="" mode="edit" layout="" uniqueid="MyFieldEditor">
         <columns>
            <column width="33.3%">
               <sections>
                  <section title="" collapsible="no">
                     <fields>
                        <field id="AccountId" valuehalign="" type=""/>
                     </fields>
                  </section>
               </sections>
            </column>
            <column width="33.3%">
               <sections/>
            </column>
            <column width="33.3%">
               <sections/>
            </column>
         </columns>
      </basicfieldeditor>
   </components>
   <resources>
      <labels/>
      <javascript>
         <jsitem location="inline" name="pageLoad" cachelocation="false" url="">(function(skuid){
var $ = skuid.$;
$(function(){
   //get a reference to all of our models and rows
   var models = skuid.model.map();
   var contactModel = models.Contact;
   var contactRow = contactModel.getFirstRow();
   var accountModel = models.Account;
   //on every focus out run the followingfunction
   //"MyFieldEditor" is the Id of the field editor
$('#MyFieldEditor').find('input').on('focusout', function(){
   var text = $(this).val();
   //if you want, you can have the update only run if the user has 
   //narrowed down the selection to a specific amount of options
   //if($('.ui-menu-item').length &gt; 5) return;
   //if we have a value that was selected
   if(text &amp;&amp; text !== ""){
       //query the Account model for the name
       var nameCondition = accountModel.getConditionByName('Name');
       accountModel.setCondition(nameCondition, text);
       accountModel.updateData(function(){
           //after the query finishes
           var accountRow = accountModel.getFirstRow();
           if(accountRow &amp;&amp; accountRow.Id){
               //if we got a row back, update the Account field on Contact
               contactModel.updateRow(contactRow, {
                   AccountId : accountRow.Id,
                   Account : accountRow
               });
           }
       });
   }
});
});
})(skuid);</jsitem>
      </javascript>
      <css/>
   </resources>
</skuidpage>

</code>  
Photo of Charles Zink

Charles Zink

  • 388 Points 250 badge 2x thumb
Moshe, I've been so busy with other aspects of our development that I just now got around to trying out your code.

This is absolutely fantastic! It will definitely hold my guys over until Skuid comes up with something more official. Thank-you so much.
Photo of Charles Zink

Charles Zink

  • 388 Points 250 badge 2x thumb
If I can bother you one last time.. I'm having trouble getting this to work with a field in a table row.

Apparently you can't assign a field a uniqueid, so I'm using jQuery's nth-child() selector to grab the proper input. When I test it in Chrome's console jQuery is able to correctly find the right field, but it doesn't seem to actually be working in practice.

Code: https://gist.github.com/anonymous/e770ec50946186c63981
Photo of Moshe Karmel

Moshe Karmel, Champion

  • 8,646 Points 5k badge 2x thumb
I would imagine that "find('input.ui-autocomplete-input')" may be returning more than one element. You can try to loop through all of the found elements and add a listener to each one:
$('#CustomFieldEditor').find('input.ui-autocomplete-input').each(function(i, elem){
    $(elem).on('focusout', function(){
        console.log('test');
    });
});
Photo of Craig Rosenbaum

Craig Rosenbaum

  • 4,776 Points 4k badge 2x thumb
I had a similar need and solved it with a dummy text field. My script would take the dummy entry and on enter press, loop through the parent model for the lookup field, find that record, and update that row's real look up field with the Id from the parent model.

The problem with this approach in your context is you have to have the name exactly right and there is no auto assist to help you type. We are using this with barcode scanners so it will always be correct and there is no need for look up functionality. The positive side is it is lightning fast and allows the user to add multiple rows rapidly by typing in the serial number and pressing enter to get a new line.