Create a parent from child elements using javascript - javascript

Say i have a list of ids [[1,2],[4,5,6]]
I am trying to create a parent element for each set of ids, say a div
currently its:
<span id="data-inject">
<br> <br>
<span id=1>Barack</span>
<br> <br>
<span id=2>Obama</span>
<span id=3>xx</span>
<span>
I would like it to be:
<span id="data-inject">
<br> <br>
<div id=test>
<span id=1>Barack</span>
<br> <br>
<span id=2>Obama</span>
</div>
<span id=3>xx</span>
</span>
is there any way to achieve the same using java script?
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id="data-inject"><br> <br> <span id="0">xx</span> <span id="1">Barack</span> <span id="2">Obama</span> <span id="3">xx</span> <span id="4">Barack</span> <span id="5">Obama</span> <span id="6">Barack</span> <span id="7">Obama</span><br> <br> <span id="8">sdsds</span> <span id="9">Barack</span> <span id="10">Obama</span></span>

Try this :
$('#data-inject').find('span').slice(0,2).wrapAll('<div id="test"></div>').after(' ');
Here is a Jsfiddle : https://jsfiddle.net/8L1mutxr/
.after(' ')
add spaces after elements. But your HTML is very dirty by the way.

Using jquery you can easily create a new element for each array item and then loop through the inner array to search and append to the newly create item,
the example should be auto explanatory:
var arr = [[1,2],[4,5,6], [7,8,9,10]]
arr.forEach((x, i) => {
// we create a parent div for each item
var parent = $('<div class="parent'+ i + '"></div>')
// we append it
$('#data-inject').append(parent)
// we loop through inner arrays and append them to newly created 'parent'
x.forEach(z => {
parent.append( $('#' + z) )
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id="data-inject">
<span id="0">xx</span>
<span id="1">Barack</span>
<span id="2">Obama</span>
<span id="3">xx</span>
<span id="4">Barack</span>
<span id="5">Obama</span>
<span id="6">Barack</span>
<span id="7">Obama</span>
<span id="8">sdsds</span>
<span id="9">Barack</span>
<span id="10">Obama</span>
</span>

Related

How to for loop span tags in html/javascript?

How can I condense this many span tags? I am trying to get it as small as possible. Any advice helps, thanks!
<header>
cat <i class="fa-d fa-ct"></i>>
<div class="particle">
<span style="--i:50;"></span>
<span style="--i:21;"></span>
<span style="--i:16;"></span>
<span style="--i:18;"></span>
<span style="--i:13;"></span>
<span style="--i:22;"></span>
<span style="--i:15;"></span>
<span style="--i:24;"></span>
<span style="--i:17;"></span>
<span style="--i:28;"></span>
<span style="--i:12;"></span>
<span style="--i:26;"></span>
<span style="--i:23;"></span>
<span style="--i:13;"></span>
<span style="--i:17;"></span>
<span style="--i:11;"></span>
<span style="--i:21;"></span>
<span style="--i:16;"></span>
</div>
</div>
This is why I am trying to get. Each --i:Number creates a particle at random times.
In case you were looking for a more compact way of generating the HTML, then maybe the following is helpful?
const html=[...new Array(18)].map(_=>`<span style="--i:${Math.ceil(Math.random()*40+10)};"></span>`).join("\n");
console.log(html); // can be commented out ...
document.querySelector(".particle").innerHTML=html;
<header>
cat <i class="fa-d fa-ct"></i>
<div class="particle"></div>
</header>

How to find start and end index of DOM text selection?

In jQuery Terminal I want to add an API that will return indices of the selection.
Example HTML I have:
<div class="cmd" style="width: 100%; --cursor-line:1; top: 0px;">
<div class="cmd-wrapper" style="">
<span class="cmd-prompt" style="visibility: visible; margin-left: 0px;">
<span data-text="> ">
<span style="width: 2ch;">> </span>
</span>
</span>
<div role="presentation" aria-hidden="true" class="cmd-end-line">
<span data-text="H">
<span>H</span>
</span>
<span data-text="e">
<span>e</span>
</span>
<span data-text="l">
<span>l</span>
</span>
<span data-text="l">
<span>l</span>
</span>
<span data-text="o">
<span>o</span>
</span>
<span data-text=" ">
<span> </span>
</span>
<span data-text="W">
<span>W</span>
</span>
<span data-text="o">
<span>o</span>
</span>
<span data-text="r">
<span>r</span>
</span>
<span data-text="l">
<span>l</span>
</span>
<span data-text="d">
<span>d</span>
</span>
<span data-text=" ">
<span> </span>
</span>
</div>
<div class="cmd-cursor-line" role="presentation" aria-hidden="true">
<span>
<span data-text="x">
<span>x</span>
</span>
<span data-text="x">
<span>x</span>
</span>
<span data-text="x">
<span>x</span>
</span>
<span data-text="x">
<span>x</span>
</span>
<span data-text="x">
<span>x</span>
</span>
</span>
<span class="cmd-cursor" style="">
<span data-text="" class="end">
<span> <span></span></span>
</span>
</span>
<span></span>
</div>
</div>
<textarea autocapitalize="off" spellcheck="false" tabindex="1" class="cmd-clipboard" data-cmd-prompt="> " style=""></textarea>
</div>
This is copy-paste of the DOM after entering "Hello World\nxxxxx" and formatted and pretty printed using https://jsonformatter.org/html-pretty-print
My question is what should I do to get the selection indices?
For example, I have a command like this:
> He|lo wor|d
I should get [2, 8] and if the selection is outside of the range: example
>|>> Hello| world
where >>> is prompt I should get [0, 5] I don't care about the negative. I should also handle when the whole selection is outside
|>>>| Hello World
it should return [0, 0] or null.
How would to implement something like this? Note: that I only care about window.getSelection API it's 100% support, not need to be silly and support
IE8.
You want something like
var range = window.getSelection().getRangeAt(0);
var start = range.startOffset;
var end = range.endOffset;
Note that this code assumes that range.startContainer === range.endContainer (which it often does). If you want to get the text / the length of the text between the start and the end containers, you need to recursively traverse the DOM between them. There is also an issue where the length of the text in the DOM is not the same as the length of the text in HTML (browsers sometimes add spaces and other HTML elements)
You'd be right if you guessed that I've worked a bunch in Javascript with selections. IMO it's kind of a nightmare. Tim Down has written a very popular package called Rangy which I recommend it a lot. You should check it out and see if it meets the requirements of what you are doing.
I've solved the issue myself:
var selection = window.getSelection();
var start = $(selection.anchorNode);
var end = $(selection.focusNode);
var before = start.closest('.cmd [role="presentation"]').prevUntil('.cmd-prompt');
var count = 0;
if (before.length > 1) {
count = before.find('[data-text]').length;
}
var s = start.closest('.cmd [role="presentation"] [data-text]');
var e = end.closest('.cmd [role="presentation"] [data-text]');
if ((s.length || e.length)) {
start = count + s.index();
end = count + e.index() + 1;
console.log({start, end});
}

javascript array from existing divs innerHTML

Let's say i create dynamically some divs, each has it's dynamically created id (div0, div1, div2, etc.) and i'd like with a function to pass through currently existent divs and put their innerHTML into an array (one, two, three in this case), how can i achieve this in javascript?
html example:
<div contenteditable="false" id="div0">
one
<span id="one-close">
<i class="material-icons">close</i>
</span>
</div>
<div contenteditable="false" id="div1">
two
<span id="two-close">
<i class="material-icons">close</i>
</span>
</div>
<div contenteditable="false" id="div2">
three
<span id="three-close">
<i class="material-icons">close</i>
</span>
</div>
You could also use spread syntax
const divsContents = [...document.querySelectorAll("div>a")].map(e=>e.innerHTML);
console.log(divsContents);
<div contenteditable="false" id="div0">
one
<span id="one-close">
<i class="material-icons">close</i>
</span>
</div>
<div contenteditable="false" id="div1">
two
<span id="two-close">
<i class="material-icons">close</i>
</span>
</div>
<div contenteditable="false" id="div2">
three
<span id="three-close">
<i class="material-icons">close</i>
</span>
</div>
Using some magic from here, because document.querySelectorAll returns a NodeList and not an array, we can get the div elements into an array and use .map() to return the div content into an array.
var divs = [].slice.call(document.querySelectorAll('div'));
console.log(divs.map(div => div.innerHTML));
<div contenteditable="false" id="div0">
one
<span id="one-close">
<i class="material-icons">close</i>
</span>
</div>
<div contenteditable="false" id="div1">
two
<span id="two-close">
<i class="material-icons">close</i>
</span>
</div>
<div contenteditable="false" id="div2">
three
<span id="three-close">
<i class="material-icons">close</i>
</span>
</div>
Ideally you should be using a selector like #divcontainer > div to fetch all the divs in the container, but if you know all the ID's, you can use a selector such as:
document.querySelectorAll('#div0, #div1, #div2')
you can use jquery or javascript function for get your div:
myArray[0] = document.getElementByID("div0").innerHtml;
myArray[1] = document.getElementByID("div1").innerHtml;
myArray[2] = document.getElementByID("div2").innerHtml;
Give same class to divs and access by $('.class-name') or add a container div and get your div array by $('#divId div').
Use a loop after creating a divs collection using querySelectorAll:
let divs = document.querySelectorAll('div');
let arr = [];
for (let i = 0; i < divs.length; i++) {
arr.push(divs[i].innerHTML);
}
console.log(arr);
<div>hi</div>
<div>hi2</div>
<div>hi3</div>
Here is your solution
var arr = [];
function myFunction() {
var anchors = document.getElementsByTagName("a");
for(var i = 0; i < anchors.length; i++){
arr.push(anchors[i].text);
}
}
console.log(arr);
So many ways of doing this. Yet an other way: using ES6 Array.from
let divsA = Array.from(document.querySelectorAll("[id^='div'] a"));
divsA.map(a => console.log(a.innerHTML));
<div contenteditable="false" id="div0">
one
<span id="one-close">
<i class="material-icons">close</i>
</span>
</div>
<div contenteditable="false" id="div1">
two
<span id="two-close">
<i class="material-icons">close</i>
</span>
</div>
<div contenteditable="false" id="div2">
three
<span id="three-close">
<i class="material-icons">close</i>
</span>
</div>

How can i remove span tags from elements?

I want to remove all the span tags having class article and attach a new span tags to the content
<div class="asd">
<span class="location">Foo</span>
<span class="article">bar</span>
<span class="article">lorem</span>
<span class="article">ipsum</span>
</div>
In the javascript i've a text,
var text = "bar lorem ipsum";
I want javascript to find this in the DOM and if it is there, then remove the span tags from the elements and put all of them in a single span tag, like this
<div class="asd">
<span class="location">Foo</span>
<span class="article">bar lorem ipsum</span>
</div>
Any help would be greatly appreciated.
You can use jQuery each() function for this, check updated snippet below:
var newHTML ='';
$('.asd span.article').each(function(){
newHTML += $(this).text() + " ";
$(this).remove();
})
$('.asd').append("<span class='article'>"+newHTML+"</span>");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="asd">
<span class="location">Foo</span>
<span class="article">bar</span>
<span class="article">lorem</span>
<span class="article">ipsum</span>
</div>
Here you check with jquery:
<div class="asd">
<span class="location">Foo</span>
<span class="article">bar</span>
<span class="article">lorem</span>
<span class="article">ipsum</span>
</div>
Js
$(".article").remove();
$(".asd").append('<span class="article">bar lorem ipsum</span>');
Hope this helps you.
Try this .use with each function jquery .check the class name includes in array .Is not Then pass the the class name to array .
And also added the respected text with eq(0)(first element of same classname)
var arr=[];
$('.asd').children('span').each(function(a){
var cls =$(this).attr('class');
if(!arr.includes(cls)){
arr.push(cls);
}
else{
$('.'+cls).eq(0).text($('.'+cls).eq(0).text()+' '+$(this).text())
$(this).remove()
}
})
console.log($('.asd').html())
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="asd">
<span class="location">Foo</span>
<span class="article">bar</span>
<span class="article">lorem</span>
<span class="article">ipsum</span>
</div>

Get value of a span inside the div when other span is clicked

Here is the structure that I have:
<div class="div1">
<span class="span1">
<span class="span2">X</span>
<span class="span3">some text</span>
</span>
</div>
Question that I have when I click on the span2, is how to pick up via alert for example text of span3?
jQuery
$('.span2').on('click', function() {
var $span3 = $(this).closest('.span1').find('.span3');
console.log($span3.text());
});
Check Fiddle
Vanilla JS
let span2 = document.querySelectorAll('.span2');
Array.from(span2).forEach(function(elem) {
elem.addEventListener('click', function() {
let span3 = this.parentNode.querySelector('.span3');
console.log(span3.innerHTML);
});
});
Check Fiddle
You would need to target the closest parent which is span1 here that contains span3 and then get the text of that element.
Since you're using jQuery you've several choices so you could use .parents() or .siblings() or .next() or also closest() (as shown in Sushanth's answer), to target the related .span3 span :
$('.span2').on('click', function(){
$(this).parents('.span1').find('.span3').text();
//Or
$(this).siblings('.span3').text();
//Or
$(this).next('.span3').text();
})
Hope this helps.
$('.span2').on('click', function(){
console.log( $(this).parents('.span1').find('.span3').text() );
//Or
console.log( $(this).siblings('.span3').text() );
//Or
console.log( $(this).next('.span3').text() );
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="div1">
<span class="span1">
<span class="span2">X</span>
<span class="span3">some text</span>
</span>
</div>
Edit: Changed it if there are mutliple sets.
Here's a JavaScript example using .nextElementSibling property:
SNIPPET
var d1 = document.querySelector('.div1');
d1.addEventListener('click', function(e) {
var txt = e.target.nextElementSibling.textContent;
alert(txt);
}, false);
.span2 {
border: 1px solid black;
}
.span3 {
pointer-events: none
}
<div class="div1">
<span class="span1">
<span class="span2">X</span>
<span class="span3">some text 1</span>
</span>
<br>
<span class="span1">
<span class="span2">X</span>
<span class="span3">some text 2</span>
</span>
<br>
<span class="span1">
<span class="span2">X</span>
<span class="span3">some text 3</span>
</span>
<br>
<span class="span1">
<span class="span2">X</span>
<span class="span3">some text 4</span>
</span>
</div>

Categories

Resources