JQuery Unique() function not working properly - javascript

I'm working on an interface that allows the user to select multiple "cards". Each card has a "data-name" attribute and may also have a corresponding menu item. If they select the card in the main view, it also highlights the menu item. When something is clicked, I add the "selected" class to it. I then get all the 'selected' items and count the unique data-name attributes to get the number of actual items selected.
This works very well when selecting up to 5 items. For some reason, on the 6th item the unique() function seems to stop working correctly. I was unable to duplicate this issue with jsfiddle, but the code was a bit less complex, as locally I'm also dealing with "types", but I think that's irrelevant to the problem.
So here are some screenshots of the relevant arrays after I have selected the 5th item.
Here you see ALL selected items. There are 10, as expected. This breakpoint is just before the unique() call.
Here you see unique selected items. There are 5, as expected.
And then I select the 6th one... 12, as expected...
Aaand now we have a mysterious duplicate! Why???
This happens consistently; every single time. And note that it doesn't matter which item I select last. I've added as many as 10 dummy items and it's always the 6th one that it gets confused on.

Taken from jQuery.unique():
Description: Sorts an array of DOM elements, in place, with the duplicates removed. Note that this only works on arrays of DOM elements, not strings or numbers.
If you want to get a unique array of string or numbers, you will need to use your own function. Here's one taken from a previously answered question similar to yours:
function unique(array) {
return $.grep(array, function(el, index) {
return index == $.inArray(el, array);
});
}

Related

multiple items in container (drag and drop)

I have a problem with my drag and drop code. I want to put multiple items (dragged) in three containers (drop), and then return all values put in the container (thanks to alert(droppableResults);). But this code only returns the first item dropped, and I went all of the items.
Thanks for your help!
I put code in jsfiddle.net for better understanding.
https://jsfiddle.net/vbyyvt2o/1/
The problem you have is that the data-r="" value gets overwritten with every drop.
This results in only the last drop being recorded (not the first one).
Since .dropAble can contain several elements that approach doesn't work. You might however remove the data-r attribute from .dropAble and add a data-q attribute to your.dragAble elements. Then you could modify your JS accordingly and it should work fine.
Here is a modified fiddle:
https://jsfiddle.net/vbyyvt2o/4/

get index of element selected by Document.getElementByID("id_name")

For a page ("Bill4Time"), the Dashboard shows a table for displaying time entries and entering a new time entry but several control elements do not have ID's associated with them. Interestingly enough, the control to add a new time entry line (an icon of a clipboard with a small plus sign in the lower right hand corner) always has the same index number (so I can select it with Document.all("index_no") to add a new time entry. But once you edit that line by entering a new time entry, the control icon changes (to a generic clipboard, like all the other time entries in the table) and the index becomes dynamic -- and there is no id associated with that control. However, I found that the parent element (i.e., the table cell) does have a unique ID which never changes (while it is the most recently added time entry) so currently I go to it (using Document.getElementByID("unique_id").focus()) and then send a {tab} to move over to the control element (and send {enter} to go to the correct details page).
If I could get the index number of the unique_id element, and increment that by one, I could more reliably get to the control I want, so my question is, if one has gotten a DOM element by id, how can one find its index number?
When I search here (or google) I get a lot of results for finding the index of the included elements within the parent, or results based on .selectedIndex and the like, and I suppose I could loop through all the DOM elements until I find the one with ID = unique_id, but there should be a better way to get an index number of a selected element.
TIA,
At least if doing it with IE and AutoHotkey this will give you the index
index := wb.document.getElementByID("unique_id").sourceIndex
But you don't need the index if you have the parent element
element := wb.document.getElementByID("unique_id").childnodes[0]
Also a lot of times elements that don't have an ID often have a Name or Class attribute, both of them can also be used to find the element you need...
You mentioned looping, but I think that may be the way to do it since IDs are unique. Getting a matching element by its ID gives you that element, not an array of elements (like if you matched by class) which would all have an index.
If you know the ID of the table you want to focus on, you can do something like this if you don't want to use jQuery.
//get all the tables
var thisEleArr = document.getElementsByTagName('table');
var indexOfTableIWant;
//loop through the array of tables
for (var i=0;i<thisEleArr.length;i++) {
//if the id of the current table in the loop matches the known id
if (thisEleArr[i].getAttribute('id')==='knownTableID') {
//get the index of it
indexOfTableIWant = i;
}
}
My example using lists: https://jsfiddle.net/ksumarine/ga06n54u/

Sorting the checked items which are on top of list

With the help of Moving checked items to the top after unchecking all items I have implemented moving of checked items to the top.If unique alphabets are there the sorting is rendering fine.But, if we have two or more options having same alphabet, the sorting is not rendering fine .If we click our and ours after one, it is sorting but Five is still in the last element which is not sorted.I tried to get the content and used jquery sort function to sort it.But it doesn't helped me.
Here is what I see from your example fiddle : your checkboxes are sorted by their checked status, and if two checkboxes have the same checked status, their relative ordering is the same as their initial ordering.
Initially, Five is at the end of your list, so it will always be sorted after all other nodes (with respect to its checked status).
You seem to want to see Five appear before Our or Ours : why don't you fix the order in the initial html ?

How to have a observable collection that can be updated from two sources without causing a loop in knockout.js

I am working with knockout.js. I have a situation where I have a collection of items which each have a observable boolean isleader. Where one of them can be active at a time. If people swap an item in the collection with one from another collection then I check if the old one isleader is true and if so I set it on the new one. This works fine. Now I need to add a second input mechanism which is a dropdown which is bound to the collection to show all the items from the collection. I want the one item in the collection with the isleader set to true to be the selected item and if the selected item is changed I would like the isleader to be updated to reflect this.
How can I do this without creating an infinite loop between the dropdown and the collection constantly updating the selected item.
You can do a peek.
this.selectedItem.peek()
as opposed to
this.selectedItem()
as you are propably doing.
Both will return the fields value, but the first will do it without creating a dependency. In other words, peek will get the value, but it won't subscribe to it.

Appending/creating/removing items from a javascript array, ideas?

I have a requirement whereby I have two panes on a page, the pane on the left holds a series of records specific to a option selected from a drop down. Each record has a plus sign next to it, if this is pressed it will be 'moved' to the right hand pane and displayed under the option the user selected.
Multiple records can be put into each option selected.
I'm a bit unsure of the best approach to go with this. At first I was thinking about creating an array in Javascript and each click of plus would add the item to the array. When the form is ready to be submitted, use jQuery/Ajax to pass the array to a php function.
I suggest having this structure:
Options={
'opt1':{},
'opt2':{},
'opt3':{}
}
and you have these records
//following is a structure view, not code
1: Record #1
2: Record #2
3: Record #3
4: Record #4
when user chooses to attach record#2 to opt3, you do:
Options['opt3'][2]='Record #2';
New Options object:
Options={
'opt1':{},
'opt2':{},
'opt3':{
2:'Record #2'
}
}
removing added options is as easy as:
delete Options['opt3'][2]
I've had to do similar things with arrays in javascript and I used the splice method
This is the definition:
The splice() method adds and/or removes elements to/from an array, and returns the removed element(s).
This is where I would start.

Categories

Resources