1

I have two dropdown elements below that are populated with data from the result array.

I simply want to sort each option coming from the result array alphabetically in the drop-down elements.

Would also like to mention that in my dev environment the result data is actually coming from an API.

Thanks in advance!

let result = [{
    name: "B name",
    tag: "B tag",
    price: "50"
  },
  {
    name: "C name1",
    tag: "C tag",
    price: "10"
  },
  {
    name: "A name",
    tag: "A tag",
    price: "20"
  },
  {
    name: "E name",
    tag: "E tag",
    price: "30"
  },
  {
    name: "D name",
    tag: "D tag",
    price: "40"
  }
];

//Generic function to fill a dropdown with options 
let populateDropDown = (params) => {
  let set = new Set()
  params.optionsToPopulate.forEach(item => {
    const txt = item[params.text];
    if (!set.has(txt)) {
      params.element.add(new Option(txt, txt))
       set.add(txt);
    }
  })
}

//Initialize tags dropdown
(function() {
  document.getElementById("tags").addEventListener('change', (event) => {
    tagChanged(event);
  });

  let params = {
    optionsToPopulate: result,
    element: document.getElementById("tags"),
    id: "tag",
    text: "tag"
  }
  populateDropDown(params);

})();

//Tags dropdown change event.
let tagChanged = (event) => {
  let tagValue = event.target.value;

  //filter the results based on the value of tags dropdown
  let optionsToAdd = result.filter(item => item.tag === tagValue);
  let names = document.getElementById("names");
  names.options.length = 1;
  let params = {
    optionsToPopulate: optionsToAdd,
    element: names,
    id: "name",
    text: "name"
  }
  populateDropDown(params);
}
<!DOCTYPE html>
<html>

<head>
  <title></title>
</head>

<body>
  Tags:
  <select id="tags">
  <option value="please select">please select</option> 
  </select>

  <br><br><br> Names:
  <select id="names">
  <option value="please select">please select</option> 
  </select>

</body>

</html>
Aib Syed
  • 3,118
  • 2
  • 19
  • 30

3 Answers3

1

Try like this

-Just add sort function before populateDropDown().

-this will sort result by name key value in ascending order.

result = result.sort((a, b) => (a['name'] > b['name']) ? 1 : ((b['name'] > a['name']) ? -1 : 0));

-result will look like this

enter image description here

Santosh Shinde
  • 1,206
  • 10
  • 16
1

let result = [{
    name: "B name",
    tag: "B tag",
    price: "50"
},
{
    name: "C name1",
    tag: "C tag",
    price: "10"
},
{
    name: "A name",
    tag: "A tag",
    price: "20"
},
{
    name: "E name",
    tag: "E tag",
    price: "30"
},
{
    name: "D name",
    tag: "D tag",
    price: "40"
}
];

// Sort Alphabetically
var sortedResult = result.sort(function (a, b) {
    var tagA = a.tag.toLowerCase();
    var tagB = b.tag.toLowerCase();

    if (tagA < tagB)
        return -1;
    else if (tagA > tagB)
        return 1;
});

//Generic function to fill a dropdown with options 
let populateDropDown = (params) => {
    let set = new Set()
    params.optionsToPopulate.forEach(item => {
        const txt = item[params.text];
        if (!set.has(txt)) {
            params.element.add(new Option(txt, txt))
            set.add(txt);
        }
    })
}

//Initialize tags dropdown
(function () {
    document.getElementById("tags").addEventListener('change', (event) => {
        tagChanged(event);
    });

    let params = {
        optionsToPopulate: sortedResult,
        element: document.getElementById("tags"),
        id: "tag",
        text: "tag"
    }
    populateDropDown(params);

})();

//Tags dropdown change event.
let tagChanged = (event) => {
    let tagValue = event.target.value;

    //filter the results based on the value of tags dropdown
    let optionsToAdd = sortedResult.filter(item => item.tag === tagValue);
    let names = document.getElementById("names");
    names.options.length = 1;
    let params = {
        optionsToPopulate: optionsToAdd,
        element: names,
        id: "name",
        text: "name"
    }
    populateDropDown(params);
}
Tags:
<select id="tags">
    <option value="please select">please select</option>
</select>

<br><br><br> Names:
<select id="names">
    <option value="please select">please select</option>
</select>
Shahnawaz Hossan
  • 2,695
  • 2
  • 13
  • 24
  • Thank you for the working example. I would be happy to mark this as the correct answer but would you mind providing some context, or adding comments on what the code is actually doing? Thanks! – Aib Syed Jul 24 '20 at 16:09
  • 1
    Obviously, let me help you. If `compare (a,b)` is less than zero, the `sort( )` method sorts `a` to a lower index than `b`. In other words, `a` will come first. If `compare (a,b)` is greater than zero, the `sort( )` method sort `b` to a lower index than `a`, i.e., `b` will come first. That's it. – Shahnawaz Hossan Jul 24 '20 at 16:20
  • 1
    Also, you can write `return 0` at the end of the function, it means both strings are equal and it will remain the string's position in the array unchanged. – Shahnawaz Hossan Jul 24 '20 at 16:25
1

Sort the array

SO - sort-array-of-objects-by-string-property-value

let result = [{
    name: "B name",
    tag: "B tag",
    price: "50"
  },
  {
    name: "C name1",
    tag: "C tag",
    price: "10"
  },
  {
    name: "A name",
    tag: "A tag",
    price: "20"
  },
  {
    name: "E name",
    tag: "E tag",
    price: "30"
  },
  {
    name: "D name",
    tag: "D tag",
    price: "40"
  }
];

result.sort(compare)

//Generic function to fill a dropdown with options 
let populateDropDown = (params) => {
  let set = new Set()
  params.optionsToPopulate.forEach(item => {
    const txt = item[params.text];
    if (!set.has(txt)) {
      params.element.add(new Option(txt, txt))
       set.add(txt);
    }
  })
}

//Initialize tags dropdown
(function() {
  document.getElementById("tags").addEventListener('change', (event) => {
    tagChanged(event);
  });

  let params = {
    optionsToPopulate: result,
    element: document.getElementById("tags"),
    id: "tag",
    text: "tag"
  }
  populateDropDown(params);

})();

//Tags dropdown change event.
let tagChanged = (event) => {
  let tagValue = event.target.value;

  //filter the results based on the value of tags dropdown
  let optionsToAdd = result.filter(item => item.tag === tagValue);
  let names = document.getElementById("names");
  names.options.length = 1;
  let params = {
    optionsToPopulate: optionsToAdd,
    element: names,
    id: "name",
    text: "name"
  }
  populateDropDown(params);
}

function compare( a, b ) {
  if ( a.tag < b.tag ){
    return -1;
  }
  if ( a.tag > b.tag ){
    return 1;
  }
  return 0;
}
<!DOCTYPE html>
<html>

<head>
  <title></title>
</head>

<body>
  Tags:
  <select id="tags">
  <option value="please select">please select</option> 
  </select>

  <br><br><br> Names:
  <select id="names">
  <option value="please select">please select</option> 
  </select>

</body>

</html>
gillall
  • 111
  • 1
  • 7