Search code examples
javascriptjqueryfor-loopsearchbaronkeyup

How to create search bar that matches the input text and displays only images(href) that has that text in their attributes ??? JQuery


Trying to create a search bar ... when user writes text in the input field i want to display only those images(their href) that contain that text in their caption(they all have captions and those captions are added as attributes to them)... here is the code... the lightbox.option is just a plugin for the pictures

const mainDiv = $('<div></div>').addClass('wrapper');
mainDiv.appendTo('body');

const input = $('<input>').attr({'id':'searchInput','type':'text','placeholder':'Search(16pt)'});
input.appendTo(mainDiv);

const imgsMainWrap = $('<div></div>').addClass('imgsWrpaer');
imgsMainWrap.appendTo(mainDiv);

const captions = [
    '',
    'I love hay bales. Took this snap on a drive through the countryside past some straw fields.',
    'The lake was so calm today. We had a great view of the snow on the mountains from here.',
    'I hiked to the top of the mountain and got this picture of the canyon and trees below',
    'It was amazing to see an iceberg up close, it was so cold but didn’t snow today.',
    'The red cliffs were beautiful. It was really hot in the desert but we did a lot of walking through the canyons.',
    'Fall is coming, I love when the leaves on the trees start to change color.',
    'I drove past this plantation yesterday, everything is so green!',
    'My summer vacation to the Oregon Coast. I love the sandy dunes!',
    'We enjoyed a quiet stroll down this countryside lane.',
    'Sunset at the coast! The sky turned a lovely shade of orange.',
    'I did a tour of a cave today and the view of the landscape below was breathtaking.',
    'I walked through this meadow of bluebells and got a good view of the snow on the mountain before the fog came in.' 
]


for(let i =1; i <= 12; i++){
    const innerImgWrapper = $('<div></div>').addClass('innerImgWrapper');
    $(innerImgWrapper).appendTo(imgsMainWrap);

    const links = $('<a></a>').attr({'href':'photos/0' + [i] + '.jpg','data-lightbox':'images', 'data-title': captions[i]});
    if(i > 9){
        links.attr('href','photos/' + [i] + '.jpg');
    }
    $(links).appendTo(innerImgWrapper);

    const img = $('<img>').attr({'src':'photos/0'+[i]+'.jpg'});
    if(i > 9){
        img.attr({'src':'photos/'+[i]+'.jpg'});
    }
    $(img).appendTo(links);


    input.on('keyup', function(){
        const inputValue = $(input).val().toLowerCase();
        const captions = $(links).attr('data-title');
        if(captions.indexOf(inputValue) != -1){
            ???????????
        }
    // }
    });
}


// Next comes the fun part. Start trying to find ways to check if the current value of the
// search input is included within any of the captions, and if so, log the associated image
// to the console.



lightbox.option();


Solution

  • You can use data-attribute selector * which looks for matching characters anywhere in data-* attribute.

    Here is a list of other data selector type you can use (source):

    [data-value] {
      /* Attribute exists */
    }
    
    [data-value="foo"] {
      /* Attribute has this exact value */
    }
    
    [data-value*="foo"] {
      /* Attribute value contains this value somewhere in it */
    }
    
    [data-value~="foo"] {
      /* Attribute has this value in a space-separated list somewhere */
    }
    
    [data-value^="foo"] {
      /* Attribute value starts with this */
    }
    
    [data-value|="foo"] {
      /* Attribute value starts with this in a dash-separated list */
    }
    
    [data-value$="foo"] {
      /* Attribute value ends with this */
    }
    

    Also, you need to take the input keyup event outside the loop so it is not attached multiple times to the same element.

    The logic is to hide elements on search using .hide() then show the elements filtered with the data selector using .show().

    See this example:

    const mainDiv = $('<div></div>').addClass('wrapper');
    mainDiv.appendTo('body');
    
    const input = $('<input>').attr({
      'id': 'searchInput',
      'type': 'text',
      'placeholder': 'Search(16pt)'
    });
    input.appendTo(mainDiv);
    
    const imgsMainWrap = $('<div></div>').addClass('imgsWrpaer');
    imgsMainWrap.appendTo(mainDiv);
    
    const captions = [
      '',
      'I love hay bales. Took this snap on a drive through the countryside past some straw fields.',
      'The lake was so calm today. We had a great view of the snow on the mountains from here.',
      'I hiked to the top of the mountain and got this picture of the canyon and trees below',
      'It was amazing to see an iceberg up close, it was so cold but didn’t snow today.',
      'The red cliffs were beautiful. It was really hot in the desert but we did a lot of walking through the canyons.',
      'Fall is coming, I love when the leaves on the trees start to change color.',
      'I drove past this plantation yesterday, everything is so green!',
      'My summer vacation to the Oregon Coast. I love the sandy dunes!',
      'We enjoyed a quiet stroll down this countryside lane.',
      'Sunset at the coast! The sky turned a lovely shade of orange.',
      'I did a tour of a cave today and the view of the landscape below was breathtaking.',
      'I walked through this meadow of bluebells and got a good view of the snow on the mountain before the fog came in.'
    ]
    
    
    input.on('keyup', function() {
      const inputValue = $(input).val().toLowerCase();
      imgsMainWrap.children().hide();
    
      const links = imgsMainWrap.find("a").filter("[data-title*='" + inputValue + "']");
    
      if (links.length > 0) {
        links.parent().show();
      }
      // }
    });
    
    
    for (let i = 1; i <= 12; i++) {
      const innerImgWrapper = $('<div></div>').addClass('innerImgWrapper');
      $(innerImgWrapper).appendTo(imgsMainWrap);
    
      const links = $('<a></a>').attr({
        'href': 'photos/0' + [i] + '.jpg',
        'data-lightbox': 'images',
        'data-title': captions[i]
      });
      if (i > 9) {
        links.attr('href', 'photos/' + [i] + '.jpg');
      }
      $(links).appendTo(innerImgWrapper);
    
      const img = $('<img>').attr({
        'src': 'photos/0' + [i] + '.jpg'
      });
      if (i > 9) {
        img.attr({
          'src': 'photos/' + [i] + '.jpg'
        });
      }
      $(img).appendTo(links);
    
    
    }
    
    
    // Next comes the fun part. Start trying to find ways to check if the current value of the
    // search input is included within any of the captions, and if so, log the associated image
    // to the console.
    
    
    
    //lightbox.option();
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>