6
\$\begingroup\$

The logic is like this:

  • All brands have 2 products (Rose and Tulip)
  • Each brand names their product name differently (such as Brand 1 names their rose as No. 1 Rose and Brand 2 names their rose as No. 2 Rose )
  • All brands don't have products from all countries (Such as Brand 1 has Roses from USA and US whereas Brand 2 has Roses from Canada and China)

This is the working prototype of this function given below (Or, the fiddle):

$(document).ready(function() {

    $(document).on("input", "#intBrand, #intProcudt", function() {

        var intBrand = $('#intBrand').val();
        var intProcudt = $('#intProcudt').val();

        if (intBrand == "bAll") {
            if (intProcudt == "rose") {
                product = 'Rose';
            } else if (intProcudt == "tulip") {
                product = 'Tulip';
            }
        } else if (intBrand == "b1") {
            if (intProcudt == "rose") {
                product = 'No. 1 Rose';
            } else if (intProcudt == "tulip") {
                product = 'No. 1 Tulip';
            }
        } else if (intBrand == "b2") {
            if (intProcudt == "rose") {
                product = 'No. 2 Rose';
            } else if (intProcudt == "tulip") {
                product = 'No. 2 Tulip';
            }
        }

        var item1 = product + ' from US(1)<br>';
        var item2 = product + ' form USA(2)<br>';
        var item3 = product + ' from Canada(3)<br>';
        var item4 = product + ' from China(4)<br>';


        if (intBrand == "bAll") {
            roseP = item1 + item2 + item3 + item4;
            tulipP = item1 + item2 + item4;
        } else if (intBrand == "b1") {
            roseP = item1 + item2;
            tulipP = item1;
        } else if (intBrand == "b2") {
            roseP = item3 + item4;
            tulipP = item3 + item4;
        }

        $('#allRoseItems').html(roseP);
        $('#allTulipItems').html(tulipP);

    });

    $("#intBrand").trigger("input");
});
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
   <div class="col-6">
      <b>Select Brand:</b><br>
      <select id="intBrand" name="intBrand" required>
         <option value="bAll" >All items</option>
         <option value="b1" selected>Brand 1</option>
         <option value="b2" >Brand 2</option>
      </select>
   </div>
   <div class="col-6">
      <b>Select Product:</b><br>
      <select id="intProcudt" name="intProcudt" required>
         <option value="rose" >Rose</option>
         <option value="tulip">Tulip</option>
      </select>
   </div>
</div>
<div class="container">
   <div id="allRoseItems"></div>
   <br>
   <div id="allTulipItems"></div>
</div>

My question is just keeping the following section untouched, could it be built in a better way?

var item1 = product + ' from US(1)<br>';
var item2 = product + ' form USA(2)<br>';
var item3 = product + ' from Canada(3)<br>';
var item4 = product + ' from China(4)<br>';

I'd really appreciate your suggestions on how it could be written in a more efficient way with fewer lines of code.

\$\endgroup\$

migrated from stackoverflow.com May 4 '18 at 2:10

This question came from our site for professional and enthusiast programmers.

  • \$\begingroup\$ at its least, write a function for similar code fragments, pass parameters to process differences. that is the motto of coding, and your if blocks do the opposite. \$\endgroup\$ – Yılmaz Durmaz May 4 '18 at 2:03
  • \$\begingroup\$ oh, and try to use switch blocks when you work with strings. \$\endgroup\$ – Yılmaz Durmaz May 4 '18 at 2:05
4
\$\begingroup\$

I was in the process of answering your question on StackOverflow but it was moved to Code Review -- so I'll answer it here.

You might be able to avoid using switch or multiple if conditions if you build a data structure that fits your needs.

$(function() {

  // data structure
  var products = {
    bAll: {
      rose: {
        name: 'Rose',
        countries: ['US(1)', 'USA(2)', 'Canada(3)', 'China(4)']
      },
      tulip: {
        name: 'Tulip',
        countries: ['US(1)', 'USA(2)', 'China(4)']
      }
    },
    b1: {
      rose: {
        name: 'No. 1 Rose',
        countries: ['US(1)', 'USA(2)']
      },
      tulip: {
        name: 'No. 1 Tulip',
        countries: ['US(1)']
      }
    },
    b2: {
      rose: {
        name: 'No. 2 Rose',
        countries: ['USA(3)', 'China(4)']
      },
      tulip: {
        name: 'No. 2 Tulip',
        countries: ['USA(3)', 'China(4)']
      }
    }
  };

  $(document).on("input", "#intBrand, #intProcudt", function() {

    var intBrand = $('#intBrand').val();
    var intProcudt = $('#intProcudt').val();

    // using the data structure, it makes it much easier to get information

    // get product
    var product = products[intBrand][intProcudt]['name'];

    // get rose countries
    var roseCountries = products[intBrand]['rose']['countries'];

    // get tulip countries
    var tulipCountries = products[intBrand]['tulip']['countries'];

    // build HTML string using product's rose countries
    var roseP = roseCountries.map(function(country) {
      return product + ' from ' + country;
    }).join('<br />');

    // build HTML string using product's tulip countries
    var tulipP = tulipCountries.map(function(country) {
      return product + ' from ' + country;
    }).join('<br />');

    $('#allRoseItems').html(roseP);
    $('#allTulipItems').html(tulipP);
  });

  $("#intBrand").trigger("input");

  // alternate way is to get the data from a JSON file
  // instead of having the large data in our file;

  // you would need to wait for the response from the $.getJSON
  // before triggering the initial load automatically

  /*
  var products;
  $.getJSON('path/products.json', function (res) {
      // store the data, so that we can use it
      products = res;
      // trigger initial oninput
      $("#intBrand").trigger("input");
  });
  */
});
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
  <div class="col-6">
    <b>Select Brand:</b><br>
    <select id="intBrand" name="intBrand" required>
      <option value="bAll">All items</option>
      <option value="b1" selected>Brand 1</option>
      <option value="b2">Brand 2</option>
    </select>
  </div>
  <div class="col-6">
    <b>Select Product:</b><br>
    <select id="intProcudt" name="intProcudt" required>
      <option value="rose">Rose</option>
      <option value="tulip">Tulip</option>
    </select>
  </div>
</div>
<div class="container">
  <div id="allRoseItems"></div>
  <br>
  <div id="allTulipItems"></div>
</div>

You should also cache your jQuery objects if you are going to be re-using them. There's no need to search the DOM every time.

\$\endgroup\$
  • \$\begingroup\$ Wow! It's really wonderful. But if I build a data structure like this, would it be possible to keep it in a separate js file and use that data source in to build the logic? Because say if I have 100 products, then the data structure sitting on top of it would be pretty large. \$\endgroup\$ – Ashonko May 4 '18 at 2:57
  • \$\begingroup\$ @Ashonko You can if you store the data structure in the global namespace in another file. The script file would need to be included first before this script file. Sometimes, I store my data structures in a JSON file and use $.getJSON to fetch the data once. Though, for your example, you would need to wait till you get the data first before triggering the initial oninput -- if you choose to do this 2nd approach. \$\endgroup\$ – Mikey May 4 '18 at 3:03
  • \$\begingroup\$ Would it be possible to get the json data first before triggering the initial oninput? \$\endgroup\$ – Ashonko May 4 '18 at 3:09
  • 1
    \$\begingroup\$ @Ashonko Yes, I have edited my answer with a comment at the bottom on how the code would look. One last thing, ensure that your JSON file is valid i.e. keys must be wrapped in double quotes, no trailing commas, watch out for whitespace characters such as tabs and newlines, etc. There are many JSON validators online if you are unsure. \$\endgroup\$ – Mikey May 4 '18 at 3:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.