How to remove searched entry from array in AngularJS - javascript

I am creating a angular application, which has one li with ng-repeat and a text box for searching the out put in ng-repeat, the repeated item has a delete "X" button which deletes the record from DB. problem i am facing is how to remove searched record from the array using splice.
http://plnkr.co/edit/oPBofD2wL2ZUrD23f8Rr?p=preview
go to above plnkr click on any of the "x" without searching, then it will get removed from the list . but when you search for something lets say ruby then only ruby will come into the list but by clicking on "x" it will still appear . I need help in removing the searched field from the array using array operation, i dont want to regenerate that array again.

instead of just using the index as a parameter, calculate your index with a search of the json element in the array.
Like so:
$scope.delete = function(project) {
idx = $scope.projects.indexOf(project);
$scope.projects.splice(idx, 1);
};
DEMO

The problem is that your idx is set to $index. That is the index of the ng-repeat, not the index of the array so when the list is filtered you're now deleting the wrong element.
(You'll notice this if you clear the search-box after deleting)
If you change your HTML to
X
The delete function will receive the actual element that needs to be removed and can be rewritten to
$scope.delete = function(project) {
$scope.projects.splice($scope.projects.indexOf(project), 1)
};

The reason is that you are sending the $index for removing, instead of that pass the id like
X
Working Demo
Try this out
$scope.delete = function(idx) {
for ( var i = 0; i < $scope.projects.length; i++){
if ($scope.projects[i].id === idx)
{
$scope.projects.splice(i, 1);
}
}
};

Related

How to implement a loop in a multi parameters filter in a ng-repeat?

I would like to make a loop in a filter parameters
Hey,
I'm doing a multi filters table. Each column as an input to add a string to filter on.
For each column, I call the parameter name with the filter input in the filter function :paramN: filter[n]
Is there a way to make a loop in it so I won't have to write every parameter one by one ?
I have everything I need in an array but I don't know how (if it's possible) to call it in the filter.
Should I use a custom filter ? If so, what would be the syntax, and, would it slow the process ?
Here the code of my filter :
<tr ng-repeat="folder in listFolders|
filter:{param1:filter[1],
param2:filter[2],
param3:filter[3],
...
paramN: filter[n]
} as listVisible
">
Here is my array :
$scope.parametres=[
{int:1, libelle:'name1', variable:'param1'},
{int:2, libelle:'name2', variable:'param2'},
{int:3, libelle:'name3', variable:'param3'},
...
{int:n, libelle:'nameN', variable:'paramN'}
]
Thanks !
In case someone someday face the same problem as me :
I made this function in my controller (it's called every time a change is made in the filters inputs via a ng-change)
$scope.filteringFunction = function(){
var filtered=angular.copy($scope.listFolders);
for(var i=0; i<$scope.parametres.length; i++){
if($scope.filter[$scope.parametres[i].int]!==''){
var filter =$rootScope.toNoCase($scope.filter[$scope.parametres[i].int]);
var param = $scope.parametres[i].variable;
filtered = filtered.filter(function (item) {
return $rootScope.toNoCase(item[param]).includes(filter);
});
}
}
$scope.listFoldersFiltered=filtered;
};
and I changed a bit the ng-repeat (basically remove the filter and change the list listFolders to listFoldersFiltered)
<tr ng-repeat="folder in listFoldersFiltered as listVisible">
If someone know an other method to do it, I'm all ears !

Filtering through a list of JQuery selected items

I am in a situation where I haven't found a selector or a selector function that quite does what I would like it to do.
Therefore I am trying to filter the list to contain only the items I would like it to.
I have a selector
var html = $(".foo .foobar")
This returns what I wanted it to.
Then I have a for loop that loops through those selected items and identifies the ones I want to keep in that list.
However, I need to keep the modified list the same type as a selector so that I can perform jquery actions to them later.
how do I create a copy of the 'html' variable (or a filtered original) but with only the desired rows that were found in the function (Keeping it still in a state as if it was a selector itself)?
Later I have an 'each' loop that begins like this:
html.each(function(i, el) {
$(this).replaceWith(tempArr[i]);
I am trying to achieve a result where 'html.each' has 'html' as the modified list previously selected.
Thanks.
// Update
var htmlTemp;
for (var primaryCounter = 0, secondryCounter = 0; primaryCounter < htmlTemp.length; primaryCounter++) {
if (firstFound) {
secondryCounter++;
if (secondryCounter % columnCount === 0) {
html.push(htmlTemp[primaryCounter]);
}
} else {
if (primaryCounter === currI) {
html.push(htmlTemp[primaryCounter]);
firstFound = true;
}
}
}
Above is the function including the logic that I wanted to use (Which isn't going to run). Is there a way with 'filter' possibly where I can call this function and instead of 'push()' just include at these indexes found? Thanks.
Assuming html as an array, you can use html.filter(callbackFunc) to get a new list every time.
Check this https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

Angular Sorting and counting, Dragula

I have the following scenario:
A JSON object array gets fetched with angular ajax and displayed as list with ng-repeat.
The list gets sorted by object property "index", which is set as default input value of the respective list item.
The user can change the input values.
On press of a button, the list gets redrawn, sorted by the updated input values.
Now there should be a counter, ++ whenever a list item changes position.
I so far managed to count all list items with updated values.
How do I register position changes for the other list items that change position?
For example: #3 changes position to #1, then #1 and #2 also change position.
Second, using Dragula, the list items are now draggable.
How can I resort the list after list items were dragged?
I also tired Angular Dragula without success.
here is my code on github.
Thank you for your help!
I had a similar issue. You need a way of getting the DOM indexing and updating the JavaScript object to match. I looped through the DOM elements, got their index values, found the corresponding item in the data object and then set the index value in the object to that of the DOM index value. Hope this example helps someone.
var updateIndexes = function() {
// this gets the index of any DOM element, like jQuery index()
function getIndex(el) {
for (var i = 0; el = el.previousElementSibling; i++);
return i;
}
// loop through the list DOM elements
for (var i = 0; i < dataArray.length; i++) {
var dataId = dataArray[i].id;
var domIndex = getIndex(document.getElementById(dataId));
dataArray[i].index= domIndex;
}
};

Batch adding items to Selectize.js control stalling the browser completely

i am using selectize.js to display a multiselect dropdown list witch zipcodes and cities. Its functioning well when searching and adding one item at a time, with the autocomplete search, but when im trying to add a batch of zipcodes from a multidimensional array, it totally frezzes the page, and takes more than 20 seconds to complete with insertion of a batch of 100 zip codes or so.
The following is my two add and remove functions, using data from my multidimensional array of zipcodes, with a parent region id. The events are fired via a dropdown of regions with the value of the first dimension in the region_relations array.
var control = new Array();
control.push($select[0].selectize);
control.push($select[1].selectize);
function addItemToselect(key_index, region){
var index;
for (index = 0; index < region_relations[region].length; ++index) {
control[key_index].addItem(region_relations[region][index]);
}
}
function removeItemToselect(key_index, region){
var index;
for (index = 0; index < region_relations[region].length; ++index) {
control[key_index].removeItem(region_relations[region][index]);
}
}
I can't seem to find a solution to this problem - i thought i could maybe use jQuery to set the original options checked and call the refreshItems() function in selectize, but it seems like selectize is actually emptying the original , and so options will only be present in this element if an item has been selected using selectize - the script itself includes a addItems() function, but it basically does the same as above, i hoped the selectize addItem had a efficient way of batch adding items, but as it seems right now, i might be out of luck, and we are talking a max of 100 items to add or remove at a time....?
Do you have any suggestions?
My problem can be demonstrated "real life" on this page: http://onlineboligsalg.dk/soeg-bolig/ , the controls are found on the left.
thanks in advance for your help

How to delete the last item of WinJS Group Binding List

I am writing a Windows 8 app with WinJS. I am using a Grouped Binding List
var groupedSortedListProjection = list.createGrouped(groupKey, groupData, groupSorter);
that will have two groups with keys of 'doing' and 'done'. So, when a user click on an item in group 'doing', an item will be added to 'done'.
I am trying to limit the number of items in group 'done' to only 5 items. So every time a new item is added to group 'done', the last (oldest) item will be deleted. I need an index to do that. However, I do not know how to get to the index for the last item.
What's more, I found this method in MSDN:
List.lastIndexOf
The example is:
var number = list.lastIndexOf(searchElement, fromIndex);
I think this is the answer but I have no idea how to use this method.
This is my HTML code for the ListView:
<div class="appViewContentMask">
<div class="appViewContent">
<div id="gridViewToDo" data-win-control="WinJS.UI.ListView" data-win-options="{
itemTemplate:select('#toDoTemplate'),
groupHeaderTemplate: select('#headerTemplate'),
layout:{type:WinJS.UI.GridLayout},
itemsDraggable : true,
itemsReorderable : true}"></div>
</div>
</div>
I wire up the data with Javascript:
Thank you for reading. I hope my question is clear enough. If you need more information, tell me and I will post more.
One way to be able to delete the oldest finished task is to add finishTime into the item and have it part of the sorting key . That way - the oldest item can be found at the end of the list. Sorting based on this key needs to be done in the createSorted projection.
Thereafter createGrouped projection needs to be used to group the items and order the groups.
The item is to be modified and removed in the iteminvoked handler.
For full details and code listing, refer here.
You can use the splice method (http://msdn.microsoft.com/en-us/library/windows/apps/hh700810.aspx) on the List which operates like that of an array. Once you find the index of the item you would like to remove you simply say:
groupedSortedListProjection.splice(index, 1);
In order to find the index you can ask the group, or in your case since you know the 'done' group is second and is the last group in the collection then the last element in that group will also conveniently be the last item in the collection, do your code is:
var index = groupedSortedListProjection.length - 1;
groupedSortedListProjection.splice(index, 1);
However, if it you didn't have that invariant and had to instead find the right group the code would look something like:
var groups = groupedSortedListProjection.groups;
var group = {}; // start with an empty object to make the for loop condition simpler
for (var i = 0; i < groups.length && group.key !== "done"; i++) {
group = groups.getItemAt(i);
}
var index = group.firstItemIndexHint + group.groupSize - 1;
groupedSortedListProjection.splice(index, 1);
Hope that helps.
-josh

Categories