Simple practical example for two way data binding in AngularJS - angularjs

Can any one help me out to understand what exactly two way data binding in AngularJS means with a help of simple code.

One way data binding -
The model values are automatically assigned to the HTML placeholder elements specified through the data binding notation, but the HTML elements don't change the values in the model(one way).
Example :
Controller :
app.controller('MainCtrl', function($scope) {
$scope.firstName = 'John';
});
HTML :
<span>First name:</span> {{firstName}}<br />
Two Way Data Binding -
The model values are automatically assigned to the HTML placeholder elements specified through the data binding notation, where HTML elements can change the value in the model(two way).
Example :
Controller :
app.controller('MainCtrl', function($scope) {
$scope.firstName = 'John';
});
HTML
<span>First name:</span> {{firstName}}<br />
<span>Set the first name: <input type="text" ng-model="firstName"/></span><br />
In above example we can change firstName model value with the help of HTML Input element.
Working example : http://plnkr.co/edit/GxqBiOoNFuECn55R4uJZ?p=preview

Retrieved from the AngularJS homepage (2015.06.02):
<!doctype html>
<html ng-app>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
</head>
<body>
<div>
<label>Name:</label>
<input type="text" ng-model="yourName" placeholder="Enter a name here">
<hr>
<h1>Hello {{yourName}}!</h1>
</div>
</body>
</html>
This is possibly the simplest example of two-way data binding in Angular.
The <input> is associated to a yourName model, and the same model is used to fill the content of the <h1> tag. Modifying one will automatically update the other.
Although the data binding in the example can be seen as one-way, because you can't modify the <h1> directly, this should get you started. The AngularJS docs and tutorials contain a lot of great resources.

Related

Getting a variable from the ng-change function angularjs

I eventually need to create a select box with 4 options - Module 1 to 4. When an option is selected I need to send the number which was selected to the controller so that it can return different datasets for a chart.
That is the end goal, however experimenting with different code pens I simplified my problem down to just trying to get a variable from an input box.
I can get the value to appear on the template but I can not access it in the controller. How can I make the function in the controller work with the passed input data?
html
<body ng-app="plunker" ng-cloak>
<div ng-controller="MainCtrl">
<h1>Hello {{name}}</h1>
<p>Start editing and see your changes reflected here!</p>
</div>
<input placeholder="Module" type="text" ng-change="moduleChange(myModule)"
ng-model="myModule" ng-model-options="{debounce: 1000}">
{{myModule}}
</body>
script.js
angular.module('plunker', []).controller('MainCtrl',
function($scope) {
$scope.name = 'Plunker';
$scope.moduleChange = function(myModule) {
alert(myModule);
console.log(myModule);
$scope.name = myModule;
}
});
I thought that I would get an alert every time I changed the input but nothing is happening. nothing is logged to the console and the $scope.name variable appears to not change.
Where am I going wrong? Thx
Also any pointers for making it work inside a select box would be great too!
plunkr
Move ng-controller="MainCtrl" to the outer element (thats the reason why the function was not fired):
<body ng-app="plunker" ng-controller="MainCtrl" ng-cloak>
You don't need to pass the value into the function, you have the value with ng-model:
<input placeholder="Module" type="text" ng-change="moduleChange()" ng-model="myModule" ng-model-options="{debounce: 1000}">
$scope.moduleChange = function() {
alert($scope.myModule);
console.log($scope.myModule);
$scope.name = $scope.myModule;
}

AngularJS Formly - dynamic change of field type

What I wish to achieve is a single page (a form) used for both edit and display a record's data. I would like to have an edit button which would switch modes from edit to display and vice versa.
In terms of layout both modes looks the same.
In edit mode I have inputs/selects/typeaheads/multiple selects/datetime pickers etc. But in display mode values are displayed like in simple span. Something like that :)
So my question is: Is it possible to change field type after form is being rendered by formly? Any tips how to achieve such behaviour?
You can simply hide an edit form and bind your data to each form so that changes on one of them will be visible on another. Here is a quick demo:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.text = "demo";
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-if="!edit">
{{$parent.text}}
</div>
<div ng-if="edit">
<input type="text" ng-model="$parent.text" />
</div>
<button ng-click="edit = !edit">Edit</button>
</div>

Binding raw object output to a form representation

I'm trying to update models from a JSON representation of an object to a form. Here's a link to an example
To recreate my issue,
Change the data in the form (see that the JSON changes).
Change the JSON (See that the form doesn't change).
Here's my code:
JS
var ppl = {
createdby: "foo",
dateCreated: "bar",
}
angular.module('myApp', [])
.controller("Ctrl_List", function($scope) {
$scope.people = ppl
$scope.print = JSON.stringify($scope.ppl)
})
HTML
<div ng-app="myApp">
<div class="container" ng-controller="Ctrl_List">
<!-- FORM -->
<div class="row" ng-repeat="(key,val) in people track by $index">
<div class="col-md-12">
<label for="{{key}}">{{key}}</label>
<input class=form-control" id="{{key}}" ng-model="people[key]">
</div>
</div>
<!-- JSON -->
<div class="editable" contenteditable="true" ng-model="people">{{people}}</div>
</div>
</div>
When a user changes the JSON, the form should update in real-time.
Here's some things I have tried:
Change the JSON display element from div to input but it prints [Object][Object]
Also <input ng-model="JSON.stringify(people)"> but I get an "unbindable element" error.
Also tried adding a new model: $scope.print = JSON.stringify(people) but it shows nothing in the raw output.
Is it even possible to update a live object or am I gonna have to do some sort of event that triggers the form to change?
PS: Angular 1.5.8
There are several reasons why this doesn't work:
ng-model on a div doesn't do anything
even if it did, it would save a string to people, and your form would thus not work anymore.
You should use a textarea to make it work, and bind it to another variable, of type string. Using ng-change on the textarea, and on the inputs of the form, allows populating the people object by parsing the JSON string, and vice-verse, populating the JSON string from the people object.
See https://codepen.io/anon/pen/peexPG for a demo.
Refering to Contenteditable with ng-model doesn't work,
contenteditable tag will not work directly with angular's ng-model because the way contenteditable rerender the dom element on every change.

AngularJS Basic Model Value Editing without Controller

I am looking at this basic example of AngularJS:
<!doctype html>
<html ng-app>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular.min.js"></script>
</head>
<body>
<div>
<label>Name:</label>
<input type="text" ng-model="yourName" placeholder="Enter a name here">
<hr>
<h1>Hello {{yourName}}!</h1>
</div>
</body>
</html>
It is the first example on the website and has no controller or anything. A textfield is attached to the model field yourName.
Now, I was wondering: since editing the text in the textfield changes the model value, how do I change the value of "yourName" programmatically? Thus far, I have found no simple way of doing this without adding a controller and whatnot.
Also, how can I attach a listener to that model to be notified whenever it changes?
In this case, you don't need a controller for this simple example. Angular behind the scenes is "creating"
$scope.yourName
In terms of changing it programmatically, you have to use a controller. In terms of watching for changes, use $scope.$watch
$scope.$watch($scope.yourName, function (newVal, oldVal) {
if (newVal !== oldVal) {
// logic here
}
});

Backbone.stickit works on forms but not contenteditable

I'm using Backbone.stickit for two way binding between a View and a Model. I would like to use a contenteditable span as the bound DOM element, but that's not working.
If I use this template:
<script type="text/template" id="textbox-template">
<!--<span id="content" contenteditable/>-->
<input type='text' id='content'/>
</script>
two way binding works as anticipated. If I use the span rather than the input element, changes do not push back to the model. Note that onGet works, so the original model attribute value is visible. However, I've confirmed that onSet is not called, so an event isn't firing properly.
The Backbone.stickit looks for the contenteditable attribute where its value is true so to make it work you need to write:
<script type="text/template" id="textbox-template">
<span id="content" contenteditable="true"/>
<input type='text' id='content'/>
</script>

Resources