AngularJS Stop Replacement of Default Input Value - javascript

In AngularJS I have input that is populated by php like so:
<form method="post" ng-controller="PostCtrl">
<input type="text" name="post_title" ng-model="post_title" />
</form>
Now in my Controller, I never to specify ng-model, so I lets imagine I have empty controller:
EngagementApp.controller('PostCtrl', ['$scope',
function($scope) {
return function($scope) {
}
}]);
The problem I am having is that anything tied to an ng-model automaticcaly gets replaced with an empty value. My question is how can I stop the default php value from being replaced if no value in the controller is set?

You can use ng-init to set an inital value. For example
<input type="text" name="post_title"
ng-model="post_title" ng-init="post_title='<?$=phpValue;?>'" />
The HTML value attribute is ignored by AngularJS.

You should could the default values from your controller:
$scope.post_title = 'default value';
But initializing the model from the html by using ng-init ( like #Thomas suggested ) makes more sense in this particular case.

Related

getting values from sessionStorage

I am trying to get the value from sessionStorage and map it to my ng-model, but
when i do that in my ng-init its not working.
The problem is in my actual code i am inside a ng-repeat so my sessionStorage becomes like below:
sessionStorage.getItem(item.itemId)
HTMl Code:
<div ng-app="">
<div ng-controller="MyCtrl">
Not Working <input ng-init = 'name = sessionStorage.getItem("SavedString")' type="text" ng-model="name" >
Working <input type="text" ng-model="name1" >
</div>
</div>
Controller:
function MyCtrl($scope) {
sessionStorage.setItem("SavedString","I'm a value saved with SessionStorage");
//RETRIEVE VALUE
$scope.name = "test"
$scope.name1 = sessionStorage.getItem("SavedString");
$scope.hi = 'Hello World';
}
Fiddle:
http://jsfiddle.net/393revrn/
i too tried in your way but i didn't find a the requirements to achieve this ......so i tried with making a function call with in init and appended session data to that model then i can see the proper output by making ng-init ='some()' here is the working plunker
UPDATE
From some source i found that HTML cannot understand session variables directly.
The sessionStorage, when accessed from the ng-init directive, is not understood by Angular; it will be parsed and interpreted as if it were a $scope function (which, I assume, is not).
So, in order for your example to work, you should do something like this in your controller:
$scope.sessionStorage = sessionStorage;

Difference between ng-model and angular expression - {{}}

{{}} is working fine but ng-model is not, at the same place.
I am using the following html-
<body ng-app="crud">
Gray input fields will not be visible.
<div ng-controller="ctrl">
<input type="text" value="sdf" ng-model="asdf"/>
<h1 ng-model="asdf"></h1> <!-- this doesn't work-->
<h1>{{asdf}}</h1> <!-- this work-->
</div>
</div>
</body>
asdf is defined in this js app like this
var app = angular.module("crud", []);
app.controller("ctrl", ['$scope', function($scope) {
$scope.asdf="ankur";
}]);
Can someone explain why is it so ?
The ng-model directive is to be used on the input fields such as input, select for two way data binding and to get an input from a user.
Where as the one way data binding expression {{}} or ng-bind directive is used to output the data in the view.
var app = angular.module("crud", []);
app.controller("ctrl", ['$scope', function($scope) {
$scope.asdf="ankur";
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="crud">
Gray input fields will not be visible.
<div ng-controller="ctrl">
<input type="text" value="sdf" ng-model="asdf"/>
<h1 ng-bind="asdf"></h1>
<h1>{{asdf}}</h1>
</div>
</div>
Use ng-bind for display purposes, instead of ng-model.
<h1 ng-bind="asdf"></h1>
You only want to use ng-model when binding to an element that will be editing the variable, such as a text field.
From documentation:
The ngModel directive binds an input, select, textarea (or custom form control) to a property on the scope using NgModelController, which is created and exposed by this directive.
You are trying to use it on a <h1>. Use ng-bind instead.
According the doc
the ngModel directive binds an input,select, textarea (or custom form control) to a property on the scope using NgModelController, which is created and exposed by this directive.
so you will not use it for display an H1
For the brackets they will be dirty checked and refreshed in every $digest, even if it's not necessary. So it's slower. Plus thez may appear while your angularjs is bootstrapping
ng-model : This directive binds the values of AngularJS application data to HTML input controls.
{{}} This use For Printing purpose only. you can put expression also like {{2*2}} it prints 4
Refer This for study basic syntax https://angularjs.org/

How to mix struts1 with angularjs to auto populate a field

I'm building a jsp page with struts1 (i cannot use struts2) where i have a field i'm auto populating with a value coming from the form, but the user is free to overwrite anything in that text field. I have also used AngularJS to be able to give options while the user types (google-like search) when they are overriding the value pre-populated by struts.
My problem is that the tags ng-model and uib-typeahead are not recognized by the html:text tag in struts. If i switch to a plain html input tag then the angular feature works but now i cannot pre-populate the field with struts.
script.js:
angular.module('plunker', ['ui.bootstrap','ngAnimate']).controller('TypeaheadCtrl', function($scope, $http) {
$scope.selected = undefined;
// Any function returning a promise object can be used to load values asynchronously
$scope.getLocation = function(val) {
return $http.get('http://maps.googleapis.com/maps/api/geocode/json', {
params: {
address: val,
sensor: false
}
}
).then(function(response){
return response.data.results.map(function(item){
return item.formatted_address;
});
});
};
});
mypage.html
<body ng-controller="TypeaheadCtrl">
<div class='container-fluid typeahead-demo' >
<div class="section">
<!-- OPTION 1: angular works and gives suggestions, but the field doesn't get pre-populated by struts-->
<input type="text" name="city" id="city" class="gui-input" ng-model="asyncSelected" uib-typeahead="address for getLocation($viewValue)" placeholder="Type city name">
<html:hidden property="city"/>
<!-- OPTION 2: auto-populates value but it can't compile with ng-model and typegead tags -->
<html:text property="city" styleClass="gui-input" styleId="cityStyle" />
</div>
</div>
Can someone please tell me what the best way or appropriate way of doing this is? how do i mix the functionality of Option 1 and Option 2?
Thanks in advance.
I already resolved it by setting the value of the field using jquery on load, but if someone has a better solution or better practice to do this, i'd like to know.

HTML input has both {{}} and ng-model

I have a form which contains two input fields, I want to sync the next input field when user is typing in the first input field by default, and user can edit the second field as they like, below code works fine:
<input type="text" ng-model="name">
<input type='text' value='{{name}}'>
<button ng-click='submit()'>submit</button>
However, to be able to get the value of second field, I need to put ng-model to the second field, and once I put ng-model, it won't sync anymore.
This is the example
How should I get the second field's value if I don't put a ng-model to it.
Thank you.
You can use ng-change. When user changes input 1 the ng-change method will be called and input2 will be updated .but when user change input 2 nothing will be called .
<DIV ng-app='app'>
<form ng-controller='myController'>
<input type='text' ng-model='name' ng-change="callMe()"/>
<input type='text' ng-model="name2" />{{name2}}
</form>
</DIV>
and controller js
var app = angular.module('app', []);
app.controller('myController', function($scope){
$scope.callMe =function(){
$scope.name2=$scope.name;
}
//$scope.name
//$scope.name2
})
update fiddle example
You could use the $scope.$watch Method for your needings.
I have updatet your fiddle.
What i did is easy, everytime the model changes, the $watch will be called with the new value of the model, then you just need to copy the value into the second model.
First approach that came to my mind was to ng-bind a property with a setter that would do what you want:
<input type='text' ng-model='nameModel' />
then
app.controller('myController', function($scope) {
Object.defineProperty($scope, 'nameModel', {
get: function() { return $scope.name1; },
set: function(x) { $scope.name1 = $scope.name2 = x; }
});
});
This causes any edit to nameModel to affect both name1 and name2.
Fiddle
You could do a similar wrapper around name2 to track whether it has ever been modified (dirty/pristine), and have nameModel only change scope.name2 if it is pristine.
Fiddle with better user experience
(If you're using Angular forms, it tracks the field status for you, so you could directly look at form.name2.$pristine.)
It seems that what you need is to set the value to the scope variable.
So your code would then look like this:
<input type="text" ng-model="name">
<input type='text' value="{{name}}" ng-model="somethingelse">
<button ng-click='submit()'>submit</button>
Hope that helps.

AngularJS - Value attribute on an input text box is ignored when there is a ng-model used?

Using AngularJS if I set a simple input text box value to something like "bob" below. The value does not display if the ng-model attribute is added.
<input type="text"
id="rootFolder"
ng-model="rootFolders"
disabled="disabled"
value="Bob"
size="40"/>
Anyone know of a simple work around to default this input to something and keep the ng-model? I tried to use a ng-bind with the default value but that seems not to work either.
That's desired behavior, you should define the model in the controller, not in the view.
<div ng-controller="Main">
<input type="text" ng-model="rootFolders">
</div>
function Main($scope) {
$scope.rootFolders = 'bob';
}
Vojta described the "Angular way", but if you really need to make this work, #urbanek recently posted a workaround using ng-init:
<input type="text" ng-model="rootFolders" ng-init="rootFolders='Bob'" value="Bob">
https://groups.google.com/d/msg/angular/Hn3eztNHFXw/wk3HyOl9fhcJ
Overriding the input directive does seem to do the job. I made some minor alterations to Dan Hunsaker's code:
Added a check for ngModel before trying to use $parse().assign() on fields without a ngModel attributes.
Corrected the assign() function param order.
app.directive('input', function ($parse) {
return {
restrict: 'E',
require: '?ngModel',
link: function (scope, element, attrs) {
if (attrs.ngModel && attrs.value) {
$parse(attrs.ngModel).assign(scope, attrs.value);
}
}
};
});
The Angular way
The correct Angular way to do this is to write a single page app, AJAX in the form template, then populate it dynamically from the model. The model is not populated from the form by default because the model is the single source of truth. Instead Angular will go the other way and try to populate the form from the model.
If however, you don't have time to start over from scratch
If you have an app written, this might involve some fairly hefty architectural changes. If you're trying to use Angular to enhance an existing form, rather than constructing an entire single page app from scratch, you can pull the value from the form and store it in the scope at link time using a directive. Angular will then bind the value in the scope back to the form and keep it in sync.
Using a directive
You can use a relatively simple directive to pull the value from the form and load it in to the current scope. Here I've defined an initFromForm directive.
var myApp = angular.module("myApp", ['initFromForm']);
angular.module('initFromForm', [])
.directive("initFromForm", function ($parse) {
return {
link: function (scope, element, attrs) {
var attr = attrs.initFromForm || attrs.ngModel || element.attrs('name'),
val = attrs.value;
if (attrs.type === "number") {val = parseInt(val)}
$parse(attr).assign(scope, val);
}
};
});
You can see I've defined a couple of fallbacks to get a model name. You can use this directive in conjunction with the ngModel directive, or bind to something other than $scope if you prefer.
Use it like this:
<input name="test" ng-model="toaster.test" value="hello" init-from-form />
{{toaster.test}}
Note this will also work with textareas, and select dropdowns.
<textarea name="test" ng-model="toaster.test" init-from-form>hello</textarea>
{{toaster.test}}
Update: My original answer involved having the controller contain DOM-aware code, which breaks Angular conventions in favor of HTML. #dmackerman mentioned directives in a comment on my answer, and I completely missed that until just now. With that input, here's the right way to do this without breaking Angular or HTML conventions:
There's also a way to get both - grab the value of the element and use that to update the model in a directive:
<div ng-controller="Main">
<input type="text" id="rootFolder" ng-model="rootFolders" disabled="disabled" value="Bob" size="40" />
</div>
and then:
app.directive('input', ['$parse', function ($parse) {
return {
restrict: 'E',
require: '?ngModel',
link: function (scope, element, attrs) {
if(attrs.value) {
$parse(attrs.ngModel).assign(scope, attrs.value);
}
}
};
}]);
You can of course modify the above directive to do more with the value attribute before setting the model to its value, including using $parse(attrs.value, scope) to treat the value attribute as an Angular expression (though I'd probably use a different [custom] attribute for that, personally, so the standard HTML attributes are consistently treated as constants).
Also, there is a similar question over at Making data templated in available to ng-model which may also be of interest.
If you use AngularJs ngModel directive, remember that the value of value attribute does not bind on ngModel field.You have to init it by yourself and the best way to do it,is
<input type="text"
id="rootFolder"
ng-init="rootFolders = 'Bob'"
ng-model="rootFolders"
disabled="disabled"
value="Bob"
size="40"/>
This is a slight modification to the earlier answers...
There is no need for $parse
angular.directive('input', [function () {
'use strict';
var directiveDefinitionObject = {
restrict: 'E',
require: '?ngModel',
link: function postLink(scope, iElement, iAttrs, ngModelController) {
if (iAttrs.value && ngModelController) {
ngModelController.$setViewValue(iAttrs.value);
}
}
};
return directiveDefinitionObject;
}]);
Hi you can try below methods with initialize of model.
Here you can initialize ng-model of textbox two way
- With use of ng-init
- With use of $scope in js
<!doctype html>
<html >
<head>
<title>Angular js initalize with ng-init and scope</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
</head>
<body ng-app="app" >
<h3>Initialize value with ng-init</h3>
<!-- Initlialize model values with ng-init -->
<div ng-init="user={fullname:'Bhaskar Bhatt',email:'bhatt.bhaskar88#gmail.com',address:'Ahmedabad'};">
Name : <input type="text" ng-model="user.fullname" /><br/>
Email : <input type="text" ng-model="user.email" /><br/>
Address:<input type="text" ng-model="user.address" /><br/>
</div>
<!-- initialize with js controller scope -->
<h3>Initialize with js controller</h3>
<div ng-controller="alpha">
Age:<input type="text" name="age" ng-model="user.age" /><br/>
Experience : <input type="text" name="experience" ng-model="user.exp" /><br/>
Skills : <input type="text" name="skills" ng-model="user.skills" /><br/>
</div>
</body>
<script type="text/javascript">
angular.module("app",[])
.controller("alpha",function($scope){
$scope.user={};
$scope.user.age=27;
$scope.user.exp="4+ years";
$scope.user.skills="Php,javascript,Jquery,Ajax,Mysql";
});
</script>
</html>
The issue is that you have to set the ng-model to the parent element to where you want to set the ng-value/value .
As mentioned by Angular:
It is mainly used on input[radio] and option elements, so that when the element is selected, the ngModel of that element (or its select parent element) is set to the bound value.
Eg:This is an executed code :
<div class="col-xs-12 select-checkbox" >
<label style="width: 18em;" ng-model="vm.settingsObj.MarketPeers">
<input name="radioClick" type="radio" ng-click="vm.setPeerGrp('market');"
ng-value="vm.settingsObj.MarketPeers"
style="position:absolute;margin-left: 9px;">
<div style="margin-left: 35px;color: #717171e8;border-bottom: 0.5px solid #e2e2e2;padding-bottom: 2%;">Hello World</div>
</label>
</div>
Note: In this above case I alreday had the JSON response to the ng-model and the value, I am just adding another property to the JS object as "MarketPeers". So the model and value may depend according to the need, but I think this process will help, to have both ng-model and value but not having them on the same element.
I had similar issue. I was not able to use value="something" to display and edit.
I had to use the below command inside my <input>along withe ng model being declared.
[(ngModel)]=userDataToPass.pinCode
Where I have the list of data in the object userDataToPass and the item that I need to display and edit is pinCode.
For the same , I referred to this YouTube video

Categories

Resources