1

I have an array that holds some checkbox id numbers that are added when a user clicks on some checkboxes in a table. I want to disable a button if the array is empty and enable it when it has some items.

    var ids = [];

         $('#Table tbody').on('click', '.checkbox', function () {

             var idx = $.inArray($(this).attr("id"), ids);
             if (idx == -1) {
                 ids.push($(this).attr("id"));
             } else {
                 ids.splice(idx, 1);
             }
        });

What's the best way to monitor the array and check whether an element has been added to the id array or brought back down to 0 to enable/disable the button?

<input class="btn disabled" type="submit" name="submit" id="btnsubmit" value="Submitselected"/>
user3266638
  • 429
  • 8
  • 25

2 Answers2

2

You've already got the function running when a checkbox is clicked (altho maybe the change event is better suited for you) - just modify the disabled prop on the button now:

$("#btnsubmit").prop("disabled", ids.length === 0);
tymeJV
  • 103,943
  • 14
  • 161
  • 157
1

I wanted to expand on @PeterRadar 's answer here, because it's actually a great recommendation. Basically the idea here is to wrap the watched array in a Proxy, and then using that proxy to basically "subscribe" to changes. Combining that recommendation with this answer and @tymeJV's, the resulting code would look something like this snippet:

var array = [true];

    var updateButtonVisibility = function() {
           $("#test").prop("disabled", array.length === 0);
      }

$( document ).ready(function() {
          var arrayChangeHandler = {
           get: function(target, property) {
                updateButtonVisibility();
                console.log('getting property ', property);
                return target[property];
           },
           set: function(target, property, value, receiver) {
           target[property] = value;
           updateButtonVisibility();
           console.log('setting property ' + property + ' length is ' + array.length);
           return true;
           }
      }

      var wrappedArray = new Proxy(array, arrayChangeHandler )

      
       $("#add").click(function() {wrappedArray.push(true);});
      $("#subtract").click(function() {wrappedArray.pop();});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

  <body>

    <button id="test" type="submit">HELLO</button>
    <button id="add" type="submit">Add</button>
    <button id="subtract" type="submit">Subtract</button>
  </body>

Why do this?

Using the proxy (the wrappedArray object) in this way allows you to run custom behavior any time that object is written to/read from using its setter and getter. In your example, the means the function to disable your button runs any time your object is changed, not just when another ui component is clicked. This means your implementation of the button's disabled/enabled state is not tied to any specific UI component. As long as access is used through this wrappedArray, no matter what causes the set/get, your disabled/enabled state will be updated the way you want.

istrupin
  • 1,423
  • 16
  • 32