Jquery .clone() method. Removing clones - javascript

I noticed some interesting behavior when dealing with the .clone() function.
If I have a function to create rows and columns dynamically like this:
function appendDiv(n) {
for (var i=0;i<n;i++) {
$rows.append($columns.clone()); //assume I put $('.rows') & others in a var
}
for (var i=0;i<n;i++) {
$wrapper.append($rows.clone());
}
}
And I then delete the elements from the DOM maybe like this:
function deleteClones() {
$wrapper.off();
$wrapper.html('');
$('body').append($wrapper);
num = prompt("Enter another number.");
return num;
}
So I'd be calling the functions in an order like this:
appendDiv(num);
num = deleteClones();
appendDiv(num);
Can someone tell me why when I call appendDiv(num); again after removing those elements, the old columns are added along with the new ones? Here is a preschool level demonstration of what I mean: http://jsfiddle.net/wj6sgeeu/. Notice upon inspecting the html document, the clones that were created before we called deleteClones() are added again when we call appendDiv(num) for the second time.
I'm new to jquery, so maybe this is a self evident and obvious fact (maybe using a different method to remove clones?) but does someone have an explanation for this behavior?
Thank you!

You need to remove the previously added columns from the row, else you are just keep adding more columns to the existing columns
function appendDiv(n) {
$rows.empty();
for (var i = 0; i < n; i++) {
$rows.append($columns.clone());
console.log('ok');
}
for (var i = 0; i < n; i++) {
$wrapper.append($rows.clone());
console.log('ok2');
}
}
Demo: Fiddle

Related

Iterate through a single column of HTML table efficiently and properly

You may want to look for the check() function HERE
function check(){
var i = 0;
var s = 0;
for(i = 0; i < tbody.rows.length; i++){
if(tbody.childNodes[i].childNodes[0].textContent == "unit_3"){
s = i;
}
}
return s ;
}
I did this function to iterate through a specific column of my table. I was wondering since I don't know much about Javascript and iterations if there is a better & faster way to look for a specific value in a column because in a real case I may have actually a lot of rows so I want the iteration to be fast. I suck with jQuery but any suggestion is welcome :)
Thank you in advance
ECMAScript 6 introduces findIndex (which can be polyfilled):
function check() {
return [].findIndex.call(tbody.rows, function(row) {
return row.cells[0].textContent == "unit_3";
});
}

How to match and remove an object from javascript array?

I am trying to delete an element based on string match for a object property but when I do a slice on the javascript array the array size decreases and indexes change. Please help e with a solution. Here is a jsfiddle link for the same.
Code
var selection = JSON.parse('[{"Connectors":"c1"},{"Connectors":"c2"},{"Schedules":"s1"},{"Schedules":"s2"},{"Gauges":"g1"},{"Gauges":"g2"},{"Gauges":"g3"}]');
removeitem("Gauges");
function removeitem(item) {
for (var i = 0; i < selection.length; i++) {
if (selection[i].hasOwnProperty(item)) {
selection.splice(i, 1);
}
}
}
Add i--;
function removeitem(item) {
for (var i = 0; i < selection.length; i++) {
if (selection[i].hasOwnProperty(item)) {
selection.splice(i, 1);
i--;
}
}
}
jsfiddle example
Assuming you don't have a problem with having undefined as the new value, then you could call delete[i]; instead of selection.splice(i, 1); in that case the length does not change and neither will the indices.
Both Abhi1964 and Loolooii solution seems to work fine and solve problem, but i would personally keep the filtered results in separate array instead of manipulating index/deleting value in the same array, reason being, separate array would make code look simpler to read and understand. Reviewer need not to understand the index manipulation or keep track of undefined.
var selection = JSON.parse('[{"Connectors":"c1"},{"Connectors":"c2"},{"Schedules":"s1"},{"Schedules":"s2"},{"Gauges":"g1"},{"Gauges":"g2"},{"Gauges":"g3"}]');
removeitem("Gauges");
var filteredResult = [];
function removeitem(item) {
for (var i = 0; i < selection.length; i++) {
if (selection[i].hasOwnProperty(item)) {
}else{
filteredResult.push(item);
}
}
}
//use filtered result as per your need.
Note:
I have not run this code, if some error seems to be there, please feel free to edit.

Get all files for all .uploadedFiles

Im looking for a javascript/jquery (doesn't matter which way) to collect all the files i've uploaded.
I have the following code, where .afbeelding is the class for a couple of file input fields
var geuploadeAfbeeldingen = $('.afbeeldingen').files;
for (var i = 0; i < geuploadeAfbeeldingen.length; i++) {
}
This somehow doesnt seem to work. When i try document.getElementsByClassName it also doesn't work. The funny thing however is, that document.getElementById seem to work on one input field
Any ideas?
This should do what you want
var files = [],
geuploadeAfbeeldingen = $('.afbeeldingen').each(function(){
for (var i = 0; i < this.files.length; i++){
files.push(this.files[i]);
}
});
You end up with an array (files) that holds each file you have selected through the input elements..
Demo at http://jsfiddle.net/gaby/GJW7Y/1/
If you only want the filenames then change
files.push(this.files[i]);
with
files.push(this.files[i].name);
Try this way :
var geuploadeAfbeeldingen = $('.afbeeldingen');
for (var i = 0; i < geuploadeAfbeeldingen.length; i++) {
alert(geuploadeAfbeeldingen[i].files[0].name);
}
This may help you.
Edit :
$('.afbeeldingen').files is not work and document.getElementById().files is worked because first one return JQuery object( array of objects) and second one return DOM object.The jQuery object (created by the $ method) is a wrapper around a DOM element or a set of DOM elements. The normal properties and methods are not available with JQuery object.
You need to loop through each input element and return the files property.
Something like this is probably the shortest way, using map to iterate through an array:
var geuploadeAfbeeldingen = $('.afbeeldingen').map(function(k, v) { return v.files[0]; }).get();

GetElementByTagName[ 0 ].setAttribute inside a loop

I just curious about this.
I created an function that add ID value to a dynamically create li tag.
the function looks like this.
function limenu(lix,liy){
document.getElementsByTagName("li")[0].setAttribute("id",lix);
document.getElementsByTagName("li")[1].setAttribute("id",liy);
} limenu("icon-dice","icon-clock");
My thought is, can I use an for-loop? that let me insert how many events I want without need to create document.getElementsByTagName("li")[1]-[2]-[3].. etc
so when i call the function liemenu(), I would be able to add as many events i want.
I could use Jquery but i really want to do this with Javascript.
Thanks
function limenu() {
var lis = document.getElementsByTagName("li");
var count = Math.min(lis.length, arguments.length);
for (var x = 0; x < count; x++) {
lis[x].setAttribute('id', arguments[x]);
}
}
http://jsfiddle.net/ExplosionPIlls/72hdS/

JavaScript array sort(function) to sort table rows- not sorting

I am trying to sort a dynamically constructed table on the client side. So far I have done my research to discover JavaScript's sort() method will take a callback. Here is what I have so far:
function retrvCatalog(e){
var merch = document.getElementById('merch');
var tRows = merch.rows;
var tBody = merch.tBodies;
var rowArr = [];
for (x in tRows){
rowArr[x] = tRows[x];
}
rowArr.sort(function(a, b){
if (a.cells.textContent < b.cells.textContent){
return -1;
}
if(a.cells.textContent > b.cells.textContent){
return 1;
}
return 0;
});
}
Stepping through it in Firebug, it appears to not change the order of the rows. Can someone please help me figure out what I am missing?
FINAL ALGORITHM
function retrvCatalog(e){
var fltr = e.id;
var merch = document.getElementById('merch');
var tblHead = merch.tHead;
merch.deleteTHead();
var tRows = merch.rows;
var rowArr = [];
for (var i=0; i<tRows.length; i++){
rowArr[i] = tRows[i];
}
rowArr = rowArr.sort(function(a, b){
if (fltr > 3){
a = parseFloat(a.cells[fltr].innerHTML);
b = parseFloat(b.cells[fltr].innerHTML);
}
else{
a = a.cells[fltr].innerHTML;
b = b.cells[fltr].innerHTML;
}
if (a>b){
return 1;
}
if(a<b){
return -1;
}
return 0;
});
while(merch.hasChildNodes()) {
merch.removeChild(merch.firstChild);
}
merch.appendChild(tblHead);
for (i=0;i<rowArr.length;i++){
merch.appendChild(rowArr[i]);
}
}
The final two columns in the row are numbers, so that is why the method to sort is slightly variable.
Several problems in your code.
First, you didn't declare the x variable.
for(var x...
Second, don't use for-in to iterate an array like collection. Use for.
for (var x = 0, len = tRows.length; x < len; x++){
rowArr[x] = tRows[x];
}
Third, there is no textContent property of a cells collection.
This is easy to test by logging its value. This should have been the first thing you tried.
console.log(a.cells.textContent); // undefined
You need to decide which cell you want, and ask for it by index.
console.log(a.cells[0].textContent);
Finally, you should be aware that this technique will not show the result of the sorting in the DOM. You're only sorting the Array. You'll need to append the new ordering to the DOM.
Maybe you knew this, but you didn't show it in your code.
I don't know the relationship of the rows to the tBodies, so I can't give an example. But if all the rows are in one tbody, just loop the Array, and tBody[0].appendChild(rowArr[i])
I'm not sure if I'm missing something, but I'm pretty sure you can't use textContent on the cells array. You need to index cells so you know which column to actually sort on. If your rows have 4 columns each (or even if there's only 1), you still need to tell the sort function which column to sort on.
So in your sort function, if you wanted to sort by the second column, you'd want something like:
rowArr.sort(function (a, b) {
if (a.cells[1].textContent < b.cells[1].textContent) {
return -1;
} else if (a.cells[1].textContent > b.cells[1].textContent) {
return 1;
}
return 0;
});
And I'm not sure what's in your cells, but you may want to use .innerHTML, not .textContent.
rowArr.sort(function(a,b) {
a = parseFloat(a.cells.textContent);
b = parseFloat(b.cells.textContent);
return (a-b);
};
"don't use for-in to iterate an array like collection." - user1673729
tRows is not an array, it's an HTML collection. That is why I used "for in" – nodirtyrockstar
An HTML Collection is an array like collection. Do not use for-in.

Categories

Resources