changing innerHTML of child element using javascript - javascript

I would like to change my icon from expand_more to expand_less in following code
<li class="dropdown-bt" onclick="dropdown('content');">
<a>dropdown-content <i class="material-icons">expand_more</i></a>
</li>
I am going to use same code multiple times so it would be better to using function multiple times. I thought of using ID for every piece of code but it would be to hectic. So I want to write single function do it but I don't know how, so please help.

Just pass an object event as a parameter, say e to your dropdown() and use the textContent property to retrieve the current element content, check it's value and replace the content with another text content like this:
var btn = document.getElementById("dropdownBt");
function dropdown(e) {
var innerText = e.target.children[0];
if(innerText.textContent == "expand_more") {
innerText.textContent = "expand_less";
} else {
innerText.textContent = "expand_more";
}
}
btn.addEventListener('click', dropdown);
<li class="dropdown-bt" id="dropdownBt"><a>dropdown-content <i class="material-icons">expand_more</i></a></li>

Related

Dynamically added class cannot be referenced for some reason

When I use clicks on a link, I add a class to the element:
<a class="js-link" data-category="cat123" href="#">some category</a>
The javascript is:
$(".js-link").click(function (e) {
e.preventDefault();
$(this).addClass(".js-category-selected");
});
When the user submits a search form, I am trying to get the link that was clicked:
var selectedCategory = $(".js-category-selected").data("category");
console.log('selectedCategory:' + selectedCategory);
This always returns undefined.
I can't seem to find the element. Is something wrong with this approach?
Is it because this class is added dynamically? But I'm not binding anything, just trying to located the element.
You were giving class name with a . while adding the class. Just give the name and access using . and to get data write the function inside a handler, outside it, it will be accessed before even the link will get new class and you will always get undefined.
Use $(this).addClass("js-category-selected"); instead of using $(this).addClass(".js-category-selected");
$(".js-link").click(function(e) {
e.preventDefault();
$(this).addClass("js-category-selected");
var selectedCategory = $(".js-category-selected").data("category");
console.log('selectedCategory:' + selectedCategory);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a class="js-link" data-category="cat123" href="#">some category</a>
You need to remove the . at the start of the class you're adding:
$(".js-link").click(function(e) {
e.preventDefault();
$(this).addClass("js-category-selected");
var selectedCategory = $(".js-category-selected").data("category");
console.log('selectedCategory:' + selectedCategory);
});
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<a class="js-link" data-category="cat123" href="#">some category</a>

javascript - avoid repetable code

I have a page with a button that calls a menu modal. The modal contains two more buttons that call two submenus - one for each button. Watch the pen:
https://codepen.io/t411tocreate/pen/yoxJGO
It actually works. But the current problem is that I re-write a repeatable code to call each submenu:
$('.show-submenu-1').on('click', function () {
$('.submenu-1.offcanvas').addClass('offcanvas--active');
})
$('.show-submenu-2').on('click', function () {
$('.submenu-2.offcanvas').addClass('offcanvas--active');
})
This approach seems to be pretty dumb. I need a solution with less repetition, something like forEach function for arrays:
var menus = [
'.show-submenu-1',
'.show-submenu-2'
];
menus.forEach(function(menu){
$(menu).on('click', function () {
$(`${menu}.offcanvas`).addClass('offcanvas--active');
})
});
Of course, this scenario won't work. How can I make my code DRY?
Use markup:
<div class="submenu" data-index="1">
<div class="submenu" data-index="2">
<button class="show-submenu-button" data-submenu-index="1">
<button class="show-submenu-button" data-submenu-index="2">
Then:
$('.show-submenu-button').on('click', function () {
var index = $(this).attr('data-submenu-index');
$('.submenu[data-index="' + index + '"]').addClass('offcanvas--active');
})
There is little value to using classnames that are so specific that they identify every element on the page individually. Classnames should define a class of elements that behave the same way.
Hi I hope I got the question right but you could use data-attributes for something like this. Just set a general class for .show-submenu and mark their connection to the menus with a number in a data-submenu=x attribute. Where x would be the number in .submenu-x.
And then you do something like this:
Notice that i changed .show-submenu-1 to .show-submenu. Make sure every trigger has this class. Also add a data-submenu=x for every submenu you want to use.
$('.show-submenu').on('click', function () {
var number = $(this).attr("data-submenu");
var selector = '.submenu-' + number + '.offcanvas'
$(selector).addClass('offcanvas--active');
})
So the data-submenu is used to pair the trigger and the modal. This way you can stick to an easy to read html code and a short bit of jquery.
Try this:
var menus = [1, 2];
menus.forEach(index => {
$(`.show-submenu-${index}`).on('click', () => {
$(`.submenu-${index}.offcanvas`).addClass('offcanvas--active');
});
});
You can use this as well.
$('.show-submenu-1, .show-submenu-2').on('click', function (event) {
$(event.target).hasClass('show-submenu-1'){
$('.submenu-1.offcanvas').addClass('offcanvas--active');
}else{
$('.submenu-2.offcanvas').addClass('offcanvas--active');
}
})
it would be better to have your show-submenu-1(as showmenu) and submenu-1(as submenu) in same parent element that allows you to use closest() method and make life easy
for eg:
$('.show-submenu').on('click', function (event) {
$(event.target).closest('.submenu').addClass('offcanvas--active');
})

How do I change the last textual node child in JavaScript

My Solution (EDIT : 2015-12-08) :
// FIRST WE GET THE PARENT ELEMENT
var parentEstim = document.getElementById("onglet_estim");
// MAKE A TABLE OF HIS CHILD
var enfantsEstim = parentEstim.childNodes;
// KNOW HOW MANY CHILDREN THE PARENT ELEMENT HAVE WITH .length
var Nbenfants = enfantsEstim.length;
....
for (var i = 0; i <= Nbenfants; i++) {
// IF THE CHILD ELEMENT [i] IS A HTML ELEMENT
if (enfantsEstim[i].nodeType === 1) {
enfantsEstim[i].lastChild.data = ''; // REMOVE LAST TEXT NODE
enfantsEstim[i].classList.remove('isActive');
}
document.getElementById('onglet_estim').style.width = '220px';
ClickedElement.className = 'isActive';
// ADD NEW VALUE IN THE LAST TEXT NODE FOR THE CLICKED ELEMENT
ClickedElement.lastChild.data = ' Gares';
}
DEMO : http://codepen.io/Zedash/details/pjMEMY
The Problem :
I have a little problem, I want to change the last textual node child value of a link <a> element.
For exemple, for the first link, we see the word "Saisie" wrote in it and I want to remove the text in this element if the user click on an other link and add a right text for the clicked element.
function changeInputAdresse(ClassName) {
if (ClassName.className !== 'isActive') {
ClassName.className = 'isActive';
switch(ClassName.id) {
case 'linkGares' :
ClassName.insertAdjacentHTML('beforeEnd',' Gares');
ClassName.previousElementSibling.classList.remove('isActive');
ClassName.nextElementSibling.classList.remove('isActive');
ClassName.previousElementSibling.insertAdjacentHTML('beforeEnd','');
ClassName.nextElementSibling.insertAdjacentHTML('beforeEnd','');
break;
}
}
};
// THE CODE IS NOT FINISHED OF COURSE !
a {
text-decoration:none;
color:#000;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet"/>
<a id="linkSaisie" class="isActive" href="#n" onclick="changeInputAdresse(this);"><i class="fa fa-map-marker"></i> Adresse</a>
<a id="linkGares" href="#n" onclick="changeInputAdresse(this);"><i class="fa fa-train"></i></a>
<a id="linkAeroports" href="#n" onclick="changeInputAdresse(this);"><i class="fa fa-plane"></i></a>
<a id="linkLoisirs" href="#n" onclick="changeInputAdresse(this);"><i class="fa fa-fort-awesome"></i></a>
<!--THE PART OF CODE WHERE I HAVE SOME PROBLEMS-->
Thanks for your ansewers ! :)
I don't quite get what you exactly would like, but to target and change the element after an italic I would use this jQuery and vanilla JS combination:
$("#myLink").find(">i").get(0).nextSibling.nodeValue = "Changed text";
DEMO: http://jsfiddle.net/u9jq2bvy/
IIRC there is no jQuery method to target a text node, so you need some native JS.
Please let me know if I misunderstood the question and I'm gonna delete my answer.
UPDATE
Based on the comment here is a possible solution.
$(document).on("click", ".myLink", function() {
// clear all texts
$(this).parent().find("a>span").text("");
$(this).addClass("active");
$(this).children("span").text("Active text");
});
DEMO http://jsfiddle.net/u9jq2bvy/1
And here is a modified version which simply shows/hides the spans.
DEMO http://jsfiddle.net/u9jq2bvy/3/
You can use jQuery siblings
changeInputAdresse(element){
element = $(element)
if(!element.hasClass('isActive')){
element.addClass('isActive');
element.siblings().removeClass('isActive');
element.text(element.attr('id').replace('link','')) //if that's the way you get value
element.siblings().text('')
}
}

Unstoppable addEventListener

When I click on the link it's working perfectly but only ONCE.
I want to be able to be able to keep the addEventListener even after it's been executed.
<div id=myBox>
append
</div>
document.getElementById("append").addEventListener("click", appendMore);
function appendMore() {
myBox.innerHTML += '1';
}
You'll want to use a separate element to insert your content into.
document.getElementById("append").addEventListener("click", appendMore);
function appendMore() {
tgt.innerHTML += "1";
}
<div id=myBox>
append
<span id="tgt"></span>
</div>
// Parent element
var el = document.querySelector('#myBox');
// Find append and add listener
el.querySelector("#append").addEventListener("click",appendMore);
function appendMore( event ) {
// Append new text node
el.appendChild( document.createTextNode('1') );
}
It would be achieved easily by using jQuery.
$('#append').click(function () {
$('#myBox').append('1');
});
find this JSFIDDLE
NB: Please let us know if you want to achieve this using just plain javascript.

Bind value of elements

Can i execute custom function when some properties of html tag is changed?
For example:
HTML code
<a id="link1">title</a>
<a id="link2">title</a>
When we change link2 text i want to change link1 text. So i want something like DataBinding in Windows Presentation Foundation.
We are changing link2: $('#link2').text('blablablaballba'); and value of link1 must be "blablablaballba". I dont want to write additional code $('#link1').text('blablablaballba'); and so on. link1 must be changed automatically.
You can write:
$('#link2, #link1').text('blablablaballba');
You can use a periodic interval to check the contents, like:
var timerID;
function watchLink2() {
var el = document.getElementById("link2");
return function () {
if (el.innerHTML != "title") {
document.getElementById("link1").innerHTML = el.innerHTML;
clearInterval(timerID);
}
};
}
timerID = setInterval(watchLink2(), 200);
But, er..., how do you think the attribute's value is changed?

Categories