Fill ng-model default value from html in AngularJS [duplicate] - angularjs

Say you have a form that has values loaded from database. How do you initialize ng-model?
Example:
<input name="card[description]" ng-model="card.description" value="Visa-4242">
In my controller, $scope.card is undefined initially. Is there a way besides doing something like this?
$scope.card = {
description: $('myinput').val()
}

If you can't rework your app to do what #blesh suggests (pull JSON data down with $http or $resource and populate $scope), you can use ng-init instead:
<input name="card[description]" ng-model="card.description" ng-init="card.description='Visa-4242'">
See also AngularJS - Value attribute on an input text box is ignored when there is a ng-model used?

This is a common mistake in new Angular applications. You don't want to write your values into your HTML on the server if you can avoid it. If fact, if you can get away from having your server render HTML entirely, all the better.
Ideally, you want to send out your Angular HTML templates, then pull down your values via $http in JSON and put them in your scope.
So if at all possible, do this:
app.controller('MyController', function($scope, $http) {
$http.get('/getCardInfo.php', function(data) {
$scope.card = data;
});
});
<input type="text" ng-model="card.description" />
If you absolutely MUST render your values into your HTML from your server, you could put them in a global variable and access them with $window:
In the header of your page you'd write out:
<head>
<script>
window.card = { description: 'foo' };
</script>
</head>
And then in your controller you'd get it like so:
app.controller('MyController', function($scope, $window) {
$scope.card = $window.card;
});

This is an obviously lacking, but easily added fix for AngularJS. Just write a quick directive to set the model value from the input field.
<input name="card[description]" value="Visa-4242" ng-model="card.description" ng-initial>
Here's my version:
var app = angular.module('forms', []);
app.directive('ngInitial', function() {
return {
restrict: 'A',
controller: [
'$scope', '$element', '$attrs', '$parse', function($scope, $element, $attrs, $parse) {
var getter, setter, val;
val = $attrs.ngInitial || $attrs.value;
getter = $parse($attrs.ngModel);
setter = getter.assign;
setter($scope, val);
}
]
};
});

IMHO the best solution is the #Kevin Stone directive, but I had to upgrade it to work in every conditions (f.e. select, textarea), and this one is working for sure:
angular.module('app').directive('ngInitial', function($parse) {
return {
restrict: "A",
compile: function($element, $attrs) {
var initialValue = $attrs.value || $element.val();
return {
pre: function($scope, $element, $attrs) {
$parse($attrs.ngModel).assign($scope, initialValue);
}
}
}
}
});

You can use a custom directive (with support to textarea, select, radio and checkbox), check out this blog post https://glaucocustodio.github.io/2014/10/20/init-ng-model-from-form-fields-attributes/.

You can also use within your HTML code:
ng-init="card.description = 12345"
It is not recommended by Angular, and as mentioned above you should use exclusively your controller.
But it works :)

I have a simple approach, because i have some heavy validations and masks in my forms. So, i used jquery to get my value again and fire the event "change" to validations:
$('#myidelement').val('123');
$('#myidelement').trigger( "change");

As others pointed out, it is not good practice to initialize data on views.
Initializing data on Controllers, however, is recommended. (see http://docs.angularjs.org/guide/controller)
So you can write
<input name="card[description]" ng-model="card.description">
and
$scope.card = { description: 'Visa-4242' };
$http.get('/getCardInfo.php', function(data) {
$scope.card = data;
});
This way the views do not contain data, and the controller initializes the value while the real values are being loaded.

If you like Kevin Stone's approach above https://stackoverflow.com/a/17823590/584761
consider an easier approach by writing directives for specific tags such as 'input'.
app.directive('input', function ($parse) {
return {
restrict: 'E',
require: '?ngModel',
link: function (scope, element, attrs) {
if (attrs.ngModel) {
val = attrs.value || element.text();
$parse(attrs.ngModel).assign(scope, val);
}
}
}; });
If you go this route you won't have to worry about adding ng-initial to every tag. It automatically sets the value of the model to the tag's value attribute. If you do not set the value attribute it will default to an empty string.

Here is a server-centric approach:
<html ng-app="project">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script>
// Create your module
var dependencies = [];
var app = angular.module('project', dependencies);
// Create a 'defaults' service
app.value("defaults", /* your server-side JSON here */);
// Create a controller that uses the service
app.controller('PageController', function(defaults, $scope) {
// Populate your model with the service
$scope.card = defaults;
});
</script>
<body>
<div ng-controller="PageController">
<!-- Bind with the standard ng-model approach -->
<input type="text" ng-model="card.description">
</div>
</body>
</html>
It's the same basic idea as the more popular answers on this question, except $provide.value registers a service that contains your default values.
So, on the server, you could have something like:
{
description: "Visa-4242"
}
And put it into your page via the server-side tech of your choice. Here's a Gist: https://gist.github.com/exclsr/c8c391d16319b2d31a43

This one is a more generic version of the ideas mentioned above...
It simply checks whether there is any value in the model, and if not, it sets the value to the model.
JS:
function defaultValueDirective() {
return {
restrict: 'A',
controller: [
'$scope', '$attrs', '$parse',
function ($scope, $attrs, $parse) {
var getter = $parse($attrs.ngModel);
var setter = getter.assign;
var value = getter();
if (value === undefined || value === null) {
var defaultValueGetter = $parse($attrs.defaultValue);
setter($scope, defaultValueGetter());
}
}
]
}
}
HTML (usage example):
<select class="form-control"
ng-options="v for (i, v) in compressionMethods"
ng-model="action.parameters.Method"
default-value="'LZMA2'"></select>

I tried what #Mark Rajcok suggested. Its working for String values (Visa-4242).
Please refer this fiddle.
From the fiddle:
The same thing that is done in the fiddle can be done using ng-repeat, which everybody could recommend. But after reading the answer given by #Mark Rajcok, i just wanted to try the same for a form with array of profiles.
Things work well untill i have the $scope.profiles = [{},{}]; code in the controller. If i remove this code, im getting errors.
But in normal scenarios i cant print $scope.profiles = [{},{}]; as i print or echo html from the server.
Will it be possible to execute the above, in a similar fashion as #Mark Rajcok did for the string values like <input name="card[description]" ng-model="card.description" ng-init="card.description='Visa-4242'">, without having to echo the JavaScript part from the server.

Just added support for select element to Ryan Montgomery "fix"
<select class="input-control" ng-model="regCompModel.numberOfEmployeeId" ng-initial>
<option value="1af38656-a752-4a98-a827-004a0767a52d"> More than 500</option>
<option value="233a2783-db42-4fdb-b191-0f97d2d9fd43"> Between 250 and 500</option>
<option value="2bab0669-550c-4555-ae9f-1fdafdb872e5"> Between 100 and 250</option>
<option value="d471e43b-196c-46e0-9b32-21e24e5469b4"> Between 50 and 100</option>
<option value="ccdad63f-69be-449f-8b2c-25f844dd19c1"> Between 20 and 50</option>
<option value="e00637a2-e3e8-4883-9e11-94e58af6e4b7" selected> Less then 20</option>
</select>
app.directive('ngInitial', function () {
return {
restrict: 'A',
controller: ['$scope', '$element', '$attrs', '$parse', function ($scope, $element, $attrs, $parse) {
val = $attrs.sbInitial || $attrs.value || $element.val() || $element.text()
getter = $parse($attrs.ngModel)
setter = getter.assign
setter($scope, val)
}]
}
});

If you have the init value in the URL like mypage/id, then in the controller of the angular JS you can use location.pathname to find the id and assign it to the model you want.

Related

Refresh the data in controller when scope gets changed in AngularJS

I'm pretty new with angular and I've read a lot of threads here and googled this topic but I cannot get a clear answer. what i am really trying to achieve is. lets suppose I have a controller A, this is a actual source for data. I passed it to one directive through binding it to a HTML. From this directive I am acually getting the source at another controller.
So I need to find out the way where I can change the data of controller when the data of controller A gets changed.
Controller A
angular.module('page.leadAndOpportunity.ctrl', []).controller('LeadAndOpportunityController', ['$scope', '$rootScope', '$timeout', function ($scope, $rootScope, $timeout, leadAndOpportunityService) {
$scope.selectDataSource = function (condition) {
var dataSource = [];
var dataSource = $scope.leadsDataSource.filter(function (item) {
return item.typeName === condition;
});
$scope.leadsDataSource = [];
$scope.leadsDataSource = dataSource;
console.log($scope.leadsDataSource);
}
}]);
HTML
<ng-senab-grid datasource="{{ leadsDataSource }}" defaultdata="{{defaultColumns}}" skipdata="{{ skipColumns }}" enablepersonalisation="true"></ng-senab-grid>
Directive
angular.module('page.gridView.drct', []).directive("ngSenabGrid", ["$rootScope", function ($rootScope) {
return {
restrict: "E",
templateUrl: "pages/gridView/page.gridView.tpl.html",
scope: {
enablePersonalisation: "#enablepersonalisation",
datasource: "#datasource",
defaultdata: "#defaultdata",
skipdata: "#skipdata"
},
}
}]
);
Controller B
var _datasource = JSON.parse($scope.datasource);
//rest the data follows
So when $scope.leadsDataSource gets changes on Controller A, then the
var _datasource = JSON.parse($scope.datasource);
also should get changed
I dont know if it is possible or not. But I need to change the data
Thanks in advance
remove the curly brackets of the variable.since this is a directive no need to add curly brackets
<ng-senab-grid datasource="leadsDataSource" defaultdata="defaultColumns" skipdata="skipColumns" enablepersonalisation="true"></ng-senab-grid>
if u want to get the value of the variable then use "=" if u use "&" it will only get the string
scope: {
enablePersonalisation: "=enablepersonalisation",
datasource: "=datasource",
defaultdata: "=defaultdata",
skipdata: "=skipdata"
},
also inject the directive module to ur angular module
angular.module('page.leadAndOpportunity.ctrl', ['page.gridView.drct'])
A simple explanation to keep in mind about different types of scopes would be below.
# Attribute string binding (String)
= Two-way model binding (model)
& Callback method binding (method)
According this you should be using Two-way binding instead of Attribute string binding because The model in parent scope is linked to the model in the directive's isolated scope. Changes to one model affects the other, and vice versa.
I would prefer using bindToController property definition in the directive. When set to true in a directive with isolated scope that uses controllerAs, the component’s properties are bound to the controller rather than to the scope.
That means, Angular makes sure that, when the controller is instantiated, the initial values of the isolated scope bindings are available on this, and future changes are also automatically available.
Check the Below sample fiddle example for more understanding
var myApp = angular.module('myApp', []);
myApp.controller('MyController', function($scope) {
$scope.change = function() {
$scope.fullname = 'Keshan';
}
$scope.reset = function() {
$scope.fullname = 'Fill Your Name';
}
});
myApp.directive('myDirective', function() {
return {
restrict: 'E',
scope: {
name: '='
},
controller: function($scope) {
this.name = 'Fill Your Name';
},
controllerAs: 'ctrl',
bindToController: true,
template: '{{ctrl.name}}',
};
});
<script src="https://code.angularjs.org/1.3.7/angular.js"></script>
<div ng-app="myApp" ng-controller="MyController">
<button ng-click="change()">Change</button>
<button ng-click="reset()">Reset</button>
<my-directive name="fullname"></my-directive>
</div>
Further Reading

Why do ng-bind-html and $sanitize produce different results?

I'm trying to sanitize the content of some text areas, I cannot use ng-bind-html because it breaks two way binding (ng-model does not work at the same time)
Strangely when I apply ng-bind-html to a model it produces a different result to when I use $sanitize or $sce inside of a directive.
Here's a sample I made up
http://plnkr.co/edit/iRvK4med8T9Xqs22BkOe?p=preview
First text area uses ng-bind-html, the second uses $sanitize and the third should be the code for the ng-bind-html directive as I ripped out of the AngularJS source code.
" is only corrected changed to " when using ng-bind-html, in the other two examples it changes to "
How can I replicate the results of ng-bind-html in my directive - while keeping the two way binding?
angular.module('sanitizeExample', ['ngSanitize'])
.controller('ExampleController', ['$scope', '$sce',
function($scope, $sce) {
$scope.value = 'This in "quotes" for testing';
$scope.model = 'This in "quotes" for testing';
}
]).directive('sanitize', ['$sanitize', '$parse', '$sce',
function($sanitize, $parse, $sce) {
return {
restrict: 'A',
replace: true,
scope: true,
link: function(scope, element, attrs) {
var process = function(input) {
return $sanitize(input);
//return $sce.getTrustedHtml(input);
};
var processed = process(scope.model);
console.log(processed); // Output here = This in "quotes" for testing
$parse(attrs.ngModel).assign(scope, processed);
//element.html(processed);
}
};
}
])
.directive('sanitizeBindHtml', ['$parse', '$sce',
function($parse, $sce) {
return {
restrict: 'A',
replace: true,
scope: true,
link: function(scope, element, attrs) {
var parsed = $parse(attrs.ngModel);
function getStringValue() {
var value = parsed(scope);
getStringValue.$$unwatch = parsed.$$unwatch;
return (value || '').toString();
}
scope.$watch(getStringValue, function ngBindHtmlWatchAction(value) {
var processed = $sce.getTrustedHtml(parsed(scope)) || '';
$parse(attrs.ngModel).assign(scope, processed)
});
}
};
}
]);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular-sanitize.js"></script>
<!doctype html>
<html lang="en">
<body ng-app="sanitizeExample">
<div ng-controller="ExampleController">
<textarea ng-bind-html="value"></textarea>
<br/>{{value}}
<br/>
<br/>
<textarea sanitize ng-model="model"></textarea>
<br/>
<br/>
<textarea sanitize-bind-html ng-model="model"></textarea>
</div>
</body>
It turns out like we would expect, the sanitation service is returning the same result. Placing a breakpoint inside the ngBindHtmlDirective, We can step in and see what is happening. We dive in and examine the values inside the $SanitizeProvider. The value of buf that will be returned back to the ngBindHtmlDirective is:
This in "quotes" for testing
The exact same as we get for calling $sanitize, so what's the real difference? The real difference is between a textbox's innerHTML and value. View this example plunker. You can see the difference between calling the two different methods, with the different ways of escaping a double quote. I didn't go digging though the w3 spec or the browser code, but I assume the innerHTML assignment is doing additional work under the hood of creating a documentFragment, grabbing it's textContent, then assigning that to the textbox's value. Obviously value is just grabbing the string and inserting it as is.
So what's the problem with your directives? I see that element.html(processed) is in a comment, but uncommenting it doesn't have an affect. Well the truth is that it does work for a split second! Stepping though with the debugger, the value of the textbox is correctly set, but then a $digest cycle gets fired and immediate changes it! The truth is the ngModelDirective is getting in the way, specifically it's the $render function of the baseInputType. We can see in the code it is using the element.val method.
How can we fix this in the directives? Require the ngModelController and override its $render function to use element.html method instead (example plunker).
// Add require to get the controller
require: 'ngModel',
// Controller is passed in as the 4th argument
link: function(scope, element, attrs, ngModelCtrl) {
// modify the $render function to process it as HTML
ngModelCtrl.$render = function() {
element.html(ngModelCtrl.$isEmpty(ngModelCtrl.$viewValue) ? '' : ngModelCtrl.$viewValue);
};

How to prefill a calculation form with initial values?

I've a long calculation form and want to prefill some values for displaying initial results. These initial values should live in the template to have these easily editable. It seems, the angular way is to use a directive which reads the input value fields and initializes the app with these values.
Here is one way to to set the model value from the input field:
<input name="card[description]" value="Visa-4242" ng-model="card.description" ng-initial>
Coffeescript:
app = angular.module 'forms', []
app.directive 'ngInitial', ->
restrict: 'A'
controller: ['$scope', '$element', '$attrs', '$parse', ($scope, $element, $attrs, $parse) ->
val = $attrs.sbInitial || $attrs.value
getter = $parse($attrs.ngModel)
setter = getter.assign
setter($scope, val)
]
Source: Angular js init ng-model from default values
Unfortunately this doesn't work in my app. The values are displayed but the results aren't calculated. I have to manual fill out the fields in the browser to start the calculation.
The input fields are watched in my controller, like so:
$scope.$watch(
'inputValues.permeatCapacity',
function (newValue, oldValue) {
if (newValue === oldValue) {
return;
}
permeatCapacity = $scope.inputValues.permeatCapacity;
permeatPerDay = permeatFactory.getPermeatPerDay(permeatCapacity);
$scope.permeatPerDay = $filter('number')(permeatPerDay, 2);
}
);
What's the best directive for this problem or is there a better way in Angular.js?
UPDATE
I've just found a really dirty way in the controller to update the input fields after initialization that make use of the bound calculations. It not only feels like an bad idea, the initial values also don't live in the template:
$timeout(function () {
$scope.inputValues.overallRecovery = 40;
$scope.inputValues.permeatCapacity = 7.2;
}, 0);
In comparison, this initial object in my controller fills out the fields but doesn't trigger the watchers (important for the bound calculations):
$scope.inputValues = {
overallRecovery: 40,
permeatCapacity: 7.2
};
But there is a better way to do this, isn't it?
Ok, here's what I found out. The condition:
if (newValue === oldValue) {
return;
}
in my watch methods blocked the initial calculation. I can now use a really simple directive for my usecase:
An input field in the template:
<input type="text" id="overall-recovery" value="40" ng-model="inputValues.overallRecovery" initial-value>
The directive:
angular.module('ksbApp')
.directive('initialValue', function ($compile) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ngModel) {
var initialValue = attrs.value;
ngModel.$setViewValue(initialValue);
}
};
});
In this case, the value "40" is pushed to the model during initialization.
Is there anything I could do better?
Not sure why you would need a directive for this, unless I dont understand the question fully. Spin up the model in scope, setting the values where on the controller, and then bind them using ngmodel.
in the controller:
scope.inputValues = {permeatCapacity: 1};
scope.calc = function(){
return permeatFactory(scope.inputValues.perMeatCapacity);
};
in the view:
<input ng-model="inputValues.permeatCapacity" type="text">
<button ng-click="calc()" />
In later versions of angular you can even have the calculation run AS the values in the model change using ng-change.

Binding the placeholder to the model causes ng-change to execute on load in IE

Using angularjs, if I bind the placeholder of an input to its model, the change event is fired when the document loads in IE. This does not appear to be correct and I'm not seeing this behavior in other browsers.
JS Fiddle
Html:
<div ng-app="angularjs-starter" data-ng-controller="MainCtrl">
<div data-ui-view="viewMain">
<input
placeholder="{{theValue}}"
data-ng-model="theValue"
data-ng-change="valueChanged(theValue)" />
</div>
Javascript:
var app = angular.module('angularjs-starter', []);
app.controller('MainCtrl', function($scope) {
$scope.valueChanged = function(theValue) {
alert("Value Change Called On Load in IE.");
};
});
It's possible to use the built-in ng-attr-placeholder directive as well.
ng-attr-placeholder="{{theValue}}"
I know this is old but just in case anyone else runs in to this I created a small directive that goes around putting a dynamic value in the placeholder and instead have it assign when it changes:
.directive('dynamicPlaceholder',
function() {
return {
restrict: 'A',
link: function ($scope, element, attrs) {
attrs.$observe('dynamicPlaceholder', function(value) {
element.attr('placeholder', value);
});
}
};
});
Then to use this all you need to do is use dynamic-placeholder instead of placeholder:
<input ng-model='someValue' dynamic-placeholder='{{someDynamicPlaceholder}}' />
Not sure what is causing the problem in IE though

Angular js init ng-model from default values

Say you have a form that has values loaded from database. How do you initialize ng-model?
Example:
<input name="card[description]" ng-model="card.description" value="Visa-4242">
In my controller, $scope.card is undefined initially. Is there a way besides doing something like this?
$scope.card = {
description: $('myinput').val()
}
If you can't rework your app to do what #blesh suggests (pull JSON data down with $http or $resource and populate $scope), you can use ng-init instead:
<input name="card[description]" ng-model="card.description" ng-init="card.description='Visa-4242'">
See also AngularJS - Value attribute on an input text box is ignored when there is a ng-model used?
This is a common mistake in new Angular applications. You don't want to write your values into your HTML on the server if you can avoid it. If fact, if you can get away from having your server render HTML entirely, all the better.
Ideally, you want to send out your Angular HTML templates, then pull down your values via $http in JSON and put them in your scope.
So if at all possible, do this:
app.controller('MyController', function($scope, $http) {
$http.get('/getCardInfo.php', function(data) {
$scope.card = data;
});
});
<input type="text" ng-model="card.description" />
If you absolutely MUST render your values into your HTML from your server, you could put them in a global variable and access them with $window:
In the header of your page you'd write out:
<head>
<script>
window.card = { description: 'foo' };
</script>
</head>
And then in your controller you'd get it like so:
app.controller('MyController', function($scope, $window) {
$scope.card = $window.card;
});
This is an obviously lacking, but easily added fix for AngularJS. Just write a quick directive to set the model value from the input field.
<input name="card[description]" value="Visa-4242" ng-model="card.description" ng-initial>
Here's my version:
var app = angular.module('forms', []);
app.directive('ngInitial', function() {
return {
restrict: 'A',
controller: [
'$scope', '$element', '$attrs', '$parse', function($scope, $element, $attrs, $parse) {
var getter, setter, val;
val = $attrs.ngInitial || $attrs.value;
getter = $parse($attrs.ngModel);
setter = getter.assign;
setter($scope, val);
}
]
};
});
IMHO the best solution is the #Kevin Stone directive, but I had to upgrade it to work in every conditions (f.e. select, textarea), and this one is working for sure:
angular.module('app').directive('ngInitial', function($parse) {
return {
restrict: "A",
compile: function($element, $attrs) {
var initialValue = $attrs.value || $element.val();
return {
pre: function($scope, $element, $attrs) {
$parse($attrs.ngModel).assign($scope, initialValue);
}
}
}
}
});
You can use a custom directive (with support to textarea, select, radio and checkbox), check out this blog post https://glaucocustodio.github.io/2014/10/20/init-ng-model-from-form-fields-attributes/.
You can also use within your HTML code:
ng-init="card.description = 12345"
It is not recommended by Angular, and as mentioned above you should use exclusively your controller.
But it works :)
I have a simple approach, because i have some heavy validations and masks in my forms. So, i used jquery to get my value again and fire the event "change" to validations:
$('#myidelement').val('123');
$('#myidelement').trigger( "change");
As others pointed out, it is not good practice to initialize data on views.
Initializing data on Controllers, however, is recommended. (see http://docs.angularjs.org/guide/controller)
So you can write
<input name="card[description]" ng-model="card.description">
and
$scope.card = { description: 'Visa-4242' };
$http.get('/getCardInfo.php', function(data) {
$scope.card = data;
});
This way the views do not contain data, and the controller initializes the value while the real values are being loaded.
If you like Kevin Stone's approach above https://stackoverflow.com/a/17823590/584761
consider an easier approach by writing directives for specific tags such as 'input'.
app.directive('input', function ($parse) {
return {
restrict: 'E',
require: '?ngModel',
link: function (scope, element, attrs) {
if (attrs.ngModel) {
val = attrs.value || element.text();
$parse(attrs.ngModel).assign(scope, val);
}
}
}; });
If you go this route you won't have to worry about adding ng-initial to every tag. It automatically sets the value of the model to the tag's value attribute. If you do not set the value attribute it will default to an empty string.
Here is a server-centric approach:
<html ng-app="project">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script>
// Create your module
var dependencies = [];
var app = angular.module('project', dependencies);
// Create a 'defaults' service
app.value("defaults", /* your server-side JSON here */);
// Create a controller that uses the service
app.controller('PageController', function(defaults, $scope) {
// Populate your model with the service
$scope.card = defaults;
});
</script>
<body>
<div ng-controller="PageController">
<!-- Bind with the standard ng-model approach -->
<input type="text" ng-model="card.description">
</div>
</body>
</html>
It's the same basic idea as the more popular answers on this question, except $provide.value registers a service that contains your default values.
So, on the server, you could have something like:
{
description: "Visa-4242"
}
And put it into your page via the server-side tech of your choice. Here's a Gist: https://gist.github.com/exclsr/c8c391d16319b2d31a43
This one is a more generic version of the ideas mentioned above...
It simply checks whether there is any value in the model, and if not, it sets the value to the model.
JS:
function defaultValueDirective() {
return {
restrict: 'A',
controller: [
'$scope', '$attrs', '$parse',
function ($scope, $attrs, $parse) {
var getter = $parse($attrs.ngModel);
var setter = getter.assign;
var value = getter();
if (value === undefined || value === null) {
var defaultValueGetter = $parse($attrs.defaultValue);
setter($scope, defaultValueGetter());
}
}
]
}
}
HTML (usage example):
<select class="form-control"
ng-options="v for (i, v) in compressionMethods"
ng-model="action.parameters.Method"
default-value="'LZMA2'"></select>
I tried what #Mark Rajcok suggested. Its working for String values (Visa-4242).
Please refer this fiddle.
From the fiddle:
The same thing that is done in the fiddle can be done using ng-repeat, which everybody could recommend. But after reading the answer given by #Mark Rajcok, i just wanted to try the same for a form with array of profiles.
Things work well untill i have the $scope.profiles = [{},{}]; code in the controller. If i remove this code, im getting errors.
But in normal scenarios i cant print $scope.profiles = [{},{}]; as i print or echo html from the server.
Will it be possible to execute the above, in a similar fashion as #Mark Rajcok did for the string values like <input name="card[description]" ng-model="card.description" ng-init="card.description='Visa-4242'">, without having to echo the JavaScript part from the server.
Just added support for select element to Ryan Montgomery "fix"
<select class="input-control" ng-model="regCompModel.numberOfEmployeeId" ng-initial>
<option value="1af38656-a752-4a98-a827-004a0767a52d"> More than 500</option>
<option value="233a2783-db42-4fdb-b191-0f97d2d9fd43"> Between 250 and 500</option>
<option value="2bab0669-550c-4555-ae9f-1fdafdb872e5"> Between 100 and 250</option>
<option value="d471e43b-196c-46e0-9b32-21e24e5469b4"> Between 50 and 100</option>
<option value="ccdad63f-69be-449f-8b2c-25f844dd19c1"> Between 20 and 50</option>
<option value="e00637a2-e3e8-4883-9e11-94e58af6e4b7" selected> Less then 20</option>
</select>
app.directive('ngInitial', function () {
return {
restrict: 'A',
controller: ['$scope', '$element', '$attrs', '$parse', function ($scope, $element, $attrs, $parse) {
val = $attrs.sbInitial || $attrs.value || $element.val() || $element.text()
getter = $parse($attrs.ngModel)
setter = getter.assign
setter($scope, val)
}]
}
});
If you have the init value in the URL like mypage/id, then in the controller of the angular JS you can use location.pathname to find the id and assign it to the model you want.

Resources