0

http://jsfiddle.net/jy3UR/2/

Above given is the fiddle.

I have a simple login form. Username, password textfield & a submit button. Submit button is kept disabled until both username & password is entered. And I have successfully done that using the jQuery function given below.

var $input = $('input'),
$register = $('#signin');
$register.attr('disabled', true);

$input.keyup(function() {
    var trigger = false;
    $input.each(function() {
        if (!$(this).val()) {
            trigger = true;
        }
    });
    trigger ? $register.attr('disabled', true) : $register.removeAttr('disabled');
});

Given below is my form.

<div class="form-group">
    <label for="txtusername" class="col-sm-4 control-label">Username</label>
    <div class="col-sm-8">
        <input type="text" class="form-control" id="txtusername" name="txtusername" placeholder="Username">
    </div>
</div>
<div class="form-group">
    <label for="txtpassword" class="col-sm-4 control-label">Password</label>
    <div class="col-sm-8">
        <input  type="password" class="form-control" id="txtpassword" name="txtpassword" placeholder="Password">
    </div>
</div>
<div class="form-group">
    <div class="col-sm-offset-4 col-sm-8">
        <div class="checkbox">
            <label><input type="checkbox">Remember me</label>
        </div>
    </div>
</div>
<div class="form-group">
    <div class="col-sm-offset-4 col-sm-8">
        <button type="submit" id="signin" class="btn btn-default"  >Sign in</button>

</div>

You know when a user enters his credentials and submits the button, web browsers ask for storing password & if the user clicks yes, his password & username is stored in the browser. So the next time, when he visits the page, his username & password is already filled in the filed. Now comes the problem, even though the web browser (chrome, firefox) automatically filled in the form for the user, the button is still disabled. For enabling the button, user needs to enter any one of fields (even a single alphabet) of the fields for enabling that button. Technically speaking, this is not right. As data is already filled in the form (by the browser), the button has to be enabled. Any suggestions to make it as like that???

Smokey
  • 1,857
  • 6
  • 33
  • 63
  • Button is enabled only if we enter the details from a keyboard. As a browser, fills the fields automatically, the button is not enabled. My jQuery works only based on key press. – Smokey Jun 05 '14 at 10:10
  • Maybe if you add `if ( $('idhere').val() != '' ) { enablebutton(); }` on pageload you can play around with it? – Déjà vu Jun 05 '14 at 10:11
  • write your code when document loads, use $(document).ready(function(){}) – shairya Jun 05 '14 at 10:12
  • Why not use [required attribute](http://www.w3schools.com/tags/att_input_required.asp) – Sharad D Jul 01 '14 at 16:20

16 Answers16

2
$.fn.extend({
    has_value: function() {
        return this.filter( function() {
            return $( this ).val().length == 0;
        }).length;
    }
});

var $input = $( 'input.form-control' ),
    $register = $('#signin');

$input.on( 'change keyup', function() {
    $register.prop( 'disabled', $input.has_value() );       
}); 

$input.trigger( 'change' );

Explanation

  • The first part is an example of extending the jQuery prototype object, has_value() method is added, and since that method is now part of jQuery it can be called as any other method on collection of DOM elements. This method filters elements by value, and returns true if there are no elements with empty value.

  • To successfully monitor the changes in the input fields, at least two events, change and keyup, must be used. Input elements the for username and password are bound to that two events. Change event is fired when element loses focus, and keyup is fired when user releases a key.

  • Event handler enables or disables the button, to do that it sets the disabled property with .prop() method, recommended by jQuery to avoid inconsistent behaviors.

  • This code should be placed inside the domready event, where can we immediately fire the change event and test whether the fields are auto-filled by browser.

  • FIDDLE

Browser autocomplete

Because of inconsistencies of web browsers, you can't rely that the change event will be triggered when browser autocompletes an input field. There is a simple workaround to use the setInterval() function that will monitor for changes at regular intervals. Since we are dealing with small form with only a couple of input fields it can be used safely without noticeable lags.

setInterval( function() {
    $input.trigger( 'change' );
}, 100 );

Suggestion

Instead of writing all that code manually, HTML5 required attribute ( supported by any sane browser ) does all that. This attribute specifies that the user must fill in a value before submitting a form. Browser will prevent form submission if any required field is empty, and the user will also get a notification to fill that field.

Additional Info

jQuery extend: jQuery.fn.extend()
jQuery events: .change() .keyup()
jQuery properties: .prop() .prop() vs .attr():
Autocomplete: Browser Autofill, Autocomplete and JavaScript Change Event
HTML5: required attribute

Community
  • 1
  • 1
Danijel
  • 12,408
  • 5
  • 38
  • 54
  • This answer is almost near to perfection. It's just one step behind. Now the button gets enabled even when the browser automatically fills data. BUT...I have to click on any of the text boxes to enable the button, I don't have to fill the data. Earlier when browser fills data, I had to remove any one character from any of the text boxes to enable the button. This is not needed now. Now I have to click on any one of the fields. How to improve this? @Danijel – Smokey Jun 30 '14 at 04:36
  • Button is shown disabled even when the browser fills the data (actually its enabled. Thanks to your code). To make it enabled either I have to click on the button twice or I have to click inside any one of the text fields. @Danijel – Smokey Jun 30 '14 at 07:12
  • I made some update to answer regarding browsers behavior on autocomplete and js change event, also a few related links are included. – Danijel Jun 30 '14 at 12:51
  • Where should I add this setInterval function?? @Danijel – Smokey Jul 03 '14 at 05:59
  • 1
    Replace `$input.trigger( 'change' );` with `setInterval( function() { $input.trigger( 'change' ); }, 100 );` – Danijel Jul 03 '14 at 14:52
1

You can add the following code. So that it will check initially without any key trigger.

$(document.ready(function(){
   $input.each(function() {
                if (!$(this).val()) {
                    trigger = true;
                }
        });

 });
Suresh Ponnukalai
  • 13,820
  • 5
  • 34
  • 54
1

Might be the reason is that you remove the "disable" attribute of button inside the key-up event of input. that's OK in the case when user fill up form manually. But if input's are filled up by the browser automatically then you must have to check the input values on the document ready event and based on the result you need to apply disable attribute to button. Below is the example :

$(document).ready(function(){
  HandleButtonState();
  $input.keyup(function() {
      HandleButtonState();
  });
}); 

function HandleButtonState(){
    var trigger = false;
    $input.each(function() {
       if (!$(this).val()) {
          trigger = true;
       }
    });
    trigger ? $register.attr('disabled', true) : $register.removeAttr('disabled');
}
Smokey
  • 1,857
  • 6
  • 33
  • 63
Arpit Jain
  • 455
  • 3
  • 8
1

You can check weather the form is blank on load and also on keyup as followed :

$(function(){
  var $input = $('input:not(:checkbox)'),// Check box is having some value even when not checked so ommitting it.
              $register = $('button:submit');
              $register.attr('disabled', !isFilledForm());

  $input.keyup(function() {
      $register.prop('disabled', !isFilledForm())
  });

  function isFilledForm(){
      var isFilled = true;
      $input.each(function(){
        if(!$(this).val()) isFilled = false;
      })
      return isFilled
  }
})

Please find the updated fiddle in which I have deleberately given value for password field so as to demostrate prefilled value in any input. The sign In button is being enabled.

UPDATED FIDDLE

Updated Fiddle with sign in button enabled only when both fields are filled

Revised Fiddle kept everything in document.ready.

I have checked this in browser. Hope this help.

raviture
  • 959
  • 7
  • 11
  • And where's that fiddle? I don't see anything attached with your answer. @ravi1991 – Smokey Jun 27 '14 at 07:21
  • ALmost near to perfection. But button gets enabled when one field is entered. It shouldn't be that way. Button has to get enabled only when both the fields are filled by user or pre-filled by the browser. In all other cases, button has to remain disabled. @ravi1991 – Smokey Jun 27 '14 at 07:48
  • The above given solution works only in the fiddle. It does not enable the button if values are already filled by the browser. I tested it in the development. No use. @ ravi1991 – Smokey Jun 27 '14 at 07:53
  • I have updated revised fiddle link again. Also please alert the values on input fields on page load and share the output. – raviture Jun 27 '14 at 07:59
  • Nothing happened new. It is works like the same fiddle I passed with the question. And I alerted both the fields. They are empty. These values are stored from browser cache memory. But in your code, values are hard coded. Try this in a browser with the help of a local server. I called the function you gave on page load. And during that time..values are empty. @ravi1991 – Smokey Jun 27 '14 at 08:07
  • Please check the revised fiddle. It will work in development too. – raviture Jun 27 '14 at 08:49
1

Can you try this javascript instead of yours?

var $input = $('input'),
$register = $('#signin');
$register.attr('disabled', true);
$input.keyup(function() {
var trigger = false;
$input.each(function() {
    if (!$(this).val()) {
        trigger = true;
    }
});
trigger ? $register.attr('disabled', true) : $register.removeAttr('disabled');
});
$('.form-group').on('change', function(){
  var usr_name = $('#txtusername').val().length;
  var usr_pass = $('#txtpassword').val().length;
  if(usr_name < 1 || usr_pass < 1){
    $register.attr('disabled', true);   
  }
});

Here's fiddle to check http://jsfiddle.net/vaske1986/va4Kz/

Marko Vasic
  • 690
  • 9
  • 27
  • Uncaught SyntaxError: Unexpected end of input @MrCkobe – Smokey Jun 27 '14 at 07:43
  • Button gets enabled if values are pre-filled by the browser..but it doesn't get disabled if user clears the pre-filled values from the textboxes. @MrCkobe – Smokey Jun 27 '14 at 07:45
  • Oh, I see. I might know what to do. I'll update my answer. @TheJoker – Marko Vasic Jun 27 '14 at 07:52
  • @TheJoker can you try now? – Marko Vasic Jun 27 '14 at 07:57
  • Uncaught ReferenceError: body is not defined (index):94 (anonymous function). Now my button stays disabled forever..even if I enter inout from my keyboard. :) :) @MrCkobe – Smokey Jun 27 '14 at 08:01
  • How about now? I changed `body` to `.form-group` And what jQuery library are you using? @TheJoker – Marko Vasic Jun 27 '14 at 08:12
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/56401/discussion-between-the-joker-and-mrckobe). – Smokey Jun 27 '14 at 08:15
  • Uncaught TypeError: Cannot read property 'length' of undefined in var usr_name = $('txtusername').val().length; @MrCkobe – Smokey Jun 27 '14 at 08:18
  • Sorry, my mistake. just replace `txtusername` with `#txtusername` and `txtpassword` with `#txtpassword` @TheJoker – Marko Vasic Jun 27 '14 at 08:22
1
$(document).ready(function() {
    checkLoginStats();
    $("#txtusername").attr("onkeyup","checkLoginStats();");
    $("#txtpassword").attr("onkeyup","checkLoginStats();");
});

function checkLoginStats()
{
    var userName   = $("#txtusername").val();
    var userPass   = $("#txtpassword").val();
    var buttonStat = true;
    if(userName!="" && userPass!="")
    {
        buttonStat = false;
    }
    $("#signin").attr("disabled",buttonStat);
}

hopefully this may work out http://jsfiddle.net/jy3UR/8/

ameenulla0007
  • 2,663
  • 1
  • 12
  • 15
1

Some notes:

  • If you want to dynamically change disabled state, better use the property, not the attribute.
  • Instead of each loop you can easily use every.
  • Consider using faster vanilla-js when jQuery doesn't simplify your code.
  • If you listen to keyup instead of input event, you won't notice if the user changes the field using the mouse.

Working ES5 code:

var inputs = [].slice.call(document.getElementsByTagName('input')),
    register = document.getElementById('signin');
function check() {
    register.disabled = !inputs.every(function(inp) {
        return inp.value;
    });
}
$(inputs).on('input', check);
check();

Demo

Oriol
  • 274,082
  • 63
  • 437
  • 513
  • This answer is almost near to perfection. It's just one step behind. Now the button gets enabled even when the browser automatically fills data. BUT...I have to click on any of the text boxes to enable the button, I don't have to fill the data. Earlier when browser fills data, I had to remove any one character from any of the text boxes to enable the button. This is not needed now. Now I have to click on any one of the fields. How to improve this. @Oriol – Smokey Jun 30 '14 at 04:35
  • Button is shown disabled even when the browser fills the data (actually its enabled. Thanks to your code). To make it enabled either I have to click on the button twice or I have to click inside any one of the text fields. @Oriol – Smokey Jun 30 '14 at 07:13
  • @TheJoker Can you clarify in which situation the button is in the opposite state that you want? – Oriol Jul 03 '14 at 00:25
  • Case1: User does not fill data in any fields or in one of the two fields, button is disabled. Case 1 worked fine. Case2: Browser fills data on it's own. Your code enables button,but I will have to click on the button twice to move forward. That is, your code enables button when browser fills data..but it is shown as a disabled button. When I click on that disabled button,it gets enabled. So if a new user comes & his data his filled by browser, he won't get to know that the button has been enabled by browser until he clicks on the button at least once. I have added two links @Oriol – Smokey Jul 03 '14 at 04:18
  • Link1: http://postimg.org/image/72lh1epez/ your code enabled button in autofill, but it is shown disabled. Link2: http://postimg.org/image/bfbbzkxe1/ when I click on the button a second time, it is shown enabled. @Oriol – Smokey Jul 03 '14 at 04:21
  • @TheJoker In my [demo](http://jsfiddle.net/jy3UR/15/) it works well. Maybe in your site you have another code that disables the button at the beginning? – Oriol Jul 03 '14 at 14:11
1

just Trigger Key UP function of input

$("input").keyup();

as simple as that

it will trigger key up event for your textbox (wont add any data to textbox), so your code for keyup will check there textbox are filled with data and make button enable

fiddle link Demo

full code

  $(document).ready(function () {
     var $input = $('input'),
        $register = $('#signin');
        $register.attr('disabled', true);

        $input.keyup(function() {
            var trigger = false;
            $input.each(function() {
                if (!$(this).val()) {
                    trigger = true;
                }
            });
            trigger ? $register.attr('disabled', true) : $register.removeAttr('disabled');
        });

        $("input").keyup();

    })
Dhiraj Wakchaure
  • 2,596
  • 6
  • 21
  • 37
1

Try my fiddlejs...

http://jsfiddle.net/jy3UR/13/

I've setup a timeout which will fire 2 seconds after the page loads if you put this script right before the body end tag, ''.

 var $input = $('input'), $register = $('#signin');

$register.attr('disabled', true);

$input.keyup(function() {
    validateForm();
});

var validateForm = function (){
    var trigger = false;
    $input.each(function() {
        if (!$(this).val()) {
            trigger = true;
        }
    });
    trigger ? $register.attr('disabled', true) : $register.removeAttr('disabled');
};

setTimeout(validateForm(), 2000);
Justin Russo
  • 2,214
  • 1
  • 22
  • 26
1

I have updated the code on the fiddle here:

http://jsfiddle.net/jy3UR/14/

var $input = $('input'),
            $register = $('#signin');
            $register.attr('disabled', true);

var checkInput = function(){
    var trigger = false;
    $input.each(function() {
        if (!$(this).val()) {
            trigger = true;
        }
    });
    trigger ? $register.attr('disabled', true) : $register.removeAttr('disabled');
}

$input.keyup( function(){
    checkInput();
} );

$(document).ready( function(){
    checkInput(); 
} );

And checked that the code is working fine.

Brief Explanation of Changes:

Previously, you were checking the form values status on just keyup event. Now, we are checking it also when the document is ready. The whole condition is getting checked twice that's why it has been placed inside a function now.

Debugging:

I have placed values field on the inputs and pre-populating the username field. You can populate the password field and check that if both the fields are filled then the button becomes enabled. Vice versa, if there is no input or there is only one field filled then the button remains disabled.

Qarib Haider
  • 4,796
  • 5
  • 27
  • 38
1

Use Following JavaScript code

var $input = $('input'),

  $register = $('#signin');
  $register.attr('disabled', true);

  //update signin button    
  function isDisabled($input,$register){
         var trigger = false;
                    $input.each(function() {
                        if (!$(this).val()) {
                            trigger = true;
                        }
                    });
         trigger ? $register.attr('disabled', true) : $register.removeAttr('disabled');
    }

 //check signin button status on window load event   
 $(window).load(function(){
         isDisabled($input,$register)
    });

//check signin button status on keyup event 
  $input.keyup(function() {
                    isDisabled($input,$register)
  });
Zainul Abdin
  • 835
  • 4
  • 10
1

Put this after your jquery code. Ensure it comes after it

    var $input = $('input'),
    $register = $('#signin');
    $register.attr('disabled', true);

    $input.keyup(function() {
    var trigger = false;
    $input.each(function() {
        if (!$(this).val()) {
            trigger = true;
        }
    });
    trigger ? $register.attr('disabled', true) : $register.removeAttr('disabled');
   });


   $('.form-group > input').on('input', function () {

        var empty = false;
        $('form > input, form > select').each(function () {
            if ($(this).val() == '') {
                empty = true;
            }
        });

        if (empty) {
            $('#signin').attr('disabled', 'disabled');
        } else {
            $('#signin').removeAttr('disabled');
        }
    });

Try this and see if you get the desired results

Check this fiddle http://jsfiddle.net/DaCardinal/P2c2g/

Daniel
  • 598
  • 1
  • 6
  • 23
0

write your code when document loads, use $(document).ready(function(){ /*your validation code*/})

CSchulz
  • 10,882
  • 11
  • 60
  • 114
shairya
  • 173
  • 9
0

Depending on whether the fields are aldready filled by document.onload you can check with

$(document).ready(function () {
  // trigger validation
});

If that's too early I'm afraid you can only try adding a timeout (window.setTimeout()), if that's not working for you neither, you might get around your issue with adding autocomplete="off" to your input fields.

Kevin Sandow
  • 4,003
  • 1
  • 20
  • 33
-1

I have modified you code and here is the new working DEMO You should call a function on document load which checks whether the txtusername and password are empty or not. And if they are already filled up on page load, then you should write some code which enables the button.

Note: I have added a <form> tag around your HTML content

Comment out your existing code and try this code:

$(document).ready(function(){
    function check()
    {
        var txtusername = $('#txtusername').val();
        var txtpassword = $('#txtpassword').val();
        alert('txtusername = '+txtusername+' txtpassword = '+txtpassword);
        if(txtusername !="" && txtpassword != "")
        {
            $('#signin').attr('disabled', false);
        }
        else
        {
            $('#signin').attr('disabled', true);
        }
    }    
    var $input = $('input');
    $input.keyup(function() {
        check();
    });
    check();
});
Rahul Gupta
  • 9,775
  • 7
  • 56
  • 69
-1
var hasUsername = false
  , hasPassword = false;

$('#password').on('keyup', function(e){
    var val = $(this).val();

    if ( val.length > 8 ) {
        hasUsername = true;
    }

    checkButton();
});

$('#password').on('keyup', function(e){
    var val = $(this).val();

    if ( val.length > 8 ) {
        hasPassword = true;
    }

    checkButton();
});

function checkButton(){
    if ( hasUsername && hasPassword ) {
        $("button").attr('disabled', false);
    }
}
chovy
  • 72,281
  • 52
  • 227
  • 295