Welcome to the LimeSurvey Community Forum

Ask the community, share ideas, and connect with other LimeSurvey users!

Ajax autocomplete data from a database for multiple short text questions filters

  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
2 years 9 months ago #226430 by tpartner
...when time allows, I will develop a version using jQuery UI autocomplete which I find to be a little more powerful. (more methods, events and options)

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
The following user(s) said Thank You: Joffm, davebostockgmail

Please Log in to join the conversation.

  • tammo
  • tammo's Avatar
  • Offline
  • Official LimeSurvey Partner
  • Official LimeSurvey Partner
More
2 years 9 months ago #226433 by tammo
If the server is on https, the scripts should also be on https.
Error message: Mixed Content: The page at ' myserver.com/index.php/699959 ' was loaded over HTTPS, but requested an insecure script ' easyautocomplete.com/dist/jquery.easy-autocomplete.min.js '. This request has been blocked; the content must be served over HTTPS.


But when I change the call to the scripts to https, the following error message appears in the console:

Failed to load resource: net::ERR_CERT_COMMON_NAME_INVALID


Tammo ter Hark at Respondage
For Limesurvey reporting, education and customized themes
respondage.nl

Please Log in to join the conversation.

  • davebostockgmail
  • davebostockgmail's Avatar Topic Author
  • Offline
  • Elite Member
  • Elite Member
More
2 years 9 months ago #226434 by davebostockgmail
I cant help with that .. I always copy the scripts to a local directory

Please Log in to join the conversation.

  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
2 years 9 months ago #226436 by tpartner
Loading the files from a local directory is always preferable.

Tammo, can you activate a small sample survey?

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
The following user(s) said Thank You: tammo

Please Log in to join the conversation.

  • tammo
  • tammo's Avatar
  • Offline
  • Official LimeSurvey Partner
  • Official LimeSurvey Partner
More
2 years 9 months ago #226437 by tammo
I uploaded the scripts to the server, now it works...

research.respondage.com/index.php/699959?newtest=Y&lang=en

Thanks,

Tammo


Tammo ter Hark at Respondage
For Limesurvey reporting, education and customized themes
respondage.nl

Please Log in to join the conversation.

  • davebostockgmail
  • davebostockgmail's Avatar Topic Author
  • Offline
  • Elite Member
  • Elite Member
More
1 year 1 month ago - 1 year 1 month ago #251739 by davebostockgmail
@Tony,

It has been a while, hope you are well.

I now have to reuse this to pull in additional data from the database but this is fixed information from the record that has been selected.

The record now looks like "Lookup Field 1", "Lookup Field 2", "Fixed field 1", "Fixed field 2", "Fixed field 3",,"Fixed field 4", "Fixed field 5", "Fixed field 6"

I have changed the question to include the additional short open inputs and I can hide these, what I cannot seem to do is point to the correct data in the array to populate these extra fields.

Do I need to add in a second Ajax call to return these fields based on the inputs from the filtered lookups or do you have a way to extract these keys and populate the text boxes?

Many thanks as always
Dave
Last edit: 1 year 1 month ago by davebostockgmail.

Please Log in to join the conversation.

  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
1 year 1 month ago #251741 by tpartner
Are the fixed data dependent on "Lookup Field 2"?

Can you attach a sample of your data JSON object?

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.

Please Log in to join the conversation.

  • davebostockgmail
  • davebostockgmail's Avatar Topic Author
  • Offline
  • Elite Member
  • Elite Member
More
1 year 1 month ago #251756 by davebostockgmail
They are dependent on the second lookup value.

Attached is the sample JSON (for some reason I could not add it to the post as text), the look up is for make then filters to model, anything after that is fixed for that make / model combination:
 
Attachments:

Please Log in to join the conversation.

  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
1 year 1 month ago #251764 by tpartner
It looks to me like all of the "fixed" items have a value 0. Is this intentional?

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.

Please Log in to join the conversation.

  • davebostockgmail
  • davebostockgmail's Avatar Topic Author
  • Offline
  • Elite Member
  • Elite Member
More
1 year 1 month ago #251775 by davebostockgmail
Hi Tony,

If you look at the first line Type 1 is 1 for the first record, Type 5 is 1 for the second etc. The reason for the Types is to assign powertrain options so the cars may be available as either petrol, diesel, PHEV, Full electric etc. Also the Make Model variable is fixed as well.

Thanks
Dave

Please Log in to join the conversation.

  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
1 year 1 month ago - 1 year 1 month ago #251788 by tpartner
Given your JSON object as the fullData variable, you don't need any extra AJAX calls. After answering the second autocomplete input, you can find the corresponding row in the full data (as an object) and load values directly from that into the "fixed" inputs.

Something like this:

Code:
<script type="text/javascript" data-author="Tony Partner">  
  $(document).on('ready pjax:scriptcomplete',function(){
 
    // Identify this question
    var thisQuestion = $('#question{QID}');
 
    // Define the data
    var fullData = [
      { "make":"ABARTH","model":"124","makemodel":"ABARTH 124","type1":"1","type2":"0","type3":"0","type4":"0","type5":"0","type6":"0" },
      { "make":"ABARTH","model":"SPIDER","makemodel":"ABARTH 500","type1":"1","type2":"0","type3":"0","type4":"0","type5":"1","type6":"0" },
      { "make":"ABARTH","model":"500","makemodel":"ABARTH 595","type1":"1","type2":"0","type3":"0","type4":"0","type5":"0","type6":"0" },
      { "make":"ABARTH","model":"595","makemodel":"ABARTH 695","type1":"1","type2":"0","type3":"0","type4":"0","type5":"0","type6":"0" },
      { "make":"ABARTH","model":"695","makemodel":"ABARTH F595","type1":"1","type2":"0","type3":"0","type4":"0","type5":"0","type6":"0" },
      { "make":"ABARTH","model":"F595","makemodel":"ABARTH PUNTO","type1":"1","type2":"0","type3":"0","type4":"0","type5":"0","type6":"0" },
      { "make":"ABARTH","model":"PUNTO","makemodel":"ABARTH SPIDER","type1":"1","type2":"0","type3":"0","type4":"0","type5":"0","type6":"0" },
      { "make":"ACURA","model":"CL","makemodel":"ACURA CL","type1":"1","type2":"0","type3":"0","type4":"0","type5":"0","type6":"0" },
      { "make":"ACURA","model":"MDX","makemodel":"ACURA MDX","type1":"1","type2":"0","type3":"0","type4":"0","type5":"0","type6":"0" },
      { "make":"ACURA","model":"RL","makemodel":"ACURA RL","type1":"1","type2":"0","type3":"0","type4":"0","type5":"0","type6":"0" },
      { "make":"ACURA","model":"TL","makemodel":"ACURA TL","type1":"1","type2":"0","type3":"0","type4":"0","type5":"0","type6":"0" }
    ];
 
    // Define some elements and vars    
    var keys = ['make', 'model'];
    var inputs = $('.answer-item input:text.form-control', thisQuestion);
    var answers = {
      0: $.trim($(inputs[0]).val()),
      1: $.trim($(inputs[1]).val())
    }
 
    // Create an array of "make" values
    var makes = [];
    $.each(fullData, function(i, val) {
      if(!makes.includes(val.make)) {
        makes.push(val.make);
      }
    });
 
    // Initiate autocomplete on the first input
    var aOptions1 = {
      data: makes,
      list: {
        maxNumberOfElements: 100,
        match: {
          enabled: true
        },
        onChooseEvent: function() {
 
          //If new selection...
          if($.trim($(inputs[0]).val()) != answers[0]) {
 
            answers[0] = $.trim($(inputs[0]).val());
 
            // Reset following items
            $('li.answer-item:gt(0) input:text', thisQuestion).val('').trigger('keyup');
            $('li.answer-item:eq(1) input:text', thisQuestion).easyAutocomplete({ 'data': '' });
 
            //Initiate autocomplete on next input
            childAutocomplete(0);
          }
        }  
      }
    };    
    $(inputs[0]).easyAutocomplete(aOptions1);
 
    function childAutocomplete(index) {
 
      if((index+1) < $('li.answer-item', thisQuestion).length) {
        var parentInput = $(inputs[index]);
        var nextInput = $(inputs[(index+1)]);
 
        var key1 = keys[index];
        var key2 = keys[(index+1)];
 
        // Define the new data
        var thisFullData = fullData.filter(function(obj) {
          return (obj[key1] == $.trim(parentInput.val()));
        });
        var thisData = [];
        $.each(thisFullData, function(i, val) {
          if(!thisData.includes(val[key2])) {
            thisData.push(val[key2]);
          }
        });
 
        //Initiate autocomplete on next input
        var aOptions = {
          data: thisData,
          list: {
            maxNumberOfElements: 100,
            match: {
              enabled: true
            },
            onChooseEvent: function() {
 
              //If new selection...
              if($.trim($(nextInput).val()) != answers[(index+1)]) {
 
                answers[(index+1)] = $.trim($(nextInput).val());
 
                // Reset following items
                $('li.answer-item:gt('+index+1+') input:text', thisQuestion).val('').trigger('keyup');
 
                // Load the fixed items
                var dataRow = fullData.filter(function(obj) {
                  return (obj[key1] == $.trim(parentInput.val()) &amp;&amp; obj[key2] == $.trim(nextInput.val()));
                })[0];
                console.log(dataRow);
                // NOTE: This could be done with a loop but with only 7 items it's safer to hard-code it
                $(inputs[2]).val(dataRow.makemodel);
                $(inputs[3]).val(dataRow.type1);
                $(inputs[4]).val(dataRow.type2);
                $(inputs[5]).val(dataRow.type3);
                $(inputs[6]).val(dataRow.type4);
                $(inputs[7]).val(dataRow.type5);
                $(inputs[8]).val(dataRow.type6);
              }
            }
          }
        };
        nextInput.easyAutocomplete(aOptions);
      }
    }
 
    // Returning to page
    if($.trim($(inputs[0]).val()) != '') {
      childAutocomplete(0);
    }
  });
</script>

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
Last edit: 1 year 1 month ago by tpartner.

Please Log in to join the conversation.

  • davebostockgmail
  • davebostockgmail's Avatar Topic Author
  • Offline
  • Elite Member
  • Elite Member
More
1 year 1 month ago #251789 by davebostockgmail
Works perfectly as always Tony, you are a genius ...

Only one line needed updating

return (obj[key1] == $.trim(parentInput.val()) &amp;&amp; obj[key2] == $.trim(nextInput.val()));
})[0];

the & were replaced.

Thank you so much
Dave

Please Log in to join the conversation.

Moderators: tpartnerholch

Lime-years ahead

Online-surveys for every purse and purpose