add data- attributes by reading values from DOM - javascript

I have the below html structure and I'm trying to get the text of h tags and add as a data- attribute in the corresponding tags:
<div class="content">
<div class="body">
<h1>foo</h1>
<p>para-test1</p>
<p>para-test2</p>
<div class="link">
anchor1
anchor2
anchor3
</div>
</div>
</div>
<div class="content">
<div class="body">
<h1>bar</h1>
<p>para-test3</p>
<div class="link">
anchor4
</div>
</div>
</div>
So 'foo' should be set as a data attribute value for anchor 1,2,3 elements and
'bar' should be set as a data attribute value for anchor 4. Something like this:
<a data-custom="foo" href="#">anchor1</a>
<a data-custom="foo" href="#"">anchor2</a>
<a data-custom="foo" href="#">anchor3</a>
<a data-custom="bar" href="#">anchor4</a>
I tried to iterate over the elements and I'm struck at the second loop.
$(".content .body").each(function() {
$(this).find(".link").attr("data-hN", $(this).next(":header").text());
});

You have an extra double quote two times in your HTML. But, fixing that and foregoing JQuery (which is overkill for such a trivial task), see comments inline below:
// Loop over the links
document.querySelectorAll("div.link > a").forEach(function(item){
// Set the current link data-custom attribute to the nearest
// .body ancestor and the first heading element within that text
item.dataset.custom = item.closest(".body").querySelector(":first-child").textContent;
console.log(item);
});
<div class="content">
<div class="body">
<h1>foo</h1>
<p>para-test1</p>
<p>para-test2</p>
<div class="link">
anchor1
anchor2
anchor3
</div>
</div>
</div>
<div class="content">
<div class="body">
<h1>bar</h1>
<p>para-test3</p>
<div class="link">
anchor4
</div>
</div>
</div>

Related

TypeError: Cannot read properties of null (reading 'addEventListener') javascript

I am trying to add a button but it is showing me this error.
here is my html code
<div card-container>
<template class="mainTemplate">
<div class="cards">
<div class="card">
<img data-image src="" alt="">
<div data-title class="header"></div>
<div data-body class="body"></div>
<button data-button class="btn">read more</button>
<p data-paragraph class="fullText"></p>
</div>
</div>
</template>
</div>
here is the javascript code
let showDitail = document.querySelector(".btn");
showDitail.addEventListener("click", showMore);
function showMore(){
alert("e")
}
You're using the <template> tag, which is an element that holds html markup but it's not rendered on page load.
In order to render its contents, one has to handle the <template> element via javascript, using the html structure as - in fact - a template for filling another structure (a table, a divs grid, etc.).
Since the sub-elements of <template> are not part of the DOM yet, let showDitail = document.querySelector(".btn"); will result in null. That's why you cannot bind events to it.
Either change the tag to something else (a div maybe), or handle the template properly via javascript.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template
let showDitail = document.querySelector(".btn");
showDitail.addEventListener("click", showMore);
function showMore(){
alert("e")
}
<div card-container>
<div class="mainTemplate">
<div class="cards">
<div class="card">
<img data-image src="" alt="">
<div data-title class="header"></div>
<div data-body class="body"></div>
<button data-button class="btn">read more</button>
<p data-paragraph class="fullText"></p>
</div>
</div>
</div>
</div>

Can I check with jQuery if element has specific class and edit only this element?

if (jQuery("li.store .premise")[0]) {
jQuery(".address .arrow").remove();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="store">
<div class="address">
<span class="arrow"></span>
<div class="results-toggle">
<div class="shop-address">
<div class="street-block">
<div class="thoroughfare">demo address</div>
<div class="premise">additional info</div>
</div>
<div class="addressfield-container-inline locality-block country-BG"><span
class="locality">New York</span></div>
<span class="country">USA</span>
</div>
<div class="shop-phone">+1 4258741</div>
</div>
</div>
</div>
Is there a way to check if an element contains specific class and if it does, then to edit only this or these elements.
I have a list of stores and I want if some of them contain specific class to remove the arrows.
I tried with this but it removes all elements with a class arrow and I want to remove the only storeеthat have the specific class which in this case is class="premise"
Closest using get parent element then find class for .arrow then remove method using removed.
$(".store .premise").closest(".address").find('.arrow').remove();
Once you have a collection of premises, use .closest to navigate to their ancestor address, from which you can get to the .arrows:
$('div.store .premise').closest('.address').find('.arrow').remove();
(assuming that the .store element in your actual code is a <li>, otherwise use div.store or just .store)
$('div.store .premise').closest('.address').find('.arrow').remove();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="store">
<div class="address">
<span class="arrow">arrow here</span>
<div class="results-toggle">
<div class="shop-address">
<div class="street-block">
<div class="thoroughfare">demo address</div>
<div class="premise">additional info</div>
</div>
<div class="addressfield-container-inline locality-block country-BG"><span class="locality">New York</span></div>
<span class="country">USA</span>
</div>
<div class="shop-phone">+1 4258741</div>
</div>
</div>
</div>

Enclose whole div in an <a>

I have a div which I want to surround with an <a href>. I have the jQuery to add the <a href> after the div but I struggle to set it before and close it after the div.
This is the jQuery code I have:
$('.box_service').each(function() {
var link = $(this).html();
$(this).contents().wrap('');
});
It results in this HTML:
<div class="row">
<div class="box_service">
<a href="example.com">
<div class="inner-row"></div>
</a>
</div>
</div>
However my goal is this structure:
<div class="row">
<a href="example.com">
<div class="box_service">
<div class="inner-row"></div>
</div>
</a>
</div>
I can't enter the div before because there are more boxes in this row so I would add the <a href> to everything in there
The issue is due to your call to contents() which means you're wrapping the elements inside .box_service, not that element itself. Remove that method call.
Also note that each() is redundant, you can do what you require in a single line:
$('.box_service').wrap('');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<div class="box_service">
Box service #1
<div class="inner-row">Inner row #1</div>
</div>
</div>
<div class="row">
<div class="box_service">
Box service #2
<div class="inner-row">Inner row #2</div>
</div>
</div>
.content will wrap the contents of your div, you want to wrap the div with <a> so call wrap on the div not on contents.
$('.box_service').each(function() {
var link = $(this).html();
$(this).wrap('');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<div class="box_service">
<div class="inner-row"></div>
</div>
</div>
$('.box_service').each(function() {
var link = $(this).html();
$(this).wrap('');
});
You just need to remove contents() in between $(this).wrap() because contents() mean that you are wrapping the children of $(this).
Remove .contents() in order to wrap around each element with the class box-service:
$('.box_service').each(function() {
$(this).wrap('');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<div class="box_service">
<a href="example.com">
<div class="inner-row"></div>
</a>
</div>
</div>
$('.box_service').wrap('');

Toggle a repeated class in jQuery

I have this HTML code:
<div id="content">
<div class="profile_photo">
<img style="float:left;margin-right:7px;" src="http://gravatar.com/avatar/53566ac91a169b353a78b329bdd35c95?s=50&d=identicon" class="profile_img" alt="{username}"/>
</div>
<div class="container" id="status-#">
<div class="message">
<span class="username">{username} Debugr Rocks!
</div>
<div class="info">24-oct-2010, 14:05 GMT · Comment (5) · Flag · Via Twitter
</div>
<div class="comment_container">
<div class="profile_photo">
<img style="float:left;margin-right:7px;" src="http://gravatar.com/avatar/53566ac91a169b353a78b329bdd35c95?s=32&d=identicon" class="profile_img" alt="{username}"/>
</div>
<div class="comment_message">
<span class="username">{username}</span> Debugr Rocks! XD
</div>
<div class="comment_info">24-oct-2010</div>
</div>
</div>
<div class="profile_photo">
<img style="float:left;margin-right:7px;" src="http://gravatar.com/avatar/53566ac91a169b353a78b329bdd35c95?s=50&d=identicon" class="profile_img" alt="{username}"/>
</div>
That is repeated two or more times. What I want to do, is to when I click the "Comments (5)" link, the class "comment_container" appears, but only the one in the same "container" class.
It's this possible?
You can use .closest() to go up to the .container then .find() to look inside it, like this:
$(".toggle_comment").click(function() {
$(this).closest(".container").find(".comment_container").show();
});
You can try it here, if you're curious about finding other things relative to this here's a full list of the Tree Traversal functions.
As an aside, there's an error in your HTML that needs correcting, this:
<span class="username">{username} Debugr Rocks! </div>
Should be:
<span class="username">{username} Debugr Rocks! </span>

jQuery: Wrap only first and second child, not the rest of children

In my actual code:
<div id="mother">
<div id="child-01"></div>
<div id="child-02"></div>
<div id="child-03"></div>
</ul>
I need to produce:
<div id="mother">
<div id="myWrap">
<div id="child-01"></div>
<div id="child-02"></div>
</div>
<div id="child-03"></div>
</ul>
I was playing with wrap, .wrapAll() and children, but I'm stuck.
If in my actual code i have:
<div id="mother">
<div id="child-01"></div>
<div id="child-02"></div>
<div id="child-03"></div>
</ul>
<div id="uncle">
<div id="cousin-01"></div>
<div id="cousin-02"></div>
<div id="cousin-03"></div>
</ul>
How do i produce:
<div id="mother">
<div id="myWrap">
<div id="child-01"></div>
<div id="child-02"></div>
<div id="cousin-02"></div>
</div>
<div id="child-03"></div>
</ul>
First as Adam said remove the # prefix from your id attributes. Also match your closing tags, currently you have a </ul> where a </div> should be.
Then, you can do it using :lt() and .wrapAll() like this:
$("#mother div:lt(2)").wrapAll("<div id='myWrap'></div>");
This gets everything less than index 2 (0 and 1 are the first 2), then wraps it. You can test it here.
Remove # from your HTML ids.
$("#mother div:eq(0), #mother div:eq(1)").wrapAll("<div id='father'></div>")
sharp should not be part of the id's. Then you can do:
$('#child-01, #child-02').wrapAll('<div id="#mywrap" />');
$(document).ready(function(){
$(".new-grid__item:nth-child(1), .new-grid__item:nth-child(2)").wrapAll('<div class="child"></div>');
});

Categories