Swap the constant of td using jquery - javascript

I want to swap the content of two td's with each other by clicking on move up button.
I mean I want to swap content between the 2nd td and 3rd td.
I got that done but I am facing little problem in that i.e. "the swapped td's are not toggling the class that shows the current td is clicked or not after the swapping."
I am using this code for swapping the content of td's as below
var currentTr = $("#selectedTab td.backgroundcolor").parent();
var previousTr = currentTr.prev();
var temp = currentTr.html();
$(currentTr).html(previousTr.html());
$(previousTr).html(temp);

HTML manipulation in the DOM can be destructive. You should instead move the DOM nodes themselves.
var currentTr = $("#selectedTab td.backgroundcolor").parent();
var previousTr = currentTr.prev();
var temp = currentTr.contents().detach();
currentTr.append(previousTr.contents());
previousTr.append(temp);
This way you're not serializing, destroying and rebuilding all the nodes. You're just moving them.

Related

Datatables multiple custom toolbar elements

I'm adding custom toolbar elements to a Datatables table, but I am not sure how to add more than one.
I run the JS below and it moves one element into the toolbar:
var elementOne = $('#elementOne');
$("div.toolbar").html(elementOne);
How do I add a second element to the toolbar?
I tried adding just the html of each element:
var elementOne = $('#elementOne');
var elementTwo = $('#elementTwo');
$("div.toolbar").html(elementOne.html() + elementTwo.html());
But this resulted in duplicate elements and one of them (button) did not work properly. However, I could probably fix this but I'm wondering if there's a better way.
Also, I cannot generate one of the elements within JavaScript. It must be either moved, which I'd prefer, or copied.
I figured it out. I had to use the append JQuery method:
var elementOne = $('#elementOne');
var elementTwo = $('#elementTwo');
$("div.toolbar").append(elementOne);
$("div.toolbar").append(elementTwo);

Best practice for appending child text in a for loop

Here i create a span element for an icon and then add a class to hide it (until hovered). I do the same for a second span that will hold a tooltip and adds CSS to style it.
I then loop through shipCell which is a column of cells, and append the btnSpan and the tipSpan. while adding the icon (a clipboard) using .inerHTML and adding the text "Copy ShipID" to the tipSpan using .innerText.
var btnSpan = document.createElement("span");
btnSpan.classList.add('quickLink'); // Add class to all quickLinks
var tipSpan = document.createElement("span");
tipSpan.classList.add('tooltip'); // Add class to all tooltips
for(var i=0;i<shipCell.length;i++){
btnSpan.innerHTML = '📋';
shipCell[i].appendChild(btnSpan.cloneNode(true)); //add button to each cell
tipSpan.classList.add('copytip'); //add class for copy buttons specifically
tipSpan.innerText = 'Copy ShipID';
shipCell[i].appendChild(tipSpan.cloneNode(true)); //add tool tip to each cell");
};
This all works as it should (especially after learning of cloneNode(true) which allows it to be appended to every cell rather than just the first.
My question here is would it be a smarter move to create text nodes for the things I used .innerHTML on? If so, how? Because i tried creating a text node and appending it in the loop but it would add a new copy EVERY time, so the second cells tooltip said "Copy ShipIDCopy ShipID" (yes, twice)
Well, while your existing code is not incorrect, most code in the for loop is unnecessary and can be cut down to:
var btnSpan = document.createElement("span");
btnSpan.classList.add('quickLink'); // Add class to all quickLinks
btnSpan.innerHTML = '📋'; // Moved this out from loop
var tipSpan = document.createElement("span");
tipSpan.classList.add('tooltip'); // Add class to all tooltips
tipSpan.innerText = 'Copy ShipID'; // Moved this out from loop
for (var i = 0; i < shipCell.length; i++){
shipCell[i].appendChild(btnSpan.cloneNode(true)); //add button to each cell
shipCell[i].appendChild(tipSpan.cloneNode(true)); //add tool tip to each cell");
};
Because by using .cloneNode(true), you are also cloning all its child nodes inside. Meaning, you don't have to keep assigning .innerHTML and .innerText because by using true in .cloneNode(), they will be cloned too.
You will only need to reassign them IF you use .cloneNode(), without true argument. However, in that case, your existing code will need some minor tweaking.
var btnSpan = document.createElement("span");
btnSpan.classList.add('quickLink'); // Add class to all quickLinks
var tipSpan = document.createElement("span");
tipSpan.classList.add('tooltip'); // Add class to all tooltips
var btnSpanClone,
tipSpanClone;
for (var i = 0; i < shipCell.length; i++){
btnSpanClone = btnSpan.cloneNode(); // New btnSpan element without childNodes
tipSpanClone = tipSpan.cloneNode(); // New tipSpan element without childNodes
btnSpanClone.innerHTML = '📋';
tipSpanClone.innerText = 'Copy ShipID';
shipCell[i].appendChild(btnSpanClone);
shipCell[i].appendChild(tipSpanClone);
};
As for your question of whether it is smarter to use .createTextNode(), it makes no difference in this specific case because there is nothing else to be added to your btnSpan and tipSpan. If there is, then it MIGHT be better to use it for better code organisation and readability.
The most important thing is to make your code easily understood by anyone.
So if you think using .createTextNode() can make the code more readable and easier to understand, then use it. If not, then don't.
If you are talking about code performance here, you can compare both implementation yourself using jsPerf or some other JS benchmark tools. Most likely, the performance difference will be very tiny and can be ignored.

js - appendChild Method spoiling the whole page

I am making a simple web app. In one part of it, I have a dynamically generated list:
which is achieved with:
for(var i=0; i<goalsObj.length; i++){
var node = document.createElement("li");
node.setAttribute("class", "list");
node.setAttribute('id','g'+i);
var checkbox = document.createElement("input");
checkbox.setAttribute("type","checkbox");
checkbox.setAttribute("class", "tickbox");
node.appendChild(checkbox);
var textnode = document.createTextNode(goalsObj[i]);
node.appendChild(textnode);
document.getElementById("sortable").appendChild(node);
}
And I have a jQuery function executed when any item on the list is clicked, to app a Calendar below it.
which is achieved with:
var cal = document.createElement("p");
cal.innerHTML=calendar_html;
document.getElementById($(this).attr('id')).appendChild(cal);
Anyhow, I am getting a very shabby output:
What's wrong? What should I do? How do I make the pre-existing elements(all made dynamically) to make way for the newly created ones?
Generate the whole content at once and not in parts. Hide the content that you do not want on initialization of the page. Write a function to show the hidden content when the list items are clicked.
Paragraph ("p" element) is for organization of information into paragraphs.
http://www.w3.org/TR/html401/struct/text.html#h-9.3
I suppose you should try to use div instead of p
var cal = document.createElement("div");
cal.innerHTML=calendar_html;

Need to remove table from DOM, and place Body into a td and put table back into DOM

Ok, if you go here: http://devs.dream-portal.net/smf205/index.php?action=forum
You will notice a table element that contains (under the menu) a forum (board index) on the right and 2 blocks of content on the left. All of this is within a table element with the class dp_main on the table element. On the right is SMF content and here's where it gets tricky. Ok, this td element has an id of smf_col I need to take out ALL HTML from within the #smf_col td element and place it just before (or in the same spot in the DOM) the table element is. Than I need to remove the table element .dp_main altogether from the DOM (and all of it's contents), than place all contents from within the body tag into the EMPTY #smf_col td element of the table, and than put that table into the body tag.
I can only do this in the body tag, so that's why the table needs to be removed from the DOM and placed back into it once the entire body contents gets placed into the td element with id = smf_col.
Using the following jQuery (a lot of manipulating here, because I can only do this in the body tag):
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript">
jQuery(document).ready(function($) {
var $smf_content = $("#smf_col").contents();
$("#smf_col").empty();
$($smf_content).insertBefore($(".dp_main"));
var $dptable = $(".dp_main").contents();
$(".dp_main").remove();
var $body = $("body").contents();
$("body").empty();
$("body").html($dptable);
$("#smf_col").html($body);
});
</script>
The page is here: http://devs.dream-portal.net/smf205/index.php?action=forum
I will disable my code for now, since it doesn't work anyways, and leave it in it's original state so you can see exactly what I am talking about, before manipulating anything, this is what I have to work with. Basically, this this is done properly, the 2 blocks on the left should be ALL the way to the left and the rest of the page should be on the right.
Final Result should look something like the image below:
Try
var $dpmain = jQuery('.dp_main');
var $body = jQuery('body');
var $col = jQuery('#smf_col');
var $ct = jQuery('<div />').insertBefore($dpmain);
$body.append($dpmain);
$col.contents().appendTo($ct);
$body.contents().not($dpmain).appendTo($col)

Change DIV in one remove/append

Here is what I am doing, I create a div structure dynamically
var divt = $('<div id="toplevel"></div>');
divt.append('<div id="child1"><div class="content1"></div></div>');
divt.append('<div id="child2"><div class="content1"></div></div>');
I then store a clone to a separate node and add it to the DOM.
this.emptydivt = $(divt).clone();
maindiv.append(divt);
Later on in my code I want to replace the contents of the top level DIV using one remove/append.
Firstly I create a new node from my previously saved...
this.newdivt = this.emptydivt.clone();
Here I want to get the child divs and append some new content , I have tried various function but can't get it to work eg.
var childdiv = this.newdivt.find('#child1').html();
childdiv.append('<div> new content</div>');
then after I will replace the top level div
maindiv.remove('#toplevel');
maindiv.append(this.newdivt);
So is there a way to get the child div from a Jquery or JS node that is not in the DOM ?
I see 2 typos in your code, not sure if on your real code they are not present
this.newdivt = this.emptydivt.clone(); // you missed ()
and
var childdiv = this.newdivt.find('#child1').html(); // you missed '' around #child1
Also, this code is not valid as clone doesn't accept a jQuery object as parameter
this.emptydivt = $(eventGrid).clone(divt);
Maybe you just want divt.clone()?
EDIT
Remove all white spaces on your elements ids as white spaces are not allowed on id attribute.

Categories