ng-model not binding to select options - javascript

I have googled this a lot, and can't figure out what is wrong in my code. My ng-model is not updating on selecting an option from the select box.
<div ng-controller="UserRegistrationController as userReg">
<select name="selectOrganisation" ng-required="true" ng-model="userReg.candidateData.BusinessUnit">
<option>Select Organisation</option>
<option>ABC</option>
<option>XYZ</option>
<option>KLM</option>
</select>
</div>
Controller:
(function (window) {
'use strict';
angular.module('myApp.userRegistration.controllers')
.controller('UserRegistrationController', ['UserRegistrationService', '$scope', function (UserRegistrationService, $scope) {
var vm = this;
vm.candidateData = {
FirstName: '',
LastName: '',
Email: '',
PhoneNumber: '',
JobId: '',
PrimarySkills: '',
SecondarySkills: '',
BusinessUnit: '',
CreatedBy: 'SPAN54',
CreatedOn: new Date(),
resume: '',
OfferStatus: 1,
Remarks: ''
};
}]);
})(window);
On console.log(vm.candidateData.BusinessUnit) inside my post function(not visible here), I see " ".
UPDATE 1: The " is there in my code. I just overlooked it while pasting it here. Have updated above code now. But my code is still not working.
UPDATE 2: Finally, I figured the issue. I am using Materialize.css in my app, and my select element is getting wrapped up in a div and ul-li. So when user selects a value, he is actually modifying the ul-li, not the select element. But I am not able to figure out how I can capture the selected value like this. Any ideas? Thanks.
UPDATE 3: Added a fiddle.

Tried the code you posted. And its working for me. I added Working Code Snippet below.
Did these changes to make it work. If its still not working for you, could you share a working snippet.
Add double quote to end the ng-controller atrribute.<div ng-controller="UserRegistrationController as userReg>
Removed UserRegistrationService declaration from controller as its not defined or shared.
var app = angular.module('sample', []);
app.controller('UserRegistrationController', ['$scope', function($scope) {
var vm = this;
vm.candidateData = {
FirstName: '',
LastName: '',
Email: '',
PhoneNumber: '',
JobId: '',
PrimarySkills: '',
SecondarySkills: '',
BusinessUnit: '',
CreatedBy: 'SPAN54',
CreatedOn: new Date(),
resume: '',
OfferStatus: 1,
Remarks: ''
};
$scope.change = function() {
console.log(vm.candidateData.BusinessUnit);
}
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="sample">
<div ng-controller="UserRegistrationController as userReg">
<select ng-change="change()" name="selectOrganisation" ng-required="true" ng-model="userReg.candidateData.BusinessUnit">
<option>Select Organisation</option>
<option>ABC</option>
<option>XYZ</option>
<option>KLM</option>
</select>
</div>
</body>

Here is your Working code JS FIDDLE
You missed out the ' " ' in ng-controller
<div ng-controller="UserRegistrationController as userReg">

Related

Binding ng-model to ng-repeat not working

I'm trying to bind ng-model dynamically with ng-repeat, but it doesn't seem to work. input.placeholder and input.fa both work as expected, but I can't seem to bind ng-model to anything as it gives me an error.
The relevant HTML
<li class="animate-repeat" ng-repeat="input in accountInfo">
<div class="input-group input-group-icon">
<input type="text" placeholder="{{input.placeholder}}" ng-model="{{input.model}}"/>
<div class="input-icon"><i class="fa {{input.fa}}"></i></div>
</div>
</li>
My accountInfo array of objects.
$scope.accountInfo = [
{
model: 'user.fullName',
placeholder: 'Full Name',
fa: 'fa-user',
},
{
model: 'user.email',
placeholder: 'Email Address',
fa: 'fa-envelope',
},
{
model: 'user.password',
placeholder: 'Password',
fa: 'fa-key',
},
{
model: 'user.phone',
placeholder: 'Phone Number',
fa: 'fa-phone',
},
];
The error i get
error link
Please help
ng-model is not interpolated; you shouldn't wrap it in {{. So,
<input ... ng-model="input.model">
should work fine.
Edit: Sorry, I didn't see that you were trying to dynamically set the ng-model -- my apologies.
The easiest solution would be to use references in the accountInfo, if user is available in that scope:
$scope.accountInfo = [{
model: user.fullName,
placeholder: 'Full Name',
...
Otherwise, you can declare an object on the $scope and manually link it to the models:
// ... some place without access to `user`
$scope.accountInfo = [{
model: 'fullName',
placeholder: 'Full Name',
...
// some place with access to `user`
$scope.inputs = {
fullName: user.fullName,
email: user.email,
...
};
// html
<input ... ng-model="inputs[input.model]">
Since ng-model only accepts a reference, variations of this are essentially all you can reasonably do.

AngularJS ng-click to go to view

Hi I have a button that I have a ng-click directive on that I just want to load a view. I've looked at some pages online, and I'm not able to figure out how to get the button to work. My button looks like this:
<button class="btn default-btn lookupbtn" ng-click="go('/lookup')">Lookup</button>
and my controller like this:
(function () {
'use strict';
angular.module('crm.ma').controller('LookUpCtrl', LookUpCtrl, function($location){
function LookUpCtrl() {
var vm = this;
vm.results = [
{
accountId: 1,
accountName: 'some name',
address: '201 some st',
city: 'Columbus',
state: 'OH',
zip: 'zip',
phone: '899-629-7645',
parentName: 'Parent 1',
accountType: 'Type 1',
accountStatus: 'Status 1',
creditTerm: 'Term 1'
},
{
accountId: 2,
accountName: 'house home',
address: '2963 this st',
city: 'Columbus',
state: 'OH',
zip: 'zip',
phone: '899-627-7592',
parentName: 'Parent 2',
accountType: 'Type 2',
accountStatus: 'Status 2',
creditTerm: 'Term 2'
}
];
vm.go = function (path) {
$location.path(path);
};
}
})
}());
I'm really new to Angular and I'm just not sure what I'm doing wrong. If any other code is needed please let me know. Thanks.
Instead of that you could convert that button to anchor & apply the CSS classes of button of bootstrap, that will give you look and fill of button it & then use ng-href attribute to have redirection URL on it inside SPA.
<a class="btn btn-md" ng-href="#/lookup">Lookup</a>
Additionally as #charlietfl suggested you need to add missing dependency of $location, $scope would also needs to add if you are following the second way.
Controller definition is incorrect. Should look like:
angular
.module('crm.ma')
// only 2 arguments, name and function
.controller('LookUpCtrl', LookUpCtrl);
// add the dependency injections to function
function LookUpCtrl($location) {
var vm = this;
vm.results = [... ];
vm.go = function (path) {
$location.path(path);
};
}
Then for go() you have no function go() in your controller and if you did you wouldn't use a leading / for $state.go()
Can use ui-sref to point to a state in html if using ui-router:
<a class="btn btn-md" ui-sref="lookup">Lookup</a>

accessing collection inside json object angular

I am new to angular
in the following controller i need to access the object store in my html. But it is not working. Any help
(function () {
'use strict';
angular.module('app').controller('BookController', ['$scope', function ($scope) {
$scope.book = {
id: 1,
name: 'Harry Potter',
author: 'J. K. Rowling',
stores: [
{ id: 1, name: 'Barnes & Noble', quantity: 3 },
{ id: 2, name: 'Waterstones', quantity: 2 },
{ id: 3, name: 'Book Depository', quantity: 5 }
]
};
}]);
});
<div ng-controller="BookController">
{{book.stores}}
</div>
You need to first invoke your anonymous function first using () after the final closing bracket and before the final semi-colon so that the last line looks like this: })();.
You should define angular module first and then amend it with the angular component like controller, service , factory, directive, filters, etc.
angular.module('app', [])
then add ng-app="app" on your page.
Markup
<div ng-app="app" ng-controller="BookController">
{{book.stores}}
</div>
Plunkr Here
Update
If suppose you have multiple store inside the stores object, and you want to show them on the html, then for that you could ng-repeat directive. It will repeat each element on html
<div ng-repeat="s in book.stores">
<span>{{s.name}}</span>
<input type="text" ng-model="s.name" />
<input type="numeric" ng-model="s.quantity" />
</div>
Updated Plunkr

Form with nested controllers and "controller as" syntax

I'm trying to create a more than average complex form with custom actions on some controls. The main controller of the view is holding the model that will be saved at the end. Inside this main controller, I have a separate controller for each input control that has some specific actions.
Here is a short example and the question is, if I want to implement the UserChoiceCtrl.selectLastUser function, how can I do without using $scope ?
More generally, how can I access to a model in the main controller in a child controller ? It's easy in the view, but how can I do in the controller code ?
#Plunker if you prefer
angular.module('myApp', []);
angular.module('myApp')
.controller('TaskCtrl', [
function() {
var viewModel = this;
// This is injected in controller in real life
viewModel.users = [
{login: 'Tom', password: '123'},
{login: 'Stanley', password: '123'},
{login: 'Joe', password: '123'},
{login: 'Katy', password: '123'},
{login: 'Kate', password: '123'},
{login: 'Tony', password: '123'}
];
viewModel.task = {
user: viewModel.users[0],
description: ''
};
viewModel.save = function() {
alert(angular.toJson(viewModel.task));
};
}
]);
angular.module('myApp')
.controller('UserChoiceCtrl', [
function() {
var viewModel = this;
viewModel.selectLastUser = function() {
// No way to access the task variable # TaskCtrl ?
// The following line is working but using $scope
// $scope.taskCtrl.task.user = $scope.taskCtrl.users[5];
};
}
]);
body {
font-family: 'Arial';
}
label,
input,
textarea {
display: block;
}
label {
margin-top: 8px;
}
<!DOCTYPE html>
<html data-ng-app="myApp">
<head>
<script data-require="angular.js#1.4.0" data-semver="1.4.0" src="https://code.angularjs.org/1.4.0/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body data-ng-controller="TaskCtrl as taskCtrl">
<h1>New task</h1>
<form name="taskCtrl.taskForm">
<label>Description</label>
<textarea data-ng-model="taskCtrl.task.description"></textarea>
<div data-ng-controller="UserChoiceCtrl as userChoiceCtrl">
<label>User</label>
<select data-ng-model="taskCtrl.task.user" data-ng-options="user as user.login for user in taskCtrl.users"></select>
<button data-ng-click="userChoiceCtrl.selectLastUser()">Last user of list</button>
</div>
<br>
<button data-ng-click="taskCtrl.save()">Save</button>
</form>
</body>
</html>
Try this
<button data-ng-click="userChoiceCtrl.selectLastUser(taskCtrl.task.user)">Last user of list</button>
viewModel.selectLastUser = function(user) {
alert(user);
// No way to access the task variable # TaskCtrl ?
// The following line is working but using $scope
// $scope.taskCtrl.task.user = $scope.taskCtrl.users[5];
};
A way could be creating the main controller as a service and injecting it to the children:
http://fdietz.github.io/recipes-with-angular-js/controllers/sharing-code-between-controllers-using-services.html
See if this serves the purpose,
basically i am getting an instance of the task controller using the $controller service.
angular.module('myApp')
.controller('UserChoiceCtrl', function ($controller) {
var task = $controller('TaskCtrl');
console.log("Task", task);
var viewModel = this;
viewModel.selectLastUser = function () {
// No way to access the task variable # TaskCtrl ?
// The following line is working but using $scope
// $scope.taskCtrl.task.user = $scope.taskCtrl.users[5];
task.task.user = task.users[5];
alert ( task.task.user.login);
};
console.log("User", viewModel)
});

Can you write pure JavaScript expressions in Kendo MVVM views (as with Knockout)?

In the following, isDirty returns a boolean, depending on whether the user has changed any of the observable properties.
HTML
<div class="status-message" data-bind="text:isDirty ? user.nickName : user.suffix>
JS
viewModel = new kendo.observable({
user: {
emailAddress: user.emailAddress,
firstName: user.firstName,
middleInitial: user.middleInitial,
lastName: user.lastName,
title: user.title,
suffix: user.suffix,
nickName: user.nickName
}
});
I've done it with Knockout, but for some reason I can't get this to work with Kendo's MVVM.
Is this just a limitation of Kendo?
You can't use JS in data-bind, but there are other ways to achieve what you want to do.
One way would be to create two status-message divs and use the visible binding on both.
Another way would be to use a method to get the data to display.
HTML:
<div id="bindme">
<!-- alternative #1 -->
<input type="text" data-bind="value: user.emailAddress" />
<div data-bind="visible: isDirty">
<div class="status-message" data-bind="text: user.nickName"></div>
</div>
<div data-bind="invisible: isDirty">
<div class="status-message" data-bind="text: user.suffix"></div>
</div>
<!-- alternative #2 -->
<div class="status-message" data-bind="text: currentValue"></div>
</div>
JS:
viewModel = new kendo.observable({
isDirty: false,
user: {
emailAddress: "a",
firstName: "b",
middleInitial: "c",
lastName: "d",
title: "e",
suffix: "f",
nickName: "g"
},
currentValue: function () {
return this.get("isDirty") ? this.get("user.nickName") : this.get("user.suffix")
}
});
viewModel.bind("change", function () {
this.set("isDirty", true);
});
kendo.bind($("#bindme"), viewModel);
(demo)

Categories

Resources