ngSubmit and ngDisabled not working, but ngModel is bound to controller - javascript

This doesn't look any different than what I thought I would normally write when I put a form together in AngularJS, but for whatever reason ngSubmit is not working, and ngDisabled isn't disabling the button when the fields are empty. I took the section and pasted it into a new project to see if it was just acting out due to some other dependencies, but it still doesn't work even after trimming the fat. Can anyone see what is wrong, it's obvious after this amount of time I'm not going to see it myself.
I preloaded the form fields using the controller to verify that they are talking, interpolated the user data in pre tags which are bound to ng-model since I can see it update as I type, and there are no ng errors occuring, even looking at Chromes angular plugin it looks fine. But, login() is never invoked on ngSubmit and the button is never ngDisabled when the required fields are blank.
Stripped down version of the issue that still doesn't work:
<div ng-app="myApp">
<div ng-controller="LoginController as loginCtrl">
<form name="loginForm" role="form" ng-submit="loginCtrl.login()" novalidate></form>
<div class="form-group">
<label for="username">Username</label>
<input type="text" class="form-control" id="username" name="username" ng-model="loginCtrl.user.username" required>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" id="password" name="password" ng-model="loginCtrl.user.password" required>
</div>
<div class="form-group clearfix">
<button type="submit" class="btn btn-primary btn-block" ng-disabled="loginForm.$invalid">Login</button>
</div>
<pre>user data = {{loginCtrl.user | json}}</pre>
<pre>form invalid = {{loginForm.$invalid}}</pre> <!-- always says false... but it is invalid -->
</form>
</div>
</div>
<script>
(function() {
'use strict';
angular.module('myApp', [])
.controller('LoginController', [function() {
var self = this;
self.user = { username: 'asdf', password: 'asdf' };
self.login = function() {
console.log("hello world");
};
}]);
})();
</script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.24/angular.min.js"></script>
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>

make sure that angular libraries are included.
https://docs.angularjs.org/misc/downloading
and have a look at these solutions
https://github.com/angular/angular.js/issues/2513
and if you like to see my working form...
<div class="col-md-10">
<form class="tab-pane active form-horizontal" id="first" name="userForm" novalidate ng-submit="save()">
<h2>Sign up</h2>
<div class="form-group" ng-class="{'has-error' : submitted && userForm.username.$invalid}">
<label class="control-label col-md-3">UserName <span class="required">* </span> </label>
<div class="col-md-4">
<input type="text" name="username" class="form-control" ng-model="user.username" required placeholder="username"/>
</div>
<p ng-show=" submitted && userForm.email.$invalid" class="help-block">Username is required.</p>
</div>
<div class="form-group" ng-class="{'has-error' : submitted && userForm.email.$invalid}">
<label class="control-label col-md-3">Email <span class="required">* </span> </label>
<div class="col-md-4">
<input type="email" name="email" class="form-control" ng-model="user.email" required placeholder="email"/>
</div>
<p ng-show=" submitted && userForm.email.$invalid" class="help-block">Email is required.</p>
</div>
<div class="form-group" ng-class="{'has-error' : submitted && userForm.password.$invalid}">
<label class="control-label col-md-3">Password <span class="required">* </span> </label>
<div class="col-md-4">
<input type="text" name="password" class="form-control" ng-model="user.password" required placeholder="1.2"/>
</div>
<p ng-show="submitted && userForm.password.$error.required" class="help-block">Password is required.</p>
</div>
<div class="form-group">
<label class="control-label col-md-3">Confirm Password </label>
<div class="col-md-4">
<input type="text" name="password_confirmation" class="form-control" ng-model="user.password_confirmation"
placeholder="password_confirmation"/>
</div>
<p ng-show="submitted && userForm.password_confirmation.$invalid" class="help-block">password_confirmation is required.</p>
</div>
<div class="form-group">
<div class="pull-left">
<a class="btn btn-default" href="/app/assets/images"> Back</a>
<button type="submit" class="btn btn-primary" ng-click="submitted=true">Submit</button>
</div>
</div>
</form>
</div>

Related

When clicking the Submit button on my web form, how come the validation errors for the Input fields display, even when these fields have values?

When testing my web form that was built using HTML, CSS, Bootstrap, PHP and jQuery, the first thing I do is click the Submit button. When I do this, the text-danger errors display below the Input and Text Area fields as expected since the fields are empty. If I add a value in the Input field "Name" and click the Submit button again, the text-danger field continues to display below the Name field. The same goes when I try the same thing for the Email and Security Check fields.
When I add a value in the Message Text Area field, the text-danger error for the message field disappears along with the other errors. The message field needs to have a value in order for the errors for all of the fields to disappear.
How should I set up my jQuery so that once a value is added to a field and I click the Submit button to test, the text-danger error for that specific field no longer displays?
HTML and jQuery Code
<div class="container">
<div class="row">
<form method="post" action="index.php" class="form-horizontal">
<div class="form-group">
<label for="name" class="col-sm-2 control-label">Name</label>
<div class="col-sm-10">
<input type="text" id="name" name="name" placeholder="Enter your name" class="form-control" value="<?php echo $name;?>">
<p class="text-danger">You need to enter a name value</p>
</div>
</div>
<div class="form-group">
<label for="email" class="col-sm-2 control-label">Email</label>
<div class="col-sm-10">
<input type="email" id="email" name="email" placeholder="your#email.com" class="form-control" value="<?php echo $email;?>">
<p class="text-danger">You need to enter a valid email</p>
</div>
</div>
<div class="form-group">
<label for="message" class="col-sm-2 control-label">Message</label>
<div class="col-sm-10">
<textarea id="message" name="message" rows="4" class="form-control"><?php echo $message;?></textarea>
<p class="text-danger">You need to enter a message</p>
</div>
</div>
<div class="form-group">
<label for="secCheck" class="col-sm-2 control-label">
<?php echo $_SESSION["a"] .'+'.$_SESSION["b"];?>
</label>
<div class="col-sm-10">
<input type="text" id="secCheck" name="secCheck" class="form-control">
<p class="text-danger">Answer the question above</p>
</div>
</div>
<div class="form-group">
<div class="col-sm-10 col-sm-offset-2">
<input type="submit" value="Send" class="btn btn-primary btn-large btn-block" id="submit" name="submit">
</div>
</div>
<div class="form-group">
<div class="col-sm-10 col-sm-offset-2">
<?php echo $result; ?>
</div>
</div
</form>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
$('form').on('submit',function(){
$(".text-danger").hide();
var holderValue = false;
$(this).find('input[type!="hidden"]').each(function(){
if(!$(this).val()){holderValue=true; $(this).parent().find(".text-danger").show();}
})
if(!$("#message").val()){holderValue=true; $(this).parent().find(".text-danger").show();};
if(holderValue){return false;}
// event.preventDefault();
// console.log('form submitted');
})
$("input").on("change paste keyup", function() {
if($(this).val()){
$(this).parent().find(".text-danger").hide();
}
});
$("textarea").on("change paste keyup", function() {
if($(this).val()){
$(this).parent().find(".text-danger").hide();
}
});
</script>
Bootstrap Custom Form
There are a couple of key Bootstrap attributes and classes needed for custom validation:
HTML
<form ... novalidate>
All <input ... required>
Remove all <p class='danger-text'>...
Replace the previous with <aside class='invalid-feedback'>
Also the tags have been changed from <div> to a more semantic tag, but it isn't required. The layout has been changed as well -- originally the layout had only one .row which now has several .form-rows (not sure if that was intentional or not, but it looks better when using .form-control).
jQuery
On each .form-control ...
$('.form-control').each(function() {...
...if the current .form-control is invalid...
if ($(this).is(':invalid')) {...
...stop the from submitting and show the invalid message...
e.preventDefault();
$(this).next('.invalid-feedback').show();...
...otherwise hide the invalid message if need be.
} else {
$(this).next('.invalid-feedback').hide();
}
Demo
$('.invalid-feedback').hide();
$('#main').on('submit', function(e) {
$('.form-control').each(function() {
if ($(this).is(':invalid')) {
e.preventDefault();
$(this).next('.invalid-feedback').show();
} else {
$(this).next('.invalid-feedback').hide();
}
});
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet">
<main class="container">
<form id='main' class="form-horizontal" method="post" action="index.php" novalidate>
<section class="form-row">
<fieldset class="form-group col-sm-10">
<label for="name" class="control-label">
Name
</label>
<input id="name" name="name" class="form-control" type="text" placeholder="Enter your name" required>
<aside class="invalid-feedback">
You need to enter your name.
</aside>
</fieldset>
</section>
<section class="form-row">
<fieldset class="form-group col-sm-10">
<label for="email" class="control-label">
Email
</label>
<input id="email" name="email" class="form-control" type="email" placeholder="your#email.com" required>
<aside class="invalid-feedback">
You need to enter your email.
</aside>
</fieldset>
</section>
<section class="form-row">
<fieldset class="form-group col-sm-10">
<label for="message" class="control-label">
Message
</label>
<textarea id="message" name="message" class="form-control" rows="4" required></textarea>
<aside class="invalid-feedback">
You need to enter a message.
</aside>
</fieldset>
</section>
<section class="form-row">
<fieldset class="form-group col-sm-10">
<label for="secCheck" class="control-label">
</label>
<input id="secCheck" name="secCheck" class="form-control" type="text" required>
<aside class="invalid-feedback">
Answer the security question above.
</aside>
</fieldset>
</section>
<section class="form-row">
<fieldset class="form-group col-sm-10 col-sm-offset-2">
<input id="submit" name="submit" class="btn btn-primary btn-large btn-block" type="submit" value="Send">
</fieldset>
</section>
<section class="form-row">
<fieldset class="form-group col-sm-10 col-sm-offset-2">
<output id='result'></output>
</fieldset>
</section>
</form>
</main>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.2.1/js/bootstrap.min.js"></script>

reCAPTCHA 2 causes 'too much recursion'

I am using bootstrap 4 in my Umbraco CMS project.
I want to add reCAPTCHA 2 in a registration form but I am having no luck with it.
Generated the keys for the recaptcha and set them in web.config where I can get later.
Here is my code of how I am trying to do it.
At the end of the header tag I included this scripts:
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
Then the form looks like this:
#using (Html.BeginUmbracoForm<AccountSurfaceController>("RegisterUser", null, new { id = "RegisterForm" }, FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-group">
<div class="alert alert-info alert-dismissible fade show" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<small>Te gjitha fushat e meposhtme duhen plotesuar.</small>
</div>
</div>
<div class="form-group">
<label for="FirstName" class="form-control-label">Emri:</label>
<input type="text" class="form-control" name="FirstName" id="FirstName">
</div>
<div class="form-group">
<label for="LastName" class="form-control-label">Mbiemri:</label>
<input type="text" class="form-control" name="LastName" id="LastName">
</div>
<div class="form-group">
<label for="Username" class="form-control-label">Username:</label>
<input type="text" class="form-control" name="Username" id="Username">
</div>
<div class="form-group">
<label for="Email" class="form-control-label">Email:</label>
<input type="text" class="form-control" name="Email" id="Email">
</div>
<div class="form-group">
<label for="Password" class="form-control-label">Password:</label>
<input type="password" class="form-control" name="Password" id="Password">
</div>
<div class="form-group">
<label for="ConfirmPassword" class="form-control-label">Konfirmo Password:</label>
<input type="password" class="form-control" name="ConfirmPassword" id="ConfirmPassword">
</div>
<div class="form-group">
<div class="col-6">
<label for="captchaContainer" class="form-control-label">Captcha:</label>
</div>
<div class="col-6">
<div id="captchaContainer" class="g-recaptcha" data-sitekey="#ConfigurationManager.AppSettings[DictionaryKeys.ReCaptchaPublicKey]"></div>
</div>
</div>
<button type="submit" class="btn btn-primary">Regjistrohu</button>
}
I read some questions like this in SO but they did not solve my problem.
The recaptcha item shows in the page but when I click on it it creates the error 'too much recursion' in console and shows nothing.
Does anybody know why might cause this issue ?
Thanks in advance.
I found the issue and it was pretty strange indeed.
I had more than one form in my webpage.
The first one had the recaptcha while the other forms did not.
But other forms did have a field as below:
<input name="tagName" type="hidden" value="array" />
And that was the problem because when I change te name attribute to semthing else it works, for example:
<input name="anotherName" type="hidden" value="array" />
I think there is a bug in recaptacha logic to handle this scenario if you put name attribute equal to tagName.
Anyway will report this to recaptach team and let know if this is a bug or there is something I am missing.

stop refresh when form is submitted if any error and refresh if no error

I have 2 forms log in and sign up written on same index.php and they toggle according to the users need.The log in form appears when you open index.php while the sign up form is hidden and appears only when you click on signup here link.
Now my issue is that while signing up if there is any error(validation,database error) then the page refreshes when submit button is clicked obviously and returns to my login form which appears when you open/refresh index.php.Again I have to click on signup here link to solve the errors.
I just want to stay on signup form when errors appear that means I dont want the page to be refreshed when clicked on submit but want the errors to appear and solve them then and there.
$.ajax({
type: "POST",
url: "phpindex.php",
data: $("#signUpForm").serialize(),
success:function(data)
{
if ("#error".val(data))
{
e.preventDefault();
}
}
});
});
My validation and database code is written in phpindex.php
***************signup form************************
<form method="post" id="signUpForm">
<div class="container" id="signupContainer">
<h1>Sign Up</h1>
<div id="error"><?php if ($error!="") {
echo '<div class="alert alert-danger" role="alert">'.$error.'</div>';
} ?></div>
<div class="form-group row">
<label class="col-sm-2 form-control-label">Name</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="name" placeholder="Your name">
<span class="fa fa-user"></span>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 form-control-label">Address1</label>
<div class="col-sm-10">
<input type="text" id="address1" class="form-control" name="address1" placeholder="Home address">
<span class="fa fa-map-marker"></span>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 form-control-label">Address2</label>
<div class="col-sm-10">
<input type="text" id="address2" class="form-control" name="address2" placeholder="City,Pincode....">
<span class="fa fa-map-marker"></span>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 form-control-label">Email</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="email" placeholder="Email Address">
<span class="fa fa-envelope"></span>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 form-control-label">Password</label>
<div class="col-sm-10">
<input type="password" class="form-control" name="password" placeholder="Password">
<span class="fa fa-key"></span>
</div>
</div>
<div class="form-group row">
<div class="col-sm-offset-5 col-sm-10">
<input type="submit" id = "submit1"class="btn btn-success btn-lg" value="Sign In" name="submit">
</div>
</div>
<p><a class="toggleForms">Back to Log in</a></p>
</div>
</form>
***************login form*****************
<form method="post" id="logInForm">
<div class="container" id="logInContainer">
<h1>Log In</h1>
<div id="success"><?php if ($success!="") {
echo '<div class="alert alert-success" role="alert">'.$success.'</div>';
} ?></div>
<div class="form-group row">
<label class="col-sm-3 form-control-label">Emai</label>
<div class="col-sm-8">
<input type="email" class="form-control" placeholder="Email" name="email">
<span class="fa fa-envelope"></span>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 form-control-label">Password</label>
<div class="col-sm-8">
<input type="password" class="form-control" placeholder="Password" name="password">
<span class="fa fa-key"></span>
</div>
</div>
<div class="form-group row">
<div class="col-sm-offset-4 col-sm-10">
<input type="hidden" name="signUp" value="0">
<input type="submit" id = "submit2" class="btn btn-success btn-lg" value="Log In" name="submit">
</div>
</div>
<p><a class="toggleForms">Sign Up Here</a></p>
</div>
</form>
Firstly, there are numerous errors in the code you have submitted. I believe they are mainly due to clumsy copy and pasting, but there is one that I think you just have in your code, and it is the missing jQuery reference for "#error".
"#error".val(data)
I think you wanted to write something like this
$("#error").val(data)
This error would stop "preventDefault" from happening.
Secondly, I wonder where is your submit handler for those forms and how it looks like. If you have none, then there is you answer. You just do not catch the submit event.
Lastly, I would consider calling, instead of preventDefault:
return false
Please see this thread as for the reasons why
event.preventDefault() vs. return false

Parsleyjs 2 and Bootstrap 3 input text field with addon obscuring on errors

I am currently trying to implement Parsleyjs 2.2 to work nicely with Bootstrap 3.3. But I am experiencing some problems with getting the errors displayed beneath the text-field with an addon (input-group-addon).
I have tricked a bit with the HTML/CSS to get the kind of responsive behaviour that I wanted, but here is the underlying HTML/JS:
$('.signupForm').parsley({
successClass: 'has-success',
errorClass: 'has-error',
classHandler: function(el) {
return el.$element.closest(".form-group");
},
errorsWrapper: '<span class="help-block"></span>',
errorTemplate: "<span></span>"
});
<form class="signupForm" method="post" accept-charset="utf-8" action="" data-parsley-validate="">
<div class="form-group">
<label class="control-label" for="subdomainInput">Subdomain</label>
<div class="input-group">
<span class="input-group-addon" id="subddomainAddon">https://</span>
<input type="text" class="form-control input-lg" id="subdomainInput" required="">
<span class="input-group-addon" id="subddomainAddon">.domain.com</span>
<!-- <span class="help-block">Errors appears here</span> -->
</div>
<!-- <span class="help-block">Errors should be here</span> -->
</div>
<div class="container-fluid">
<div class="row">
<span class="form-group">
<div class="col-sm-1">
<label for="nameInput" class="inlineLabel">Name</label>
</div>
<div class="col-sm-5">
<input type="text" class="form-control" id="nameInput" placeholder="John Doe" required="">
</div>
</span>
<div class="form-group">
<div class="col-sm-1">
<label for="emailInput" class="inlineLabel">Email</label>
</div>
<div class="col-sm-5">
<input type="text" class="form-control" id="emailInput" placeholder="john#example.com" required="">
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<br/>
<button type="submit" class="btn btn-danger">Register</button>
</div>
</div>
</div>
You were soo close! You need to set the errors container to the .form-group as well.
errorsContainer: function(el) {
return el.$element.closest('.form-group');
},

AngularJS form validation not showing error message

I'm trying to do form validation with AngularJS but somehow the page won't show my required message.
Can anyone point me in the right direction what I'm missing at this time? I've just picked up AngularJS and I'm trying to write a proof of concept, so we can use this in production.
HTML
<form id="signup" class="form-horizontal" name="signup" novalidate>
<legend>Register</legend>
<div class="control-group">
<div class="control-group">
<label class="control-label">Username</label>
<div class="controls">
<div class="input-prepend">
<span class="add-on"><i class="icon-user"></i> </span>
<input type="text" class="input-xlarge" id="uname" ng-model="register.uname" name="uname" placeholder="Username" required>
<span ng-show="signup.uname.$error.required" class="help-inline">Required</span>
</div>
</div>
</div>
JavaScript
function registerController($scope){
$scope.master = {};
$scope.reset = function(){
$scope.register = angular.copy($scope.master);
}
};
As J.Pip stated, the message wasn't shown due to mis formatted HTML code. It should be solved with the code below.
HTML code
<form id="signup" class="form-horizontal" name="signup" novalidate>
<legend>Register</legend>
<div class="control-group">
<label class="control-label">Username</label>
<div class="controls">
<div class="input-prepend">
<span class="add-on"><i class="icon-user"></i> </span>
<input type="text" class="input-xlarge" id="uname" ng-model="register.uname" name="uname" placeholder="Username" required />
<span ng-show="signup.uname.$error.required" class="help-inline">Required</span>
</div>
</div>
</div>
</form>

Categories