jQuery - Find and remove multiple attributes of divs - javascript

I am trying to find all divs with class "comment-like" that also has "data-id" attributes equals to 118603,1234,1234,118601,118597 and if some div contains one of these data value, then remove that data attribute.
So far I created this, but it is not working currently.
remove_comments = 118603,1234,1234,118601,118597;
$('.comment-like').find('[data-id="' + remove_comments + '"]').removeAttr('data-id');

You can dynamically create a query string to capture all the divs you are looking for. The query string would look like this:
.comment-like[data-id="118603"], .comment-like[data-id="1234"], etc...
var ids = [118603, 1234, 1234, 118601, 118597];
var queryString = ids
.map(function(id) {
return '.comment-like[data-id="' + id + '"]';
})
.join(', ');
$(queryString).each(function(i, el) {
$(el).removeAttr('data-id');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="comment-like" data-id="118603"></div>
<div class="comment-like" data-id="1234"></div>
<div class="comment-like" data-id="0"></div>

Easy solution is just loop through your ids
remove_comments = 118603,1234,1234,118601,118597;
rc = remove_comments.split(",");
for (var i = 0; i < rc.length; i++) {
$('.comment-like').find('[data-id="' + rc[i] + '"]').removeAttr('data-id');
}

If you open the developer console in Chrome and typ this in:
remove_comments = 118603,1234,1234,118601,118597;
remove_comments
You can see what is actually happening.
One approach that should work is to put it in an array, and then loop over it:
var remove_comments = [118603,1234,1234,118601,118597];
for (var i = 0; i < remove_comments.length; i++) {
$('.comment-like').find('[data-id="' + remove_comments[i] + '"]').removeAttr('data-id');
}

Related

Why my Layout Position changes when i use appendChild() method?

I am changing the text content in <p> tags. While setting the new text content to <p> tags, the sequence of <p> tags is changing.
Is there any way to fix the issue ?
var userInput = "optin-monster";
var all_script = "Benedict_Cumberbatch ";
var all=$("p:contains(" + userInput + ")").attr('id', 'xyz');
var len_all=$('p').length;
var all_array=[];
for (var i=0; i < len_all; i++) {
all_array.push($(all[i]).text());
}
all_array = all_array.filter(item => item);
changed_array=[];
for (var i = 0; i < all_array.length; i++)
{
var indexEqu=all_array[i].indexOf("=");
var slicedVal=all_array[i].slice(indexEqu+2,indexEqu+22);
var result = all_array[i].replace(all_array[i],all_script);
var out=result+slicedVal+" Enrique_Iglesias";
changed_array.push(out);
}
for (j= 0, n = changed_array.length; j< n; j++) {
var line = document.getElementById("xyz");
line.innerHTML = changed_array[j];
document.body.appendChild(line);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>vmware</p>
<p>[optin-monster slug="wxjxpdi2nhbn7xlmmljo"]</p>
<p>product design</p>
<p>[optin-monster slug="i2nlmmljodhbn7wxjxpx"]</p>
<p>[optin-monster slug="mljodhbn7wxji2nlmxpx"]</p>
Purpose : The changed paragraph tags should be in there actual positions after getting new text content.
Expected :
vmware
Benedict_Cumberbatch wxjxpdi2nhbn7xlmmljo Enrique_Iglesias
product design
Benedict_Cumberbatch i2nlmmljodhbn7wxjxpx Enrique_Iglesias
Benedict_Cumberbatch mljodhbn7wxji2nlmxpx Enrique_Iglesias
From the description of the expected output in the question, your goal is to update the content of the elements in place. As such you don't need to use appendChild(). You can edit the element's content in-place.
In addition, as you've included jQuery in the page already you may as well use it to simplify the logic. You can provide a function to text() which accepts the existing text as an argument, retrieves the slug value from it and returns that with the added prefix/suffix.
To get the slug value you can use a regular expression which you simply concatenate the other string values to:
let userInput = "optin-monster";
let prefix = "Benedict_Cumberbatch";
let suffix = "Enrique_Iglesias"
$(`p:contains(${userInput})`).text((i, t) => {
let slug = t.match(/(?:"[^"]*"|^[^"]*$)/)[0].replace(/"/g, '');
return `${prefix} ${slug} ${suffix}`;
});
// non-es6 version
/*
$('p:contains(' + userInput + ')').text(function(i, t) {
let slug = t.match(/(?:"[^"]*"|^[^"]*$)/)[0].replace(/"/g, '');
return prefix + ' ' + slug + ' ' + suffix;
});
*/
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>vmware</p>
<p>[optin-monster slug="wxjxpdi2nhbn7xlmmljo"]</p>
<p>product design</p>
<p>[optin-monster slug="i2nlmmljodhbn7wxjxpx"]</p>
<p>[optin-monster slug="mljodhbn7wxji2nlmxpx"]</p>
Also note that I removed the part of the logic where you set the same id on all the elements. This is invalid as id must be unique. If you need a method of identifying these elements as a group, use a class.

Best ways to transform a text on an html page

I need to replace some words on an HTML page with links, i.e. "linkify" these words. I have an array of identifier descriptors, like this:
var symbols_desc = [
{
id: 'id_one',
name: 'struct my_struct_one',
},
{
id: 'id_two',
name: 'my_name_two',
},
/* ... */
]
So in certain areas of HTML page I need to transform all occurrences of struct my_struct_one to struct my_struct_one, etc.
I'm not an expert in the Web field, so, I use probably the dumbest way: I update HTML by means of jQuery. Like this:
$(document).ready(function() {
$(".some-class1, .some-class2").each(function() {
var o = $(this);
symbols_desc.forEach(function(desc){
o.html(
o.html().replace(
new RegExp('(\\b' + desc.name + '\\b)', 'g'),
'<a class="symb-link" href="#' + desc.id + '">$1</a>'
)
);
});
});
});
It works, but it is unacceptably slow. There are about 70 identifiers, HTML page is about 200 KB, and it takes about 5 seconds.
Given the complexity and awesomeness of some Web applications that I use from time to time, I'm sure there should be better ways to perform this simple task. I'd be glad to hear your suggestions.
In your case I think all we have do is to change comfortable forEach to simple for and use more variables, so please try:
$(".some-class1, .some-class2").each(function() {
var html = $(this).html();
for (var i = 0; i < symbols_desc.length; i++) {
html.replace(
new RegExp('(\\b' + symbols_desc[i].name + '\\b)', 'g'),
'<a class="symb-link" href="#' + symbols_desc[i].id + '">$1</a>'
);
}
$(this).html(html);
});
First off, no need to use jQuery. It probably contributes to slowing everything down. Get your HTML areas by using
var fooElements = document.querySelectorAll('.someclass1, .someclass2')
This returns a nodelist, and array like object, that can be looped using a normal for.
Also, your dictionary doesn't have to be an array.
var symbols_desc = {
'id_one' : 'struct my_struct_one',
'id_two' : 'my_name_two'
}
Now we can have one regex to replace everything in one go per html element you want to work on, instead of looping n * m times
var fooRegex = new RegExp(Object.keys(symbols_desc).join("|"),"gi");
All that remains is to do the actual work
for(var i = 0; i < fooElements.length; i++){
fooElements[i].innerHTML = fooElements[i].innerHTML.replace(fooRegex,function(matchedString){
return mapObj[matchedString.toLowerCase()];
});
}
Working example, it should be pretty fast:
var dictionary = {
'mouse': 'cat',
'dog': 'mouse',
'horse': 'dog',
'cat': 'horse'
}
var fooElements = document.querySelectorAll('.some-class1, .some-class2');
var fooRegex = new RegExp(Object.keys(dictionary).join("|"), "gi");
for (var i = 0; i < fooElements.length; i++) {
fooElements[i].innerHTML = fooElements[i].innerHTML.replace(fooRegex, function(matchedString) {
return dictionary[matchedString.toLowerCase()];
});
}
<div class="some-class1">
Dog, cat, mouse
</div>
<div class="some-class2">
Horse, cat, dog
</div>

how to loop though div and get each value

I am trying to figure out how to get each value within my div. I am using
var cart = $('.basic-cart-cart-node-title.cell').text();
It is giving the results of OI-01OP-01OS-10-5SOR-04OR-05
I need to view them one by one: OI-01, OP-01, OS-10-5S, OR-04 OR-05.
So that I can match them against another field.
If you care to help me further, I have another div on the page:
var ParNum = $('.assess-title').text();
I would like to compare the values returned from the var cart and see if that value is in the ParNum. If it is there, I would like to apply a class.
Any help would be greatly appreciated.
Thanks!
You can store the values in an array using .map() method:
var values = $('.basic-cart-cart-node-title.cell').map(function() {
return $.trim( $(this).text() );
}).get();
For checking existence of the ParNum value in the array:
var does_exist = values.indexOf(ParNum) > -1;
Try this to iterate over elements:
var text = '';
$('.basic-cart-cart-node-title.cell').each(function (i, div) {
text += ' ' + $(div).text();
});
or this to get an array of matching div elements:
var divs = $('.basic-cart-cart-node-title.cell').toArray();
for (var i = 0; i < divs.length; i++) {
// $(div).text();
}
Reason for this is that $('.basic-cart-cart-node-title.cell') returns all div's at once, and you need to loop through the result. More specifically, $(selector) returns a so-called "wrapped set". It can be used to access each matching element (as I've shown above) or it can be used to apply any other jQuery function to the whole set at once. More info here.
var text = "";
$('.basic-cart-cart-node-title.cell').each(function(){
text += $(this).text() + ", ";
});
// remove the last ", " from string
text = text.substr(0, text.length -2);
var cart = [];
$('.basic-cart-cart-node-title.cell').each(function {
cart.push($(this).text());
}
This performs the matching and class adding you mentioned in the question.
var ParNum = $('.assess-title').text();
$('basic-cart-cart-node-title.cell').each(function () {
if ($(this).text() == ParNum) {
$(this).addClass("someclass");
}
}
You should try using
var cart ='';
$('.basic-cart-cart-node-title'.find('.cell').each(function()
{
cart = cart + $(this).val();
});
Hope it works for you.
var cart = $('.basic-cart-cart-node-title.cell').text().match(/.{5}/g);
This will give you an array with items 5 chars long. Regexes arent very fast, but a loop might be slower
Or easier to read, and in a string with commas:
var cart = $('.basic-cart-cart-node-title.cell').text(); // get text
cart = cart.match(/.{1,5}/g); // split into 5 char long pieces
cart = cart.join(",",); join on comma

DOM element not being found after cloning and appending unique ID

So I'm creating a random string value:
var randomString = function(stringLength) {
var i = 0;
stringLength = stringLength || 10;
var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz';
var randomString = '';
for (i = 0; i < stringLength; i += 1) {
var rNum = Math.floor(Math.random() * chars.length);
randomString += chars.substring(rNum, rNum + 1);
}
return randomString;
};
And associating it with a list element on one pane:
var addUniqueId = function($thumbnail) {
var random = randomString(10);
$thumbnail.attr('id', 'rand-' + random);
};
And then cloning it and moving that list element to the right:
var cloneImage = function($thumbnail) {
addUniqueId($thumbnail);
var $lastImgAdded = $('.js-gallery-edit-pane li').last();
var span = $('<span />');
span.addClass('x').text('x');
var $clone = $thumbnail.clone(true, true).appendTo($('.js-gallery-edit-pane')).prepend(span).hide().fadeIn(200).unbind('click');
bindRemoveHandler($clone);
};
Then I add an overlay to the list element on the left to "gray" it out. Everything works at this point.
From there, a user can remove the recently cloned items on the right hand side by clicking the "X" on the image. This works fine and removes that recently cloned image, however, the original overlay is not being found. It should be associated with the random string value, so I'm just looking for that in $('.js-gallery-select-pane').find('#rand-' + string).find('.overlay').remove(); but for some reason it's not finding it...
Any idea why?
JSFiddle Demo
If you put an alert(string) in your code, you will see that the string already includes rand- so in your selector just do:
$('.js-gallery-select-pane').find('#' + string).find('.overlay').remove();
Here is the working JSFiddle
You have two collections of elements with ID pairs in them.
There's three problems though. The first two problems problem are here..
You were taking the complete id of the clone 'rand-etctcetc'
then adding rand- to it again 'rand-rand-etcetcetc' then using it as a selector. $('rand-rand-etcetcetc'). Instead I changed it to just add the neccessary # to the id. You also need to remove the js-gallery-editing class in order to let you add things back to the list on right hand side.
var bindRemoveHandler = function($thumbnail) {
$thumbnail.on('click', function() {
$(this).fadeOut(200, function() {
var string = $(this).attr('id');
$('.js-gallery-select-pane').find('#' + string).removeClass('js-gallery-editing').find('.overlay').remove();
$(this).remove();
updatePictureCount();
});
});
};
You could stop here but, you also have a different problem. The ID attribute is intended to be unique. Try using a custom attribute and the Jquery attribute equals selector. The query you want would look something like this..
$('.js-gallery-select-pane').find('[pairid="' + string +'"]');
Here, have a fiddle: http://jsfiddle.net/s3dCB/

Get array of ids from e.g xx_numbers

How can I retrieve an array of ids with only a prefix in common?
E.g.
I've got a list of say 50 divs and they all got and ID looking like: aa_0000. Where 'a' is a prefix and '0' represents random numbers.
You want all elements of which their id starts with something common?
Assuming they are all div elements, this should work....
// Just so we can stay DRY :)
var prefix = 'aa_',
matchElement = 'div';
// Do we have an awesome browser?
if ('querySelectorAll' in document) {
var matchedDivs = document.querySelectorAll(matchElement + '[id^="' + prefix + '"]');
} else {
var allDivs = document.getElementsByTagName(matchElement),
matchedDivs = [],
regex = new RegExp('^' + prefix);
for (var i = 0, allDivsLength = allDivs.length; i < allDivsLength; i++) {
var element = allDivs[i];
if (element.id.match(regex)) {
matchedDivs.push(element);
}
}
}
console.log(matchedDivs.length); // Expect 3
jsFiddle.
If you want to explicitly match ones with numbers, try the regex /^aa_\d+$/.
If you have jQuery floating around, you can use $('div[id^="aa__"]').
For people using jQuery:
$('div[id^="aa_"]')

Categories

Resources