Angularjs bind ng-model dynamically to an value - angularjs

i want change the reference for the ng-model value dynamically. i can do this for example like that:
$scope.test = {
normalStringValue1 : [],
normalStringValue2 : []
}
if($scope.status == 'A') {
$scope.values= $scope.test.normalStringValue1;
} else {
$scope.values= $scope.test.normalStringValue2;
}
<input ng-model="values" type="radio" name="xValues" ng-value="header.id | num">
this works but my problem is, the reference change did only work if the "normalStringValue1 or 2 is an array! if the normal string value looks like that:
$scope.test = {
normalStringValue1 : null,
normalStringValue2 : null
}
and i want only save a String like normalStringValue1 : 'Hello' the reference wil not change correctly why is that so ? and how can i fix this ?

try this
$scope.test = {
normalStringValue1 : '',
normalStringValue2 : ''
}

Related

How to check if a sub-array of objects contains string in Angular Filter

I have an object with arrays of objects inside like this:
Companies =
{
"-KGZPUea1ZtWVXspLRGF" : {
"assignedUsers" : [ {
"email" : "talon#gmail.com"
} ],
"name" : "Talon"
},
"-KGcS8doqRw1Jcemhxuz" : {
"assignedUsers" : [ {
"email" : "billy#gmail.com",
"status" : "active"
} ],
"name" : "Billy"
}
}
I wan't to be able to create an angular filter which filters out only companies where a specific email is assigned and their status is active.
Something like this
<div ng-repeat="company in Companies | filter:{assignedUsers contains 'billy#gmail.com' && assignedUsers.status == 'active'}">
Is something like that possible?
Yes, this is doable. No, it can't be done purely in your view.
Benefiting from the fact that filters can take functions to evaluate, you could write this logic into your controller.
scope.testCompany = function(company) {
if (!company || !company.assignedUsers) return false;
for (var i = 0; i < company.assignedUsers.length; i++) {
var e = company.assignedUsers[i];
if (e.email === 'billy#gmail.com' && e.status === 'active') {
return true;
}
}
return false;
};
Then you can just use that.
<div ng-repeat="company in Companies | filter:testCompany">
If you want to dynamically set the email address, you have two options. One would be to set up a new filter (as in, angular.module(...).filter(...)), or you could just set up your function from above to accept a parameter. The filter option is probably a bit better philosophically, but either works.
scope.testCompanyForEmail = function(emailAddress) {
return function(company) {
if (!company || !company.assignedUsers) return false;
for (var i = 0; i < company.assignedUsers.length; i++) {
var e = company.assignedUsers[i];
if (e.email === emailAddress && e.status === 'active') {
return true;
}
}
return false;
}
};
Utilized as:
<div ng-repeat="company in Companies | filter:testCompanyForEmail('billy#gmail.com')">

ng-class - finding a value inside object

I have an object that looks like this:
$scope.things = [
{
name: 'Bob!',
short_name: 'bob',
info: 'something something'
},
{
name: 'Steve',
short_name: 'steve',
info: 'something something something'
},
];
I loop through them like this and add an ng-click:
<div ng-repeat="thing in things" ng-click="addThing(thing.name, thing.short_name, thing_info" ng-class="thingClass(thing.name)">content goes here</div>
the ng-click="addThing()" basically bunches up the values and adds them to the object.
When clicked, it should add the class selected - this worked fine and dandy when I wasn't using a multidimensional object, because it was simply looking for name inside the object / array (at this point, I think it's an object... but at the time, it was an array)
I can't work out how to do the equivalent to this...
$scope.thingClass= function(name) {
if($scope.thingSelected.indexOf(name) != -1) {
return 'selected';
}
};
...with the object as it now stands. I've tried to adapt a few answers from here that I found through google, such as:
$scope.teamClass = function(name) {
var found = $filter('filter')($scope.thingSelected, {id: name}, true);
if (found.length) {
return 'selected';
}
};
...but with no joy.
Can anyone point / nudge me in the right direction?
You could simply pass the thing object to thingClass:
... ng-class="thingClass(thing)" ...
and implement thingClass as follows:
$scope.thingClass= function(thing) {
return $scope.thingSelected.indexOf(thing) >= 0 ? 'selected' : '';
}
And maybe your should apply this technique to addThing also:
... ng-click="addThing(thing)" ...
$scope.addThing = function(thing) {
if ($scope.thingSelected.indexOf(thing) < 0)
$scope.thingSelected.push(thing);
}
But instead of tracking the selected things in an array its much easier to introduce a selected property in each thing:
$scope.addThing = function(thing) {
thing.selected = true;
}
$scope.thingClass= function(thing) {
return thing.selected ? 'selected' : '';
}

If statment on ng-click?

I need to call function on ng-click but only if $scope.currentActiveMenu = 1;.
How can i do that?
ng-click="GetAllTickets(0,25) = currnetActiveMenu==1">
or something like that?
Don't put any Condition Expression in Template, do it in the Controller.
ng-click="checkCurrentActiveMenu(currentActiveMenu)">
Controller :
$scope.checkCurrentActiveMenu = function(value) {
if (value == 1) {
GetAllTickets(0,25);
}
}
If you really need this in the template, you can use this (if the first condition isn't true, the second one will not be called):
ng-click="currentActiveMenu==1 && GetAllTickets(0,25)">
Like this:
ng-click="currnetActiveMenu === 1 && GetAllTickets(0,25)"
Create a function in your controller:
ng-click="GetAllTicketsForMenu(0,25, currnetActiveMenu)">
in your controller:
$scope.GetAllTicketsForMenu = function(val1,val2, currnetActiveMenu){
if(currnetActiveMenu === 1){
$scope.GetAllTickets(val1,val2);
}
};
You could also try a ternary:
ng-click="currnetActiveMenu==1 ? GetAllTickets(0,25) : null ">

AngulaJS filter on array of object

I have this JSON object.
var UsersList=[
{
"User" : {
"IdUser" : "admin",
"FirstName" : "mirco",
"LastName" : "sabatino"
}
}, {
"User" : {
"IdUser" : "coordinator",
"FirstName" : "coordinator",
"LastName" : ""
}
}, {
"User" : {
"IdUser" : "test",
"FirstName" : "publisher",
"LastName" : "Diaz"
}
}, {
"User" : {
"IdUser" : "work",
"FirstName" : "ingester",
"LastName" : "Brown"
}
}
] ;
I want filter in ng-repeat for LastName value.
<div class="col-md-6" ng-repeat="users in UsersList | filter: {User.LastName : filterSearchLetter}">
filterSearchLetter value in my controler is populated by
$scope.filterLetterUser=function(letter){
$scope.filterSearchLetter=letter;
console.log($scope.filterSearchLetter);
};
But this don't work.
See my plnkr for the solution http://plnkr.co/edit/l27xUQ?p=preview. I also have implemented your required UI behavior using ng-change. Hope it helps.
For detailed explanation I offer you Todd Motto's blog - http://toddmotto.com/everything-about-custom-filters-in-angular-js/
To invoke a filter, the syntax is the filter function name followed by the parameters.
To define a filter you need to do (This is copy of Todd Motto's code modified for your data)
todos.filter('startsWithLetter', function () {
return function (items, letter) {
var filtered = [];
var letterMatch = new RegExp(letter, 'i');
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (letterMatch.test(item.User.LastName.substring(0, 1))) {
filtered.push(item);
}
}
return filtered;
};
});
This is not a valid object: {User.LastName : filterSearchLetter} It should actually throw an exception saying something like
Uncaught SyntaxError: Unexpected token .
What you probably want to try instead is: {"User": {"LastName" : filterSearchLetter} }
To iterate over an array of Objects see:
angularjs - ng-repeat: access key and value from JSON array object
You may have to convert to valid JS object using JS_Obj=JSON.parse(JSON_Obj);
Maybe something like this:
//iterate through array
<ul ng-repeat="users in UsersList">
//iterate through Object
<li ng-repeat=(key, value) in users | filter: {User.LastName : filterSearchLetter}>
{{key}} : {{value}}
</li>
</ul>

How to bind 1/0 instead of true/false on checked property of a checkbox

<input type="checkbox" data-bind="value : 1, checked: FgActive" />
I want FgActive to be 1 and 0 instead of true and false. Is there a simple way of doing that?
The easiest thing to do is to create a ko.computed that converts the checked boolean binding to/from a 1/0 numeric.
self.fgActiveNumeric = ko.computed({
read: function () {
return self.fgActive() == 1 ? true : false;
},
write: function (newValue) {
self.fgActive(newValue ? 1 : 0);
}
});
Use it like a normal checked binding:
<input type='checkbox' data-bind='checked: fgActiveNumeric' />
You can read more about this technique here: http://knockoutjs.com/documentation/computedObservables.html
See the Fiddle
I came across a solution. I created a custom binding that works on the update, after the checked binding. Dont know if is the best solution, but worked just fine.
ko.bindingHandlers.NumChecked = {
update: function (element, valueAccesor) {
var func = valueAccesor();
if (typeof (func) == 'function' && func() == true)
func(1);
else if ((typeof (func) == 'function'))
func(0);
}
};
<input type="checkbox" data-bind="NumChecked: FgActive, checked: FgActive" />
This is how I do it, using jQuery:
var myVal = ( $('#myCheckbox').is(':checked') ) ? 1 : 0;
alert('myVal is: ' +myVal); //alerts 1 if checked, 0 if not checked
jsFiddle Demo

Resources