event.preventDefault with Firefox and AngularJS - angularjs

I know there are lot of threads with this question but mine is a little different I will explain why.
Background:
I am using angular JS to submit a form. I have a groovy tags like below in my GSP
<form action="formAction" class="form-horizontal" id="UserForm" name="UserForm"
useToken="true" ng-app="angularApp" ng-controller="angularController" novalidate="" ng-submit="onSubmitClick();">
<input type="button" name="next" value="submit"
id="submit" />
( Actually a submit tag in Groovy but StackOverflow doesnt allow me to write that )
This is a form tag with Action and ng-submit specified.
What I am trying to achieve:
When the submit button is clicked "onSubmitButtonClick()" function is invoked and if the form is invalid it needs to prevent submit.
onSubmitButtonClick is defined in angular Controller. Now the problem is Angular JS will submit the form as long it finds the "action" URL defined. I cannot remove value for that URL because it is coming from serverside at run time. so I started using event.preventDefault().
event.preventDefault doesnot work in Firefox so I started passing event in function call onSubmitButtonClick(event) and I realize that for Firefox this comes as undefined.
So, is there a way to access event in firefox ? I cannot use 'return false' or event.returnValue=false because Angular just ignores them. So, I need to get event.preventDefault to work.
Below is how onSubmitButtonClick code looks like :
$scope.onSubmitButtonClick=function(evt){
if($scope.UserForm.$invalid)
{
var browserObj=browserDetectFunction();
if(browserObj.browser=='Firefox')
{
evt.preventDefault(); // this throws evt undefined error in Firefox
} else
{
event.preventDefault();
} } }
Any help is appreciated. Thanks

Not exactly answering your question, but a different route to take that should work (looking at your code):
<input type="button" name="next" value="submit"
id="submit" ng-disabled="UserForm.$invalid" />
Or you remove your submit button if invalid, and replace it with a non-functioning button:
<input type="button" name="next" value="submit"
id="submit" ng-if="UserForm.$valid" />
<button type="button" name="next" value="submit"
ng-if="UserForm.$invalid" />

Related

Prevent Angular form submit when invalid AND using a form action URL

I have a form with a URL action set. When form.$invalid is true (or form.$valid is false) I want to make the form NOT submit to the URL and show the invalid form errors in the UI.
In my particular case here, I'm using a framework that provides an Angular Controller for me, where I do not have the ability to add/modify functions on it! I need to be able to do this only by making changes to the template.
Here's what I have so far (simplified)
<form novalidate
name="form"
method="post"
ng-attr-action="{{model.loginUrl}}"
ng-submit="return form.$valid">
<div class="form-group" ng-class="{'has-danger' : form.$submitted && form.username.$invalid}">
<input type="text"
name="username"
required
class="form-control"
ng-model="model.username">
<div class="form-control-feedback" ng-if="form.$submitted && form.username.$invalid">
A username is required!
</div>
</div>
<button type="submit">Sign In</button>
</form>
A lot of what I've seen online says to do something like
ng-submit="form.$valid && model.myCustomSubmitFn()"
but that doesn't use a URL form action, and I do not have the ability to add a custom function with this framework
Angular passes the $event in the context of ng-submit. So you call $event.preventDefault(). Your ng-submit would change to
<form novalidate
name="form"
ng-attr-action="{{model.loginUrl}}"
ng-submit="form.$invalid && $event.preventDefault();form.$submitted=true;"
>
See plunker.
THE BELOW IS AN ANSWER THAT WILL NOT WORK FOR THIS QUESTION-- I AM ONLY LEAVING IT HERE SO NO ONE ELSE TRIES THIS AS THE SOLUTION
Might ngDisabled work for you in this case?
<button type="submit" ng-disabled="form.$invalid">Sign In</button>
This is certainly a tricky situation since you only have access to edit the template. I'm not seeing an "angular" way to solve your problem with being able to edit the controller. Luckily though, this can be solved in the template alone with some vanilla JavaScript.
Try adding an onclick event handler to your button that prevents form submission if your form's input(s) do not match your validation criteria.
<button type="submit" onclick="if(form.username.value.length < 1) { event.preventDefault(); }">Sign In</button>
I'm not incredibly proud of this solution and it will certainly get dirty if you have more than one input in your form, however it looks like the only work-around for your unfortunate situation.
Reactive Forms
If you wanted to declair this in the HTML of your reactive form you can simply do something like this:...
<form [formGroup]="formGroupVar" (ngSubmit)="formGroupVar.valid ?
submitFunc() : null" novalidate>...</form>
So what you are doing is making your (ngSubmit) a ternary operator, the comparison would be your formGroupVar.valid, when true, you would execute your submitFunc() else null.
NOTE: There is no reason why you wouldn't just do this in your TypeScript file, it would make sense to keep your HTML as 'clean' as possible, but that doesn't mean it is not possible!

Save on Chrome's autofill from an AngularJS's single page application

How can I have my AngularJS single page application to register the user's input on the browser's autofill settings when submitting a form? Angular doesn't really submit the form in the "default" way, so the browser does not catch the input.
The following will NOT save in Chrome's autofill:
<form id="header-search" class="navbar-form form-inline" ng-submit="submit()">
<input type="search" name="q" ng-model="Search.term" ng-required="true"/>
<button type="submit" class="btn btn-default glyphicon glyphicon-search"></button>
</form>
It works with <form action='/search'>, but I don't it to break my SPA behavior by posting and coming back.
Without any code, it's very difficult to tell what the problem is. Using angular forms with an ngSubmit, should allow for submitting forms in a normal enough way to trigger autocomplete.
I had similar problem with login form, where Chrome autofilled username and password. I added into login controller following code:
$(document).ready( function() {
$timeout(function(){
$scope.username = $('div#login input[name="username"]').val();
$scope.password = $('div#login input[name="password"]').val();
},300);
});
You can also try to trigger input on all your input elements to force update ngModel. I think this should work too.
$('yourInputsIdentifier').trigger('input');

AngularJS Disabling Forms When Controllers are Created

AngularJS disables (cannot submit) forms that do not have a specific action set:
<form action="">
when you create a controller. It does not have this issue when creating directive or factories.
You can see this in a plunk here:
http://plnkr.co/edit/gWFRMKGO3FzZtOgs4VmW?p=preview
Form is defined as:
<form action="" method="post">
If you delete the starting on line 6, you will be able to submit the form.
A simple solution is to define the action, but I'd rather not do this, as it is not necessary.
UPDATE
Some details can be found here on trying to get this change in Angular:
https://github.com/angular/angular.js/pull/3776
You can use ng-submit to handle that.
<form ng-submit="submitForm()" method="post">
<input name="test" value="11111111" />
<button type="submit" name="submit" value="1">Send</button>
<input type="submit" name="submit2" value="Send2" />
</form>
That way the form will submit normally and you must actually send the data on your submitForm function (just an example name).
Here is a quick plnkr: http://plnkr.co/edit/lwWVG0CDHSGMtMU0B8Nj?p=preview
Notice that you can submit using the buttons and also by pressing enter on the field. I hope that's what you've been asking for.
Thanks

AngularJS: Required form field not woking with ng-click submit

<div ng-app>
<div ng-controller="Ctrl">
<form ng-submit="submit() ">
<textarea ng-model="text" required></textarea>
<div ng-click="submit()" style="background-color:#ff00ff;cursor:pointer;width:100px;">Create !</div>
<button type="submit" style="background-color:#ff00ff;cursor:pointer;width:100px;">Create !</button>
</form>
{{list}}
</div>
</div>
I want to submit an Angular form with a custom div button but when I do it like above, the "required" statements are not taken into account like it is done for the button.
When the textarea is empty the first button runs the submit() function anyway.
Is it possible to have the same behavior as the button ?
Here is a JsFiddle illustrating this:
http://jsfiddle.net/xKkvj/55/
I think you should be using an input rather than a div, eg:
<input type="submit" ng-click="submit()" style="background-color:#ff00ff;cursor:pointer;width:100px;">Create !</input>
I've tested it on your jsFiddle, and it works fine.
If you really must use a <div>, use it to wrap the <input>
UPDATE
It looks like you can't use anything other than an input or a button as that is what ngForm listens to for form submission. You could either extend ngForm or you could use a hidden button and trigger that from your div like so:
<div onClick="document.getElementById('hiddenButton').click();" style="background-color:#0000ff;cursor:pointer;width:100px;">Create !</div>
<button id='hiddenButton' type="submit" style="display:none;">Create !</button>
jsFiddle here. Hopefully this'll do the trick for you.
If you want to submit form from a div element, then you should manually test if form is valid in your submit handler:
function sumbit() {
if (form.$invalid) {
return;
}
// Other code...
}
The point is that when you submit your form via <input type="submit"/>, then form validation check is performed internally & form handler do not invoked in case of invalid form.
UPDATE
Your jsfiddle form handler should look like:
$scope.submit = function () {
if ($scope.submitCreateSurveyForm.$invalid) {
return;
}
if ($scope.text) {
$scope.list.push($scope.text);
$scope.text = '';
}
console.log("sent");
};

Non-jquery, angularish blur() or focus() after carriage return or softkeyboard "go"

The main issue I'm trying to solve is closing soft keyboards when a user clicks their keyboard's "go" and submits a search form (see below). If the user clicks the form's submit button, there's no problem because the text field is no longer in focus and the keyboard closes.
I've dug through stackoverflow for answers. I've seen answers that involve creating directives, controllers, and factories to handle this problem. Or say 'wait until 1.1' or whatever when angular has built in focus() and blur() directives (which do not address my problem).
I'm currently using a jquery selector (see below) in the Controller method that is triggered on form submission. Simple, but I feel 'dirty' using it and want a better way that doesn't involve 30 lines of code, which is even more ugly IMO than using a jquery selector.
ng-focus handles attaching behavior to focus events. I'm trying to either blur() away from the text box or set focus somewhere.
<form class="navbar-form navbar-left ng-valid ng-dirty">
<div class="input-group">
<span class="input-group-btn">
<button type="submit" data-ng-click="triggerBigO()" class="btn btn-default btn-primary">Invoke Orgasm</button>
</span>
<input type="text" placeholder="Search" data-ng-model="search.search_term" class="form-control ng-valid ng-dirty">
</div>
</form>
<div id="somewhereElse" grass="greener"></div>
my ugly solution:
PleasureApp.controller("FunTimes", function($scope) {
$scope.triggerBigO = function() {
... do unsavory stuff ...
$("input").blur();
}
}
I think angularish way is to create a directive like this and attach it to the form :
app.directive('blurOnSubmit', function() {
return function(scope, form) {
form.submit(function() {
form.find(":focus").blur();
});
}
});
and in html
<form ... blur-on-submit> ... </form>
It may look a bit overcompilcated but now it is easy to reuse it for other forms as well.
Here is jsfiddle you may try - http://jsfiddle.net/GRaAL/qTWgP/1/

Resources