Angular, validate form when submitting from outside form [duplicate] - html

Given this code:
<div ng-controller="MyCtrl">
<form ng-submit="onSubmitted()">
Header inputs:
<input type="name" ng-model="sample" required/>
<input type="name" ng-model="sampleX" required/>
<input type="submit" value="This submit triggers validation. But I wanted to put this button at the end of the page"/>
</form>
<hr/>
Some other form here. Think line items
<hr />
<a class="btn" ng-click="/* what could should be put here, so this can trigger the firt form's validation, then submit? */">Wanted this submit button to trigger the validation+submit on the form in which this button doesn't belong</a>
</div>
var app = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.onSubmitted = function() {
alert('submitted!');
};
}
I want the last button to trigger the validation(then submit when things are valid) on first form. As of now, only the button inside the form can trigger that form's validation and submission. Is there any possible way for a button outside the form to do that?
Live test: http://jsfiddle.net/dzjV4/1/

You can create directive which you can then attach to <a class="btn".... Check this jsfiddle
http://jsfiddle.net/dzjV4/2/
Note that I added to <input type='submit' id='clickMe'... and linked it with link at the bottom <a class='btn' linked="clickMe"...

for (control of $scope.[form name].$$controls) {
control.$setDirty();
control.$validate();
}
You can try the above codes. Make it running before submit.

Ideally there'd be a programmatic way to cause validation to re-run across a form. I have not investigated that completely but had a situation that required multiple controls to be re-validated based on different data in the scope -- without the user interacting with the individual controls. This arose because the form had two action buttons which each required different validation rules be in play when they were clicked.
The UI requirement changed before I fully implemented forcing re-validation but before it did I got most of what I needed by copying and then re-setting the form's data. This forced re-validation across the form within the current scope. Basically, it's along the lines of the following (not tested, but taken from the code that was working). In this case the form's data was bound to the properties in one object.
var formData = $parse(<form's model>);
var dataCopy = angular.copy( formData($scope) );
formData.assign( $scope, dataCopy );

This may or may not be acceptable, but if you can get away with the SUBMIT button being disabled until the form is completed, you can do this:
<form name="formName">
<input ng-required="true" />
</form>
<button ng-click="someFunction()" ng-disabled="formName.$invalid" />
It's also worth noting that this works in IE9 (if you're worried about that).

Give your form a name:
<div ng-controller="MyCtrl">
<form name="myForm">
<input name="myInput" />
</form>
</div>
So you can access your form validation status on your scope.
app.controller('MyCtrl', function($scope) {
$scope.myForm.$valid // form valid or not
$scope.myForm.myInput // input valid or not
// do something with myForm, e.g. display a message manually
})
angular doc
There is no way to trigger browser form behavior outside of a form. You have to do this manually.

Since my form fields only show validation messages if a field is invalid, and has been touched by the user:
<!-- form field -->
<div class="form-group" ng-class="{ 'has-error': rfi.rfiForm.stepTwo.Parent_Suffix__c.$touched && rfi.rfiForm.stepTwo.Parent_Suffix__c.$invalid }">
<!-- field label -->
<label class="control-label">Suffix</label>
<!-- end field label -->
<!-- field input -->
<select name="Parent_Suffix__c" class="form-control"
ng-options="item.value as item.label for item in rfi.contact.Parent_Suffixes"
ng-model="rfi.contact.Parent_Suffix__c" />
<!-- end field input -->
<!-- field help -->
<span class="help-block" ng-messages="rfi.rfiForm.stepTwo.Parent_Suffix__c.$error" ng-show="rfi.rfiForm.stepTwo.Parent_Suffix__c.$touched">
<span ng-message="required">this field is required</span>
</span>
<!-- end field help -->
</div>
<!-- end form field -->
I was able to use this code triggered by a button to show my invalid fields:
// Show/trigger any validation errors for this step
angular.forEach(vm.rfiForm.stepTwo.$error, function(error) {
angular.forEach(error, function(field) {
field.$setTouched();
});
});
// Prevent user from going to next step if current step is invalid
if (!vm.rfiForm.stepTwo.$valid) {
isValid = false;
}

Related

I made the html & js code to do the validation check. But the data is submitted before checking the data

<form name="mForm" action="${pageContext.request.contextPath}/login/insertSeller.do" method="post">
id : <input type="text" name="id" />
<input type="submit" value="register" onClick="doAction()" />
</form>
<script>
function doAction() {
var f = document.mForm;
var id = f.id;
if (id.value == "") {
alert("insert your id");
id.focus();
return false;
}
return true;
}
</script>
Is there any error to correct?
If I click the button, the alert window opens with a message,
but the data is submitted without the validation check.
What do I need to do?
Please help me :)
You really shouldn’t have inline event handlers in modern HTML. Nevertheless, you could try the following:
<input … onclick="return doAction()">
The return in the onclick causes the input to wait for permission.
For the sake of completeness, here is how I would do it in a modern browser:
First, use a button instead:
<button type="submit">register</button>
Second, give your button a name
<button name="register" type="submit">register</button>
You can give a name to the older style input element, and the process will still work.
Next, add the following to your JavaScript:
document.addEventListener('DOMContentLoaded',function() {
document.querySelector('button[name="register"]).onclick=doAction;
},false);
The main function acts as a startup script. The point of it is that it is waiting for the DOM to have loaded. Otherwise it’s not possible to look for elements that aren’t there yet.
Note that you assign to the onclick event handler the name of the function.

input tag (type=submit) not working as a link

I tried this html code
<input type="submit" value="Login" class="button" />
It is a part of my html form.
I want to use submit button to submit the data and show ( error.html ) page.
You will wrap it with <form action="error.html"></form>
You can use like this
<html>
<form action="error.html">
<input type="submit" value="Login" class="button"> </input>
</form>
</html>
I am a bit unsure of what you want to do, since you say you already have a form then I guess that the error.html is not calling to the form because you already have another link to the form already. Then this is could be a way to call on two pages almost at the same time. Submit first to the form and then after the sumbit it goes to the linked error page.
Working to call on BOTH the form html and the error.html link:
JavaScript:
<script language="JavaScript">
/** Delay me BEGIN **/
function DelayMyError(){
var count = 0;
// delay in milliseconds
var delay = 100;
var interval = setInterval(function(){
if (count++ < 1) {
window.location.href='error.html';
} else {
clearInterval(interval);
}
}, delay);
}
/** Delay me END **/
</script>
HTML:
<form action="YourFormPage.html">
<input type="button" onclick="form.submit();DelayMyError();" value="Login"></input>
</form>
I hope this was the answer you were searching for. Please contact me back if it worked, I am curious too. Theoretically speaking it should work that it first submits and then after 100 milliseconds it calls for the link called error.html.
How ever if you just want to do a link without a delay you could do it like this, but there is a risk that this more simple approach will not call on the form and that it will only work as a link skipping the submit:
OPTIONAL but I am unsure if this one will call on both the form html and the error.html or not:
<form action="YourFormPage.html">
<input type="button" onclick="form.submit();window.location.href='error.html';" value="Login"></input>
</form>

Refresh Angular output on input reset

I have several <input> fields within a <form>. Angular takes the value from those fields regardless of the <form> (which is actually there only for Bootstrap to apply the right styles to inner fields).
Now, I want to be able to reset the fields, and so get Angular update the output associated to them as well. However, a regular <input type="reset"/> button is not working. It resets the values of all the <input> fields, but Angular is not refreshing the output that is based on the fields after it.
Is there any way to tell Angular to refresh the outputs based on the current state of the fields? Something like a ng-click="refresh()"?
Let's say you have your model called address. You have this HTML form.
<input [...] ng-model="address.name" />
<input [...] ng-model="address.street" />
<input [...] ng-model="address.postalCode" />
<input [...] ng-model="address.town" />
<input [...] ng-model="address.country" />
And you have this in your angular controller.
$scope.reset = function() {
$scope.defaultAddress = {};
$scope.resetAddress = function() {
$scope.address = angular.copy($scope.defaultAddress);
}
};
JSFiddle available here.
You should have your values tied to a model.
<input ng-model="myvalue">
Output: {{myvalue}}
$scope.refresh = function(){
delete $scope.myvalue;
}
JSFiddle: http://jsfiddle.net/V2LAv/
Also check out an example usage of $pristine here:
http://plnkr.co/edit/815Bml?p=preview

Making 'file' input element mandatory (required)

I want to make (an HTML) 'file' input element mandatory: something like
<input type='file' required = 'required' .../>
But it is not working.
I saw this WW3 manual which states 'required' attribute is new to HTML 5. But I am not using HTML 5 in the project I am working which doesn't support the new feature.
Any idea?
Thanks to HTML5, it is as easy as this:
<input type='file' required />
Example:
<form>
<input type='file' required />
<button type="submit"> Submit </button>
</form>
You can do it using Jquery like this:-
<script type="text/javascript">
$(document).ready(function() {
$('#upload').bind("click",function()
{
var imgVal = $('#uploadfile').val();
if(imgVal=='')
{
alert("empty input file");
return false;
}
});
});
</script>
<input type="file" name="image" id="uploadfile" size="30" />
<input type="submit" name="upload" id="upload" class="send_upload" value="upload" />
As of now in 2017, I am able to do this-
<input type='file' required />
and when you submit the form, it asks for file.
You could create a polyfill that executes on the form submit. For example:
/* Attach the form event when jQuery loads. */
$(document).ready(function(e){
/* Handle any form's submit event. */
$("form").submit(function(e){
e.preventDefault(); /* Stop the form from submitting immediately. */
var continueInvoke = true; /* Variable used to avoid $(this) scope confusion with .each() function. */
/* Loop through each form element that has the required="" attribute. */
$("form input[required]").each(function(){
/* If the element has no value. */
if($(this).val() == ""){
continueInvoke = false; /* Set the variable to false, to indicate that the form should not be submited. */
}
});
/* Read the variable. Detect any items with no value. */
if(continueInvoke == true){
$(this).submit(); /* Submit the form. */
}
});
});
This script waits for the form to be submitted, then loops though each form element that has the required attribute has a value entered. If everything has a value, it submits the form.
An example element to be checked could be:
<input type="file" name="file_input" required="true" />
(You can remove the comments & minify this code when using it on your website)
var imgVal = $('[type=file]').val();
Similar to Vivek's suggestion, but now you have a more generic selector of the input file and you don't rely on specific ID or class.
See this demo.
Some times the input field is not bound with the form.
I might seem within the <form> and </form> tags but it is outside these tags.
You can try applying the form attribute to the input field to make sure it is related to your form.
<input type="file" name="" required="" form="YOUR-FORM-ID-HERE" />
I hope it helps.
All statements above are entirely correct. However, it is possible for a malicious user to send a POST request without using your form in order to generate errors. Thus, HTML and JS, while offering a user-friendly approach, will not prevent these sorts of attacks. To do so, make sure that your server double checks request data to make sure nothing is empty.
https://www.geeksforgeeks.org/form-required-attribute-with-a-custom-validation-message-in-html5/
<button onclick="myFunction()">Try it</button>
<p id="geeks"></p>
<script>
function myFunction() {
var inpObj = document.getElementById("gfg");
if (!inpObj.checkValidity()) {
document.getElementById("geeks")
.innerHTML = inpObj.validationMessage;
} else {
document.getElementById("geeks")
.innerHTML = "Input is ALL RIGHT";
}
}
</script>

show JSON in new window

I have a problem with json. I'd like to display the result of my form in the new browser window in JSON. (When user fills all fields in the form, button becomes enabled and shows JSON in specified format (I did it)). I translated it in JSON but dunno how to output it...I'm thinking of create new html page and do window.open on button on 1st page, but then it doesn't read data from 1st page which user entered. Or should I save it somehow in JSON file and then read it from other page?
For example:
<form name="form" ng-controller="MyCtrl">
<label> <b> * Date: </b> </label> <input type="datetime-local" ng-model="date" name="date" onkeyup="changeButtonStatus()" onchange="changeButtonStatus()" required> </input>
<button type="submit" id="btn" class="btn" disabled="disabled">Submit</button>
</form>
I have some form with date field and button:
I can easily get JSON of date field by {{date | json}} on the same page, but I just want to output it in new browser window. How can I do this? Please help me with some tips. Thanks.
If it's not too big you can send the information to the new window as a data URL.
The frame will be reused once it is open.
This might be a start, showing how to plug in the JSON data and break it up over multiple lines for display.
window.open('data:application/json,'
+JSON.stringify(location).replace(/([[{,])/g, "$1%0a"),
'jsonFrame',
'resizeable,top=100, left=100, height=200, width=300,status=1')
See MDN for all the details.
You should be able to get at the window.opener from the new window and parse values out of it. The following plunker shows storing data from the current scope in an accessible area when the controller's submit is clicked. From the new window it then parses the content from the opener into the window's scope for further processing.
http://plnkr.co/edit/OkKX5zxYVSoZ7w81WV8J?p=preview
You'll notice here too how to get an angular friendly way of calling the submission and the disabling of the button until ready.
Hope this helps.
How about to save your input data into a cookie on one page and then get it via JavaScript when you will open a new window?
I could prepare the code in jsFiddle, but seems like it does not import external resources at this moment. So I'll post it here:
page 1:
...
<form name="form" ng-controller="MyCtrl">
<label> <b> * Date: </b> </label> <input id="date" type="datetime-local" ng-model="date" name="date" onkeyup="changeButtonStatus()" onchange="changeButtonStatus()" required> </input>
<button id="btn" class="btn" >Submit</button>
</form>
<script type="text/javascript" src="https://raw.github.com/carhartl/jquery-cookie/master/jquery.cookie.js"></script>
<script type="text/javascript">
$('#btn').click( function() {
var cookie_value = $('#inut_test').val();
/*cookie_value should be your json string*/
$.cookie("json_cookie", cookie_value, { path: '/' });
window.open("http://localhost/page2");
return false;
});
</script>
...
page 2:
...
<a id="see-cookie" href="#">
click me!!!
</a>
<script type="text/javascript" src="https://raw.github.com/carhartl/jquery-cookie/master/jquery.cookie.js"></script>
<script type="text/javascript">
$('#see-cookie').live('click', function() {
alert($.cookie('json_cookie'));
return false;
});
</script>
...
Do not forget about { path: '/' } cookie property to set it for all site and about including jQuery cookie library into your page.