Can you group those into one line, I know how to do this without concatenation but with, not working.
$('#vda'+event.target.id).remove();
$('#a'+event.target.id).remove();
$('#'+event.target.id).remove();
$('#da'+event.target.id).remove();
here is your one liner.
$(
'#vda' + event.target.id +
', #a' + event.target.id +
', #' + event.target.id +
', #da' + event.target.id
).remove();
it seems more, but I divided to better readability.
https://api.jquery.com/multiple-selector/ here is the documentation for multiple selector of jQuery
Try this
var str = ['#vda', '#a', '#', '#da'].join(event.target.id + ',') + event.target.id;
$(str).remove();
The join() method joins all elements of an array into a string.
str = arr.join([separator = ','])
or you can use reduce function
var str = ['#vda', '#a', '#', '#da'].reduce(function(p,c, i,arr){
if(i !== arr.length - 1)
return p + event.target.id + ',' + c
else
return p + event.target.id+ ',' + c + event.target.id
});
$(str).remove();
jQuery allows you to select as you do in CSS
So for the sake of an example, if you want to make a selector that matches all divs with test class, and all the p elements as well, in CSS you would select them using:
div.test, p { property:value }
In jQuery, do the same thing:
$("div.test, p").remove()
So you can just replace the div.test, p with whatever you selector you like
Here's a nice reference for CSS selectors
['vda','a','',da].forEach(function(val,key){
$('#'+event.target.id).remove();
})
If you do not have any extra elements with similar IDs, you can try ends with pattern selector:
$("[id$='pattern']")
$("#btn").on("click", function() {
var target = "test"; // e.target.id
$('[id$="test"]').remove();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div>
<div id="test">test</div>
<div id="atest">atest</div>
<div id="datest">datest</div>
<div id="vdatest">vdatest</div>
</div>
<button id="btn">Test</button>
You can try to make an array of all possible combinations and use map + join to get string
$("#btn").on("click", function() {
var target = "test"; // e.target.id
var selector_list = ["#", "#a", "#da", "#vda"];
var el_str = selector_list.map(function(item) {
return item + target;
}).join();
console.log(el_str);
$(el_str).remove();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div>
<div id="test">test</div>
<div id="atest">atest</div>
<div id="datest">datest</div>
<div id="vdatest">vdatest</div>
</div>
<button id="btn">Test</button>
Just for a record, you can do with pure JS selector API in ES6 style as follows;
[...document.querySelectorAll(['#vda','#a','#','#da'].join(",")].forEach(e => e.parentElement.removeChild(e));
Related
this is my code
html :
<input type="text" class="js-input">
<div class="js-autofill"></div>
jquery :
var myarray = ['apple' , 'orange'];
myarray.forEach(element => {
$('.js-autofill').append(
`<div class="js-item" data-value="`+element+`">` +element+ `</div>`
)
})
$(document).on('click','.js-item',function(){
$('.js-input').val($(this).attr('data-value'))
})
problem is .js-item onclick not working at firsttime - it's work when i doubleclick
i can't find why
You need to change .val() to .text() for the div click.
From Docs
The .val() method is primarily used to get the values of form elements such as input, select and textarea. When called on an empty collection, it returns undefined.
$('.js-input').val($(this).text())
2 - Your div string in append has mismatch quotes, the correct order should be as below.
`<div class='js-item' data-value='` + element + `'>` + element + `</div>`
Also its helpful for you to read: When should I use double or single quotes in JavaScript?
Working code below
var myarray = ['apple', 'orange'];
myarray.forEach(element => {
$('.js-autofill').append(
`<div class='js-item' data-value='` + element + `'>` + element + `</div>`
)
})
$(document).on('click', '.js-item', function() {
$('.js-input').val($(this).text())
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" class="js-input">
<div class="js-autofill"></div>
I generate with a loop for every section on my html site a list element.
<section class="page1" id="name1"></section>
<section class="page2" id="name2"></section>
<section class="page3" id="name3"></section>`
In my jQuery function, see below, I create for every section a link.
for( var i = 0; i < sections.length; i++){
_addClass(sections[i], "ops-section")
sections[i].dataset.index = i + 1;
sections[i].id=document.getElementById(sections[i].id);
if(settings.pagination == true) {
paginationList += '<li><a data-index="'
+ (i + 1) + '" href="#' + (i + 1)
+ '"></a><p class="lead">'
+ sections[i].id + '</p></li>';
}
with sections[i].id=document.getElementById(sections[i].id); I want to read out the text behind id, for example: name1. name2, name3 and so on. I want to add the id-name then as text between the p-tag, so that I get the following list element:
<li><a data-index="1" href="#1" class="active"></a><p class="lead">name1</p></li>
but actually I get this:
<li><a data-index="1" href="#1" class="active"></a><p class="lead">[object HTMLElement]</p></li>
Where is my mistake? What's wrong?
I think you are going about this the wrong way and making the code harder to follow in the process. Your issue is that you are concatenating an entire DOM node, rather than a value of one of the attributes of that node because of this line:
sections[i].id = document.getElementById(sections[i].id)
.getElementById() returns a DOM node so later, when you use:
sections[i].id
You aren't referring to the id at all, you are referring to the entire element returned from:
document.getElementById(sections[i].id)
You don't really even need any of that entire line anyway.
If you use a .forEach() loop to enumerate the section elements, you won't have to set up or manage a counter.
If you create the elements via the DOM API (instead of building a string), you can configure each element much more simply and get out of concatenation hell.
Look at the solution below, it's a little more overall code than your solution, but it is so much cleaner and easier to follow.
// Get the section elements into an array
var theSections = Array.prototype.slice.call(document.querySelectorAll("section[class^='page']"));
// Loop over the elements in the array
theSections.forEach(function(section, index){
// Create li, a and p elements
var li = document.createElement("li");
var a = document.createElement("a");
var p = document.createElement("p");
// Configure each new element
a.setAttribute("data-index", index + 1);
a.href = index + 1;
a.classList.add("active");
p.classList.add("lead");
p.textContent = section.id;
// Inject new elements into the DOM
li.appendChild(a);
li.appendChild(p);
document.body.appendChild(li);
// Just for testing
console.log(a, p);
});
<section class="page1" id="name1"></section>
<section class="page2" id="name2"></section>
<section class="page3" id="name3"></section>
Why is it not working?
First, document.getElementById retrieves an HTML element. Then, you are overriding the id in sections[i].id with the HTML element, resulting in [object HTMLElement].
Solution
As suggested by Liora Haydont, simply remove the line sections[i].id=document.getElementById(sections[i].id);.
for( var i = 0; i < sections.length; i++){
_addClass(sections[i], "ops-section")
sections[i].dataset.index = i + 1;
if(settings.pagination == true) {
paginationList += '<li><a data-index="'
+ (i + 1) + '" href="#' + (i + 1)
+ '"></a><p class="lead">'
+ sections[i].id + '</p></li>';
}
In your code you're attaching an entire HTML element to the section id which is why you're getting that error. Scott just beat me with his answer, but I'm in agreement with him. Using forEach will allow you to make your life a little easier.
In this example I'm also using template literals to create the HTML. YMMV, however.
const sections = document.querySelectorAll('section');
const out = document.getElementById('out');
const settings = {
pagination: true
}
sections.forEach((section, i) => {
const index = i + 1;
const id = section.id;
section.classList.add('ops-section');
section.dataset.index = index;
if (settings.pagination) {
const para = `<p class="lead">${id}</p>`;
const li = `<li><a data-index="${index}" href="#${index}" class="active">test</a>${para}</li>`;
out.insertAdjacentHTML('beforeend', li);
}
});
<section class="page1" id="name1">section1</section>
<section class="page2" id="name2">section2</section>
<section class="page3" id="name3">section3</section>
<ul id="out"></ul>
Why not using JQuery ? This is a small demo on how you can get the id attribute of your section and use it in the JQuery code:
$(document).ready(function() {
$('section').each(function( key, value ) {
// alert($(this).attr('id') + " - " + key + ": " + value );
$('pagination').append("<p class='lead'>* <a data-index='"+ key +"' href=#></a>" + $(this).attr('id') + '</p>');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="page1" id="name1"></section>
<section class="page2" id="name2"></section>
<section class="page3" id="name3"></section>
<pagination></pagination>
Suppose you have this for your HTML:
<div class="contentBox">
<p>I have some content that is good to read</p>
</div>
However you would like to add a span tag after a certain amount of characters, lets say 26 characters, which would be right after the word "that". The result would look like this:
<div class="contentBox">
<p>I have some content that<span> is good to read</span></p>
</div>
It has to be after a certain amount of characters, because the paragraph will change from time to time.
Set the amount of characters after you want to set the span. Get text of the p element. Substring from start until the amount of chars, add the span, continue with the rest and add the closing span
Try:
var after=26;
var html = $(".contentBox p").html();
html = html.substring(0, after) + "<span>" + html.substring(after)+"</span>";
$(".contentBox p").html(html);
DEMO
String.prototype.insertTextAtIndices = function (text) {
return this.replace(/./g, function (char, index) {
return text[index] ? text[index] + char : char;
});
};
//usage
var range = {
25: "<span style='color:red'>",
40: "</span>"
};
document.getElementsByTagName("p")[0].innerHTML = document.getElementsByTagName("p")[0].innerHTML.insertTextAtIndices(range);
http://jsfiddle.net/4zx37Lhm/1/
You can make use of JavaScript's substr method.
function addSpan($elems) {
$elems.each(function() {
var $elem = $(this),
text = $elem.text();
if (text.length <= 25)
return;
var start = text.substr(0, 25), // "I have some content that "
end = text.substr(25, text.length); // "is good to read"
$elem.html(start + '<span>' + end + '</span>');
});
}
addSpan($('.contentBox').find('p'));
span {
color: #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="contentBox">
<p>I have some content that is good to read</p>
</div>
<div class="contentBox">
<p>I have some content that is good to read and this is a much longer string!</p>
</div>
Try this : get first part and second part of the string using substring() and modify text with span element to put it into html of p tag.
Below function will iterate all p under contentBox div, but if you are targeting only one div then you can use it without .each()
$(function(){
$('.contentBox p').each(function(){
var text = $(this).text();
var first = text.substring(0,26);
var second = text.substring(26,text.length);
$(this).html(first + '<span>' + second + '</span>');
});
});
DEMO
I'm writing my own blog using Blogger. I want to mark some prominent words. For example, when I write *Red* in an editor. It should automatically add a key class and wrap it with the span tag. So, the final result should be as following:
<span class="key">Red</span>
Now, I am trying to write a JQuery script but it still doesn't work properly.
$markText = $('span').filter(function(){
$t = $(this).text();
return $t.charAt(0) === "*" && $t.charAt(4) === "*"}).each(function() {
$s1 = $t.slice(1,4);
$s2 = $t.slice(5);
$(this).replaceWith('<span class="key">' + $s1+ '</span>' + '<span>'+$s2+'</span>');
});
Please see the demo on jsFiddle
Your code can be fixed by what RaymondM has suggested, but you could try something like this as well:
$markText = $('span').each(function (i, e) {
$e = $(e);
while ($(e).text().indexOf('*') != -1) {
$e.html($e.html().replace('*', '<span class="key">').replace('*', '</span>'));
}
});
This makes use of the fact that the replace method only modifies the first occurrence of the target string.
DEMO
The $t in side the each function should be replaced by $(this).text()
$markText = $('span').filter(function(){
$t = $(this).text();
return $t.charAt(0) === "*" && $t.charAt(4) === "*"}).each(function() {
$s1 = $(this).text().slice(1,4);
$s2 = $(this).text().slice(5);
$(this).replaceWith('<span class="key">' + $s1+ '</span>' + '<span>'+$s2+'</span>');
});
I have a string with multiple elements with id's like below:
var data = "<div id='1'></div><input type='text' id='2'/>";
Now I'm using this regex to find all the id's in the string:
var reg = /id="([^"]+)"/g;
Afterwards I want to replace all those id's with a new id. Something like this:
data = data.replace(reg, + 'id="' + reg2 + '_' + numCompare + '"');
I want reg2, as seen above, to return the value of the id's.
I'm not too familiar with Regular Expressions, so how can I go about doing this?
Instead of using regex, parse it and loop through elements. Try:
var data = "<div id='1'></div><div id='asdf'><input type='text' id='2'/></div>",
numCompare = 23,
div = document.createElement("div"),
i, cur;
div.innerHTML = data;
function updateId(parent) {
var children = parent.children;
for (i = 0; i < children.length; i++) {
cur = children[i];
if (cur.nodeType === 1 && cur.id) {
cur.id = cur.id + "_" + numCompare;
}
updateId(cur);
}
}
updateId(div);
DEMO: http://jsfiddle.net/RbuaG/3/
This checks to see if the id is set in the first place, and only then will it modify it.
Also, it is safe in case the HTML contains a comment node (where IE 6-8 does include comment nodes in .children).
Also, it walks through all children of all elements. In your example, you only had one level of elements (no nested). But in my fiddle, I nest the <input /> and it is still modified.
To get the get the updated HTML, use div.innerHTML.
With jQuery, you can try:
var data = "<div id='1'></div><div id='asdf'><input type='text' id='2'/></div>",
numCompare = 23,
div = $("<div>"),
i, cur;
div.append(data);
div.find("[id]").each(function () {
$(this).attr("id", function (index, attr) {
return attr + "_" + numCompare;
});
});
DEMO: http://jsfiddle.net/tXFwh/5/
While it's valid to have the id start with and/or be a number, you should change the id of the elements to be a normal identifier.
References:
.children: https://developer.mozilla.org/en-US/docs/DOM/Element.children
.nodeType: https://developer.mozilla.org/en-US/docs/DOM/Node.nodeType
jQuery.find(): http://api.jquery.com/find/
jQuery.attr(): http://api.jquery.com/attr/
jQuery.each(): http://api.jquery.com/each/
Try using
.replace(/id='(.*?)'/g, 'id="$1_' + numCompare + '"');
Regex probably isn't the right way to do this, here is an example that uses jQuery:
var htmlstring = "<div id='1'></div><input type='text' id='2'/>";
var $dom = $('<div>').html(htmlstring);
$('[id]', $dom).each(function() {
$(this).attr('id', $(this).attr('id') + '_' + numCompare);
});
htmlstring = $dom.html();
Example: http://jsfiddle.net/fYb3U/
Using jQuery (further to your commments).
var data = "<div id='1'></div><input type='text' id='2'/>";
var output = $("<div></div>").html(data); // Convert string to jQuery object
output.find("[id]").each(function() { // Select all elements with an ID
var target = $(this);
var id = target.attr("id"); // Get the ID
target.attr("id", id + "_" + numCompare); // Set the id
});
console.log(output.html());
This is much better than using regex on HTML (Using regular expressions to parse HTML: why not?), is faster (although can be further improved by having a more direct selector than $("[id]") such as giving the elements a class).
Fiddle: http://jsfiddle.net/georeith/E6Hn7/10/