Hide parent DIV when h4 contains certail text - javascript

What I'd like to do is try to hide the parent div of the following (it would be hiding the div class called "eB cer") if h4 includes the word "bulk."
<div class="eB cer">
<h4>Bulk Load Files to CERs</h4>
<div class="tooltip"><b>Description: </b>You will add files to your CERs using the Bulk Load and Attribute Update Utility.<span class="tooltiptext">In this module you will learn how to add files to your CERs in bulk and modify any attributes as needed.</span>
</div>
<p><b>Link: </b>Bulk Load Files to CERs</p>
</div>
I have this and it's hiding the h4, but not the entire div.
var searched_string = "eB cer";
var foundmatch = [];
for(i=0; i < leftFilteredArray.length; i++){
if(leftFilteredArray[i].match(searched_string)){
foundmatch.push(leftFilteredArray[i]);
$("div h4:contains('" + searched_string +"')").hide();
}
Any suggestions what I'm doing wrong?

You can use indexOf() which returns the first index at which the specified string is found. Else it returns -1.
if($('.eB.cer>h4').text().toLowerCase().indexOf('bulk')!==-1)
$('.eB.cer').hide()

To recreate your situation I ended up looking at the jQuery line. Then I plugged it into the rest of the code. Here is what I got working.
var searched_string = "Bulk";
var foundmatch = [];
for(i=0; i < leftFilteredArray.length; i++){
if(leftFilteredArray[i].match(searched_string)){
foundmatch.push(leftFilteredArray[i]);
$("div h4:contains('" + searched_string +"')").parent().hide();
}
}
This line sets the text to lower case for less issues.
var searched_string = "Bulk";
var foundmatch = [];
for(i=0; i < leftFilteredArray.length; i++){
if(leftFilteredArray[i].match(searched_string)){
foundmatch.push(leftFilteredArray[i]);
// $("div h4:contains('" + searched_string +"')").parent().hide();
if( $(".eB.cer h4").html().toLowerCase().indexOf(searched_string.toLowerCase()) > -1) {
$(".eB.cer").hide();
}
}
}

Related

Add Different Data Attribute to Anchors

I'm attempting to add data-webpart attributes to all the anchors within a document, but populate their values with the data attributes of their containing divs.
However the code I wrote appears to be populating all of the anchors with only one of the data attributes (or rather, adding the first one to all, then adding the second).
Any help would be much appreciated!
HTML
<body>
<div data-webpart="form">
Test Link
Test Link
Test Link
</div>
<div data-webpart="icon-grid">
Test Link
Test Link
Test Link
</div>
</body>
JavaScript
// data attributer
var webParts = document.querySelectorAll("[data-webpart]");
var webPartAnchors = document.querySelectorAll("[data-webpart] > a");
function addDataAttr() {
var closestWebPartAttr;
for (i = 0; i < webPartAnchors.length; i++) {
for (e = 0; e < webParts.length; e++) {
closestWebPartAttr = webParts[e].getAttribute("data-webpart");
webPartAnchors[i].setAttribute("data-web-part", closestWebPartAttr);
}
}
}
window.onload = function() {
if (webParts !== null) { addDataAttr(); }
};
Your nested loops are copying the data attribute from every DIV to every anchor, because there's nothing that relates each anchor to just their parent. At the end they all have the last data attribute.
Since the anchors are direct children of the DIV, you don't need to use querySelectorAll() to get them, you can just use .children() within the loop.
function addDataAttr() {
for (var i = 0; i < webParts.length; i++) {
var webpart = webParts[i].dataset.webpart;
var children = webParts[i].children;
for (var j = 0; j < children.length; j++) {
children[j].dataset.webpart = webpart;
}
}
}

JavaScript Hiding li tag by selecting an html attribute not working

I have 3 columns which include dynamically generated list elements (li tags)
these have an attribute that I try to use to hide a row / li when an amount of character is not reached in this element.(by using opacity property)
I have it working...sometimes and sometimes it only works for one column out of the 3...
So I'd appreciate some insight on what's wrong here.
(function() {
// selecting all elements with class
// class="checkout-tariff-meta-maybe-hidden"
var elems = $(".checkout-tariff-meta-maybe-hidden");
// interact between founded elements
for (var k = 0; k < elems.length; k++) {
// getting text content size
var textSize = elems[k].textContent.length;
// if text size is one we will hide element
if (textSize <= 1) {
// hiding
elems[k].style.opacity = "0";
}
}
}());
You can just go straight to the point and do something like:
// Adjust as needed
$(document ).ready(function() {
$('.checkout-tariff-meta-maybe-hidden').filter( function() {
return $(this).text().length<3; } ).hide();
});
Since you're using jQuery, to hide an element you can just do:
$(elems[k]).hide();
Alternatively, if you're looking to hide it without collapsing (since you're changing opacity, I assume this is the case), look into .fadeTo():
$(elems[k]).fadeTo(1, 0);
You might look at ...
if (textSize <= 1) {
elems[k].style.opacity = "0";
} else {
elems[k].style.opacity = "1";
}
... to ensure they get turned back on when longer.

How do I filter an unorderded list to display only selected items using Javascript?

I have this JSFiddle where I am trying to make it so that the items in an unordered list are visible only if the option selected in a drop down matches their class. List items may have multiple classes, but so long as at least one class matches, the item should be made visible.
The Javascript looks like this:
function showListCategories() {
var selection = document.getElementById("listDisplayer").selectedIndex;
var unHidden = document.getElementsByClassName(selection);
for (var i = 0; i < unHidden.length; i++) {
unHidden[i].style.display = 'visible';
}
};
The idea is that it gets the current selection from the drop down, creates an array based on the matching classes, then cycles through each item and sets the CSS to be hidden on each one.
However, it's not working. Can anyone tell me where I'm going wroing?
Note that I haven't yet coded the "show all" option. I think I'll probably be able to figure that out once I have this first problem solved.
In your fiddle change load script No wrap - in <head>.
Just change your function like following
function showListCategories() {
var lis = document.getElementsByTagName('li');
for (var i = 0; i < lis.length; i++) {
lis[i].style.display = 'none';
}
//above code to reset all lis if they are already shown
var selection = document.getElementById("listDisplayer").value;
lis = document.getElementsByClassName(selection);
for (var i = 0; i < lis.length; i++) {
lis[i].style.display = 'block';
}
};
and in css it should be none not hidden
.cats, .rats, .bats {
display: none;
}
If you want to show all li when showAll is selected, add all classes to all lis.
You have a few things going on. First, your fiddle is not setup correctly, if you open the console you'll see:
Uncaught ReferenceError: showListCategories is not defined
This means that the function doesn't exist at the point you attach the event or that the function is out of scope, because by default jsFiddle will wrap your code in the onLoad event. To fix it you need to load the script as No wrap - in <body>.
Second, there's no such thing as a display:visible property in CSS. The property you want to toggle is display:none and display:list-item, as this is the default style of <li> elements.
Now, to make this work, it is easier if you add a common class to all items, let's say item, that way you can hide them all, and just show the one you want by checking if it has a certain class, as opposed to querying the DOM many times. You should cache your selectors, it is not necessary to query every time you call the function:
var select = document.getElementById('listDisplayer');
var items = document.getElementsByClassName('item');
function showListCategories() {
var selection = select.options[select.selectedIndex].value;
for (var i=0; i<items.length; i++) {
if (items[i].className.indexOf(selection) > -1) {
items[i].style.display = 'list-item';
} else {
items[i].style.display = 'none';
}
}
}
Demo: http://jsfiddle.net/E2DKh/28/
First there is no property in Css like display:hidden; it should be display: none;
here is the solution please not that i am doing it by targeting id finished
Js function
var selection = document.getElementById("listDisplayer");
var list = document.getElementsByTagName('li');
selection.onchange = function () {
var value = selection.options[selection.selectedIndex].value; // to get Value
for (var i = 0; i < list.length; i++) {
if (list[i].className.indexOf(value) > -1) {
list[i].style.display = "list-item";
} else {
list[i].style.display = "none"
}
}
}
css Code
.cats, .rats, .bats {
display: none;
}
JSFIDDLE
You have many things wrong in your code and a wrong setting in the jsFiddle. Here's a working version that also implements the "all" option:
Working demo: http://jsfiddle.net/jfriend00/5Efc5/
function applyToList(list, fn) {
for (var i = 0; i < list.length; i++) {
fn(list[i], list);
}
}
function hide(list) {
applyToList(list, function(item) {
item.style.display = "none";
});
}
function show(list) {
applyToList(list, function(item) {
item.style.display = "block";
});
}
function showListCategories() {
var value = document.getElementById("listDisplayer").value;
var itemList = document.getElementById("itemList");
var items = itemList.getElementsByTagName("li");
if (value === "all") {
show(items);
} else {
// hide all items by default
hide(items);
show(itemList.getElementsByClassName(value));
}
}
Changes made:
You have to fetch the .value of the select to see what the value was of the option that was picked. You were using the selectedIndex which is just a number.
A common technique for displaying only a set of objects is to hide all of them, then show just the ones you want. Since the browser only does one repaint for the entire operation, this is still visually seamless.
When finding items that match your class, you should be searching only the <ul>, not the entire document. I added an id to that <ul> tag so it can be found and then searched.
To save code, I added some utility functions for operating on an HTMLCollection or nodeList.
Tests for the "all" option and shows them all if that is selected
Changed the jsFiddle to the Head option so the code is available in the global scope so the HTML can find your change handler function.
Switched style settings to "block" and "none" since "visible" is not a valid setting for style.display.

jQuery/JS Output from array/loop

I have several links on a page, they are turned into an array with jQuery. Basically, when the user clicks "load more" on the page I would like to generate a <ul> with 4 images inside (or less if there aren't 4 remaining. I then need to shut the </ul>. I cannot figure out how I'd write this, does anyone know? Also, is this code ok or should it be tidied up somehow?
What I'd really like is a way to hide the 4 images while they load and then slide down the new <ul> but I don't know how as I don't know where I could write a callback function in there. Feel free to point me in the right direction if you know how!
My code so far;
var hrefs = jQuery.makeArray(jQuery('ul.js a'))
jQuery('#load_more').bind('click',function(){
jQuery('.img_gallery').append('<ul>')
for(var c = 0; c < 4; c++){
if((hrefs.length) > 0){
jQuery('<li>').append(jQuery('<img>', {src:hrefs[0]})).appendTo(jQuery('.img_gallery'))
hrefs.splice(0,1)
}
}
jQuery('.img_gallery').append('<ul>')
})
Thanks : )
Try this approach .. this is lot cleaner
var hrefs = jQuery.makeArray(jQuery('ul.js a'))
jQuery('#load_more').bind('click', function() {
var html = '<ul>'
for (var c = 0; c < 4; c++) {
if ((hrefs.length) > 0) {
html += '<li><img src="' + hrefs[0] + '" /></li>' ;
hrefs.splice(0,1);
}
}
html += '</ul>'
jQuery('.img_gallery').append(html )
})​
Your hrefs array contains DOM elements, not URLs. Try this instead:
var hrefs = jQuery.map(jQuery('ul.js a'), function(el,i) {
return $(el).attr('href');
});
Incidentally, you can optimize your for loop as follows:
for (var c = 0; c < 4; c++) {
if (hrefs.length) {
jQuery('<li>').append(jQuery('<img>', {
src: hrefs.shift() // removes and returns the first array element
})).appendTo(jQuery('.img_gallery'));
};
};​
When you use jQuery you are not appending html tags, you are appending html elements.
When you do $('.img_gallery').append('<ul>'), and then $('.img_gallery').append('<li>'), you end up with a structure like this:
<div class="img_gallery">
<ul></ul>
<li></li>
</div>
You do not have to worry about closing tags, just creating elements. jQuery "closes" all the tags for you in a sense. You need to append your li elements to the ul, not the .img_gallery. Just append to the last ul:
var hrefs = $.makeArray(jQuery('ul.js a'))
$('#load_more').bind('click',function(){
$('.img_gallery').append('<ul>');
for(var c = 0; c < 4; c++){
if((hrefs.length) > 0){
$('<li>').append($('<img>', {
src: $(hrefs[0]).attr('href'); // get the link reference from the element
})).appendTo($('.img_gallery ul').last()); // append to the last ul, not .img_gallery
hrefs.splice(0,1);
}
}
});
Or, you can keep your ul as a variable, add your li's and append the list after the loop:
var hrefs = $.makeArray(jQuery('ul.js a'))
$('#load_more').bind('click',function(){
var newul = $('<ul>'); // Makes an element, not a tag
for(var c = 0; c < 4; c++){
if((hrefs.length) > 0){
$('<li>').append($('<img>', {
src: $(hrefs[0]).attr('href'); // get the link reference from the element
})).appendTo(newul); // append to the ul you created
hrefs.splice(0,1);
}
}
$('.img_gallery').append(newul);
});

JavaScript: how to get img and div elements using getElementsByTagName

I have a tree structure as follows:
<ul id="theul275">
<li>
<div id="red"></div>
<img id="green" />
<script></script>
<div id="blue"></div>
</li>
</ul>
There are multiple UL's likes this on my page each with a different id. I am getting each UL by doing this:
var child = document.getElementById('theul' + id).getElementsByTagName('*');
the problem is, I only want to get the children of each ul which are either div's or img's.
Is there a way to get elements by multiple tag names?
I really appreciate any help because I am kind of new to JavaScript! Thanks!
Depending on what browsers you may to support, you could use the CSS selector interface.
document.getElementById('theul275').querySelectorAll('div, img');
Or use a library. There are plenty of options out there. I am familiar with two,
MooTools
$('theul275').getElements('div, img');
jQuery
$('#theul275').find('div, img');
Or get a reference to the li node, and loop through each node and check if the nodeName is DIV or IMG.
for (var i = 0, l = child.length; i < l; i++)
{
if (child[i].nodeName == 'DIV' || child[i].nodeName == 'IMG')
{
//...
}
}
You could use a iterative method for this.
var elemArray = document.getElementById('theul' + id).childNodes,
getChildByNodeName = function (elem, pattern) {
var childCollection = [],
re = new RegExp(pattern, 'g'),
getChild = function (elements) {
var childs = elements.childNodes,
i = 0;
if (childs) {
getChild(childs);
for (i = 0; i < childs.length; i += 1) {
if (childs[i].nodeName.match(pattern)) {
childCollection.push(childs[i]);
}
}
}
};
getChild(elem);
return childCollection;
}
var childs2 = getChildByNodeName(elemArray, '^(DIV|IMG)$'); // array of match elements
And just change the pattern ('^(DIV|IMG)$') to suite your needs.
If you can use jQuery, try
var child = $("#theul" + id).find("div,img");
Otherwise, see JavaScript NodeList.

Categories

Resources