Count the current number of inputs with a specific property after a function has run which has changed these properties

StackOverflow https://stackoverflow.com/questions/17552672

  •  02-06-2022
  •  | 
  •  

Question

Related to this question: Using jQuery, keep a form's submit button disabled until all of the required textbox, radio, checkbox elements have a value (or are checked)

I was very kindly helped to put together this function

    $('input[type=submit]').prop('disabled', true).addClass('disabled');

    var required = $('[required]');

    required.bind('change keyup', function()
    {
        var flag = 0;
        required.each(function()
        {   
            if ($(this).not(':checkbox, :radio').val() || $(this).filter(':checked').val())
            {
                flag++;
            }
        });

        if (flag == required.length)
        {
            $('input[type=submit]').prop('disabled', false).removeClass('disabled');
        }
        else
        {
            $('input[type=submit]').prop('disabled', true).addClass('disabled');
        }
    });

What's happening here is that the submit button of a form is staying disabled until all fields with the "required" property have some sort of value (or have been checked, etc.).

Part of a bigger picture, another jQuery function (which works fine) is hiding some of these fields depending on the value of a select box.

Effectively, when those fields are hidden, the required property should be removed. With the required property being removed, I would expect the above function to count (required.length) only the remaining required fields, but in fact, it counts all of them -- even those ones that no longer have the required property.

Any ideas on a way around this?

Was it helpful?

Solution

You are comparing the same set of elements over and over again. You need to re-select the ones that you need during each check.

Change

required.each(function()

To

$([required]).each(function()

You are selecting all the element and then looping through them regardless of the properties that they now have. You want to have jQuery re-select the elements that now have the required property so that you get an updated list. This should then perform as you expect.

OTHER TIPS

you have not only remove required atribute, but also 1. .unbind('change keyup') for this element 2. remove it from collection with required = required.not('[required]');

this fiddle gives basic idea: before you click button both required inputs alert their number, after you click it, total length is reduced and second input stops to alert

don't forget to bind change keyup if you make it required again

You can add:

|| $(this).css('display') === 'none')

to the if around flag++.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top