ng-repeat filter by function - javascript

I'm trying to use a filter on my ng-repeat that is a function that has a parameter passed in, however the filter doesn't seem to work.
This is the filter function that i am using. It compares 2 arrays to see what matches in each then should return true or false.
$scope.ifinfav1 = function(f){
return e.indexOf(f) !== -1;
};
This is my HTML where the filter is being used.
<ion-view view-title="Favourites">
<ion-content>
<ion-list>
<ion-item id="fav" class="item-icon-right" collection-repeat="office in offices|filter:ifinfav1(office.id)" ng-controller="ModalCtrl" ng-click="openModal(office.id); lastview(office.id);">
<p>{{office.id}}</p>
<p id="details">{{office.LocAddressLine1 + ", " + office.LocAddressLine2 + ", " + office.LocCity + ", " + office.LocCountryDescription + ", " + office.LocZipPostalCode}}</p>
<i ng-class="{'icon ion-android-star': liked(office.id), 'icon ion-android-star-outline': liked(office.id)}" ng-click="togglefav(office.id); $event.stopPropagation();"></i>
</ion-item>
</ion-list>
</ion-content>
</ion-view>

You can not choose what arguments are passed to the function you use as a predicate to your filter.
That is, you can not do:
<p ng-repeat="office in offices | filter:isInFavourites(offices.id)">
You can only specify the function itself, not the arguments that are gonna be passed to it when invoked. Thus, only the following is valid:
<p ng-repeat="office in offices | filter:isInFavourites">
As specified in AngularJS's documentation for filter (link):
The function is called for each element of the array, with the element, its index, and the entire array itself as arguments.
What's interesting here for you is the element itself, the first argument your function is being passed. You simply have to update it to work with your office objects instead of their ids.
For example:
$scope.ifinfav1 = function(office){
return e.indexOf(office.id) !== -1;
};
... would do wonders!
Here's a link to a working JSFiddle illustrating my suggestion with sample data.

Related

Convert click for static pages in AngularJS

I've setup this structure in my Ionic v1 app.
This is for contents and load more effect.
$scope.toggleItem= function(item) {
if ($scope.isItemShown(item)) {
$scope.shownItem = null;
} else {
$scope.shownItem = item;
}
};
$scope.isItemShown = function(item) {
return $scope.shownItem === item;
};
DEMO
But now I need another solution. I have a static content in the page so I should change this toggle method.
AFTER RESULT
I tried that but its not working. Whats the solution?
Thanks.
In your controller the members to reference are $scope.toggleGroup and $scope.isGroupShown, but you're calling $scope.toggleItem and $scope.isItemShown.
You can change the controller or view to match each other
Also, you are not using Ionic tags to make it work, you have the static content inside normal Divs!!
Finally, put parameters on the functions you're calling, the controller member function is expecting the "group" parameter:
<ion-item class="item-stable"
ng-click="toggleItem(100)"
ng-class="{active: isItemShown(100)}">
<i class="icon" ng-class="isItemShown(100) ? 'ion-minus' : 'ion-plus'"></i>
İş Sağlığı ve Güvenliği İçin Ne Gibi Önlemler Alabilirim?
</ion-item>
<ion-item class="item-accordion" ng-show="isItemShown(100)">
Tarım iş sağlığı ve güvenliği ...
</ion-item>
Note the "100" parameter in the calls to toggleItem(100) and isItemShown(100). It has to be a unique value per item, I have pass "100" just as a sample to demonstrate the idea
Working sample:
https://codepen.io/zameb/pen/Ljaymd?editors=1010
Good luck

Storing strings in array as user selects checkbox

I just started using angularJS and am trying to learn how to insert strings in array when user clicks checkbox and later access these values.
This is what I have so far:
<md-button class="toolbar-button" ng-click="removePlan()">
<md-icon>delete</md-icon>
</md-button>
<md-list-item ng-repeat="plan in plans">
<md-checkbox ng-model="plansSelected[plan._id]"> </md-checkbox>
</md-list-item>
apps.js
$scope.plansSelected = []
$scope.removePlan = function () {
for (var plan in $scope.plansSelected) {
if ($scope.plansSelected[plan] === true) {
projectResource.removePlan(plan).then(function (data) {
if (data.success) {
$scope.plans.push(data.plan)
}
})
}
}
}
projectResource.js
resource.removePlan = function (planId) {
return $http.delete(getPlanUrl(planId)).then(processResponse, processError)
}
function getPlansUrl () {
return getProjectUrl() + '/plans'
}
function getPlanUrl () {
return getPlansUrl() + '/' + $route.current.params.planId
}
In debugger this is how my array looks like:
$scope.plansSelected: Array[0]
57bd40128a58022800887d80:false
57bd40328a58022800887d88:false
57cc2bcbb452140500b0334a:false
I am checking if user removed selection from the checkbox and if the value is true then take that plan._id and pass in the loop to removePlan function.
Does anyone see what I am doing wrong, because this is not working.
Please be more specific what "this is not working" means - it's hard for us to detect that without being able to run it.
I can see that your use of $scope.plansSelected as an empty array is wrong. I would dispense with that and do it like this:
<md-list-item ng-repeat="plan in plans track by $index">
{{plan.name}} <md-checkbox ng-model="plans[$index].selected"> </md-checkbox>
</md-list-item>
This basically adds a 'selected' attribute to your plans array, and make it easier for you to iterate over the plans array and pull out the ones you want.

AngularJS ng-repeat ignores filter function

I want to use a filter with ng-repeat.
Unfortunately it seems to ignore the result of the function which is attached to the filter.
HTML:
<a ng-repeat="item in date track by $index | filter: filterFunction('2015-09-23',item)" class="item item-icon-left" >
<div class="listcontent">{{title[$index]}}
<br> <span class="subinfo">{{item}}</span>
</div>
<i class="iconarrowmore ion-chevron-right"></i>
</a>
JS:
$scope.filterFunction = function (datestamp, element) {
if (datestamp == element) {
console.log(datestamp == element);
return true;
} else {
console.log(datestamp == element);
return false;
}
};
It returns either true or false when I debug it with console.log but every item still appears in the list.
I really have no clue why its doing that.
Your filtering function is undefined. Note, that with filter: filterFunction('2015-09-23',item) you immediately execute filterFunction and use its result as filter, which is undefined because your function doesn't return anything.
To fix it make filterFunction return new filter function:
$scope.filterFunction = function(datestamp) {
return function(element) {
return datestamp == element;
};
};
Then HTML part will be the same just you don't need to pass item:
ng-repeat="item in date track by $index | filter: filterFunction('2015-09-23')"
See it working: http://plnkr.co/edit/jLQbgGcLSAxwmiCcYZdP?p=preview
Okay I found the solution.
If one is using "track by index" with a filter one has to but that behind the filter:
ng-repeat="item in date | filter: filterFunction('2015-09-23') track by $index"
I hope that helps someone.
Cheers,
Valentin

Reusable directive with dynamic ng-repeat item name

I have created reusable directive something like dropdown but dropdown open in modal which is working good.
my directive looks like this
<p-select items="deptStations" header-text="Select " text="Select departure..." text-icon="ion-chatbubble-working" text-field="City_Name_EN" text-field2="City_Code" value-field="City_Code" ng-model="deptStation.value">
</p-select>
<p-select items="arrStations" header-text="Select " text="Select arrival..." text-icon="ion-chatbubble-working" text-field="D.City_Name_EN" text-field2="D.City_Code" value-field="D.City_Code" ng-model="arrStation.value">
</p-select>
My directive html is
<ion-content>
<div class="list">
<label ng-repeat="item in items | filter:search" class="item item-text-wrap" ng-click='validateSingle(item)'>
{{item[textField]}} {{textField2 !== '' ? " (" + item[textField2] + ")" : ""}}
</label>
</div>
</ion-content>
Now my issue is when JSON is 1 level it will work as below
[{City_Name_EN:'Abu Dhabi', City_Code:'AUH' },
{City_Name_EN:'Alexandria',City_Code:'HBE' }]
But if I have 2 level JSON than it will not work
[{D:{City_Code:'AMM',City_Name_EN:'Amman'},
D:{City_Code:'BKK',City_Name_EN:'Bangkok'}}]
So how can make this part dynamic {{item[textField]}}
My plunkr http://plnkr.co/edit/GxM78QRwSjTrsX1SCxF7?p=preview
With this kind of dynamic expression of yours, it is always better to have directive consider only a specific contract provided as view model. If the directive consumer has a different data format it should be upto that component to provide the contract that directive needs, it can just map the data to the view model that directive expects. This way you can keep things clean, that would be my opinion.
Now to work around your issue you would need to do a trick to evaluate the multilevel property against an object. You can use $scope.$eval to evaluate any dynamic expression against the scope object. example you can evaluate a dynamic property evaluation of prop1.prop2.prop3 on a scope property item by doing $scope.$eval("prop1.prop2.prop3", item) or $scope.$eval("item." + "prop1.prop2.prop3")
So in your directive:
Added a scope function to get the item text and value:
$scope.getItemName = function(field, item){
//here "this" represents the current child scope of ng-repeat
return $scope.$eval(field, item);
//return this.$eval("item." + field);
}
and
$scope.validateSingle = function(item) {
$scope.text = $scope.$eval($scope.textField, item) + ($scope.textField2 !== '' ? " (" + $scope.$eval($scope.textField2, item) + ")" : "");
$scope.value = $scope.$eval($scope.valueField, item);
...
Update your template to get respective text:
<label ng-repeat="item in items | filter:search" class="item item-text-wrap" ng-click='validateSingle(item)'>
{{getItemName(textField, item)}} {{textField2 !== '' ? " (" + getItemName(textField2, item) + ")" : ""}}
</label>
Plnkr

Angular ng-model won't pass

I'm working on an app, and am trying to pass a string through ng-model like I do in other places. But this one always returns "undefined".
HTML:
<aside>
<p>List of objs:</p>
<ul>
<li class="objList" ng-repeat="obj in objs">
{{ obj.topic }}
<div class="appear" ng-show="hideBool2">
X
<input class="uName" ng-model="passWo" placeholder="Password">
<button class="btn btn-default" ng-click="connectTo(obj.info)">OK</button>
<p ng-bind="message"></p>
</div>
</li>
</ul>
</aside>
Controller function used:
$scope.connectTo = function(rName) {
alert($scope.rooms[rName].password + " " + $scope.passWo)
if($scope.rooms[rName].password != "") {
if($scope.rooms[rName].password == $scope.passWo) {
socket.emit("joinroom", { room: rName, pass: $scope.passWo }, function(success, errorMessage) {});
$location.path("/room/" + rName);
}else{
$scope.message = "Wrong password";
}
}else{
alert($scope.rooms[rName].password);
}
}
but the $scope.passWo always returns undefined.
Everything else works in the code.
Any help would be appreciated.
The problem is that the ng-model is assigning the value to its internal $scope. So when you call the connectTo function, it finds the $scope.connectTo in the controller scope, but the use of $scope.passWo, can't find the value, as ng-repeat creates a scope for each item.
The easiest way to overcome this (if you want to use a single scope value) is to create a container object inside the controller:
$scope.cont = { passWo: '' };
Then inside your view, use:
ng-model="cont.passWo"
This article might help you: http://jimhoskins.com/2012/12/14/nested-scopes-in-angularjs.html

Categories