I have an angularjs form that pulls default data from scope. With the default data the form is expected to be validated and hence enable the button for submission but the reverse is the case except data is entered on the input field and this enables the button. here is the snippet
<div ng-controller="FormValidationController as frmValidationController" class="ui basic segment">
<form class="ui form" name="frmValidation" novalidate>
<div ng-class = "{'has-error':frmValidation.option1.$invalid && !frmValidation.option1.$pristine}"
class="required field">
<label>Selection</label>
<input ng-model="option" ng-minlength="3" formcontrol
name="option1" placeholder="Option" type="text"
class="ng-dirty ng-valid ng-touched" required>
<div _ngcontent-c5="" ngxerrors="option1">
<div class="input-error-message" ngxerror="validName" hidden="">
selection should be there
</div>
</div>
<p ng-show = "frmValidation.option1.$invalid && !frmValidation.option1.$pristine"
class = "input-error-message">required</p>
</div>
if the model has data, the button should be enabled on launch but this never happens and I want it to happen
<button ng-click="submit(); frmValidationController.submitForm(frmValidation.$valid)"
ng-disabled ="!frmValidation.$dirty || frmValidation.$invalid"
class="ui primary button" tabindex="0" type="submit">
Proceed
</button>
The problem is here:
ng-disabled ="!frmValidation.$dirty || frmValidation.$invalid"
Specifically:
!frmValidation.$dirty
The form is only dirty if an actually user has interacted with it. Because you're loading default data, the form is filled in correctly but the user has NOT touched or "dirtied" it.
Remove that check and it should work as expected I believe.
Related
Disclaimer: I’m a backend programmer and I would like to minimize javascript code in my webpages.
I’m considering using the login form given here as example. In this example we have this
<form class="ui large form">
<div class="ui stacked segment">
<div class="field">
<div class="ui left icon input">
<i class="user icon"></i>
<input type="text" name="email" placeholder="E-mail address">
</div>
</div>
<div class="field">
<div class="ui left icon input">
<i class="lock icon"></i>
<input type="password" name="password" placeholder="Password">
</div>
</div>
<div class="ui fluid large teal submit button">Login</div>
</div>
<div class="ui error message"></div>
</form>
The login button is just a div which does nothing. There is no action argument in the form tag and there is no submit type input tag.
How do I get the page to send the input field values back to the backend server ?
Note that there is some javascript code visible in the source page that checks the validity of the fields. But there is no hint on how to get send the email and password to the backend and load the logged in page.
The login button is just a div which does nothing
Make it a <button>.
There is no action argument in the form tag
Add one if you want the data to be submitted to a different URL then that of the current page.
Your form should also be method="POST". Passwords do not belong in URLs (which are often logged in plain text).
How do I get the page to send the input field values back to the backend server ?
Use a <button> element to represent your submit button and not a <div> element. The <div> element is when you need a block element and HTML lacks an element with the semantics to describe your content. That isn't the case here, you want to submit a form and that is what submit buttons are for.
I've never worked with Angular or Angular2 before, but now I have to make an update to a site running on my domain that is using Angular2. I need to programatically fill out a textbox and click submit, but after setting the textbox's value using .value = "val", it still treats the textbox as if it is empty.
I've read up on angular and now understand the concept of ng-dirty and ng-pristine, but programatically changing the class to ng-dirty still doesn't work.
It seems like even if I change the classes, it is still not updating the "pristine" status and it still considers the textbox empty.
I've read about "markAsDirty()" and tried using it but I get "markAsDirty is not a function". I just need to figure out how to update the page so that it realizes that the textbox is not empty and lets me submit the form.
Thanks a lot!
Edit:
Page form:
<form id="form_register" novalidate="">
<div class="form-steps">
<div class="form-group">
<div class="input-group">
<input autocomplete="off" class="form-control ng-pristine ng-invalid ng-touched" data-is-regex="true" data-mask="[a-zA-Z0-1\.]+" id="username" name="username" ngcontrol="username" placeholder="Username" required="" style="color: black !important;" tabindex="13" type="text">
</div>
</div>
<div class="form-group">
<div class="input-group">
<input autocomplete="off" class="form-control ng-untouched ng-pristine ng-invalid" id="password" name="password" ngcontrol="password" placeholder="Password" required="" style="color: black !important;" tabindex="14" type="password">
</div>
</div>
<div class="form-group">
<button class="btn btn-block btn-lg btn-info" tabindex="4" type="submit">
Log In
</button>
</div>
</div>
</form>
My problem is that this:
document.getElementById("username").value = "testuser";
document.getElementById("password").value = "testpass";
document.getElementsByClassName("btn btn-block btn-lg btn-info")[0].click();
ends up giving me a message saying the username and password are required even though there is a value showing in the textbox. Simply clicking on the textbox, typing a character, then deleting it will allow me to submit the form, but I need to accomplish this without user interaction.
You are filling the forms with native javascript and that is not updating the angular model. In your backing component you need to use ngmodel to connect your elements to the component. Then update the variables in the component and everything will reflect correctly.
Okay, there are a few issues with your code that I can see and I'll walk through getting this to work as expected.
For a Template driven form, create and assign the form group variable (which will make our shiny NgForm which we later attach controls to with ngControl) in the template, and lets bind the submit function while we're at it:
<form #myForm="ngForm" (ngSubmit)="submit(myForm.value)" id="form_register" novalidate="">
Each of our inputs is standalone and not yet tied to the form, to do so we'll want to clear the ng- classes which should be managed by Angular 2 and add our [(ngModel)] binding to a property.
<input autocomplete="off" class="form-control" data-is-regex="true" data-mask="[a-zA-Z0-1\.]+"
id="username" name="username" placeholder="Username" ngControl="username" [(ngModel)]="username"
required style="color: black !important;" tabindex="13" type="text">
We're going to disable our submit if the form is invalid:
<button [disabled]="myForm.invalid" class="btn btn-block btn-lg btn-info" tabindex="4" type="submit">Log In</button>
Our class has the username and password properties that we bind to, and our submit function:
export class App {
password: string;
username: string;
submit(value) {
console.log("submitting: " + JSON.stringify(value));
}
}
Finally, if we really want to mark things dirty programmatically this way we will have to grab our template variable in our code with a ViewChild:
#ViewChild('myForm') formGroup;
password: string;
ngAfterContentInit() {
this.formGroup.control.markAsDirty();
}
To do it per control we either need to access it through our formGroup variable or add individual template variables on the inputs we can grab with [(ngModel)]="username" #username="ngModel", for instance.
here's a plunker you can play with to try and develop your understanding: http://plnkr.co/edit/ukJ1kq2UFBvtoCsxbyba?p=preview
I have two issues with ng-model-options="{updateOn:'blur'}" and ng-change.
When user select a value from date picker and delete the value from
the field required field message is showing that is correct. Now if
user select value again required message is not going away until
user make a off click.How to fix this issue ?
Somehow related to first issue once user select the value save button is not enabled until user make a off click from the form.
How to display required message and enable the save button ?
when user select the value it should trigger the validation event.
Just want to understand. Is it because i am using ng-model-options with ng-change ?
main.html
<form id="createRcsaFormName" name="createRcsaCycleForm" novalidate
k-validate-on-blur="false">
<div class="col-md-12>
<input kendo-date-picker type="text" class="form-control"
id="asessPrdStartDate" name="asessPrdStartDate"
onkeydown="return false;"
ng-model="rcsaCycleDTO.asessPrdStartDate"
ng-change="validateDate('asessPrdStartDate','asessPrdEndDate')"
ng-model-options="{updateOn: 'blur'}" required
k-format="'MM/dd/yyyy'">
<p class="text-danger" ng-show="createRcsaCycleForm.StartDate.$touched && createRcsaCycleForm.asessPrdStartDate.$error.required">Start Date is required</p>
</div>
</form>
<button class="btn btn-primary" type="button"
ng-disabled="createRcsaCycleForm.$invalid"
ng-click="submit()">Save
</button>
I am developing a mobile application with jquery mobile, php ,phonegap and cordova
I have a requirement that in the virtual keyboard of all form elements like Text boxes should have next and previous buttons and for the last text box the Done/Go/Enter option should be shown.
How can I handle those buttons programatically without adding plugins.
Here is my form
<form id="loginForm" name="form1">
<div class="row mainpart paddingleftandright clsfieldPadding">
<div class="col-lg-12">
<div class="input-group1" id="email_div">
<input type="email" id="login_form_email"
placeholder="EMAIL ADDRESS" value="" data-clear-btn="true"
data-mini="true" tabindex='1' class="clsPyType clsBodyTxt" autocapitalize="off" onBlur="getPasswordProtectionStatus(this.value);checkLoginEmail(this.value);">
<span class="input-group-addon"><span class="glyphicon" style='display:none;' id="glyphicon_id1">!</span></span>
</div>
</div>
</div>
<div id="login_form_email_msg" class="clsPyType"></div>
<div class="row mainpart paddingleftandright clsfieldPadding2">
<div class="col-lg-12">
<div class="input-group1" id="password_div">
<input type="password" id="login_form_password"
placeholder="PASSWORD" value="" data-clear-btn="true"
autocomplete="off" data-mini="true" tabindex='2' class="clsPyType clsBodyTxt" onBlur="checkLoginPassword(this.value);">
<span class="input-group-addon"><span class="glyphicon" style='display:none;' id="glyphicon_id2">!</span></span>
</div>
</div>
</div>
<div id="login_form_password_msg" class="clsPyType"></div>
<div class="row mainpart paddingleftandright">
<div class="col-lg-12 remember-me">
<select name="slider" data-role="slider" id="rememberMe">
<option value="0">No</option>
<option value="1">Yes</option>
</select>
<div class="col-sm-5 clsPyTypeUprBold Clsremember">Remember Login</div>
</div>
</div>
<div class="row mainpart paddingleftandright">
<div class="col-lg-12">
<!-- <a data-role="button" data-transition="flip"
data-direction="reverse" class="clsBtnHead2 clsBtnRed" id="login_form_submit" onClick="login_form_submit();"><div class="clsBtnTop">LOGIN</div></a> -->
<input type="submit" tabindex='3' id="login_form_submit" class="clsBtnHead2 clsBtnRed" onfocus=" $(this).trigger('click');" value="LOGIN"/>
</div>
</div>
If any one have better ideas please share
All of the fields within a form will have the prev / next buttons which act like tabs do on a real keyboard. The done/Go/enter buttons... well they will naturally occur if there is data to submit. I think this just boils down to semantics and building your form correctly.
In the screen shot, the first field is focused, the next button is available (chevron pointing to the right) and the form is able to be submitted via the GO button. It can be submitted as for all the device knows this form is complete, your validation will decide whether or not the data is complete. What I am getting at here is that you won't be able to hide the return/Go button at will. However you can omit it using a numerical keypad.
The 'done' message occurs above the virtual keyboard and does not submit (unless you submit on blur, as using it blurs whatever field you were focusing on), and looks like a text link.
The 'Enter' & 'Go' buttons will submit the form. So if the last field in your form is numerical (big finger buttons) then you won;t be able to use it for submission unless you submit the form on blur of that field.
Here is a working example: http://codepen.io/morganfeeney/pen/ojdRMQ
I built that to test virtual keyboards on handheld devices. Go and check it out on your iPhone ;)
FYI: the example code you supplied does not have a closing </form> tag.
I have an AngularJS Form with 3 required fields inside (using ng-required). Without touching anything on the form and just simply pressing the 'Submit' button (ng-click="submit"), how do I trigger validation for the required fields AND prevent form submission? I've tried doing:
ng-required="form.$submitted && !firstName"
which triggers the validation, but also submits the form even though the form is technically $invalid??
I would take a look at angular-validator: https://github.com/turinggroup/angular-validator. It is quite useful and really leans out your validation code. ng-Message is nice but you end up maintaining more HTML and therefore it seems it would be more watches.
<form name="categoryForm" id="categoryForm" class="smart-form" angular-validator angular-validator-submit="save(true)" novalidate autocomplete="off">
<fieldset>
<section ng-class="{ 'has-error' : categoryForm.title.$invalid}">
<label class="label">Title</label>
<label class="input">
<input name="title" type="text" ng-model="category.title" id="title" placeholder="Title" required
validate-on="dirty" required-message="'Title is required'">
</label>
</section>
<section ng-if="isAdmin()">
<div class="row">
<section class="col col-6" >
<label class="checkbox">
<input type="checkbox" name="checkbox" ng-model="category.isGlobal">
<i></i><span>Global</span></label>
</section>
</div>
</section>
</fieldset>
<footer>
<button type="submit" class="btn btn-primary" ng-disabled="(categoryForm.$dirty && categoryForm.$invalid) || categoryForm.$pristine">
Submit
</button>
</footer>
</form>
Since you mention that you are doing validation for individual elements and don't know to check whether the entire form is valid or not. You can use the following condition to check whether the form is valid or not
$scope.yourFormName.$valid
Use the above condition to check whether the form is valid or not. The above condition will become true only when all the required validations inside the form are valid. Hope this is what you're looking for
I used the ng-submit directive as it triggers form.$submitted and validates ng-required fields properly before submitting.
For the case where you have multiple buttons, for I added an ng-click to each button and simply changed a $scope variable (e.g. $scope.pressedBtn). In the function that ng-submit points to, you could do something like:
if ($scope.pressedBtn === 'button1') {
// submit
}
else if ($scope.pressedBtn === 'button2') {
// save
}