Resetting form does not work - angularjs

For some reason, my form does not want to reset after submit. I have a button with type submit and a button with type button. When using the button with type button, the form resets, but it does not with the other button.
I'm also using var vm = this.
The code for subtmitting:
vm.submit = function(form) {
if (!form.$invalid) {
vm.showQuestion(vm.indexOfQuestion);
vm.putAnswer();
form.$setPristine();
}
}
<button class="button" type="submit" ng-click="vm.submit(testForm)">
Volgende vraag
</button>
The code for button type button:
vm.resetForm = function(form) {
form.$setPristine();
}
<button class="button" type="button" ng-click="vm.resetForm(testForm)">
Test
</button>
My question is, why does the form not reset when $setPristine() is used in a subtmit button, but it works on a normal button? And how do I make it so it does reset after submitting after clicking the submit button?

I'm unsure what the reason is of why it works, but resetting the form by using $setPristine() works by adding a $timeout function.
vm.submit = function(form) {
if (!form.$invalid) {
vm.showQuestion(vm.indexOfQuestion);
vm.putAnswer();
$timeout(function() {
form.$setPristine();
});
}
}

Related

Angular 1.4: Disable button after click

I have a situation where I want to disable the button for a few seconds when clicked. Here is the code for button:
<button uib-popover="Create TO" popover-trigger="mouseenter" data-ng-click="createTransportOrder(item.confirmed_price_id)" data-ng-disabled="item.transport_order_id || !item.confirmed_price_id" class="btn btn-info btn-xs">
<i class="fa fa-truck"></i>
</button>
And here is the createTransportOrder method:
$scope.createTransportOrder = function (priceResponseId) {
var priceResponseIds = [priceResponseId];
PriceRequestsModel.createTransportOrdersByIds(priceResponseIds).then(
function (response) {
$scope.messages = response.messages;
updateSelectedPriceRequests();
getPriceRequests();
},
function (response) {
$scope.messages = response.messages;
}
)
};
I have tried a couple of things but in vain. How can I do this?
You can add setTimeout at the end of createTransportOrder
this.button.nativeElement.disabled = true;
setTimeout(function(){
this.button.nativeElement.disabled = false;
},5000);
Add #mybutton to your button <button (click)="yourclick()" #mybutton>Your button</button>
add variable #ViewChild('mybutton') button; to your component
Stackbliz demo code: https://stackblitz.com/edit/angular-disable-5second
With angular 1.4 you can change to
Set an id to your button as <button id="mybutton">
Add these code to below of click function.
document.getElementById('mybutton').disabled = true;
setTimeout(function(){
document.getElementById('mybutton').disabled = false;
},5000);

How to prevent doubleclicking on a button with angularjs?

I want to select an element in my case a button on the page in my angularcontroller and then disable it. The button looks like this:
myBtn= $element.by.buttonText('submit')
I don't want the user to click the button twice in order to avoid to post requests in the backend. When I get the code above I get an angular reference order. What is an easy way to select a button and then set the disabled property to true so the user cannot click the button twice?
You can use ng-disabled to disable your button according to a flag set in your submit function. For example:
<form ng-submit="submit()">
...
<button type="submit" ng-disabled="isSubmitting">Submit</button>
</form>
and in your controller:
$scope.submit = function() {
$scope.isSubmitting = true;
$http.post('...').finally(function() {
$scope.isSubmitting = false;
});
};
if you have many buttons on page, then its better to create a directive so that on any button which is clickable, it doesnt get pressed twice
app.directive('ngClickDisable', function() {
return {
scope: {
clickAndDisable: '&'
},
link: function(scope, iElement, iAttrs) {
iElement.bind('click', function() {
iElement.prop('disabled',true);
scope.clickAndDisable().finally(function() {
iElement.prop('disabled',false);
})
});
}
};
});
This can be used on a button as follows:
<button ng-click-disable="functionThatReturnsPromise()">Click me</button>

Add an event on ng-show

i'm not an angular master and i try to do something.
Suppose a fonctionality like "i like / i dislike".
When you're on an article, you can click on the "i like" button. If you already liked the article, this button is hidden and the "i don't like anymore" appears.
<button ng-hide="like" class="btn btn-success btn-xs pull-right" ng-click="iLike()">I like</button>
<button ng-show="like" class="btn btn-danger btn-xs pull-right" ng-click="notLike()">Don't like anymore</button>
Everything work as expected when i reload the page but not on click action.
Basically my iLike function looks like and i think miss behavior comes from a missing return or an event to fire :(
$scope.iLike = function(){
##hereIDoAnAPICalls##, function(){
$scope.like = false;
}, function(){
$scope.like = true;
}
}
Try to wrap scope variable assignment into apply, I think it could help since API call is probably asynchronous and click event is invoked from outside of angular
$scope.iLike = function() {
APIcall.then(function () {
$scope.$apply(function() {
$scope.like = false;
});
}, function () {...the same...});
};

Prevent form submission on enter key

How can I prevent the enter key from submitting the form in angular?
Is there a way to catch the 13 key and disable it or set the form as invalid unless submitting from a button with ID of x?
Thanks
Since you have ng-click anyways, you could also use <button type="button">, even inside the form tag. The default behaviour of the button element is type="submit", which is what you want to prevent. So, no javascript needed at all!
Other users have already written that [button type="submit"] will cause this trouble. PLEASE NOTE: buttons WITHOUT any type="..." declaration are "submit" by default! So make sure you always use type="button".
After a couple hours, this weird code was the only thing that worked.
I'm waiting for better answers, won't accept this monster:
app.directive('onKeyup', function() {
return function(scope, elm, attrs) {
var allowedKeys = scope.$eval(attrs.keys);
elm.bind('keydown', function(evt) {
angular.forEach(allowedKeys, function(key) {
if (key == evt.which) {
evt.preventDefault(); // Doesn't work at all
window.stop(); // Works in all browsers but IE
document.execCommand("Stop"); // Works in IE
return false; // Don't even know why it's here. Does nothing.
}
});
});
};
});
and trigger it by using this on all form inputs:
<input on-keyup="bla" keys="[13]" .... />
For now, whenever the user press the enter key, the window try to submit, then fail to do so, not so silently. Ugly but it works.
Edit: keydown is a little better than keyup for the element bind, now enter key fails silently-ish
so simple, doesn't need to do anything. just add this to your form tag if you are using angular +2
<form (keydown.enter)="$event.preventDefault()" ...>
If you are attempting to prevent the form from being submitted on just a single element, you can add the following ng-keypress handler (this is for Angular 1.x):
<input type="text" name="myField" ng-keypress="keyPressHandler($event)"/>
With the following implementation for keyPressHandler:
$scope.keyPressHandler = function(e) {
if (e.keyCode === 13) {
e.preventDefault();
e.stopPropagation();
// Perform your custom logic here if any
}
}
I had a similar problem, I ended up taking the button out of the form.
Seeing as I use ng-click and everything is binded with ng-model it doesn't really matter if it's inside the form or not.
I realise this is bad practice but it sure as hell beats writing a custom directive to intercept keystrokes.
Check this:
if a form has 2+ input fields and no buttons or input[type=submit]
then hitting enter doesn't trigger submit
Thus if your form has 2+ input fields, you could use something like <span ng-click="submit()">Sumbit</span> to prevent key-trigger of enter key in those input fields.
I came across this issue. Yes, you would need to remove all type='submit' from your page, and make sure any other buttons have type="button" but then the challenge is still being able to use normal validation submission.
I created a directive that triggers form submission + form states for validation. Replacing:
<button type="submit">
with
<button submit-button type="button">
Directive:
export default /*#ngInject*/ function submitButton($log) {
return ({
require: '^form',
link: link,
restrict: 'A'
});
function link(scope, element, attributes, formCtrl) {
element.on('click', clickHandler);
function clickHandler() {
formCtrl.$setDirty(true);
formCtrl.$setSubmitted(true);
angular.element(element[0].form).triggerHandler('submit');
$log.info('Form Submitted');
}
}
You can still hit ENTER to submit when focused on your submit-button, better for UX and Accessibility I think.
The easiest solution to this I found is to use input type as button instead of submit and bind the form submit function with ng-click and not using the ng-submit in the form tag.
I hope this helps.
This is my weird but quick and simple solution without any directives.
HTML:
<form ng-submit='submitForm()'>
<input type='text'>
<button type='submit' ng-mousedown='doSubmit=true'>submit</button>
</form>
Controller:
$scope.submitForm = function() {
if (!$scope.doSubmit) {
return;
}
$scope.doSubmit = false;
console.log('execute some actions');
}
You can catch the default form submit in your controller using ng-submit on the form tag and it will prevent a submit:
http://docs.angularjs.org/api/ng.directive:ngSubmit
alternatively, if you really wanted to catch the key events, there are also directives for that which pass an event you can call stop:
http://docs.angularjs.org/api/ng.directive:ngKeyup
angular.element(document).ready(function () {
angular.element(window).keydown(function () {
if(event.keyCode == 13) {
event.preventDefault();
return false;
}
});
});
Try with this in angularjs controller
A form is submitted when the enter key is clicked while a control within the form has focus. If you register a listener using ng-submit you can intercept this and use prevent defaults to stop the default process (i.e. submitting the form). Have a look at th
The following should work . . . i.e., the form is only submitted on button click, and not on hitting Enter in the Input boxes. (This definitely works for reactive forms. I didn't test it for template forms).
<form #form [formGroup]="form" METHOD="GET" action="http://localhost:3000/test">
<input placeholder="Enter"/>
<input placeholder="The Dragon"/>
<button type="button" (click)="form.submit()">Submit</button>
</form>
Of course, remember all the imports and declarations:
app.module.ts
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
#NgModule({
imports: [
. . .
FormsModule,
ReactiveFormsModule
]
. . .
})
export class AppModule { }
test.component.ts
import { FormGroup, FormControl } from '#angular/forms';
#Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})
export class TestComponent {
form: FormGroup = new FormGroup({});
constructor() { }
}
Try setting a variable when you click the submit button and checking that it has been set in the form submit.
$scope.click = function () {
$scope.clicked = true;
$scope.submit();
};
$scope.submit = function () {
if ($scope.clicked) {
... submit
} else {
... prevent defaults
}
$scope.clicked = false;
};
See jsfiddle

AngularJs: How can I create a save and discard/cancel pattern in a modal form?

I have a form within a modal, see plnkr here. When editing the menu item, after making some changes, If I click cancel in the modal, I want the default menuitem without any changes being made to it to show up i.e. all changes discarded(). So the next time I go into the modal I meet the default item sans changes.
If I click save I want to keep the changes i.e. run the save method.
Both save and cancle close the modals after being clicked.
How do I create such a save and discard/cancel mechanism?
Are there other angular ways of achieving this effect, different
I am using the modal from angularStrap.
This should be helpful.
JsFiddle | Source
Html
<div ng-app>
<div ng-controller="ClickToEditCtrl">
<div ng-hide="editorEnabled">
{{title}}
Edit title
</div>
<div ng-show="editorEnabled">
<input ng-model="editableTitle" ng-show="editorEnabled">
Save
or
cancel.
</div>
</div>
</div>
Angular
function ClickToEditCtrl($scope) {
$scope.title = "Welcome to this demo!";
$scope.editorEnabled = false;
$scope.enableEditor = function() {
$scope.editorEnabled = true;
$scope.editableTitle = $scope.title;
};
$scope.disableEditor = function() {
$scope.editorEnabled = false;
};
$scope.save = function() {
$scope.title = $scope.editableTitle;
$scope.disableEditor();
};
}
Edited example: http://plnkr.co/edit/OTN4Qh?p=preview
What was changed:
Added ng-init='orginalName = menuItem.Name' to the edit menu
Changed ng-click on the cancel button to ng-click="menuItem.Name = orginalName; dismiss()"
With these changes, they will see the updates as they type, but when the changes are canceled they will be reverted.
If wanted, you can reverse this so that the edits are not updated as they type and would only be applied on save.

Resources