Rob Morris
Rob Morris

Reputation: 533

Displaying different output in select dropdown from javascript array

I'm a little way through solving my task of creating a dropdown containing the insurance companies, then a second dropdown showing the insurance types that insurance company offers e.g. property, fleet or motortrade (insurance type offered incudes a number).) Once both select dropdowns have been selected display the relevant number.

At the moment this is as far as I've got http://jsfiddle.net/3MK3D/

Heres the HTML:

<form action="" method="get" class="insurance-numbers">
  <div>
    <select id="company">
      <option value="default-company">Choose a company</option>
    </select>
  </div>
  <div>
    <select id="insurance-type">
      <option value="default-type">Choose an insurance type</option>
    </select>
  </div>
  <div id="insurance-number"></div>
</form>

Css:

#insurance-type {
  display:none;
}

And Javascript:

        var insurancecompanies = [
      { 
        name : 'Advent', 
        property : '01242 674 674', 
        fleet : '', 
        motortrade : ''
      },
      {   name : 'Allianz', 
       property : '0844 412 9988', 
       fleet : '0800 587 5858', 
       motortrade : '' 
      },
      {   name : 'Aviva', 
       property : '0800 015 1498', 
       fleet : '0800 246 876', 
       motortrade : '0800 246 876'
      },
      {   name : 'AXA', 
       property : '0870 900 0867', 
       fleet : '0870 900 0860', 
       motortrade : '0870 900 1753'
      },
      {   name : 'Catlin', 
       property : '', 
       fleet : '0800 066 5364', 
       motortrade : ''
      },
      {   name : 'Chartis', 
       property : '', 
       fleet : '0844 477 6544', 
       motortrade : ''
      },
      {   name : 'Clegg Gifford', 
       property : '', 
       fleet : '', 
       motortrade : '01708 729 529'
      },
      {   name : 'Equity Red Star', 
       property : '', 
       fleet : '0845 609 1235', 
       motortrade : ''
      },
      {   name : 'Highway/LV', 
       property : '', 
       fleet : '0845 373 1244', 
       motortrade : ''
      },
      {   name : 'NIG', 
       property : '', 
       fleet : '0845 300 4644', 
       motortrade : '0845 300 4644'
      },
      {   name : 'QBE', 
       property : '', 
       fleet : '01245 272 700', 
       motortrade : ''
      },
      {   name : 'Royal Sun Alliance', 
       property : '0845 077 0120', 
       fleet : '0845 675 0404', 
       motortrade : '0845 077 0119' 
      },
      {   name : 'Summit', 
       property : '', 
       fleet : '01254 396 655', 
       motortrade : ''
      },
      {   name : 'Zurich', 
       property : '0845 300 2055', 
       fleet : '0800 300 2055', 
       motortrade : ''
      }
    ];


    function findCompany(name) {
      var i = 0, len = insurancecompanies.length;
      for (i; i < len; i += 1) {
        if (insurancecompanies[i].name === name) {
          return insurancecompanies[i];
        }
      }
      return null;
    };

    function addInsuranceType(type) {
      if (type !== '') {
        $("#insurance-type").append('<option val="' + type + '">' + type + '</option>');
      }
    }

    var dropdown = [], i = 0, len = insurancecompanies.length;
    for (i; i < len; i += 1) {
      dropdown.push(insurancecompanies[i].name);
    }

    $.each( dropdown, function( i, val ) {
      $("#company").append( "<option val=\""+ val +"\">" + val + "</option>" );
    });

    $('#company').on('change', function() {
    var optionSelected = $("option:selected", this);
    var valueSelected = this.value;
    if(valueSelected !== 'default-company') {
      $('#insurance-type').children().remove();
      $('#insurance-number').text('');
      var selectedInsurance = findCompany(valueSelected);
      addInsuranceType(selectedInsurance.property, 'Property');
      addInsuranceType(selectedInsurance.fleet, 'Fleet');
      addInsuranceType(selectedInsurance.motortrade, 'motor trade');
      $('#insurance-type').fadeIn();
    } else {
      $('#insurance-type').fadeOut();
      $('#insurance-number').fadeOut();
    }
});

$('#insurance-type').on('change', function() {
   var optionSelected = $("option:selected", this);
   var insuranceSelected = this.value;
  $('#insurance-number').text(insuranceSelected);
  $('#insurance-number').fadeIn();
});

At the moment it displays the list of insurance companies correctly. It then selects the company chosen on change. It then displays the numbers offered by the insurance company, i need it to display the key name of those numbers and then output the number dependant on the key(select) selected.

So to demonstarte if I selected Allianz, the second dropdown would contain 'property' and 'fleet'. If the user selected 'fleet' the number '0800 587 5858' would get appended to the div#insurance-number'.

sorry if this is confusing I really need some help with this that is all.

Upvotes: 0

Views: 487

Answers (1)

David
David

Reputation: 219027

The logic here seems a little strange. The findCompany() function appears to be intending to return a single record:

function findCompany(name) {
  var i = 0, len = insurancecompanies.length;
  for (i; i < len; i += 1) {
    if (insurancecompanies[i].name === name) {
      return insurancecompanies[i];
    }
  }
  return null;
};

However, the result of the function is being treated like an array:

var selectedInsurance = findCompany(valueSelected);
for (i in selectedInsurance) {
  $("#insurance-type").append( "<option val=\""+ selectedInsurance[i] +"\">" + selectedInsurance[i] + "</option>" );
}

If selectedInsurance is just an instance of an object in the insurancecompanies array, then maybe instead of trying to loop through that object what you're looking to do is test the properties on that object to add to the select. Maybe something like this:

var selectedInsurance = findCompany(valueSelected);
if (selectedInsurance.property !== '') {
  $("#insurance-type").append('<option val="' + selectedInsurance.property + '">' + selectedInsurance.property + '</option>');
}
if (selectedInsurance.fleet !== '') {
  $("#insurance-type").append('<option val="' + selectedInsurance.fleet + '">' + selectedInsurance.fleet + '</option>');
}
if (selectedInsurance.motortrade !== '') {
  $("#insurance-type").append('<option val="' + selectedInsurance.motortrade + '">' + selectedInsurance.motortrade + '</option>');
}

It's not the most elegant solution perhaps, but should at least get you started. Seeing repeated code like that generally indicates that some functionality can be abstracted. Perhaps a common function:

function addInsuranceType(type) {
  if (type !== '') {
    $("#insurance-type").append('<option val="' + type + '">' + type + '</option>');
  }
}

Then you can just call that three times:

var selectedInsurance = findCompany(valueSelected);
addInsuranceType(selectedInsurance.property);
addInsuranceType(selectedInsurance.fleet);
addInsuranceType(selectedInsurance.motortrade);

Edit: Based on your comment (and something I suppose I glossed over in the question), it looks like you want the second select to have the value of the data, but the display of the name of the data. For my first version, that would be something like this:

if (selectedInsurance.property !== '') {
  $("#insurance-type").append('<option val="' + selectedInsurance.property + '">property</option>');
}
// ... and so on for the other two

Notice that I'm only using the selectedInsurance object for the option value, not for its text. For the text I'm just directly using the string "property" instead.

If you're using the function in my second version, a simple approach might also be to pass it the display text:

function addInsuranceType(value, text) {
  if (value !== '') {
    $("#insurance-type").append('<option val="' + value + '">' + text + '</option>');
  }
}

Then you can just call that three times:

var selectedInsurance = findCompany(valueSelected);
addInsuranceType(selectedInsurance.property, 'property');
// ... and so on for the other two

You can perhaps get a little more clever with JavaScript objects to avoid repeating the term "property" in that. Something like this:

function addInsuranceType(object, type) {
  if (object[type] !== '') {
    $("#insurance-type").append('<option val="' + object[type] + '">' + type + '</option>');
  }
}

Then you can just call that three times:

var selectedInsurance = findCompany(valueSelected);
addInsuranceType(selectedInsurance, 'property');
// ... and so on for the other two

That takes advantage of the fact that object members in JavaScript can be indexed as elements of the object. Though in some cases it may result in a trade-off with readability and supportability, so only use it where the intent is clear.

Upvotes: 1

Related Questions