0

When I click on an image it should be adding it to an array, however the max lenght of the array is 6, therefore if there are already 6 objects in the array it should alert and stop letting the user click on any new image.

When I run the following I can keep adding images and the alert never happens.

      jQuery('body').on('change', '.masonry .item :checkbox', function () {
        var urls = [];
        urls.length = 6;
        if (jQuery(urls.length > 6)) {
          alert("Puoi aggiungere un massimo di 6 immagini");
        } else {
          jQuery('.masonry .item :checkbox:checked').each(function () {
            urls.push(jQuery(this).next('label').find('img').attr('src'));
          });
        }
      });
Roberto Marras
  • 153
  • 2
  • 11

7 Answers7

2

You'll have to check the length of the checked items, not an empty array.

jQuery('body').on('change', '.masonry .item :checkbox', function () {
    var urls = [];
    var checkedItems = jQuery('.masonry .item :checkbox:checked'); // get the checked items
    if (checkedItems.length > 6) {                                 // if the checked items are more than 6, ...
        alert("No! No! No! Only 6!");
        jQuery(this).prop("checked", false);  //<<< UNCHECK THE ELEMENT JUST CHECKED SO THE COUNT REMAINS 6
    } else {
        checkedItems.each(function () {
            urls.push(jQuery(this).next('label').find('img').attr('src'));
        });
    }
});
ibrahim mahrir
  • 31,174
  • 5
  • 48
  • 73
0

use if (urls.length > 6) instead of if (jQuery(urls.length > 6))

This is working as expected.

var urls = [];
urls.length = 6;
document.write(urls.length);
document.write("<br>");
document.write(urls.length > 6)
/*declare urls array outside of your method, use click event and event.preventDefault(); to stop checkbox to being check. */
var urls = [];

jQuery('body').on('click', '.masonry .item :checkbox', function (event) {
          //alert(urls.length);
            if (urls.length > 5) {
              alert("Puoi aggiungere un massimo di 6 immagini");
              event.preventDefault();
            } else {
            //alert(jQuery(this).next('label').find('img').attr('src'))
         urls.push(jQuery(this).next('label').find('img').attr('src'));

            }
          });
Mohammad Arshad Alam
  • 9,694
  • 6
  • 38
  • 61
0

Declare your urls array as a global variable. Remove urls.length=6; it has no effect. Modify your if condition to If (urls.length >6)

0

If you need the srcs of at most 6 checked inputs, you can create an object in which you can set and delete items as per their checked status. Also, by using click event, you can prevent the checkbox from being checked unnecessarily (which will require you to uncheck it manually). Find the working fiddle here and the working snippet below.

var urls={};
console.clear();
jQuery('body').on('click', '.masonry .item :checkbox', function (e) {
 var this_id = jQuery(this).attr("id");
  var is_checked = jQuery(this).is(":checked");
   if(is_checked){
      if (Object.keys(urls).length < 6){
         urls[this_id] = jQuery(this).next('label').find('img').attr('src');
      } else {
       alert("Puoi aggiungere un massimo di 6 immagini");
        e.preventDefault();
        return false;
      }
   } else {
     delete(urls[this_id]);
   }
    
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="masonry"><div class="item"><input type="checkbox" name="thing_1" value="valuable" id="thing_1"><label for="thing_1"><img class="img-responsive" src=""></label></div><div class="item"><input type="checkbox" name="thing_2" value="valuable" id="thing_2"><label for="thing_2"><img class="img-responsive" src=""></label></div><div class="item"><input type="checkbox" name="thing_3" value="valuable" id="thing_3"><label for="thing_3"><img class="img-responsive" src=""></label></div><div class="item"><input type="checkbox" name="thing_4" value="valuable" id="thing_4"><label for="thing_4"><img class="img-responsive" src=""></label></div><div class="item"><input type="checkbox" name="thing_5" value="valuable" id="thing_5"><label for="thing_5"><img class="img-responsive" src=""></label></div><div class="item"><input type="checkbox" name="thing_6" value="valuable" id="thing_6"><label for="thing_6"><img class="img-responsive" src=""></label></div><div class="item"><input type="checkbox" name="thing_7" value="valuable" id="thing_7"><label for="thing_7"><img class="img-responsive" src=""></label></div><div class="item"><input type="checkbox" name="thing_8" value="valuable" id="thing_8"><label for="thing_8"><img class="img-responsive" src=""></label></div><div class="item"><input type="checkbox" name="thing_9" value="valuable" id="thing_9"><label for="thing_9"><img class="img-responsive" src=""></label></div><div class="item"><input type="checkbox" name="thing_10" value="valuable" id="thing_10"><label for="thing_10"><img class="img-responsive" src=""></label></div><div class="item"><input type="checkbox" name="thing_11" value="valuable" id="thing_11"><label for="thing_11"><img class="img-responsive" src=""></label></div><div class="item"><input type="checkbox" name="thing_12" value="valuable" id="thing_12"><label for="thing_12"><img class="img-responsive" src=""></label></div><div class="item"><input type="checkbox" name="thing_13" value="valuable" id="thing_13"><label for="thing_13"><img class="img-responsive" src=""></label></div><div class="item"><input type="checkbox" name="thing_14" value="valuable" id="thing_14"><label for="thing_14"><img class="img-responsive" src=""></label></div><div class="item"><input type="checkbox" name="thing_15" value="valuable" id="thing_15"><label for="thing_15"><img class="img-responsive" src=""></label></div><div class="item"><input type="checkbox" name="thing_16" value="valuable" id="thing_16"><label for="thing_16"><img class="img-responsive" src=""></label></div><div class="item"><input type="checkbox" name="thing_17" value="valuable" id="thing_17"><label for="thing_17"><img class="img-responsive" src=""></label></div><div class="item"><input type="checkbox" name="thing_18" value="valuable" id="thing_18"><label for="thing_18"><img class="img-responsive" src=""></label></div><div class="item"><input type="checkbox" name="thing_19" value="valuable" id="thing_19"><label for="thing_19"><img class="img-responsive" src=""></label></div><div class="item"><input type="checkbox" name="thing_20" value="valuable" id="thing_20"><label for="thing_20"><img class="img-responsive" src=""></label></div></div>
Yogesh Mistry
  • 2,082
  • 15
  • 19
0

In my understanding, following code is causing issue:

jQuery('.masonry .item :checkbox:checked').each(function() {
  urls.push(jQuery(this).next('label').find('img').attr('src'));
});

Say you have 10 images, so on every click, you are pushing 10 times. You should only push current element once. Try checking if element exists. If yes, do not push it.

Following is a sample fiddle of how I would do it. It does not use jQuery,, but you can adapt your code accordingly.

JSFiddle


Edit

Updated Fiddle

Issue is:

jQuery('body').on('change', '.masonry .item :checkbox', function() {
    var urls = [];

You are initialising urls in every click. So it will always have length = 0

It should be outside the handler's scope.

Rajesh
  • 24,354
  • 5
  • 48
  • 79
0

check this solution, hope it helps, you can check the console.log to see the updated url and urls count.

1st declare array urls out side the change event.

inside if using the to stop check more img

inside else empty urls array first (in case you are uncheck one checkbox, in that case you don't want to push, you want to take it out, to make it simple just empty that list and add each checked to array (for sure you need to improve this but for now this is the fastest working solution))

I have two console log at the end so you can verify the urls and length.

var urls = [];
jQuery('body').on('change', '.masonry .item :checkbox', function() {
  if ($('input[type=checkbox]:checked').length > 6) {
    alert("Puoi aggiungere un massimo di 6 immagini");
    var $checkbox = $(this);
    // Ensures this code runs AFTER the browser handles click however it wants.
    setTimeout(function() {
      $checkbox.removeAttr('checked');
    }, 0);
    event.preventDefault();
    event.stopPropagation();
  } else {
      urls = [];
    jQuery('.masonry .item :checkbox:checked').each(function() {
      urls.push(jQuery(this).next('label').find('img').attr('src'));
    });
  }
    console.log('this urls-->' + urls);
    console.log('this urls length-->' + urls.length);
});

https://jsfiddle.net/dalinhuang/5rLh3bq2/4/

Dalin Huang
  • 11,212
  • 5
  • 32
  • 49
0

You can instead get the length of the checked elements at the time the checkboxes are clicked. It's a bit more straightforward. I also prevented any checkbox after 6 from being enabled.

var urls = []; // if you wish to use it outside, make it global

$('.masonry :checkbox').on('click', function(e){

  var selected = $('.masonry :checkbox:checked');

  if( selected.length > 6 ){
    alert( 'Sorry, no more than 6' );
    e.preventDefault(); // stops the checkbox from being selected
    return;
  }

  // do what you wish with the selected ones
  // selected.each()

})

Here is a working codepen: https://codepen.io/h3raldo/pen/vmOXrJ

heraldo
  • 187
  • 7