Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How could *data inter-dependent* <select> dropdowns in rails be populated quickly?

Users need to select a car.
We have several dropdowns when picking a car in order to pick the year, make, model and submodel. Initially we don't know what to use for the select options for make/model/submodel as they are interdependent.
Once we pick year we use ajax to make requests which query ActiveRecord to populate the make dropdown.
Then when we pick make we use ajax to query and populate the model dropdown. Then when we pick model we ajax to query and populate the submodel dropdown.

The problem is that this is a lot of separate network requests and in real-world conditions of low bandwidth, network issues, etc. quite often there are pauses severely impacting the user experience and occasionally leading to failures.

What approaches could help avoid all these network requests. In there an approach would could store all of the several thousand makes-model combinations on the client browser?

Currently the data is stored in a sql database accessed via ActiveRecord in the Rails framework. Each dropdown selection results in another query because yuou can't show populate and show make until you know year and you can't populate and show model until you know make. Same for submodel (though I've omitted submodel from the rest of this post for simplicity!).

Would session (http://simonsmith.io/speeding-things-up-with-sessionstorage/) storage of the JSON data for 10,000 combinations be possible? I see that sessionStorage can generally be relied on to have at least 5MB(5,200,000 bytes) so that gives me 5200000/10000= 520 bytes per record. Probably enough? If this persists for the session and across pages then in many cases we could actually kick this off on the previous page and if that had time to finish we wouldn't need the external call at all on the relevant (next) page. We would need to refresh that data either occasionally or on demand as new year-make-models are added periodically (several times a year).

Ultimately I think the solution here could be very useful to a large number of applications and companies. The example here of picking a vehicle itself it used by dozens of major car insurance websites (who all do the multiple calls right now). The general appraoch of storing client side data for relatioship dependent sdropdown could also mapply in many other situations such as online shopping for make-brand-year-model. The backend framework to populate sessionStorage could also be done via different backend frameworks.

Another options might be to try google's Lovefield - https://github.com/google/lovefield More at https://www.youtube.com/watch?v=S1AUIq8GA1k It's open source and works in ff, chrome, IE, Safari, etc.

Seems like sessionStorage might be better for our (considerable) business than basing it on a google 100 day dev thing - though it is open source.

like image 454
Michael Durrant Avatar asked Sep 26 '22 14:09

Michael Durrant


1 Answers

Hello you can create the JSON object for all the detail and based on the Value selected you can loop the array and populate the value. Let me

var cardetail = [{
  "name": "MARUTI",
  "model": [{
    "name": "SWIFT",
    "year": ["2005", "2006", "2008"]
  }, {
    "name": "ALTO",
    "year": ["2009", "2010", "2011"]
  }]
}, {
  "name": "Hundai",
  "model": [{
    "name": "I20",
    "year": ["2011", "2012", "2013"]
  }, {
    "name": "I20",
    "year": ["2013", "2014", "2015"]
  }]
}];

var currentCumpany = null;
var currentModel = null;
$(document).ready(function() {
 $("#company").append("<option value=''>Select Company</option>");
  for (i = 0; i < cardetail.length; i++) {
    $("#company").append("<option value='" + cardetail[i].name + "'>" + cardetail[i].name + "</option>");
  };

  $("#company").change(function() {

    for (i = 0; i < cardetail.length; i++) {
      if (cardetail[i].name == $("#company").val()) {
        currentCumpany = cardetail[i];
      }
    };
     $("#model").html("");
    for (i = 0; i < currentCumpany.model.length; i++) {
      $("#model").append("<option value='" + currentCumpany.model[i].name + "'>" + currentCumpany.model[i].name + "</option>");
    };
  });
   $("#company").change(function() {

    for (i = 0; i < cardetail.length; i++) {
      if (cardetail[i].name == $("#company").val()) {
        currentCumpany = cardetail[i];
      }
    };
     $("#model").html("");
    for (i = 0; i < currentCumpany.model.length; i++) {
      $("#model").append("<option value='" + currentCumpany.model[i].name + "'>" + currentCumpany.model[i].name + "</option>");
    };
  });
  

   $("#model").change(function() {

    
     
    for (i = 0; i < currentCumpany.model.length; i++) {
      
      if (currentCumpany.model[i].name == $("#model").val()) {
        currentModel = currentCumpany.model[i];
      }
      
    };
     
     
     $("#year").html("");
     
    for (i = 0; i < currentModel.year.length; i++) {
      $("#year").append("<option value='" + currentModel.year[i] + "'>" + currentModel.year[i] + "</option>");
    };
  });
  
  

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<select id="company"></select>
<select id="model"></select>
<select id="year"></select>
like image 175
Mitul Avatar answered Sep 30 '22 06:09

Mitul