Get value from data-section based on element ID - javascript

I'd like to render the section id="zero" data-section value in the h2 in my footer section dynamically. Since all of my pages will have different data-section values, I'm hoping we can target the section id="zero". This way I can use only one footer across my site. I am just not versed in javascript or jQuery to properly assign and call. I know there is document.getElementById('zero') but then getting the value from data-section and having it appear within my H2 I am not clear on.
<section id="zero" class="section-wrap" data-section="Page Name"></section>
<section id="footer">
<h2></h2>
</section>

Here's some Javascript that should help.
//Get the data-section value
let val = document.getElementById('zero').dataset.section;
//find the first h2 inside footer section
let header = document.getElementById('footer').getElementsByTagName("h2")[0];
//set the value
header.textContent = val;

Vanilla JS way
function start(){
// Find element with id="zero"
const section = document.querySelector('#zero');
// Find the h2 element nested inside an element with id="footer"
const footer = document.querySelector('#footer h2');
// Get value of data-section attribute
const dataSectionValue = section.getAttribute('data-section');
// Set value in your h2 tag
footer.innerText = dataSectionValue;
}
window.onload = start;
jQuery way
$(document).ready(function(){
const section = $('#zero');
$('#footer h2').text(section.data('section'));
});

Related

Setting List at the bottom of the screen in JS

I have a bunch of posts and each one has a setting btn and a setting list, so in mobile version, I want to show the setting list from the bottom of the screen wherever the user is rightnow like Youtube, Facebook & Quora.
<button>Click Me 1</button>
<div class="setting">
<ul>
<li>Save</li>
<li>Edit</li>
<li>Delete</li>
<li>Report</li>
<li>Close</li>
</ul>
</div>
<script>
const btns = document.querySelectorAll('button'),
settingLists = document.querySelectorAll('.setting');
for (let i = 0; i < btns.length; i++) {
const btn = btns[i];
const settingList = settingLists[i];
btn.addEventListener('click', ()=>{
settingList.style.position = 'absolute';
settingList.style.display = 'block';
const settingListTop = btn.getBoundingClientRect().top + btn.getBoundingClientRect().height + btn.getBoundingClientRect().bottom - settingList.getBoundingClientRect().height ;
console.log(`${settingListTop}`);
settingList.style.top = `${settingListTop}`; /*******/
settingList.style.width = '99%';
})
}
</script>
the js code above really makes sense, I am getting the bounding dimensions using getBoundingClientRect() and it gives me some right results in the console, but it doesn't assign this variable value to the top of the setting div element in this line of code
settingList.style.top = ${settingListTop};
So how can I assign a variable value to the bottom of an element OR is there another way to make this task in JS?
You can use window.matchMedia() option to check for viewport width and then apply the styles accordingly from js.
Why not just edit css styles from js?

Add element to a div with javascript

I want to add an element (child, div) to a mother-div, that already has one or more children. I made a script for this action but when I execute the script I am not able to manipulate style attributes afterwards. So I assume I did something wrong in my creation-script. I also added a console message (end of the script) and that also indicates there are no style attributes filled in at the new div. So, please could someone indicate what the reason is...
As I am quite new to javascript I assume the reason is quite simple. But although I checked many other questions and solutions, I do not get the proper solution for my issue. I think it should be in appendChild or insertBefore.
function preparevideo(videonaam, titel) {
// add a div to the video-div
const nieuwetitel = document.createElement("div");
// give the new div an id so it will be unique
nieuwetitel.id = videonaam + '-id';
// give the div a class for the markup
nieuwetitel.className = 'page-roel-video-titel';
// create the text in the div
const textnode = document.createTextNode(titel);
// add the textnode to the div
nieuwetitel.appendChild(textnode);
// find the element where the new div should be added to
let videomodule = document.getElementById(videonaam);
// and finally add the new div to the video-div, as the first child
videomodule.insertBefore(nieuwetitel, videomodule.children[0]);
console.log('-------after adding div------');
console.log('-------complete style of titleblock------');
console.log(document.getElementById(videonaam + '-id').style);
console.log('prepare video afgerond');
}
preparevideo("naam1","Eerste video");
<div id="naam1"></div>
As you didn't set any style attribute before console.log that's why you didn't get any result. After implementing some style, you can log the the style. Then you will see the difference.
Here I added some style before the console.log
function preparevideo(videonaam, titel) {
// add a div to the video-div
const nieuwetitel = document.createElement("div");
// give the new div an id so it will be unique
nieuwetitel.id = videonaam + '-id';
// give the div a class for the markup
nieuwetitel.className = 'page-roel-video-titel';
// create the text in the div
const textnode = document.createTextNode(titel);
// add the textnode to the div
nieuwetitel.appendChild(textnode);
// find the element where the new div should be added to
let videomodule = document.getElementById(videonaam);
// and finally add the new div to the video-div, as the first child
videomodule.insertBefore(nieuwetitel, videomodule.children[0]);
// Applying style
document.getElementById(videonaam + '-id').style.backgroundColor = 'red';
document.getElementById(videonaam + '-id').style.color = 'white'
console.log('-------after adding div------');
console.log('-------complete style of titleblock------');
console.log(document.getElementById(videonaam + '-id').style);
console.log('prepare video afgerond');
}
preparevideo("naam1","Eerste video");
<div id="naam1"></div>
You already gave it a class, you can target it in your css and added the needed styles
The problem is that there is no unique id value for nieuwetitel element generated. When you use getElementById() method you get only first element from DOM.

Change h2 tag to h1 tag

I would like to change the product names on all product pages from h2 to h1
I would like to change this somehow to h1 with custom code.
<h2 itemprop="name" class="product_title likeh2">Aspen Ágykeret Bársony Sötétzöld 160 cm</h2>
You could to something like this:
//select all h2 elements
document.querySelectorAll('h2').forEach( element => {
//create new h1 element
const newElement = document.createElement('h1');
//set the inner html to the original h2 element
newElement.innerHTML = element.innerHTML;
//take all attributes from original element and assign them to the new one
Array.from(element.attributes).forEach( attr => {
newElement.setAttribute(attr.nodeName, attr.nodeValue)
})
//replace the node in the dom
element.parentNode.replaceChild(newElement, element);
})
Here's one way to do it. It will depend on browser support for outerHTML, but that's looking pretty good nowadays: https://caniuse.com/#search=outerHTML
querySelectorAll is used rather than getElementsByTagName because the array of elements does not change even as the elements change. When you actually update the element within that array, it uses the reference to update the actual element, but it doesn't change within the array. That way we can continue looping through and altering all <h2> tags on the document, whereas the live list returned by getElementsByTagName would lose elements each time an h2 tag is converted to an h1.
const hTwos = document.querySelectorAll('h2');
for (let i = 0; i < hTwos.length; i++) {
hTwos[i].outerHTML = hTwos[i].outerHTML.replace(/h2/g,"h1");
};
<h2>Product 1</h2>
<h2>Product 2</h2>

text/template inside js-file?

I want to move this code from my html-file to a js-file, is there any smooth way to do this without having to put the HTML-code as a string?
<script type="text/template" id="template_test">
<h4>Test</h4>
<p>blablabla</p>
</script>
Thanks!
You can use the createElement function to create HTML elements however if you intend to move alot of code you should consider using a templeting engine.
// Create the <h4> element
var heading = document.createElement("h4");
// add the text
heading.textContent = "TEST";
// Create the text node <p>
var p = document.createTextNode("blablabla");
//get the element to which you want to append the h4 and p
var container = document.getElementById("myID");
// Append h4 and p
container.appendChild(heading);
container.appendChild(p);

Jquery select object by id dynamically using a string

I have an image gallery that uses modals. In the image modal or outside it, the user can click on a star and mark the image as favorite. Favorite images have a class that makes the star change color its to 'golden'. If a user marks a favorite in the modal, I need to change the color of the star of that image outside the modal as well.
To do this, I thought I could have a
<p id = "modal_counter" class = "hidden">number</p>
in the modal, so that I can get the image number. Then I use that image number as part of a jquery selector.
The images in the gallery have something like this:
<p id = "image_number" class = "hidden"></p>
<!-- for example: <p id = "image_2" class = "hidden"></p> -->
So, all I need is to successfully select the hidden p tag next to each image, then I could use jquery's next() or parent().find().
This is the relevant code:
...
var modal_counter = div_parent.find('#modal_counter').text();
var counter = "#image_"+String(modal_counter);
/* I would like the counter to be something like "#image_2" */
var $(counter).parent().find('.star').addClass('golden')
...
This doesn't work. Jquery tries to find an object using this selector:
"#image_\n 2"
and of course, it doesn't find one. I tried removing the \n with a regex, but it still doesn't work:
counter_processed = modal_counter.replace(/(<([^>]+)>)/ig,"");
It'll probably be better to use a data-attribute on your element rather than getting the text content. Do:
<p id = "modal_counter" class = "hidden" data-counter="number">number</p>
Then you can:
...
var modal_counter = div_parent.find('#modal_counter').data('counter');
var counter = "#image_" + modal_counter;
/* I would like the counter to be something like "#image_2" */
var $(counter).parent().find('.star').addClass('golden')
...
This way you don't bind your javascript to the text inside your elements.
jQuery has a handy trim function:
var modal_counter = div_parent.find('#modal_counter').text().trim();
Try this from your console:
$.trim("\n\nHello\r\nThere\n")
See how it removes the leading and trailing white-space?
Let's say you have:
<p id="modal_1" class="hidden">Img 1</p>
you can extract the number both using:
// If you need it from the text
var n = $("[id^=modal_]").text().match(/\d+/); // 1
or
// If you need it from the ID
var n = $("[id^=modal_]")[0].id.match(/\d+/); // 1
Than to target the image like:
<img id="image_1" src="someimage.jpg" alt="SEO">
you do:
$('#image_'+ n)
If you really just have:
<p id="modal_counter" class="hidden">3</p>
than you can do:
var n = $('#modal_counter').text(); // "3"
$("#image_"+ n) // .fadeIn() or whatever...
Just make sure you don't have duplicate modal_counter ID elements on your page. ID has to be unique.

Categories

Resources