I have this HTML:
<div class="chip">java<span class="material-icons close">×</span></div>
<div class="chip">spring<span class="material-icons close">×</span></div>
<div class="chip">python<span class="material-icons close">×</span></div>
With the following script I try to retrieve the texts without the x. I get the values of the div elements using their class name, but when passed to split it, the same string returns without any split:
var skills = $('.chip').text();
var arr = skills.split('x');
for(var i=0;i<arr.length;i++){
alert(arr[i]);
}
For example:
var skills = 'javaxspringxpython';
The output remains the same. I know this is because of the .text() method, but not sure how to solve this. I tried using .val(), but that didn't work.
How can I resolve this?
Your HTML has already three separate elements.
Instead of splitting the combined text, you could get the individual contents of the tags, and kick out any other tags from that content (the span elements in your case). Then you will have three matching text nodes, which you then need to map to array items:
var skills = $('.chip').contents().filter(function() {
return this.nodeType === 3; // only immediate text in div, not in span
}).map(function() {
return $(this).text();
}).get();
console.log(skills);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="chip">java<span class="material-icons close">×</span></div>
<div class="chip">spring<span class="material-icons close">×</span></div>
<div class="chip">python<span class="material-icons close">×</span></div>
Its Work For Me..
$(document).ready(function() {
var skills = $('.chip').text();
var arr = skills.split('x');
for(var i=0;i<arr.length;i++){
// alert(arr[i]);
console.log(arr[i]);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='chip'>javaxspringxpython</div>
Hope Its Work !!!
Happy Coding !!
Related
EDIT: I changed the var to class but I might have some error in here.
Here it goes, I want to have this paragraph in which the user can change the name on the following paragraph. The code I'm using only changes one name but the rest remains the same.
<script type="text/javascript">
function changey(){
var userInput = document.getElementById('userInput').value;
var list = document.getElementByClassName('kiddo');
for (let item of list) {
item.innerHTML = userInput;
}
}
</script>
<input id="userInput" type="text" value="Name of kid" />
<input onclick="changey()" type="button" value="Change Name" /><br>
Welcome to the site <b class="kiddo">dude</b> This is how you create a document that changes the name of the <b class="kiddo">dude</b>. If you want to say <b class="kiddo">dude</b> more times, you can!
No error messages, the code only changes one name instead of all three.
Use class="kiddo" instead of id in the html.
You can then use var kiddos = document.getElementsByClassName('kiddo') which will return an array of all the elements of that class name stored in kiddos.
Then you just need to loop through the values and change what you want.
Example of loop below:
for (var i = 0; i < kiddos.length; i++) {
kiddos[i].innerHTML = userInput;
}
id should be unique on the page. Javascript assumes that there is only one element with any given id. Instead, you should use a class. Then you can use getElementsByClassName() which returns an entire array of elements that you can iterate over and change. See Select ALL getElementsByClassName on a page without specifying [0] etc for an example.
Hello You should not use id, instead use class.
Welcome to the site <b class="kiddo">dude</b> This is how you create a document that changes the name of the <b class="kiddo">dude</b>. If you want to say <b class="kiddo">dude</b> more times, you can!
After That on Js part :
<script type="text/javascript">
function changey(){
var userInput = document.getElementById('userInput').value;
var list = document.getElementByClassName('kiddo');
for (let item of list) {
item.innerHTML = userInput;
}
}
</script>
you should use class instated of id. if you use id then the id [kiddo] must be unique
In short, document.querySelectorAll('.kiddo') OR
document.getElementsByClassName('kiddo') will get you a list of elements to loop through. Take note of querySelectorAll, though - it uses a CSS selector (note the dot) and doesn't technically return an array (you can still loop through it, though).
See the code below for some full working examples (const and arrow functions are similar to var and function, so I'll put up a version using old JavaScript, too):
const formEl = document.querySelector('.js-name-change-form')
const getNameEls = () => document.querySelectorAll('.js-name')
const useNameFromForm = (formEl) => {
const formData = new FormData(formEl)
const nameValue = formData.get('name')
const nameEls = getNameEls()
// Set the text of each name element
// NOTE: use .textContent instead of .innerHTML - it doesn't get parsed, so it's faster and less work
nameEls.forEach(el => el.textContent = nameValue)
}
// Handle form submit
formEl.addEventListener('submit', (e) => {
useNameFromForm(e.target)
e.preventDefault() // Prevent the default HTTP request
})
// Run at the start, too
useNameFromForm(formEl)
.name {
font-weight: bold;
}
<!-- Using a <form> + <button> (submit) here instead -->
<form class="js-name-change-form">
<input name="name" value="dude" placeholder="Name of kid" />
<button>Change Name</button>
<form>
<!-- NOTE: Updated to use js- for js hooks -->
<!-- NOTE: Changed kiddo/js-name to spans + name class to remove design details from the HTML -->
<p>
Welcome to the site, <span class="js-name name"></span>! This is how you create a document that changes the name of the <span class="js-name name"></span>. If you want to say <span class="js-name name"></span> more times, you can!
</p>
var formEl = document.querySelector('.js-name-change-form');
var getNameEls = function getNameEls() {
return document.querySelectorAll('.js-name');
};
var useNameFromForm = function useNameFromForm(formEl) {
var formData = new FormData(formEl);
var nameValue = formData.get('name');
var nameEls = getNameEls(); // Set the text of each name element
// NOTE: use .textContent instead of .innerHTML - it doesn't get parsed, so it's faster and less work
nameEls.forEach(function (el) {
return el.textContent = nameValue;
});
};
// Handle form submit
formEl.addEventListener('submit', function (e) {
useNameFromForm(e.target);
e.preventDefault(); // Prevent the default HTTP request
});
// Run at the start, too
useNameFromForm(formEl);
<button class="js-get-quote-btn">Get Quote</button>
<div class="js-selected-quote"><!-- Initially Empty --></div>
<!-- Template to clone -->
<template class="js-quote-template">
<div class="js-quote-root quote">
<h2 class="js-quote"></h2>
<h3 class="js-author"></h3>
</div>
</template>
You have done almost everything right except you caught only first tag with class="kiddo".Looking at your question, as you need to update all the values inside tags which have class="kiddo" you need to catch all those tags which have class="kiddo" using document.getElementsByClassName("kiddo") and looping over the list while setting the innerHTML of each loop element to the userInput.
See this link for examples:https://www.w3schools.com/jsref/met_document_getelementsbyclassname.asp
try:
document.querySelectorAll('.kiddo')
with
<b class="kiddo">dude</b>
So basically every time I click on the icon '.favorite i' it should add an object to my array. If I click the first time it adds the parent div to the array, but on the second time it deletes the first one and grabs the last parent div.
I'm working with three tabs called 'Monday', 'Tuesday' and 'Favorites'. I have a toggle icon which is an empty heart at start 'favorite i'. If I'm in Monday and click on the icon, the empty heart turns to be filled out and its parent is cloned and added to the '#fav' tab. When this happens the clone is saved to local storage. So if people refresh the page, they can still see their preferences.
When the heart is clicked in one of those cloned divs that specific div is removed from '#fav' and will also have to be removed from the array and local storage too.
To conclude, I need to save each cloned div into an array/local storage and then be able to delete each one of those from the array when these are removed from the #fav tab.
How to overcome this issue? Many thanks.
HTML
<div class="container">
<div class="tabs_main">
<div class="col-md-5"><a data-target="#mon" class="btn active" data-toggle="tab">Monday</a></div>
<div class="col-md-5"><a data-target="#tue" class="btn active" data-toggle="tab">Tuesday</a></div>
<div class="col-md-2"><a data-target="#fav" class="btn active" data-toggle="tab"><i class="fa fa-heart" aria-hidden="true"></i></a></div>
</div>
<div class="tab-content">
<div class="tab-pane active" id="mon">
<br>
<div class="spaces">
<div class="box-container">
<div class="box not-selected" id="box1">
<i class="fa fa-heart-o" aria-hidden="true"></i>
</div>
<div class="box-container">
<div class="box not-selected" id="box2">
<i class="fa fa-heart-o" aria-hidden="true"></i>
</div>
</div>
</div>
<div class="tab-pane" id="tue">
<br>
<div class="spaces">
</div>
</div>
<div class="tab-pane" id="fav">
<br>
</div>
</div>
</div>
JS
$('div.tab-pane').on('click', '.favorite', function(e) {
var add = $(this).parent().parent();
add.each(function(){
if ($(add.find('.not-selected .favorite i').hasClass('fa-heart'))) {
var boxContent = $(add).clone(true, true);
var showHide = $(boxContent).find(".session").addClass('selected').removeClass('not-selected');
var get = $(boxContent).wrap('<p/>').parent().html();
$(boxContent).unwrap();
var tempArray = [];
tempArray.push(get);
var myJSONString = JSON.stringify(get);
var parseString = $.parseJSON(myJSONString);
var finalString = myJSONString.replace(/\r?\\n/g, '').replace(/\\/g, '').replace(/^\[(.+)\]$/,'$1').replace (/(^")|("$)/g, '');
var final = localStorage.setItem('sessions', finalString);
$("#fav").append(tempArray);
};
});
});
Fiddle: https://jsfiddle.net/itsfranhere/nbLLc3L0/44/
Your question title is quite clear...
But your question itself and the code you provide prevents anyone to answer with full assurance.
Here is what the provided code produces, as an attempt to reproduce.
Now if I do not bother that code, which I think no one can deduct what it should do exactly...
Your question in title can be can answered by:
Simple! You declare (using var) the tempArray at every click.
That is why it do not retain the information (whatever it is supposed to retain) of the previous click.
I'm not "satisfied" of this answer to you... So if this do not answers completely your issue, please edit your question with more details. Feel free to fork the CodePen to make it look more like your project.
EDIT
From what I get of your script, you want to save "favorited" divs to localstorage. This implies you also have to remove them from localstorage and favorites tab if one is "unfavorited".
Also, you use id on "to be cloned" element. Be extremely cautious with this. An id has to be unique. So if the id is usefull (which was not obvious in the provided code), ensure you make it unique when you clone the element.
I improved you attempt to remove spaces and line feeds in what is to be saved.
Another good advise I have to give you is to use significative variable names in your code. Make your code speak by itself. Readability helps!
Here is your code, updated to do what is mentionned above. Have a close look to comments in code.
var tempArray = [];
// Clones
$('div.tab-pane').on('click', '.favorite', function(e) {
e.preventDefault();
// Elements we play with... Having significative variable names.
var heartLink = $(this);
var box = heartLink.parent('.box');
var container = box.parent('.box-container');
var favoriteTab = $("#fav .spaces");
// I don't know what is the use for those 3 lines below.
var idFind = box.attr("id");
var idComplete = ('#' + idFind);
console.log(idComplete);
//TOGGLE FONT AWESOME ON CLICK
heartLink.find('i').toggleClass('fa-heart fa-heart-o'); // .selected or not, you need those 2 classes to toggle.
box.toggleClass("selected not-selected"); // Toggle selected and not-selected classes
// Clone div
var boxContent = container.clone(true, true);
// Change the id
var thisID = boxContent.attr("id")+"_cloned";
boxContent.attr("id", thisID);
// Get the html to be saved in localstorage
var get = boxContent.wrap('<p>').parent().html();
get = get.replace(/\r?\n/g, "").replace(/>\s*</g, "><"); // remove line feeds and spaces
console.log(get);
boxContent.unwrap();
// Decide to add or remove
if(box.hasClass("selected")){
console.log("Add to array")
tempArray.push(get);
// Add to favorites tab
favoriteTab.append(boxContent);
}else{
console.log("Remove from array");
var index = tempArray.indexOf(get);
tempArray.splice(index);
// Remove from favorite tab
favoriteTab.find("#"+thisID).remove();
}
// Save
localStorage.setItem('sessions', tempArray.join(""));
});
// Append item if localstorage is detected
if (localStorage["sessions"]) {
$("#fav .spaces").append(localStorage["sessions"]);
console.log( localStorage.getItem('sessions') );
}
Updated CodePen
Don't save div elements in localStorage. I recommend you use an object constructor function like below to create a unique object for each [whatever] pushing these into an array then to localStorage in a try block.
localStorage.setItem('myobjects', JSON.stringify(myobjects));
// Object Constructor Functions
function Myobject(id, username, password) {
this.id = id;
this.username = username;
this.password = password;
this.type = 'credential';
}
function duplicate(id,obj){
var result = false;
obj.forEach( function (arrayItem){
if (arrayItem.id == id){
result = true;
}
});
return result;
}
function deleteObject(type, id){
var obj = {};
if (type === 'foo') {
obj = myobjectwhatever;
deleteThis(obj);
//save to local storage
try {
localStorage.setItem('myobject', JSON.stringify(myobjects));
}
catch (e) {
console.log(e);
}
}
else if (type === 'bar') {
//...
}
function deleteThis(o){
try {
for (var i = 0, iLen = o.length; i < iLen; i++) {
if (o[i].id === id) {
o.splice(i, 1);
}
}
}
catch (e) {
console.log(e);
}
}
}
I am using both html and velocity and came up with this code. The names and images are stored in an array and this is the code I used to display each of the contents of this array to the page.
#foreach($starter in $starter)
<div class="product">
<div class="color"><img src= "$starter.img" width="100" height="100"></div>
<span class="product-name">$starter.name</span>
<div class="compare-wrap">
<input type="checkbox" id="">
<label id="view">Compare</label>
</div>
</div>
#end
I wanted the label to change from "Compare" to "View Compare" while at the same time storing its id in the array upon checking their correspondng check box. I eventually came up with this code:
var checkedArray = [];
$(":checkbox").change(function(){
if((this).checked){
checkedArray.push(this.id);
document.getElementById('view').innerHTML = "<a href='/compare'>View Compare</a>";
}
else{
checkedArray.splice(checkedArray.indexOf(this.id), 1);
document.getElementById('view').innerHTML = 'Compare';
}
var str = checkedArray.join(', ');
alert(str);
});
but it seems it is only applicable to the first content of the array. Any idea how I can use a foreach code at this point?
document.getElementById() only supports one name at a time and only returns a single node not an array of nodes. You should use a class:
var views = document.getElementsByClassName('view');
var i = views.length;
while(i--) {
views[i].innerHTML = "Compare";
}
HTML
<label class="view">Compare</label>
Element ID must be unique.
Hope it helps.
This is the html code:
<div id="sm-responsive-one">
<p> Step one </p>
<div style="">1</div>
<div style="">2</div>
<div style="">3</div>
<div style="">4</div>
</div>
<div id="sm-responsive-two">
<p> Step two </p>
<div style="">5</div>
<div style="">6</div>
<div style="">7</div>
<div style="">8</div>
</div>
Problem: I want to make 1,2,3 and 4 (child element of sm-responsive-one read color using JavaScript and without using any loop. Is it possible?
This is the code I am trying:
<script>
document.getElementById("sm-responsive-one").getElementsByTagName("div").style.color="red";
//document.getElementById("sm-responsive-one").getElementsByTagName("div")[2].style.color="red";
</script>
You need to use a loop, as getElements* return pseudo-arrays.
If you don't want to use the literal loop syntax, you could apply Array.prototype.forEach, but that's still a loop internally.
var children = document.getElementById("sm-responsive-one").getElementsByTagName("div");
Array.prototype.forEach.call(children, function (it) {
it.style.color="red";
});
First add this CSS rule:
.red-children div {color: red}
Then the javascript is:
document.getElementById('sm-responsive-one').className = "red-children"
getElementsByTagName returns HTML elements collection, so you need to iterate over them:
var elements = document.getElementById("sm-responsive-one").getElementsByTagName("div");
for( var i = 0, len = elements.length; i < len; i++ ) {
elements[ i ].style.color = 'red';
}
Try this:
$("#sm-responsive-one > div").css("color","red");
Check this fiddle:
http://jsfiddle.net/v6xxws1z/
i have for example this:
<td "class=name">
<span class="removed">one</span>
<span class="added">two</span>
</td>
or this:
<td class=name> one
<span class="removed">two</span>
<span class="added">three</span>
</td>
or this:
<div>
one
<span class="added">two</span>
three four
<span class="removed">five</span>
six
</div>
and want to change it with JavaScript (without JQuery) to this:
<td "class=name">
two
</td>
or this:
<td class=name>
one
three
</td>
or this:
<div>
one
two
three
four
six
</div>
can't figure it out. and only found a lot of jquery stuff like replaceWith and so on, but need pure javascript for it
Here is the best and easiest method that only requires one line of code and uses jQuery:
$('.added').contents().unwrap();
Breakdown:
$('.added') = Selects the element with the added class.
.contents() = Grabs the text inside the selected element.
.unwrap() = Unwraps the text removing the <span> and </span> tags while keeping the content in the exact same location.
If all the span tags you have that you want removing have a class of removed or added and testing them using the class doesn't affect any of your other html you could try this.
var spans = document.getElementsByTagName("span");
for(var i=0; i<spans.length;i++)
{
if(spans[i].className == "added")
{
var container = spans[i].parentNode;
var text = spans[i].innerHTML;
container.innerHTML += text;
container.removeChild(spans[i]);
}
else if(spans[i].className == "removed")
{
var container = spans[i].parentNode;
container.removeChild(spans[i]);
}
}
Otherwise you need to find a way by ID or class name perhaps to grab the container of the span tags and do something similar. For instance like this
var myDiv = document.getElementById("myDiv");
var spans = myDiv.getElementsByTagName("span");
for(var i=0; i<spans.length;i++)
{
if(spans[i].className == "added")
{
var text = spans[i].innerHTML;
}
myDiv.innerHTML += text;
myDiv.removeChild(spans[i]);
}
Hope this helps
EDIT
Try here for an idea of how to implement this code using a getElementsByClassName() function which might simplify this. It returns an array like getElementsByTagName() does which you can iterate over.
You can remove any html class with the following code:
<div id="target_div">one<span class="added">two</span>three four<span class="removed">five</span>six</div>
<script type="text/javascript">
function remove_html_tag(tag,target_div){
var content=document.getElementById(target_div).innerHTML;
var foundat=content.indexOf("<"+tag,foundat);
while (foundat>-1){
f2=content.indexOf(">",foundat);
if (f2>-1) {content=content.substr(0,foundat)+content.substr(f2+1,content.length);}
f2=content.indexOf("</"+tag+">",foundat);
if (f2>-1){content=content.substr(0,f2)+content.substr(f2+3+tag.length,content.length);}
foundat=content.indexOf("<"+tag,foundat);
}document.getElementById(target_div).innerHTML=content;}
</script>
Remove span tag