How to find nearest child to a click location? - javascript

Fiddle: http://jsfiddle.net/1bgun0k0/1/
I have a DIV with several child SPANs.
<div id="parent">
<span class="child">Alpha</span>
<span class="child">Beta</span>
<span class="child">Gamma</span>
</div>
Child elements have a margin:
#parent { padding: 5px; }
.child { margin: 5px; }
When user clicks between child elements (or at either end of the parent DIV outside a child element), I need to insert a new child there.
How do I detect between which child elements user clicked?
Update: I need to support multiple rows of children (thanks, Roko, for the heads-up). Clicks between rows should be ignored. Clicks on the left and right side of the whole row should be handled correctly.

Since margins don't receive click events, I might suggest using a 5px placeholder div instead of a margin, so that clicking between children will result in a click to the placeholder.
On that click, you insert a new child (and a new 5px placeholder) underneath.
UPDATE: Since you changed the question from clicking between to clicking beside, you might try this trick using pseudo elements (to prevent divitis)
https://stackoverflow.com/a/23243996/1998238

An alternative solution is to use CSS to mask the area you are clicking. You can do this by wrapping your elements like so:
<div id="parent">
<div id="alpha" class="spacer">
<span class="child">Alpha</span>
</div>
<div id="beta" class="spacer">
<span class="child">Beta</span>
</div>
<div id="gamma" class="spacer">
<span class="child">Gamma</span>
</div>
</div>
Here is the code: https://jsfiddle.net/theodin/5enfs52t/2/

On click:
Iterate through each child, grabbing children on the left and right based on position in relation to the cursor. (Check event.pageY to make sure they're on the right row.)
If a child to the left is found, keep iterating to the end. The last left child will be the true left child.
If a child to the right is found, stop iterating. This is the one you want.
If a left child is found, insert the text and a space after it. You're done.
If a right child is found, insert the text and a space before it.
Snippet
var n = 0;
$('#parent').click(function(e) {
if(e.target.id === 'parent') {
var parent= $(this),
firstChild= $(this).find('.child').first(),
lastChild = $(this).find('.child').last(),
leftChild,
rightChild,
text= function() {return $('<span class="child new">New child '+(++n)+'</span>');}
parent.find('.child').each(function() {
var pos= $(this).offset(),
h= $(this).height();
if(pos.top <= e.pageY && pos.top+h >= e.pageY) {
if(pos.left <= e.pageX) {
leftChild= $(this);
}
else if(pos.left >= e.pageX) {
rightChild= $(this);
return false;
}
}
});
if(leftChild) {
leftChild.after(text()).after(' ');
}
else if(rightChild) {
rightChild.before(text()).before(' ');
}
else if(!firstChild.length || e.pageY < firstChild.offset().top) {
parent.prepend(text()).before(' ');
}
else if(e.pageY > lastChild.offset().top) {
lastChild.after(text()).after(' ');
}
//otherwise, we're between rows
}
});
body {
margin: 10px;
padding: 10px;
}
#parent {
padding: 5px;
background-color: green;
cursor: pointer;
width: 450px;
line-height: 2.7em;
}
.child {
margin: 5px;
white-space: nowrap;
background-color: yellow;
border: 1px solid black;
}
.new {
background-color: lightblue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent">
<span class="child">Alpha</span>
<span class="child">Beta</span>
<span class="child">Gamma</span>
<span class="child">Delta</span>
<span class="child">Epsilon</span>
<span class="child">Zeta</span>
<span class="child">Eta</span>
<span class="child">Theta</span>
<span class="child">Iota</span>
<span class="child">Kappa</span>
<span class="child">Lambda</span>
<span class="child">Mu</span>
<span class="child">Nu</span>
<span class="child">Xi</span>
<span class="child">Omicron</span>
<span class="child">Pi</span>
<span class="child">Rho</span>
<span class="child">Sigma</span>
<span class="child">Tau</span>
<span class="child">Upsilon</span>
<span class="child">Phi</span>
<span class="child">Chi</span>
<span class="child">Psi</span>
<span class="child">Omega</span>
</div>

http://jsfiddle.net/tukqnujm/2
This was suggested previously, but you can add transparent clickable elements between the others to act as margins.
var parent = $("#parent");
parent.on("click", function(e) {
if(e.target.classList.contains("between")) {
var item = document.createElement("span");
item.classList.add("item");
var between = document.createElement("span");
between.classList.add("between");
e.target.parentNode.insertBefore(item, e.target);
e.target.parentNode.insertBefore(between, item);
}
});
Be careful though, inline-block tags add a space to the document if there are spaces between elements, and those spaces won't be clickable. That's why I put comments in the jsfiddle.
<div id="parent"><!--
--><span class="between"></span><!--
--><span class="item"></span><!--
--><span class="between"></span><!--
--></div>

You can track the position of the cursor (because the cursor will not be immediately over any .child element, so binding the click event to it is useless), and then retrieve a list of .child elements that are to the left of this coordinate. Get the last .child element that satisfy this criterea, append new element behind it.
Also, you should use .on() for the click event binding for .child, because newly added elements will not have the click event registered (because with your existing code, you are binding the click event at runtime, where newly added elements are not present on the page).
$('.child').on('click', function(e) {
e.stopImmediatePropagation();
$(".debug").removeClass("debug");
$(this).toggleClass("debug");
})
$("#parent").click(function(e) {
e.stopImmediatePropagation();
$(".debug").removeClass("debug");
$(this).toggleClass("debug");
// Get mouse position along x-axis
var xPos = e.pageX,
yPos = e.pageY;
// Get x-axis offset of child
// Return array of child elements that is to the left of mouseclick
// and get the last child, append new element after it
var $prevChild = $('.child').filter(function() {
return ($(this).offset().left < xPos && $(this).offset().top < yPos)
}),
$content = $('<span class="child">New child</span>');
// Additional logic from #AlexanderGladysh
if ($prevChild.length > 0) {
$content.insertAfter($prevChild.last());
} else {
$(this).prepend($content);
}
})
See fiddle here: http://jsfiddle.net/teddyrised/1bgun0k0/9/

Related

Clone div with new calculator for new divs

I have some Jquery that I am using to clone a div, inside the div is an input that does a calculation.
When I clone the div and it creates a new div, the calculation does not work for the new divs. I understand that the calculation only works once the way I have it written. I have searched, but cannot find what I am looking for.
I also have an issue that when I add a number in the input the calculation works for the first div, but it also removes my buttons.
How can I have a new calculation for each new cloned div?
How can I stop the calculation from removing my add/remove buttons?
function clone() {
$(this).parents(".clonedInput").clone()
.appendTo("body")
.attr("id", "clonedInput" + cloneIndex)
.find("*")
.each(function() {
var id = this.id || "";
var match = id.match(regex) || [];
if (match.length == 3) {
this.id = match[1] + (cloneIndex);
}
})
.on('click', 'button.clone', clone)
.on('click', 'button.remove', remove);
cloneIndex++;
}
function remove() {
$(this).parents(".clonedInput").remove();
}
$("button.clone").on("click", clone);
$("button.remove").on("click", remove);
// calculator
$(document).ready(function() {
$(".calculate").bind("keyup change", function(e) {
var cabwidth = parseFloat($("#cabwidth").val()) || 0;
var ply = 1.4375;
var value = cabwidth - ply;
if (!isNaN(value) && value !== Infinity) {
$("#sum").text(value);
}
});
});
body {
padding: 10px;
}
.clonedInput {
padding: 10px;
border-radius: 5px;
background-color: #def;
margin-bottom: 10px;
}
.clonedInput div {
margin: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="clonedInput1" class="clonedInput">
<input type="text" class="calculate" id="cabwidth" placeholder="Cabinet Width">
<div id="sum" />
<div class="actions">
<button class="clone">Add</button>
<button class="remove">Remove</button>
</div>
</div>
Here is a jsfiddle example: jsfiddle
Your buttons get removed because their parent <div> has its contents overwritten (due to your invalid syntax). You're attempting to self-close your sum <div> with <div id="sum" />.
The <div> element cannot be self-closed, as it is not a void element; you must explicitly state that the element is empty with <div id="sum"></div>. Making this change fixes the problem with your buttons disappearing.
Note that you can validate your HTML markup with the W3C validation service, to ensure that your HTML is valid (and thus behaves in a way that is expected). Also note that .bind() is deprecated as of jQuery 3.0; you should be using .on() instead.
As for your cloning not working, that is due to two reasons:
The first being that you are cloning based on ID, and thus duplicating the ID. IDs must be unique throughout the DOM. Use classes instead of IDs, and use $(this) to refer to the specific cloned element.
Change #sum to .sum, and instead of $("#sum").text(value), use
$(this).parent().find(".sum").text(value) to only affect the
correct element.
Change var cabwidth =
parseFloat($("#cabwidth").val()) || 0 to var cabwidth =
parseFloat($(this).val()) || 0.
Remove all use of IDs to ensure valid markup after the cloning.
The second being that event handlers do not get attached to cloned elements. You need to hoist the scope to an element that is available on DOM load, and make use of event delegation. Instead of $(".calculate").bind("keyup change", function(e), use $("body").on("keyup change", ".calculate", function(e).
This is all fixed in the following example:
function clone() {
$(this).parents(".clonedInput").clone()
.appendTo("body")
.find("*")
.on('click', 'button.clone', clone)
.on('click', 'button.remove', remove);
}
function remove() {
$(this).parents(".clonedInput").remove();
}
$("button.clone").on("click", clone);
$("button.remove").on("click", remove);
// calculator
$(document).ready(function() {
$("body").on("keyup change", ".calculate", function(e) {
var cabwidth = parseFloat($(this).val()) || 0;
var ply = 1.4375;
var value = cabwidth - ply;
if (!isNaN(value) && value !== Infinity) {
$(this).parent().find(".sum").text(value);
}
});
});
body {
padding: 10px;
}
.clonedInput {
padding: 10px;
border-radius: 5px;
background-color: #def;
margin-bottom: 10px;
}
.clonedInput div {
margin: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="clonedInput">
<input type="text" class="calculate" placeholder="Cabinet Width">
<div class="sum"></div>
<div class="actions">
<button class="clone">Add</button>
<button class="remove">Remove</button>
</div>
</div>
Hope this helps! :)
Here is an updated jsFiddle.
Some notes on what I changed:
.bind() is depreciated
Attached the change/keyup to the document, then passed .calculate as the selector, this will work with dynamic elements, whereas before it wasn't
Made sure each clone and child elements have a unique ID
Updated the calculate function to target elements relative to current input

Why is my if else statement not working? jquery

I have an if else statement that is supposed to hide/show list items when other list items are appended/removed. It only works if I put the if else statement after the #delete-square function but it only works for one list item. Here is my fiddle: http://jsfiddle.net/matty91/zqmps11b/6/
This is probably really simple to do but I don't know javascript/jquery that well.
Example: So for every blue square that is added, take away a green square. There should always be 4 squares present. (if I have 2 blue I should have 2 green. If I have 4 blue then I should have no green. The user should be able to add as many blue squares as he wants but if the blue squares go below 3 then add 1 green) Hopefully that makes sense :)
Let me know if I need to explain a bit more for what I'm trying to accomplish!
Thanks in advance!
$(document).ready(function(){
if ($("ul.db-view-list li .quad #chart_div").length == 1){
$("li.ph:last-child").hide();
} else if($("ul.db-view-list li .quad #chart_div").length == 2){
$("li.ph:nth-child(2)").hide();
} else if($("ul.db-view-list li .quad #chart_div").length == 3){
$("li.ph:nth-child(1)").hide();
} else if($("ul.db-view-list li .quad #chart_div").length >= 4){
$("li.ph:first-child").hide();
} else {
$("li.ph").show();
};
$(".add-square").click(function(){
$(".db-view-list").prepend("<li><button id='delete-square'>X</button><div class='quad'><div id='chart_div'></div></div></li>");
$(document).on('click', '#delete-square', function(){
$(this).parent().remove();
});
});
});
.db-view-list{
padding: 0px;
margin: 0px;
height: 300px;
}
.db-view-list li{
padding:0px;
list-style-type: none;
}
.quad{
width: 100px;
height: 100px;
float: left;
}
.default-message{
background-color: green;
border: solid 1px white;
width: 100%;
height: 100%;
margin:0px;
padding: 0px;
}
#chart_div{
width: 100%;
height: 100%;
background-color: blue;
border: solid 1px white;
}
#delete-square{
position:absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="db-view-list">
<li class="ph">
<div class="quad">
<p class="default-message">
click add square to add a graph first
</p>
</div>
</li>
<li class="ph">
<div class="quad">
<p class="default-message">
click add square to add a graph 2
</p>
</div>
</li>
<li class="ph">
<div class="quad">
<p class="default-message">
click add square to add a graph 3
</p>
</div>
</li>
<li class="ph">
<div class="quad">
<p class="default-message">
click add square to add a graph last
</p>
</div>
</li>
</ul>
<button class="add-square">
add square
</button>
http://jsfiddle.net/zqmps11b/28/
Keep in mind the CSS is changed as well to accommodate Classes instead of IDs.
Your if statements were setup to only be checked on document.ready which only occurs once. This should work:
var numOfNewBoxes = 0;
// declare variable to count new boxes.
$(document).ready(function () {
// the if/else statement should be removed from the document.ready function
//You're not reloading the page every time you tap the 'add square button
//change the ids to classes because there should only be 1 instance of each ID.
$(".add-square").click(function () {
$(".db-view-list").prepend("<li><button class='delete-square'>X</button><div class='quad'><div class='chart_div'></div></div></li>");
//hide the last of the original boxes that are visible
$('.default-message:visible:last').hide();
numOfNewBoxes ++;
//remove any old on click events attached to the class delete-square
$('.delete-square').off('click');
//assign the event to the delete square class only - not the document.
//This stops the event from continuously firing on click.
$('.delete-square').on('click', function () {
numOfNewBoxes --;
//show the first of the original boxes if they are hidden
// only if there are < 4 new boxes;
$(this).parent().remove();
(numOfNewBoxes < 4) ? ($('.default-message:hidden:first').show()) : false;
});
});
});
Since you need to have more than one chart_div and delete_button, you can't use that as an id. Use a class instead:
$(document).ready(function () {
var chartDivs = $("ul.db-view-list li .quad .chart_div");
if (chartDivs.length == 1) {
$("li.ph:last-child").hide();
} else if (chartDivs.length == 2) {
$("li.ph:nth-child(2)").hide();
} else if (chartDivs.length == 3) {
$("li.ph:nth-child(1)").hide();
} else if (chartDivs.length >= 4) {
$("li.ph:first-child").hide();
} else {
$("li.ph").show();
}
;
$(".add-square").click(function () {
$(".db-view-list").prepend("<li><button class='delete-square'>X</button><div class='quad'><div class='chart_div'></div></div></li>");
});
//this will apply to .delete-squares created in the future
//so you can just do it once.
$(document).on('click', '.delete-square', function () {
$(this).parent().remove();
});
});
I believe you should also put that if/else statement in a function and have it execute whenever you delete or add a div. Now, the if/else statement is only executed once: when the document is ready.

How to use Jquery to remove an overflowing element?

Pretty simple problem, but I can't find a solution. This plugin claims to do it, but I can't get it to work on my site at all, not as a called script, not inline, nothing. So, I have two columns of divs, the ones on one side larger than the other. I have set it up so the second column container will match the height of the first (which is determined elsewhere and thus varies) and set it to overflow:hidden, but what I want to do do is to remove the overflowing divs entirely so it always ends on the last complete div. Here's the fiddle: https://jsfiddle.net/bw2v39ru/2/
This is the JS to equalize the heights $('.row2').css('height', $('.row1').height()+'px');
In that example, only two of he block2 spans should be visible and the overflowing ones removed completely instead of leaving half a block.
Try this: https://jsfiddle.net/bw2v39ru/9/
Besides the code below - you will have to e.g. insert a <br style="clear:both;" /> in the parent DIV since the children has float: left
$('.row2').css('height', $('.row1').height());
var maxHeight = $("#main").outerHeight();
$("#main span").each(function() {
var elm = $(this);
if (elm.offset().top + elm.height() > maxHeight)
elm.remove();
});
as promised, here is my answer. Custom build jsfiddle from pure JavaScript.
https://jsfiddle.net/www139/vjgnsrpg/
Here is a code snippit for you. It assumes that all of your block2 elements have a fixed height. Also I changed the .row1 and .row2 classes to ids to make the solution easier to create. Feel free to change it back but remember to use document.getElementsByClassName('class')[i] instead.
//make sure you execute this script onload inside a jquery document ready or window.onload
//get the rendered height of both rows
//enter margin for blocks here
//this also assumes that the height of your block1 and block2 elements are fixed
var margin = 5;
var rowOneHeight = document.getElementById('row1').offsetHeight;
//get height of block2 element including vertical margin (multiplied twice)
var blockTwoHeight = document.getElementById('row2').getElementsByClassName('block2')[0].offsetHeight + 2 * margin;
var howManyBlocksCanFit = Math.floor(rowOneHeight / blockTwoHeight);
var numberOfBlocks = document.getElementById('row2').getElementsByClassName('block2').length;
for (var i = 0; i != numberOfBlocks - howManyBlocksCanFit; i++) {
document.getElementById('row2').removeChild(document.getElementById('row2').lastElementChild);
}
#main {
width: 240px;
}
#row1 {
float: left;
}
#row2 {
float: right;
overflow: hidden;
}
.block1 {
display: block;
margin: 5px;
width: 100px;
height: 50px;
border: 1px solid red;
}
.block2 {
display: block;
margin: 5px;
width: 100px;
height: 100px;
border: 1px solid red;
}
<div id="main">
<div id="row1">
<span class="block1"></span>
<span class="block1"></span>
<span class="block1"></span>
<span class="block1"></span>
<span class="block1"></span>
</div>
<div id="row2">
<span class="block2"></span>
<span class="block2"></span>
<span class="block2"></span>
<span class="block2"></span>
<span class="block2"></span>
</div>
</div>
Hope this helps you, please tell me if there was something I didn't understand in your question to improve my answer.
I programmed it for you, this works after your existing JS code line:
var row2 = $('div.row2'),
block2elements = row2.children('span.block2');
// Function to use also for other situations
function calculateElementsHeight(elements) {
var height = 0;
$.each(elements, function(i, elementRaw ){
height += $(elementRaw).height();
})
return height;
}
for(var i = 0; block2elements.length > i; i++) {
block2elements = row2.children('span.block2'); // Get new state of the block2 elements
if(row2.height() < calculateElementsHeight(block2elements)) {
block2elements.last().remove();
}
}

How can I access a DOM element with jQuery that I have "moved" around the page?

I have a page with two areas. There are boxes in each area. If the user clicks on a box in the top area, it gets moved to the bottom and vice versa. This works fine for the first movement. Theoretically, I should be able to move them back and forth between sections as I please.
Box HTML:
<div id="top-area">
<div class="top-box" id="blue-box"></div>
<div class="top-box" id="yellow-box"></div>
<div class="top-box" id="green-box"></div>
</div>
<hr/>
<div id="bottom-area">
<div class="bottom-box" id="red-box"></div>
<div class="bottom-box" id="gray-box"></div>
</div>
I use jQuery.remove() to take it out of the top section and jQuery.append() to add it to the other. However, when I try to move a box back to its original position, the event that I have created to move them doesn't even fire.
jQuery/JavaScript:
$(".top-box").on('click', function ()
{
var item = $(this);
item.remove();
$(this).removeClass("top-box").addClass("bottom-box");
$("#bottom-area").append(item);
});
$(".bottom-box").on('click', function ()
{
var item = $(this);
item.remove();
$(this).removeClass("bottom-box").addClass("top-box");
$("#top-area").append(item);
});
I have verified that the classes I am using as jQuery selectors are getting added/removed properly. I am even using $(document).on() to handle my event. How come my boxes are not triggering the jQuery events after they are moved once?
Please see the Fiddle: http://jsfiddle.net/r6tw9sgL/
Your code attaches the events on the page load to the elements that match the selector right then.
If you attach the listener to #top-area and #bottom-area and then use delegated events to restrict the click events to the boxes, it should work like you expect. See .on: Direct and Delegated Events for more information.
Use the below JavaScript:
$("#top-area").on('click', '.top-box', function ()
{
var item = $(this);
item.remove();
$(this).removeClass("top-box").addClass("bottom-box");
$("#bottom-area").append(item);
});
$("#bottom-area").on('click', '.bottom-box', function ()
{
var item = $(this);
item.remove();
$(this).removeClass("bottom-box").addClass("top-box");
$("#top-area").append(item);
});
Alternatively:
You could also change .on() to .live(), which works for "all elements which match the current selector, now and in the future." (JSFiddle)
JSFiddle
Here's another way you could work it:
function toBottom ()
{
var item = $(this);
item.remove();
item.off('click', toBottom);
item.on('click', toTop);
$(this).removeClass("top-box").addClass("bottom-box");
$("#bottom-area").append(item);
}
function toTop ()
{
var item = $(this);
item.remove();
item.off('click', toTop);
item.on('click', toBottom);
$(this).removeClass("bottom-box").addClass("top-box");
$("#top-area").append(item);
}
$(".top-box").on('click', toBottom);
$(".bottom-box").on('click', toTop);
#top-area, #bottom-area {
height: 100px;
border: 1px solid black;
padding: 10px;
}
.top-box::before {
content: "Top";
}
.bottom-box::before {
content: "Bottom";
}
#blue-box, #red-box, #yellow-box, #green-box, #gray-box {
width: 100px;
cursor: pointer;
float: left;
margin: 0 5px;
text-align: center;
padding: 35px 0;
}
#blue-box {
background-color: blue;
}
#red-box {
background-color: red;
}
#yellow-box {
background-color: yellow;
}
#green-box {
background-color: green;
}
#gray-box {
background-color: gray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="top-area">
<div class="top-box" id="blue-box"></div>
<div class="top-box" id="yellow-box"></div>
<div class="top-box" id="green-box"></div>
</div>
<hr/>
<div id="bottom-area">
<div class="bottom-box" id="red-box"></div>
<div class="bottom-box" id="gray-box"></div>
</div>
This basically removes the listener that switched the object to bottom to a listener that switches the object to the top and viceversa.

set a newly created div on top of the older divs

I have a bunch of divs inside a container. The position of the content divs is relative, because I want them to appear one below the other and their height is unknown.
These divs are created dynamically (appendchild) inside the container div. Now, each div appears on the end (bottom) of the stack but my requirement is that the divs have a "newest first" option too, that is, each new div appears on top, not on bottom of the content divs (if the user selects the "newest first" in the settings).
html:
<div class="container">
<div id="div1" class="content">aaa<br>aaa</div>
<div id="div2" class="content">bbb<br><br>bbb</div>
<div id="div3" class="content">ccc</div>
<div id="div4" class="content">ddd</div>
</div>
css:
.container {
position: absolute;
top: 10px;
left: 10px;
right: 10px;
bottom: 10px;
border: 1px solid red;
}
.content {
position: relative;
top: 0px;
left: 5px;
width: 200px;
height: auto;
border: 1px solid blue;
margin: 3px;
}
http://jsfiddle.net/jk559/1/
so I'd like the end-user visible order to be: div4, div3, div2, div1.
How can I achieve this? (css/js)
preferrably no jquery.
thanks in advice!
Pure css solution:
Use flexbox to achieve this.
.container {
display:flex;
flex-direction:column-reverse;
justify-content: flex-end;
align-content: flex-end;
}
Updated fiddle here.
Read more information here.
try this
theParent = document.getElementById("theParent");
theKid = document.createElement("div");
theKid.setAttribute("id","div5");
theKid.setAttribute("class","content");
theKid.innerHTML = 'eee';
// append theKid to the end of theParent
theParent.appendChild(theKid);
// prepend theKid to the beginning of theParent
theParent.insertBefore(theKid, theParent.firstChild);
Demo Fiddle http://jsfiddle.net/jk559/4/
You can easily do it with JQuery with the following function.
$('.container > div').each(function() {
$(this).prependTo(this.parentNode);
});
UPDATED FIDDLE
As you mentioned in the question, I will try to attain the expected output with the pure javascript.
You can insert content in the beginning simply using .prepend() .
$(".container").prepend("<div id='div5' class='content'>eee</div>");
Demo
JS FIDDLE UPDATED DEMO
Use prepend() to add as first child of an element
/* $( ".container" ).prepend( "Your div with id here" ); */
/* Example */
$( ".container" ).prepend( "<div id='div5' class='content' >div5 on top </div>" );
Take a look at this answer about reordering dom items.
Basically, you have to maintain a state that decides the ordering. When you insert items (see insertItem below) you append or prepend based on the state. When the user selects the newest first option (see newFirst below), you first reverse the dom elements and then flip the state so that subsequent insert happen at the right place.
var newFirst = false;
var list = document.getElementById('my-list');
function newFirst() {
var items = list.childNodes;
var itemsArr = [];
for (var i in items) {
if (items[i].nodeType == 1) { // get rid of the whitespace text nodes
itemsArr.push(items[i]);
}
}
itemsArr.reverse();
for (i = 0; i < itemsArr.length; ++i) {
list.appendChild(itemsArr[i]);
}
newFirst = !newFirst;
}
function insertItem(content) {
var item = document.createElement("div");
item.setAttribute("class","content");
item.innerHTML = content;
if(newFirst) {
list.insertBefore(item, list.firstChild);
} else {
list.appendChild(item);
}
}
try this :
$("div[id*=div]").sort(function(a,b){
if(a.id > b.id) {
return -1;
} else {
return 1;
}
}).each(function() {
var elem = $(this);
$(".container").append(elem);
});
this will sort your divs inside container like this : div4, div3, div2, div1
if you want change the order to : div1, div2, div3, div4 just change if(a.id > b.id) to if(a.id < b.id)
you can add a link called change order then call this code when you click on it

Categories

Resources