How to use ngModelOptions and $rollbackViewValue() in AngularJS 1.3 - javascript

I have a problem with my input fields in my modal view.
When I take a change in the input fields then it is updating the table list but when I leave the page and go back to this page with the table list then die changes are disappeared.
This is my modal view:
<form class="form-horizontal" name="editForm" novalidate>
<div class="modal-body">
<div class="form-group-sm has-feedback">
<label class="control-label">Firstname</label>
<input type="text"
class="form-control"
name="Fname"
ng-model="selected.fname"
ng-model-options="{updateOn: 'updateItem'}"
ng-required="true"
/>
</div>
</div>
//the same input field for lastname
...
<div class="modal-footer">
<button class="btn btn-default" ng-click="createItem(selected)" type="submit">Erstellen</button>
<button class="btn btn-default" ng-click="updateItem(selected)"> Ă„ndern</button>
<button class="btn btn-default" ng-click="cancel()">Abbrechen</button>
</div>
</form>
Modal Ctrl:
$scope.cancel = function () {
$scope.editForm.$rollbackViewValue();
$modalInstance.dismiss('cancel');
}
$scope.updateItem = function (updateItem) {
CrudService.update(updateItem);
$scope.ok();
}
Crud Service:
...
update: function (updateItem) {
updateItem.$update();
},
...
I have only seen examples of $rollbackViewValue() with one input field and the code: $scope.myForm.inputName.$rollbackViewValue() but I have more than one input fields?

you should call $rollbackViewValue() through the form name:
editForm.$rollbackViewValue()
call it in your template:
{{editForm.$rollbackViewValue.toString()}}
and you will see how it actually works:
function () {
forEach(controls, function(control) {
control.$rollbackViewValue();
});
}

A little late but for others reference (I came across this looking for another issue with $rollbackViewValue).
Using $rollbackViewValue in controller: to use $scope to reference the form from the controller, you have to use the ng-form attribute on a child element of the form (like for instance the form-group div in your example).
That makes $scope.editForm.$rollbackViewValue() available in the controller and resets the entire form.
For cases where buttons are inside the form, using ng-submit and ng-model-options="{ updateOn: 'submit' }" on input fields, then adding 'type=button' attribute to cancel button element (so submit isn't triggered) is a quick solution.
Example:
https://embed.plnkr.co/IQ4vvutC3tcHvVBH0821/

Related

How can I get a input required with vuejs

I have my chat and I dont want people to send empty message so I would like that my input become required. Thanks for your help.
I tried to put "required='required'" in the input line, I also tried veeValidate but it broke my chat when I use it, I also tried to put "Required = true" in Props and data but without a good result
This is ChatForm.vue
<template>
<div class="input-group" >
<input id="btn-input" type="text" name="message" class="form-control input-sm" placeholder="Ecrire..." v-model="newMessage" #keyup.enter="sendMessage">
<span class="input-group-btn">
<button class="btn btn-primary btn-sm" id="btn-chat" #click="sendMessage">
&#10003
</button>
</span>
</div>
</template>
<script>
export default {
props: ['user'],
data() {
return {
newMessage: '',
}
},
methods: {
sendMessage() {
this.$emit('messagesent', {
user: this.user,
message: this.newMessage
});
setTimeout(function() {
const messages = document.getElementById('mess_cont');
messages.scrollTop = messages.scrollHeight;
}, 200);
this.newMessage = '';
}
}
}
</script>
And this is my form in the app.blade.php
<div id="app" class="container-chat">
<div class="row">
<div class="col-md-12 col-md-offset-2">
<div class="col-md-12 col-md-offset-2">
<div class="panel-body panel-content" id="mess_cont">
<chat-messages id="mess" :messages="messages" :currentuserid="{{Auth::user()->id}}"></chat-messages>
</div>
<div class="panel-footer">
<chat-form
v-on:messagesent="addMessage"
:user="{{ Auth::user() }}"
></chat-form>
</div>
</div>
</div>
</div>
</div>
Try to change your ChatForm.vue like this:
<template>
<form #submit.prevent="sendMessage">
<div class="input-group" >
<input id="btn-input" type="text" name="message" class="form-control input-sm" placeholder="Ecrire..." v-model="newMessage" required>
<span class="input-group-btn">
<button class="btn btn-primary btn-sm" type="submit" id="btn-chat">
&#10003
</button>
</span>
</div>
</template>
You are not treating the input in the correct way, the input which is required needs to be inside a form and the required keyword will prevent the form submission if the input field is empty.
There are a few things I would do differently.
1/ Wrap your chat form in a tag, and execute the sendMessage() method on submit. This will give your users a nicer experience, as they can just to submit the message.
2/ Convert the button into a submit button so it triggers the form.submit event.
3/ You can easily disable the button by checking whether newMessage has contents. I don't think you need vee validate or anything else to achieve this; for something as simple as a chat form, your user doesn't need much more feedback than seeing a disabled button to realise (s)he needs to write something first.
4/ in the addMessage method you can just check the contents of newMessage and not do anything when it's empty. This is perfectly fine because you already hinted the user by disabling the button too.
I think this is a subtle way where you guide your user, but don't overdo it.
Please add name attributes to all of your form elements. Some of the element in my form had name attribute and some didn't. Element which had name attributes worked correctly but the one's which didn't had name failed.

AngularJS: Setting value of form field to various object properties

I have a simple AngularJS dynamic form that is bound by ng-model to a property modelParams.value. Each form field displays the value of modelParams.value However, I would like to have a button called "Default" that sets the values of all of the form fields to some other property in this associative array such as modelParams.defaultValue, or modelParams.oldValue. I assume that once the "Default" button is pressed this would override the value of ng-model="modelParams.value".
Here is the form:
<form name="modelParamsForm">
<div class="form-group" ng-repeat="modelParam in modelParams">
<div class="row">
//INPUT FORM FIELDS
<input type="number" class="form-control input-sm" required ng-
model="modelParam.value" >
</div>
</div>
<button class="btn btn-primary btn-sm" ng-
click="updateModelParams(modelParams, modelParamsForm)">
</button>
//DEFAULT BUTTON
<button type="button" class="btn btn-default btn-sm" ng-
click="default()">Default</button>
</form>
My JSON looks like this:
[{"model":"MAF","paramname":"CascDefaultSpreadOverride","minvalue":"0","maxvalue":"100","description":"The defaault repo spread override to use for CASC positions.","defaultvalue":1.0,"value":1.0,"datatype":"FLOAT"},{"model":"MAF","paramname":"DefaultLotSize","minvalue":"1","maxvalue":"1000","description":"The minimum lot size that must be met for a collateral allocation.","defaultvalue":1.0,"value":1.0,"datatype":"INTEGER"},{"model":"MAF","paramname":"HtbColdHaircut","minvalue":"0","maxvalue":"100","description":"The haircut to apply to positions with a Cold HTB category.","defaultvalue":0.1,"value":0.1,"datatype":"FLOAT"},{"model":"MAF","paramname":"HtbExtraHotHaircut","minvalue":"0","maxvalue":"100","description":"The haircut to apply to positions with a Extra-Hot HTB category.","defaultvalue":0.9,"value":0.9,"datatype":"FLOAT"},]
$scope.field = 'value';
$scope.change = function() {
$scope.field = 'oldValue';
}
...ng repeat blabla
<input ng-model="modelParam[field]"/>
...
<button ng-click="change()">Change</button>
EDIT: Here is a working demo: http://jsfiddle.net/zy94an54/

Angular $setPristine() not working

I'm trying to use Angular's built-in form functions, specifically setPristine() to clear the form on user submit. My controller has access to $scope.newForm (my form) with all of its methods, but running $scope.newForm.$setPristine() isn't resetting the form fields.
Here is my HTML:
<div ng-controller="NewFormController">
<h3>New Entry</h3>
<form name="newForm" method="post" novalidate>
<div class="input-group">
<label>Name</label>
<input name="name" type="text" ng-model="place.name"/>
</div>
<div class="input-group">
<label>Description</label>
<textarea name="description" type="text" ng-model="place.description"></textarea>
</div>
<div class="input-group">
<label>Neighborhood</label>
<input name="neighborhood" type="text" ng-model="place.neighborhood"/>
</div>
<div class="input-group">
<label>Address</label>
<input name="location" type="text" ng-model="place.address"/>
</div>
<input type="submit" value="Submit" ng-click="submit(place)"/>
</form>
</div>
And here is the controller where I call setPristine():
app.controller('NewFormController', function($scope, $compile) {
$scope.place = {
name: 'ExamplePlace',
description: 'This is a description!',
neighborhood: 'Manhattan',
address: '112 Street Place'
};
$scope.submit = function(place) {
$scope.newForm.$setPristine();
$scope.newForm.$setUntouched();
};
});
Here is a working codepen that reproduces my problem.
Note: I'm using Angular version 1.4.3.
$setPristine only marks the form as being $pristine, which is useful for validation-driven expressions and CSS (e.g. .ng-dirty)
So, $setPristine does not clear the form's controls. In fact, it wouldn't even know how to do that. Consider, that to "clear" could mean different things to different models. "Clear" could mean "", or undefined, or null, or anything at all that a custom input control that works with ngModel could mean.
So, to properly clear the form is to modify the View Model that drives the form to whatever definition of "clear" it needs. In most cases - yours included - it is just a matter of setting the View Model to a new object:
$scope.submit = function(place) {
$scope.newForm.$setPristine();
$scope.newForm.$setUntouched();
// clear the form
$scope.place = {};
};

Hide form on submit with Angular JS

Trying to wrap my head around some Angular items and working thru a tutorial to edit and learn.
Clicking the below button shows the below form. How do I reverse this once the form is submitted? Meaning hiding the form on submit until the button is clicked once more.
<button ng-click="addNewClicked=!addNewClicked;" class="btn btn-sm btn-primary">
<i class="fa fa-plus"></i>Add Task
</button>
Basically, the form appears, I enter something and submit, but would like the form to dissapear upon submit? Thinking something to do with ng-hide, but can I do this using only Angular? Or do I need to do something with javascript/css?
<div id="addForm" class="margin-full-5">
<form ng-init="addNewClicked=false; " ng-if="addNewClicked" id="newTaskForm" class="add-task">
<div class="form-actions">
<div class="input-group">
<input type="text" class="form-control" name="comment" ng-model="taskInput" placeholder="Add New Task" ng-focus="addNewClicked">
<div class="input-group-btn">
<button class="btn btn-default" type="submit" ng-click="addTask(taskInput)">
<i class="fa fa-plus"></i> Add Task
</button>
</div>
</div>
</div>
</form>
You can also achieve this using a combination of Angular form's attribute $submitted, ng-hide and ng-submit
<form name="myForm" ng-hide="myForm.$submitted" ng-submit="submit()">
<button>Submit</button>
</form>
Read about it here: https://docs.angularjs.org/api/ng/type/form.FormController
Somewhere in your view.
<button ng-click="showTheForm = !showTheForm">Add a Task</button>
<form ng-show="showTheForm" ng-submit="processForm()">
<button>Submit</button>
<button type="button" ng-click="showTheForm = false">Cancel</button>
</form>
Somewhere in your controller
$scope.processForm = function() {
// execute something
$scope.showTheForm = false;
}
Your form is displaying IF the addNewClicked value evaluates to true, which occurs when you click the add task button. If you want the form to disappear on submit, you just need to make the onClick to that button change your addNewClicked to false.
AngularJS Docs for Ng-If
You can do that by using ng-show/ng-hide as per example below :
<form ng-init="addNewClicked=false; " ng-if="addNewClicked" ng-hide="hideform" id="newTaskForm" class="add-task">
and modify the submit method to make the hideform = true;
$scope.addTask = function(input){
... your things
$scope.hideform = true;
}
You can also do the same using jQuery :
$("#newTaskForm").hide();
This should do the trick:
$scope.addTask = function(taskInput) {
...
$scope.addNewClicked = false;
}
You could use ng-show as you can see in this jsfiddle
This will show and hide the div element based on clicking the button. When the button is clicked it will toggle the boolean, hence acting as an on/off switch for ng-show

How to manually trigger a form's submit in AngularJS?

I have a form that I wanted be nested, but it is not possible since HTML can't accept nested form. Is there a way I can manually invoke the submit(triggers the validation, e.g. required) on first form on AngularJS?
Here's how the code looks like:
<div ng-conroller="ContactController">
<form ng-submit="saveHeaderAndDetail()">
<label for="Description">Description</label>
<input type="text" ng-model="Description" required/>
<input type="text" style="visibility:hidden" />
</form>
<form ng-submit="addToDetail()">
...
</form>
<input type="button"
ng-click="what code could trigger the first form's submit?"/>
</div>
Btw, both forms are under one controller if that helps
Try creating a directive that catches an event:
var app = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.triggerSubmit = function() {
$scope.$broadcast('myEvent');
console.log('broad');
};
$scope.onSubmitted = function() {
alert('submitted!');
};
}
app.directive('submitOn', function() {
return {
link: function(scope, elm, attrs) {
scope.$on(attrs.submitOn, function() {
//We can't trigger submit immediately, or we get $digest already in progress error :-[ (because ng-submit does an $apply of its own)
setTimeout(function() {
elm.trigger('submit');
});
});
}
};
});
<link href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css" rel="stylesheet"/>
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="http://code.angularjs.org/1.0.0/angular-1.0.0.js"></script>
<div ng-controller="MyCtrl">
<form submit-on="myEvent" ng-submit="onSubmitted()">
Form...
</form>
<hr />
<a class="btn" ng-click="triggerSubmit()">Submit</a>
</div>
Original source:
http://jsfiddle.net/unWF3/
I've answered a similar question here AngularJS - How to trigger submit in a nested form
Basically, you can trigger validation by firing $validate event
isFormValid = function($scope, ngForm) {
$scope.$broadcast('$validate');
if(! ngForm.$invalid) {
return true;
}
For working code example & a small utility method which is helpful in showing validation messages, see answer in the above link.
You can have nested forms with ng-form directive. It will be like:
<form name="accountForm">
<div data-ng-form="detailsForm">
<input required name="name" data-ng-model="name">
</div>
<div data-ng-form="contactsForm">
<input required name="address" data-ng-model="address">
</div>
<button type="submit">Save</button>
</form>
That way when submit will be triggered for the accountForm it will validate nested ng-forms also.
There's an easier way to do that, You can give a name for each form that you have in your app, then you'll be able to send the entire angular object of the form that you want to trigger or do whatever you want with it. Example:
<div ng-conroller="ContactController">
<form name="myFirstForm" ng-submit="saveHeaderAndDetail()">
<label for="Description">Description</label>
<input type="text" ng-model="Description" required/>
<input type="text" style="visibility:hidden" />
</form>
<form name="mySecondForm" ng-submit="addToDetail()">
...
</form>
<input type="button"
ng-click="saveHeaderAndDetail(myFirstForm)"/>
</div>
Then in your function
saveHeaderAndDetail (myFirstForm) {
myFirstForm.$submitted = true
...
}
We can always submit a form directly using the submit
() function from javascript.
document.getElementById("myform").submit()
In this way, we can validate the form using angularjs first and if the form is valid then submit it using the submit method.

Categories

Resources