jQuery Insert closing div tag and opeing div tag after count - javascript

I am trying to get jquery to close a div and inset an opening div with a class after x amount of items.
Here is what I have tried:
$(this).after('</div> <div class=\"bar">Bar');
it outputs:
<div class="bar">Bar</div>
What I need is:
<div class="item2">
<div class="CountThese2"> Count Me </div>
<div class="CountThese2"> Count Me </div>
</div>
<div class="bar">
<div class="CountThese2"> Count Me </div>
<div class="CountThese2"> Count Me </div>
</div>
<div class="bar">
<div class="CountThese2"> Count Me </div>
<div class="CountThese2"> Count Me </div>
</div>
<div class="bar">
<div class="CountThese2"> Count Me </div>
<div class="CountThese2"> Count Me </div>
</div>
http://jsfiddle.net/yoderman94/JEtj2/

You can't add half a tag. I think what you're trying to do is wrap the elements. Your fiddle is pretty messy, but here's a simple example of how you can do that:
http://jsfiddle.net/9Q62H/
while($('#wrapper > a:lt(2)').wrapAll('<div class="bar">bar</div>').length) { }
Which turns this:
<div id="wrapper">
1
1
1
1
1
1
1
1
</div>
into this:
<div id="wrapper">
<div class="bar">bar
1
1
</div>
<div class="bar">bar
1
1
</div>
<div class="bar">bar
1
1
</div>
<div class="bar">bar
1
1
</div>
</div>

You can't manipulate the DOM that way, with or without jQuery. To accomplish the same thing, insert a new div after the current div's parent, and then move all of the current div's following siblings to the new div:
var bar = $("<div>").addClass("bar").text("Bar");
bar.insertAfter($(this).parent());
bar.append($(this).nextAll());
Edit: To preserve text nodes, including the whitespace between your links, it's not quite as simple as $(this).nextAll(), sadly. You need to use .contents() to select the text nodes, then slice at the index of this:
var contents = $(this).parent().contents();
var bar = $("<div>").addClass("bar").text("Bar");
bar.insertAfter($(this).parent());
bar.append(contents.slice(contents.index(this) + 1));
http://jsfiddle.net/JEtj2/6/

I'm going to recommend a different approach here. When you call .after() you need to be giving it a complete open and close tag. You cannot open a tag then close it later like you are trying to above.
My advice would be to try and take an approach like the following, so you can pass a complete open and close tag to .after()
var theDiv = "<div class='bar'>";
for(var i = 0; i < 2; i++) {
theDiv += '<div class="CountThese2"> Count Me </div>';
}
theDiv += "</div>";
$('#thing').after(theDiv);
See how I constructed the whole div including contents before calling .after() ?

Related

Insert div as the .lastElementChild without 'insertBefore' without jQuery

Okay so I've usually had .box-4 as the last element inside of .s1 as shown below:
<div class="s1">
<div class="box-1"></div>
<div class="box-2"></div>
<div class="box-3"></div>
<div class="box-4"></div>
</div>
and had .box-1 move before .box-4 using the JavaScript:
var box1 = document.querySelector('.box-1');
var s1 = box1.parentNode;
s1.insertBefore(box1, s1.lastElementChild);
to receive the following outcome:
<div class="s1">
<div class="box-2"></div>
<div class="box-3"></div>
<div class="box-1"></div>
<div class="box-4"></div>
</div>
however, I have recently removed .box-4 from .s1, and consequently .box-1 no longer move/becomes the .lastElementChild. I would still like .box-1 to move, and hence become last, however, I'm unsure of what command will achieve this; desirably something like this
.insertAs(box1, s1.lastElementChild);
to achieve this:
<div class="s1">
<div class="box-2"></div>
<div class="box-3"></div>
<div class="box-1"></div>
</div>
NOTE: .box-1 changes position depending on screen-width, so simply moving the div in HTML is not an option.
NOTE: Vanilla JavaScript only - No jQquery.
Thanks in advance guys, much appreciated!
Below will append box1 as the last child (automatically removes it from it's original position).
var box1 = document.querySelector('.box-1');
var s1 = box1.parentNode;
s1.appendChild(box1);
To insert HTML without jQuery simply use insertAdjactedHTML function.
https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML
Just use .appendChild?
const box1 = document.querySelector('.box-1');
const s1 = box1.parentElement;
box1.remove();
s1.appendChild(box1);
<div class="s1">
<div class="box-1">b1</div>
<div class="box-2">b2</div>
<div class="box-3">b3</div>
<div class="box-4">b4</div>
</div>

How to know the order number of the child element selected in relation to its parent?

I have a html structure like the following:
<div id="first">
<div id="second">
<div class="inside"></div>
<div class="inside"></div>
<div class="inside"></div>
<div class="inside"></div>
<div class="inside"></div>
</div>
</div>
And the following javascript / jquery code:
$(".inside").mouseover(function(ev){
var el = ev.currentTarget;
//TODO: get real element
var el_position = 1;
});
What I want to do is check the number of ".inside" that is being hovered with the mouse. So, if I hover the first entry of ".inside" it should display "1". In the fourth it should display "4". But accessing the variable "el" (ev.currentTarget) has no "element position" property or anything of the alike that would allow me to understand the position of the actual hovered element in relation to "#second" (the first, second, third, etc .inside).
So, does anyone have any idea? Can I get some help? Thank you very much :)
You can use .index() which returns the 0-based index of the element within a collection
$(".inside").mouseover(function(ev) {
var el = ev.currentTarget;
//TODO: get real element
var el_position = $(el).index(".inside") + 1;
console.log(el_position);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<div id="first">
<div id="second">
<div class="inside">1</div>
<div class="inside">2</div>
<div class="inside">3</div>
<div class="inside">4</div>
<div class="inside">5</div>
</div>
</div>

Reorder divs in javascript without jquery

lets say I have html:
<div id="1">1</div>
<div id="2">2</div>
<div id="3">3</div>
how would I in javascript and not jquery reorder these divs to:
<div id="1">1</div>
<div id="3">3</div>
<div id="2">2</div>
You can use display:flex and the order css (I had to add a letter before the number for your id as SO didn't seem to like it for the css)
.container {display:flex; flex-direction:column}
#s1 {order:1;}
#s2 {order:3;}
#s3 {order:2;}
<div class="container">
<div id="s1">1</div>
<div id="s2">2</div>
<div id="s3">3</div>
</div>
More information about order
More information about flex
Update
Sorry read the question wrong - thought you wanted to do it without js
var div = document.getElementById('3')
div.parentNode.insertBefore(div, document.getElementById('2'))
<div id="1">1</div>
<div id="2">2</div>
<div id="3">3</div>
The solution given by the duplicate questions are incorrect because they make the assumption that the elements are next to each other. But even in this simple example, there is a text node containing white-space between the elements.
Given that the two elements are not nested, you can use this to swap two elements:
function swapElements (first, second) {
var tmpNode = document.createElement('div');
tmpNode.setAttribute('id', '_tmp');
var firstParent = first.parentNode;
firstParent.insertBefore(tmpNode, first);
second.parentNode.insertBefore(second, first);
firstParent.insertBefore(second, tmpNode);
firstParent.removeChild(tmpNode);
}
Use it like:
var first = document.querySelector('#1');
var second = document.querySelector('#2');
swapElements(first, second);

How to wrap div around multiple of the same class elements

I'm trying to wrap multiple same class divs into a div and to skip divs not with the same class. .wrap doesn't combine them, and .wrapAll throws the non-classed divs underneath. I've been tinkering around with attempts to create an alternate solution but with no avail.
Original:
<div class="entry">Content</div>
<div class="entry">Content</div>
<div class="entry">Content</div>
<div>Skip in wrap</div>
<div class="entry">Content</div>
<div class="entry">Content</div>
<div class="entry">Content</div>
continued...
Wanted Result:
<div>
<div class="entry">Content</div>
<div class="entry">Content</div>
<div class="entry">Content</div>
</div>
<div>Skip in wrap</div>
<div>
<div class="entry">Content</div>
<div class="entry">Content</div>
<div class="entry">Content</div>
</div>
You can loop pretty quickly through your <div> elements using a for loop. In the below code, just change the initial selector here to grab all those siblings divs, e.g. #content > div.entry or wherever they are:
var divs = $("div.entry");
for(var i=0; i<divs.length;) {
i += divs.eq(i).nextUntil(':not(.entry)').andSelf().wrapAll('<div />').length;
}​
You can give it a try here. We're just looping through, the .entry <div> elements using .nextUntil() to get all the .entry elements until there is a non-.entry one using the :not() selector. Then we're taking those next elements, plus the one we started with (.andSelf()) and doing a .wrapAll() on that group. After they're wrapped, we're skipping ahead either that many elements in the loop.
I just whipped up a simple custom solution.
var i, wrap, wrap_number = 0;
$('div').each(function(){ //group entries into blocks "entry_wrap_#"
var div = $(this);
if (div.is('.entry')) {
wrap = 'entry_wrap_' + wrap_number;
div.addClass(wrap);
} else {
wrap_number++;
}
});
for (i = 0; i <= wrap_number; i++) { //wrap all blocks and remove class
wrap = 'entry_wrap_' + i;
$('.' + wrap).wrapAll('<div class="wrap"/>').removeClass(wrap);
}
You could alternatively append new divs to your markup, and then append the content you want wrapped into those.
If your markup is this:
<div class="wrap">
<div class="col-1"></div>
<div class="col-1"></div>
<div class="col-1"></div>
<div class="col-1"></div>
<div class="col-1"></div>
<div class="col-2"></div>
<div class="col-2"></div>
<div class="col-2"></div>
<div class="col-2"></div>
<div class="col-2"></div>
</div>
Use the following to append two new divs (column-one and column-two) and then append the appropriate content into those divs:
// Set vars for column content
var colOne = $('.col-1').nextUntil('.col-2').addBack();
var colTwo = $('.col-2').nextAll().addBack();
// Append new divs that will take the column content
$('.wrap').append('<div class="column-first group" /><div class="column-second ground" />');
// Append column content to new divs
$(colOne).appendTo('.column-first');
$(colTwo).appendTo('.column-second');
Demo here: http://codepen.io/zgreen/pen/FKvLH

Counting div elements based on id

I have a page similar to:
<div id="content">
<div id="boxes">
<div id="box:content:1:text" />
<div id="box:content:2:text" />
<div id="another_id" />
<div id="box:content:5:text" />
</div>
</div>
I want to know the number of div with id that matches the expression box:content:X:text (where X is a number). I can use pure javascript or jquery for doing that.
But inside boxes i can have several types of divs that i don't want to count ("another_id") and i can have gaps from the X of an element and the next element, they are not in sequence.
I was searching a way to gets the elements based on a regexp but i haven't found any interesting way. Is it a possibile approach ?
Thanks
jQuery:
$("div[id]").filter(function() {
return !(/^box:content:\d+:text$/.test(this.id));
}).size();
Pure JavaScript:
var elems = document.getElementsByTagName("div"),
count = 0;
for (var i=0, n=elems.length; i<n; ++i) {
if (typeof elems[i].id == "string" && /^box:content:\d+:text$/.test(this.id)) {
++count;
}
}
To expand on Boldewyn's comment, you can provide multiple classes delimited by spaces, and then work with those classes separately or in combination.
This probably removes the need for the ids, but I've left them in just in case:
<div id="content">
<div id="boxes">
<div id="box:content:1:text" class="box content 1 text" />
<div id="box:content:2:text" class="box content 2 text" />
<div id="another_id" />
<div id="box:content:5:text" class="box content 5 text" />
</div>
</div>
And then with jQuery you can count just the desired items with:
$j('#content>#boxes>.box.content.text').length
(or perhaps just use '#boxes>.box.text' or whatever works for what you're trying to match)

Categories

Resources