I finally figured out what makes the elements I’ve dubbed ‘folders’ to open and close. The issue is when I run the HTML document through the validator, it says attribute <isfolder="true"> not allowed on div element at this point.
<p></p>
<div class="folderOpenClose" onclick="toggleAllFolders();">Open/Close Folders</div>
<p></p>
<div class="folderlabel" onclick="togglefolder('folder0');">Dice Roller</div>
<div id="folder0" class="folder" isfolder="true" style="display: none;">
</div>
<p></p>
<div class="folderlabel" onclick="togglefolder('folder1');">Slide Show</div>
<div id="folder1" class="folder" isfolder="true" style="display: none;">
</div>
<p></p>
<div class="folderlabel" onclick="togglefolder('folder2');">Carousel</div>
<div id="folder2" class="folder" isfolder="true" style="display: none;">
</div>
<p></p>
<div class="folderlabel" onclick="togglefolder('folder3');">Menu Bar</div>
<div id="folder3" class="folder" isfolder="true" style="display: none;">
</div>
<p></p>
The problem with me removing that is it what operates the Open/Close All and when I tried placing the code in the form in the , the Open/Close folder doesn’t work.
var lastChecked = null;
function togglefolder(id){
var ele = object(id);
if(ele.style.display == 'none') ele.style.display='block';
else ele.style.display = 'none';
}
function setAllFolders(how){
var way = ""+how;
if(way == "") way = "none";
if(way == "closed") way = "none";
if(way == "open") way = "block";
var divs = window.document.getElementsByTagName('div');
for(var i=0; i < divs.length; i++){
if(divs[i].getAttribute('data-isfolder')&&divs[i].getAttribute('data-isfolder')=='true')
divs[i].style.display = way;
var thisClass = ""+divs[i].getAttribute('class');
if(thisClass=='folderlabel'){
var thelabel = ""+divs[i].innerHTML;
if(thelabel.indexOf('open/close all folders') != -1)
divs[i].setAttribute('class','folderlabelopen');
}
}
last_toggle=way;
}
<div id="folder2" class="folder" isfolder="true" style="display: none;"></div>
isfolder is not a known HTML property, so it is being flagged.
One solution is to use a data-* attribute such as:
<div id="folder2" class="folder" data-isfolder="true" style="display: none;"></div>
Then your code can use:
if(divs[i].getAttribute('data-isfolder') == 'true')
There is also a nifty dataset API that you could use.
More info on data-* properties.
Related
Right, so I've managed to cobble together something that sort of works in terms of a search function within my webpage, however say I search for "Amethyst" it'll group "Placeholder1" into the search as well.
There's probably something very obvious that I'm missing here, but I'll put a small snippet of the code here, not enough to re-create but it's fairly straight forward.
var input = document.getElementById("myInput");
input.addEventListener("input", myFunction);
function myFunction(e) {
var filter = e.target.value.toUpperCase();
var list = document.getElementById("products");
var divs = list.getElementsByTagName("div");
for (var i = 0; i < divs.length; i++) {
var a = divs[i].getElementsByTagName("a")[0];
if (a) {
if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
divs[i].style.display = "";
} else {
divs[i].style.display = "none";
}
}
}
}
<input type="text" id="myInput" placeholder="Search" onkeyup="myFunction()" style="font-size:20px; padding-left: 15px;">
<div id="products" class=" w3-row w3-grayscale" style="width:100%">
<div class="w3-col l3 s6">
<a href="#"><div class="w3-container">
<div class="w3-display-container">
<img src="C:\Users\Harrison Gobey\Downloads\Dice\amethyst1.png" style="width:100%">
<div class="w3-display-middle w3-display-hover">
</div>
</div>
<p>Amethyst<br>£45.00</p>
</div></a>
<a href="#"><div class="w3-container">
<div class="w3-display-container">
<img src="C:\Users\Harrison Gobey\Downloads\Dice\bloodstone1.png" style="width:100%">
<div class="w3-display-middle w3-display-hover">
<button class="w3-button w3-black">Buy now <i class="fa fa-shopping-cart"></i></button>
</div>
</div>
<p>Placeholder1<br>£0.00</p>
</div></a>
</div>
NOTE: This is not enough code to replicate anything, but I'm fairly certain the problem lies within this code.
If there's anything else you'd need to help that I've omitted then please let me know. Thanks!
The main issue here is that you're attempting to get the value of e.target.value.toUpperCase(), which is undefined. What you actually want is the uppercased value of myInput, since that's what you'll want to find in your HTML content.
Here's a refactor of your script using querySelector with your existing HTML content that will work (and a more efficient for loop). This code will only look at the paragraph tag that contains your description.
<script>
var input = document.getElementById("myInput");
input.addEventListener("input", myFunction);
function myFunction() {
var filter = document.getElementById("myInput").value.toUpperCase();
var paragraphs = document.querySelectorAll("#products div a p")
for (let i=0, p; p = paragraphs[i]; i++)
{
if (p.innerHTML.toUpperCase().indexOf(filter) > -1)
{
p.parentElement.parentElement.style.display = "block";
}
else
{
p.parentElement.parentElement.style.display = "none";
}
}
}
</script>
I have encountered a problem with expandable divs. Here is my code:
HTML:
<div>more...</div>
<div class="expand" style="display:none">
YO DAWgGG
</div>
JS:
<script type="text/javascript" charset="utf-8">
function showHide(elementid){
if (document.getElementsByClassName("expand").style.display == 'none'){
document.getElementsByClassName("expand").style.display = '';
} else {
document.getElementsByClassName("expand").style.display = 'none';
}
}
</script>
It says that expand is undefined. But I don't see why. What am I doing wrong? Same code works if i use an ID but i need this for more than one div.
Thanks!
You need to do document.getElementsByClassName("expand")[0] as getElementsByClassName returns an array of object.
function showHide(el){
if (document.getElementsByClassName(el)[0].style.display == 'none'){
document.getElementsByClassName(el)[0].style.display = '';
} else {
document.getElementsByClassName(el)[0].style.display = 'none';
}
}
<div>more...</div>
<div class="expand" style="display:none">
YO DAWgGG
</div>
Based on the existing markup. I recommend to use document.querySelectorAll, and instead of setting an elements style, toggle its class.
var links = document.querySelectorAll('.link');
for (var i=0; i<links.length; i++) {
links[i].addEventListener('click', function(e){
e.target.parentElement.nextElementSibling.classList.toggle('show');
})
}
.expand {
display: none;
}
.expand.show {
display: block;
}
<div><a class="link" href="#">more...</a></div>
<div class="expand">
YO DAWgGG 1111
</div>
<div><a class="link" href="#">more...</a></div>
<div class="expand">
YO DAWgGG 222
</div>
<div><a class="link" href="#">more...</a></div>
<div class="expand">
YO DAWgGG 333
</div>
document.getElementsByClassName returns you a HTMLCollection and not a HTMLElement and hence you cant use .style on the collection.
So, if you need to apply some styling on all elements of the collection, you need to iterate over and apply.
Here is what you could do.
document.addEventListener('DOMContentLoaded', function() {
let anchors = document.querySelectorAll(".more");
[].forEach.call(anchors, (anchor) => {
anchor.addEventListener("click", (event) => {
event.preventDefault();
let parent = event.target.parentNode;
let ele = parent.querySelector(".expand");
if (ele.style.display == 'none') {
ele.style.display = '';
} else {
ele.style.display = 'none';
}
})
})
});
<div><a class="more" href="#">more...</a>
<div class="expand" style="display:none">
YO DAWgGG
</div>
</div>
<div><a class="more" href="#">more-2-...</a>
<div class="expand" style="display:none">
YO DAWgGG-2
</div>
</div>
I have the following html:
<div id="prog" class="downloads clearfix">
<div class="item">
<div class="image_container">
<img src="/img/downloads/company.png" width="168" height="238" alt="">
</div>
<div class="title">
pricelist: <label id="pr1"></label>
</div>
<div class="type">
pdf document
</div>
<div class="link">
<a id="pdfdocument" class="button" target="_blank" href="#">start Download </a>
</div>
</div>
</div>
I want build HTML which is inside the <div id="prog"> with Javascript:
<div id="prog" class="downloads clearfix"></div>
I'm trying to use this Javascript, but without success:
var tmpDocument, tmpAnchorTagPdf, tmpAnchorTagXls, parentContainer, i;
parentContainer = document.getElementById('prog');
for (i = 0; i < documents.length; i++) {
tmpDocument = documents[i];
tmpAnchorTagPdf = document.createElement('a id="pdfdocument" ');
tmpAnchorTagPdf.href = '/role?element=' + contentElement.id + '&handle=' + ope.handle;
tmpAnchorTagPdf.innerHTML = 'start Download';
tmpAnchorTagXls = document.createElement('a');
tmpAnchorTagXls.href = '/role?element=' + contentElement.id + '&handle=' + ope.handle;
tmpAnchorTagXls.innerHTML = 'start Download';
parentContainer.appendChild(tmpAnchorTagPdf);
parentContainer.appendChild(tmpAnchorTagXls);
}
If this is a section of code that you will be using more than once, you could take the following approach.
Here is the original div without the code you want to create:
<div id="prog" class="downloads clearfix">
</div>
Create a template in a hidden div like:
<div id="itemtemplate" style="display: none;">
<div class="item">
<div class="image_container">
<img src="/img/downloads/company.png" width="168" height="238" alt="">
</div>
<div class="title">
pricelist: <label></label>
</div>
<div class="type">
pdf document
</div>
<div class="link">
<a class="button" target="_blank" href="#">start Download </a>
</div>
</div>
</div>
Then duplicate it with jquery (OP originally had a jquery tag; see below for JS), update some HTML in the duplicated div, then add it to the document
function addItem() {
var item = $("#itemtemplate div.item").clone();
//then you can search inside the item
//let's set the id of the "a" back to what it was in your example
item.find("div.link a").attr("id", "pdfdocument");
//...the id of the label
item.find("div.title label").attr("id", "pr1");
//then add the objects to the #prog div
$("#prog").append(item);
}
update
Here is the same addItem() function for this example using pure Javascript:
function JSaddItem() {
//get the template
var template = document.getElementById("itemtemplate");
//get the starting item
var tempitem = template.firstChild;
while(tempitem != null && tempitem.nodeName != "DIV") {
tempitem = tempitem.nextSibling;
}
if (tempitem == null) return;
//clone the item
var item = tempitem.cloneNode(true);
//update the id of the link
var a = item.querySelector(".link > a");
a.id = "pdfdocument";
//update the id of the label
var l = item.querySelector(".title > label");
l.id = "pr1";
//get the prog div
var prog = document.getElementById("prog");
//append the new div
prog.appendChild(item);
}
I put together a JSFiddle with both approaches here.
I've been trying to include a simple javascript to Google Sites. However it doesn't work when pressing the button. I put the code inside an HTML Box. The code works perfectly when tested locally. Here is my code:
<script>
function expandCollapse() {
for (var i=0; i<expandCollapse.arguments.length; i++) {
var element = document.getElementById(expandCollapse.arguments[i]);
element.style.display = (element.style.display == "none") ? "inline" :
"none";
}
}
</script>
<div id="L13a" style="display: inline;">
Lent
</div>
<div id="L13b" style="display: none;">
Lent
<ul>
<li><strong>tba</strong><br/>
tba
</li>
</ul>
</div>
Is there something I made a stupid mistake?
You should change your function to this:
function expandCollapse() {
for (var i = 0; i < arguments.length; i++) {
var element = document.getElementById(arguments[i]);
element.style.display = (element.style.display == "none") ? "inline" :
"none";
}
}
And you should call it onclick and not in href
<div id="L13a" style="display: inline;"> <a onclick="expandCollapse('L13a', 'L13b');">Lent</a>
</div>
<div id="L13b" style="display: none;"> <a onclick="expandCollapse('L13a', 'L13b');">HI Lent</a>
Demo:http://jsfiddle.net/TvHdU/
when i press any key i need to display first div "d1" others hide and i press any key again it display secound div "d2" others hide and press any key again it display third div "d3" others hide ..till six div..not repeating the process again.
<div class="objects" id="d1">
<img src="images/d1.jpg" />
</div>
<div class="objects" id="d2">
<img src="images/d2.jpg" />
</div>
<div class="objects" id="d3">
<img src="images/d3.jpg" />
</div>
.......
.......
<div class="objects" id="d6">
<img src="images/d6.jpg" />
</div>
when i press any key i need to display 1st div then i press any key display 2nd div..till 6th div..
how to do it in javascript?
<html>
<head>
<style type="text/css">
.Div
{
display: none;
}
</style>
<script type="text/javascript">
var i = 0;
function KeyHandler() {
i++;
var divs = document.getElementsByClassName("Div");
for (var div = 0; div < divs.length - 1; div++) {
divs[div].style.display = 'none';
}
var ele = document.getElementById("d" + i);
ele.style.display = "block";
}
</script>
</head>
<body onkeyup="KeyHandler()">
Press any key..
<div id="d1" class="Div">
<h5>
Div1</h5>
</div>
<div id="d2" class="Div">
<h5>
Div2</h5>
</div>
<div id="d3" class="Div">
<h5>
Div3</h5>
</div>
<div id="d4" class="Div">
<h5>
Div4</h5>
</div>
<div id="d5" class="Div">
<h5>
Div5</h5>
</div>
<div id="d6" class="Div">
<h5>
Div6</h5>
</div>
</body>
</html>
Try this out
var currentVisible = 0;
document.onkeyup = function() {
// First hide all by class 'objects'
// Requires IE9+ FF3+, others are supported
var objs = document.getElementsByClassName('objects');
for (var i=0; i<objs.length; i++) {
objs[i].style.display = 'none';
}
// Show the one we are supposed to show
if (++currentVisible == 7)
currentVisible = 1;
var el = document.getElementById('d' + currentVisible);
el.style.display = 'block';
}
100% untested tho, since I have no access to any fiddle atm.