1

I have a search form that allows the user to add as many search terms as they like. When the user enters all of the search terms and their search values and clicks search, a text box will be updated with the search terms. I've got this working with a for loop, but I'm trying to improve my dev skills and am looking for a way to do this with map\filter instead.

Here's the code I'm trying to replace:

var searchTerms = $("#search-form").find(".mdc-layout-grid__inner");

var searchString = "";    

for(var i = 0; i < searchTerms.length - 1; i ++)
{

    var select = $(searchTerms[i]).find(".select2-selection")[0];

    var selectText = $(select).select2('data')[0].text + ":";        

    var textBox = $(searchTerms[i]).find(".mdc-text-field__input")[0];

    searchString = searchString += selectText.replace(/\./g,"").replace(/ /g,"") + textBox.value;

    if(i < searchTerms.length - 1)
    {
        searchString = searchString += " ";
    }

}

$("#er-search-input").val(searchString);

Here's a codepen of the current solution.

i'm trying the below, but I get the feeling I'm miles away:

const ret = searchTerms.map((u,i) => [

    $($(u[i]).find(".select2-selection")[0]).select2('data')[0].text + ":",
    $(u[i]).find(".mdc-text-field__input")[0].value,
  ]);

My question is, is it possible to do this with map?

2
  • Take a look at jQuery's .each(). You can loop through your elements using searchTerms.each(function(i) { /* use "this" to access element*/ } Commented Nov 28, 2019 at 11:41
  • I'm comfortable with forEach, and each and some. But I thought in this instance I could avoid a loop altogether. Commented Nov 29, 2019 at 3:06

1 Answer 1

1

Firstly you're repeatedly creating a jQuery object, accessing it by index to get an Element object only to then create another jQuery object from that. Instead of doing this, you can use eq() to get a specific element in a jQuery object by its index.

However if you use map() to loop through the jQuery object then you can avoid that entirely by using this to reference the current element in the iteration. From there you can access the required elements. The use of map() also builds the array for you, so all you need to do is join() the results together to build the required string output.

Finally, note that you can combine the regex expressions in the replace() call by using the | operator, and also \s is more robust than using a whitespace character. Try this:

var $searchTerms = $("#search-form").find(".mdc-layout-grid__inner");
var searchString = $searchTerms.map(function() {
  var $searchTerm = $(this);
  var selectText = $searchTerm.find('.select2-selection').select2('data')[0].text + ':';
  var $textBox = $searchTerm.find('.mdc-text-field__input:first');
  return selectText.replace(/\.|\s/g, "") + $textBox.val();  
}).get().join(' ');

$("#er-search-input").val(searchString);
Sign up to request clarification or add additional context in comments.

2 Comments

This is what I'm talking about. There's lots to unpack here for me. Let me try it out and get back to you. Thank you!
I had to do a small mount of fiddling about to get it to work, but this did work in the end. And it really helped to ferment my understanding of map. so I've been using filter and map all day now to much celebration and marriment!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.