target selected members of an array - javascript

I have a series of divs of the same class; some with title attributes set - some without:
<div class="component_wrapper cw1" title="thisTitle1">... </div>
<div class="component_wrapper cw2" title="thisTitle2">... </div>
<div class="component_wrapper cw3" title="thisTitle3">... </div>
<div class="component_wrapper cw4" title="">... </div>
<div class="component_wrapper cw5" title="">... </div>
I've constructed a javascript function that loops through these divs and displays the ones with the title attribute set by setting their css display attribute to "inline":
function checkComponent(e){
var hdrSet = document.getElementsByClassName("component_wrapper");
var titles = {};
for (var i=0; i<hdrSet.length; i++){
if ( !titles[ hdrSet[i].title ] ) {
titles[ hdrSet[i].title ] = true;
hdrSet[i].style.display = "inline";
}
}
}
checkComponent();
the problem is, when I load the page the divs that I'm trying to target display (good), but also 1 of the divs not targeted displays. In the example above, the first four divs display, when all I want is the first three. What's wrong with my code... and is there an better way to construct the function?

Your code checks for duplicate titles, not missing ones. Here's how you could fix that:
function checkComponent(){
var hdrSet = document.getElementsByClassName("component_wrapper");
for (var i = 0; i < hdrSet.length; i++){
if(hdrSet[i].title) {
hdrSet[i].style.display = "inline";
}
}
}
checkComponent();
Also, if you're open to using jQuery, it's much neater and more compatible:
function checkComponent() {
$('.component_wrapper[title]:not([title=""])').css('display', 'inline');
}
checkComponent();

Related

Check if element in array has class and add class if it doesn't - JavaScript

I am trying to check if an element in an array has a specific class, and if it doesn't, add that class. This is happening when a segment of a pie chart created with chart.js is clicked. When a segment is clicked, a corresponding hidden div should appear, and any unhidden divs should disappear. When the segment is clicked, a class is removed from the relevant div to unhide it, and any unhidden divs should have the class added back to hide it again.
My issue is that I am not sure how to loop through the array to check if any divs don't have the class, and if they don't, to add the class back.
HTML
<div id="mod0" class="m-d-hide">Some content</div>
<div id="mod1" class="m-d-hide">Some content</div>
<div id="mod2" class="m-d-hide">Some content</div>
<div id="mod3" class="m-d-hide">Some content</div>
Javascript
var activePoints = window.modulePie1.getElementsAtEvent(event);
var modDescription = [];
for(var i=0; i<9; i++) {
modDescription[i] = document.getElementById("mod"+i);
if (activePoints.length > 0) {
var clickedSegmentIndex = activePoints[0]._index;
if (clickedSegmentIndex==[i]) {
modDescription[i].classList.remove("m-d-hide");
//Everything works until here - can't add class
if (!modDescription.classList.contains("m-d-hide")) {
modDescription.classList.add("m-d-hide");
}
}
}
}
Thanks in advance for any help.
I've managed to fix this issue by adding an else statement to the
if (clickedSegment==[i])
loop, so there was no need to loop through the array and check all the classes.
Code now looks like:
var activePoints = window.modulePie1.getElementsAtEvent(event);
var modDescription = [];
for(var i=0; i<9; i++) {
modDescription[i] = document.getElementById("mod"+i);
if (activePoints.length > 0) {
var clickedSegmentIndex = activePoints[0]._index;
if (clickedSegmentIndex==[i]) {
modDescription[i].classList.remove("m-d-hide");
} else {
if (!modDescription[i].classList.contains("m-d-hide")) {
modDescription[i].classList.add("m-d-hide");
}
}
}
}

How access second div with same id using querySelectorAll javascript?

Here, I have two div on my webpage both div have almost same data.
accept type attribute.
My first div attribute have type="timeline".
and Second div attribute type ="slideshow".
When my page load it only detects the first div.
But I have a condition if my div type equal to slideshow then my code run but it detects only first div.
Here is my code.
<div type='timeline' id='slide'>
<section>
<header>Title One</header>
<article>Content</article>
</section>
<section>
<header>Title Two</header>
<article>Content</article>
</section>
<section>
<header>Title Three</header>
<article>Content</article>
</section>
<section>
<header>Title Four</header>
<article>Content</article>
</section>
</div>
var divSlide = document.querySelectorAll('#slide');
var myNodeList = divSlide.length;
for(i = 0; i < myNodeList.length; i++) {
var divMain = document.getElementById("slide");
console.log(divMain);
var align = divMain.getAttribute("type");
console.log(align);
console.log(myNodeList)
if(align=='slideshow'){
console.log("my working code");
}
}
What should i do.
Help will be appreciated.
You have a few of mistakes in your code that we need to fix first.
First, you shouldn't use the same id value more than once in your code so you need to replace the id with a class (even though our code can still work with id here).
Second mistake - in your for loop you are using the wrong variable "myNodeList.length", myNodeList variable already is the length so it does not have a length property. you should instead use the divSlide variable like this:
for(i = 0; i < divSlide.length; i++)
Third mistake- in order to access the current item that is being looped over you should use the variable that holds the list (which is divSlide here)and then add to it i in brackets to indicate the current index in use, like this
var divMain = divSlide[i];
// instead of this: var divMain = document.getElementById("slide");
Fourth - you should in most cases use triple = signs to check for values. so instead of == you should use ===
this is how the code will look like finally:
var divSlide = document.querySelectorAll('#slide');
var myNodeList = divSlide.length;
document.addEventListener("DOMContentLoaded", functionName)
function functionName(){
for(i = 0; i < divSlide.length; i++) {
var divMain = divSlide[i];
var align = divMain.getAttribute("type");
if(align ==='slideshow'){
console.log("my working code");
}
}
}
and this is codepen example
You can get div by type attribute like this:
HTML
<div type='timeline' id='slide'>
this is timeline
</div>
<div type='slideshow' id='slide'>
this is slideshow
</div>
JS
$('#slide[type=slideshow]') // get div that has id='slide' and type='slideshow'
Online Demo (jsFiddle)

changing clicked element's style in array through javascript

my html code:
<div class="mydiv" onclick="clickonelement()">div1</div>
<div class="mydiv" onclick="clickonelement()">div2</div>
<div class="mydiv" onclick="clickonelement()">div3</div>
<div class="mydiv" onclick="clickonelement()">div4</div>
<div class="mydiv" onclick="clickonelement()">div5</div>
<div class="mydiv" onclick="clickonelement()">div6</div>
<!-- javascript code -->
function clickonelement(){
mydiv = document.getElementsByClassName("mydiv");
for(i=0; i<mydiv.length; i++){
mydiv.item(i).style.backgroundColor = "red";
mydiv[this].style.backgroundColor = "#fff";
}
}
css code
.mydiv{width:300px; height:30px;}
I want on onClick event to change clicked element's background to white and other elements background remain red in color but my code
mydiv[this].style.backgroundColor = "#fff";
is not working. please solve this problem in JavaScript only. I am in basic stage of JavaScript.
You need to pass a reference to the element that you want to refer to with this, e.g. onclick="clickonelement(this)":
function clickonelement(elem) {
mydiv = document.getElementsByClassName("mydiv");
for (i = 0; i < mydiv.length; i++) {
mydiv.item(i).style.backgroundColor = "red";
elem.style.backgroundColor = "#fff";
}
}
<div class="mydiv" onclick="clickonelement(this)">div1</div>
<div class="mydiv" onclick="clickonelement(this)">div2</div>
<div class="mydiv" onclick="clickonelement(this)">div3</div>
<div class="mydiv" onclick="clickonelement(this)">div4</div>
<div class="mydiv" onclick="clickonelement(this)">div5</div>
<div class="mydiv" onclick="clickonelement(this)">div6</div>
This is JS code for your HTML code, you need add addEventListener.
function clickonelement() {
mydiv = document.getElementsByClassName("mydiv");
for (var i = 0; i < mydiv.length; i++) {
mydiv[i].addEventListener('click', function() {
this.style.backgroundColor = "red";
this.style.backgroundColor = "#fff";
});
}
}
Here is just another way of achieving the same functionality.
Objective
To remove inline event handler
Use loop only once instead of looping over all the matched class name (mydiv) on every click.
Used javascript functions & concepts
querySelectorAll : - Used to select all matched elements with same class that is mydiv. It will return an nodelist containing all matched elements
forEach:- is an array method which used to loop over list.It accepts three arguments. For this case two will be enough.
addEventListener:- Is use to attach event to an element
Closures:These functions 'remember' the environment in which they were created.
Hope this snippet will be useful
//Get all the matched Elements
var matches = document.querySelectorAll("div.mydiv");
//Use an variable to rememeber previous clicked element
var prevIndex = -1; //
// Loop over the list
matches.forEach(function(item,index){
(function(i){ // A closure is created
item.addEventListener('click',function(){
// if any previous element was clicked then rest it's background
if(prevIndex !== -1){
matches[prevIndex].style.background="red";
}
// change background of current element
item.style.background="#fff";
// update prevIndex
prevIndex = i;
})
}(index))
})
Check this DEMO

Change DIV order with jquery

I'm working on a client's HTML based site and need to randomly order a set of Divs on refresh of a page. I would normally handle this through PHP and a database call, but it's a static site.
So, I'm wondering if anyone knows how to randomly display a set of div's using jquery?
Here's an example:
<div class="myItems">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
and on refresh, it might change to:
<div class="myItems">
<div class="item">2</div>
<div class="item">3</div>
<div class="item">1</div>
</div>
Anyone know how to do that?
This willl do it
function reorder() {
var grp = $(".myItems").children();
var cnt = grp.length;
var temp,x;
for (var i = 0; i < cnt; i++) {
temp = grp[i];
x = Math.floor(Math.random() * cnt);
grp[i] = grp[x];
grp[x] = temp;
}
$(grp).remove();
$(".myItems").append($(grp));
}
Actually it's pretty simple:
$(".myItems").html($(".myItems .item").sort(function(){
return Math.random()-0.5;
}));
That's it!
Enjoy.
Another simple way is ...
1. create an array
2. generate a random number and check if it is Odd or Even
3. If odd, add your div to the top (shift method). If even, add your div to the bottom (push method).
4. So this way you will have your divs arranged randomly in the array.
5. Now simple join the array and append it to your Page.
var divArray = [];
for(var i=0; i<divs.length; i++){
//generate random number
if(rand_num == odd)
divArray.push( div[i] );
else
divArray.shift( div[i] );
}
$(myElem).html( divArray.join("") );

Remove parent element after removing last child element

I have a list of elements on a page, for the sake of discussion we can say I have the following:
<div id="group_01">
<div id="entry_1-01">stuff x</div>
<div id="entry_1-02">stuff x</div>
</div>
<div id="group_02">
<div id="entry_2-01">stuff x</div>
<div id="entry_2-02">stuff x</div>
</div>
The delete link calls an Ajax request and deletes the entry, after a succesful Ajax call, the entry div is removed from the page. My question is:
How can I remove the containing group div once all of it's entries have been deleted?
I hope that's a detailed enough question. I feel like this isn't anything new, yet two days of search has resulted in nothing.
Before you delete the child element, get its parent, count the number of children, and then after deleting the child, delete the parent if the child count is zero. Here is a quicky piece of sample code:
function d (x)
{
var e = document.getElementById(x);
var p = e.parentNode;
p.removeChild (e);
if (p.childNodes.length == 0) {
var pp = p.parentNode;
pp.removeChild (p);
}
}
I added onclicks to your divs like this:
<div id="group_01">
<div id="entry_1_01">stuff 11<a onclick="d('entry_1_01');" href="#delete">x</a></div>
<div id="entry_1_02">stuff 12<a onclick="d('entry_1_02');" href="#delete">x</a></div>
</div>
I also changed the link to "#delete". You could tidy this up in various ways.
A function like this should would work:
function removeNodeIfEmpty(node) {
var container = document.getElementById(node);
var nodeCount = 0;
for (i = 0; i < container.childNodes.length, i++) {
if (container.childNodes[i].nodeType == 1) {
nodeCount += 1;
}
}
if (nodeCount < 1) {
container.parentNode.removeChild(node);
}
}
This should account for the whitespace issue.
Assuming you do something like this to remove an entry:
entryDiv.parentNode.removeChild(entryDiv);
then you should be able to use the following code to remove the group div when the last child is removed:
var groupDiv = entryDiv.parentNode;
groupDiv.removeChild(entryDiv);
if (!groupDiv.firstChild) {
groupDiv.parentNode.removeChild(groupDiv);
}
...although you need to watch out for whitespace-only text nodes, if these entries haven't been created directly by script.
Really depends what library you're using
http://docs.jquery.com/Traversing/parent#expr
should be a suitable expression

Categories

Resources