skip to Main Content

I am creating an album feature in which the user can select photos from a group of photos, then apply them to a folder. The issue is, I am having trouble selecting specific photos and applying certain attributes to them (mainly css style, I want a border around the image when selected).

Here is the html/jquery:

HTML

<div class="demo-gallery">
  <ul id="lightgallery" class="list-unstyled grid">
    <?php foreach ( $media_items as $item ): ?>
      <li>
         <img class="img-responsive" id="lazy" data-src="<?php echo $item->image_path_sd; ?>">
      </li>
    <?php endforeach; ?>
  </ul>
</div>

Jquery

var picture = document.querySelectorAll('#lazy');
$(picture).each(function () {
    $(document).on('click', /*???*/, function () {
        if ($(/*???*/).data('clicked', true)) {
            $(/*???*/).css("border", "none");
            $(/*???*/).data('clicked', false);
        } else {
            $(/*???*/).css("border", "4px solid #00CE6F");
            $(/*???*/).data('clicked', true);
            console.log($(/*???*/).data());
        }
    });
});

My guess is I need to figure out what goes where all of the ??? comments are, however, I could be trying this in the wrong direciton.

When I console.log(picture), I get an array of every photo. When I console.log(picture[2]), it shows the third picture. This is what I want, but how am I to apply these attributes to each individual photo?

Overall: I want user to click on photos they want, applying a highlighted border around the photo to let them know it’s currently selected.

2

Answers


  1. As you are using jQuery, there’s no need to use document functions, you can grab the list of items when you select something that can be applied to multiple items (like a class name).

    The key here is with jQuery, .each(function(){ }) passes in the element itself, which you can access using this. using $(pictures).each() lets you access each individual element in that set.

    So, rather than applying a single click listener on the document, you can place a click listener on each img itself.

    To show the border, place the style in the css file as a class and use the $().toggleClass(/* class name */) function.

    var pictures = $('.lazy');
    
    $(pictures).each(function () {
        // apply click listener to each image
        $(this).on('click', function () {
        
            // toggle the checked value
            if ($(this).data('clicked') == true) {
                $(this).data('clicked', false);
            } else {
                $(this).data('clicked', true);
            }
            
            // toggles the border
            $(this).toggleClass('selected');
            
            // display contents of all the items
            $(pictures).each(function(index){
              console.log('img #' + index + ': ' + $(this).data("clicked"))
            })
        });
    });
    .lazy {
    padding: 10px;
    display: inline;
    background-color: red;
    margin: 10px;
    }
    
    .selected {
      border: 2px solid black;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <!-- Replace with PHP foreach -->
    <img class="lazy" src="#">
    <img class="lazy" src="#">
    <img class="lazy" src="#">
    <img class="lazy" src="#">
    <img class="lazy" src="#">
    <!-- Replace with PHP foreach -->

    Simplified

    The other answers reminded me that this whole block can be condensed to the following code:

    $('.lazy').on('click',function(){
      $(this).toggleClass('selected');
      })
    .lazy {
      background-color: red;
      padding: 10px;
      box-sizing: border-box;
    }
    
    .selected {
      border: 2px solid black;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <img class="lazy" src="#">
        <img class="lazy" src="#">
        <img class="lazy" src="#">
        <img class="lazy" src="#">
        <img class="lazy" src="#">

    when you submit, just use $('.lazy.selected') to grab all the selected items.

    Login or Signup to reply.
  2. You cannot use an identical id selector for multiple tags on the same HTML document, instead, use ".lazy" class selector.

    then you can do something like this.

    css:

    .selected-image{
        border:1px solid #000;
    }
    

    jquery:

    $(".lazy").click(function(){
        const img = $(this)
        if(img.hasClass("selected-image")){
            img.removeClass("selected-image")
        }
        else{
            $(this).addClass("selected-image")
        }
    })
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search