Dynamic show/hide div with javascript not working - javascript

I have a basic show/hide javascript that works, as long as i don't make it dynamic and make sure of a parameter. I would appreciate a lot if anyone could help me figure out why the dynamic version doesn't work.
Working code:
javascript
function togglesDiv(){
var catdiv = document.getElementById("addNewCat");
if(catdiv.style.display == ""){
catdiv.style.display = "none";
} else {
catdiv.style.display = "";
}
}
html
<span onclick="togglesDiv();">Add new category</span>
<div id="addNewCat" style="display: none;">
lalala
</div>
Non working code:
javascript
function togglesDiv(divsId){
var catdiv = document.getElementById("divsId");
if(catdiv.style.display == ""){
catdiv.style.display = "none";
} else {
catdiv.style.display = "";
}
}
html
<span onclick="togglesDiv(addNewCat);">Add new category</span>
<div id="addNewCat" style="display: none;">
lalala
</div>

You have a variable name wrapped in string delimiters, making it a string literal instead of a variable. Change
var catdiv = document.getElementById("divsId");
To
var catdiv = document.getElementById(divsId);
On the flipside, the call to the function needs the quotes in it's argument (because it should be a string), you can use single quotes to avoid confliction:
<span onclick="togglesDiv('addNewCat');">Add new category</span>

Your code is looking for a div with an ID "divsId" change your code to:
function togglesDiv(divsId){
var catdiv = document.getElementById(divsId);
if(catdiv.style.display == ""){
catdiv.style.display = "none";
} else {
catdiv.style.display = "";
}
}

Because you are looking for a div called "divsId" rather than the value in the variable divsId.
Remove the speach marks!

Remove quotes from
var catdiv = document.getElementById("divsId");
should be
var catdiv = document.getElementById(divsId);
And add quotes:
<span onclick="togglesDiv(addNewCat);">Add new category</span>
Should be
<span onclick="togglesDiv('addNewCat');">Add new category</span>

Remove the quotes:
var catdiv = document.getElementById("divsId");
Becomes
var catdiv = document.getElementById(divsId);
You don't have an element with an ID of "divsId".
On a completely unrelated note, you can't be sure that catdiv.style.display will always be equal to "" when it is visibile. There are other styles which cause it to be displayed ('inline', 'block', for example).
A better solution might be:
function togglesDiv(divsId){
var catdiv = document.getElementById("divsId");
if(catdiv.style.display === "none"){
catdiv.style.display = "";
} else {
catdiv.style.display = "none";
}
}
(And yes, I did mean to put the triple equals === in)

Improved function
function toggleDisplay(id){
var el = document.getElementById(id);
if(!el) return true;
// feature detect to support IE versions.
var dis = 'currentStyle' in el ? el.currentStyle.display : el.style.display;
// toggle display
el.style.display = /none/i.test(dis) ? '' : 'none';
// prevent memory leak
el = null;
}
And as mentioned, quotes are needed when writing yucky inline javascript.
<span onclick="toggleDisplay('addNewCat')"> ... etc
Tbh. pick a js toolkit/library and use it over reinventing the wheel yourself and stop writing inline javascript, your life and happiness will improve substantially if you do =P

Related

How to pass c# variable to javascript function

I have variable containing some text.Basically I am trying to do toggle(hide/show) in html using c#.I want to pass this variable to javascript function that is performing hide and show .
Here is my code:
static void Main(string[] args)
{
string res = null;
string toggle = null;
res += "<div style=\"display: none;\">This is the content that is dynamically being collapsed.</div>";
toggle += "<html><head>";
toggle += "<script type=\"text/javascript\"></script><script> function toggle2(showDetails) {var ele =document.getElementById(showDetails);if(ele.style.display == \"block\") {ele.style.display = \"none\";}else {ele.style.display = \"block\";}}</script>";
toggle += "</head>";
toggle += "<body>";
toggle += "collapse";
toggle += "</body>";
toggle += "</html>";
FileStream log = new FileStream(#"E:\report2.html", FileMode.Create);
using (StreamWriter w = new StreamWriter(log, Encoding.UTF8))
{
w.WriteLine(toggle);
}
}
On clicking collapse,it should display the content of variable res.Where am I doing wrong?
Thanks in advance
You've got multiple issues:
The "quotes" inside your string are messing with the href="quotes"
Your JavaScript function is incorrect
The general approach is unusual/ very error-prone
Nitpicking: Don't use += and null
First, those quotes
Take a look at your file report2.html in your favourite text editor and you'll probably see this:
<a href="javascript:toggle2('<div style="display: none;">This is the content that is dynamically being collapsed.</div>')">
StackOverflow's code colouring helps here - notice that display:none; is black. This is because it's essentially seeing just href="javascript:toggle2('<div style="
A simple fix is to double-escape those quotes in your res string:
<div style=\\\"display: none;\\\">This is the content..
..but yikes. This kind of thing is really not recommended unless you have to!
Second, the function
I (and many others!) really dislike JavaScript inside a string like this - it promotes bad code formatting, for starters. Let's undo that and make it pretty:
function toggle2(showDetails) {
var ele =document.getElementById(showDetails);
if(ele.style.display == "block") {
ele.style.display = "none";
}else {
ele.style.display = "block";
}
}
That's better! So, firstly, showDetails is not an ID of an element - it's a full string of content. Pass an ID instead:
function toggle2(elementID) {
var ele =document.getElementById(elementID);
if(ele.style.display == "block") {
ele.style.display = "none";
}else {
ele.style.display = "block";
}
}
This way you can instead use, e.g:
toggle+="<div id='collapsibleDiv'>"+res+"</div>";
toggle+="<div onmousedown=\"toggle2('collapsibleDiv');\">Click me!</div>";
instead. A bonus here is that it doesn't need to deal with those quotes in res.
Null and +=
Right at the start you've got this:
string res=null;
res+="...";
It's safer to just use string res=".."; instead as adding a null to anything is bad practice. Some programming languages will straight crash on you.

Overwrite text with javascript

I want to overwrite some standard text from my CMS.
<form accept-charset="UTF-8" action="/da-DK/listings" class="new_listing"
enctype="multipart/form-data" id="new_listing" method="post"
novalidate="novalidate"><div style="margin:0;padding:0;display:inline">
<input name="utf8" type="hidden" value="✓"><input name="authenticity_token" type="hidden"
value="vvEeH5tHhuGME4jNDPhw0o4w8KoWpwgchgrU7xG/7LQ="></div>
<label class="input" for="listing_title">CHANGE THIS TEXT</label>
I want to change the text where it says "CHANGE THIS TEXT" using javascript. I know very basic javascript though, so I hoped someone here could help me.
I already have code that enables me to change a text with an ID, but this label doesn't have an ID, so I don't know how to go about it.
Thank you for your time.
The script can only be posted in the head section of the whole site (even though it's specific to one ingle page).
Here is my other script that worked for ID:
<script>
var texts = [];
texts["new-listing-link"] = "NEW TEXT HERE";
var interval = setInterval(function() { setText(); }, 100);
function setText() {
var textsCopy = texts.slice();
for (var key in texts) {
var element = document.getElementById(key);
if (element != null) {
element.innerHTML = texts[key];
delete texts[key];
}
}
if (texts.length == 0) {
window.clearInterval(interval);
}
}
</script>
How can I go about it? :)
I'm pretty sure I'm only allowed to use javascript and not jQuery
Here's another way, no need to change what you've got
document.querySelector('label[for=listing_title]').innerHTML = 'New Label';
no jQuery bloat, no fumbling through arrays, quick and simple
querySelector works just like jQuery, but it has native speed and zero bloatage.
label[for=listing_title] finds the label that has an attribute "for" with the value "listing_title" ... so, while not guaranteed to be unique, not many forms have more than one label "for" an input
var texts = {}; // note {} not []
texts["label[for=listing_title]"] = "NEW TEXT";
var interval = setInterval(function() {
setText();
}, 100);
function setText() {
var textsCopy = texts.slice(); // why???
for (var key in texts) {
var element = document.querySelector(key);
if (element != null) {
element.innerHTML = texts[key];
delete texts[key];
}
}
if (texts.length == 0) {
window.clearInterval(interval);
}
}
With the above version, you can mix id's as well as the more complex selectors ... so, your original substitution could be done as well in the same loop by adding
texts["#new-listing-link"] = "NEW TEXT HERE";
Note the '#' before the id
Another hint or two:
var texts = {
"label[for=listing_title]": "NEW TEXT",
"#new-listing-link": "NEW TEXT HERE"
}; // declare the text object in one go
var interval = setInterval(setText, 100); // this is equivalent (not exactly identical, but functionally identical to your code
// rest of your code
The script can only be posted in the head section of the whole site (even though it's specific to one ingle page).
Here is my other script that worked for ID:
<script>
var texts = [];
texts["new-listing-link"] = "NEW TEXT HERE";
var interval = setInterval(function() { setText(); }, 100);
function setText() {
var textsCopy = texts.slice();
for (var key in texts) {
var element = document.getElementById(key);
if (element != null) {
element.innerHTML = texts[key];
delete texts[key];
}
}
if (texts.length == 0) {
window.clearInterval(interval);
}
}
</script>
How can I go about it? :)
I'm pretty sure I'm only allowed to use javascript and not jQuery
This should do the trick (quick'n'dirty):
slice=Function.prototype.call.bind([].slice);
slice(document.querySelectorAll(".input")).map(function(x){ return x.textContent="Killroy was here"; });
Check the Fiddle
MDN on Array.prototype.slice()
MDN on Array.prototype.map()
MDN on Document.querySelectorAll()
If you need just this label, choose:label[for=listing_title] as in Jaromanda Xs answer
var label = document.getElementsByTagName("label")[0] // If this is the first label of the page
label.value = "new text";

Javascript - change all classes for range of id's except 1

I have a basic image gallery that I have created. I want to highlight which image number is currently being viewed.
I have the following code which works as intended, but is very cumbersome and there must be a superior way to achieve the same!
function changeImg(imgId) {
document.getElementById('img').src = 'thumbs/' + imgId + '.jpg';
if (imgId == '1') {
document.getElementById('1').className = 'gallery-nav-link-current';
document.getElementById('2').className = 'gallery-nav-link';
document.getElementById('3').className = 'gallery-nav-link';
} else if (imgId == '2') {
document.getElementById('1').className = 'gallery-nav-link';
document.getElementById('2').className = 'gallery-nav-link-current';
document.getElementById('3').className = 'gallery-nav-link';
} else if (imgId == '3') {
document.getElementById('1').className = 'gallery-nav-link';
document.getElementById('2').className = 'gallery-nav-link';
document.getElementById('3').className = 'gallery-nav-link-current';
}
}
<a href="#" class="gallery-nav-link-current" id="1" onclick="changeImg(1)" ;>1</a>
<a href="#" class="gallery-nav-link" id="2" onclick="changeImg(2)" ;>2</a>
<a href="#" class="gallery-nav-link" id="3" onclick="changeImg(3)" ;>3</a>
<img class="gallery-img" src="thumbs/1.jpg" id="img">
The code I have works now, but I would like to understand and make a much less cumbersome piece of code to do the highlighting.
Any pointers gratefully appreciated.
Thanks,
Dingo Bruce
Please try the folliwng what we do here is set the imgId to current, and check others if not same imgId add normal class:
<script>
function changeImg(imgId) {
document.getElementById('img').src = 'thumbs/'+imgId+'.jpg';
document.getElementById(imgId).className = 'gallery-nav-link-current';
for(i=1; i <= 3; i++)
if(imgId != i.toString())
document.getElementById(i.toString()).className = 'gallery-nav-link';
}
</script>
Create an array of ids which do not need to be highlighted.
Loop over this array to apply gallery-nav-link class to elements matching current array item's id.
apply class gallery-nav-link-current to the input id
Here's a couple of ideas to improve the code.
Since the parameter 'imgId' matches the DOM id, you can set current link without a check.
document.getElementById(imgId).className = 'gallery-nav-link-current';
Keep track of what the current link id is in a variable - for simplicity use a global variable - and only reset that DOM element to gallery-nav-link.
So, outside you function declare
var lastNavLinkId = null;
Then, inside the changeImg function
if (lastNavLinkId ) {
document.getElementById(lastNavLinkId ).className = 'gallery-nav-link';
}
lastNavLinkId = imgId;

Javascript not updating text within a div

I must be daft, but the javascript is not changing the containing div text as I would expect once the div is clicked:
favourite.onclick = function() {
loadXMLDoc('indexFavourite');
var linkclass = favourite.className;
if(linkclass == 'favouriteOption')
favourite.className = 'favouriteOptionActive',
favourite.className.update("New text");
else
favourite.className = 'favouriteOption';
}
Your syntax is way off, missing bracket and whatnot
favourite.onclick = function() {
loadXMLDoc('indexFavourite');
var linkclass = favourite.className;
if(linkclass == 'favouriteOption') {
favourite.className = 'favouriteOptionActive',
favourite.innerHTML="New text";
}
else {
favourite.className = 'favouriteOption';
}
}
What you are doing here is changing the class of a div (probably). And even this is kinda wrong. I mean
favourite.className = 'favouriteOptionActive',
favourite.className.update("New text");
should actually produce an error, because the string favouriteOptionActive doesn't have a method update. It could have only if you patch the String.prototype.
If you want to change the div's text you should use div.innerHTML or div.innerText.
favorite.text('New text') will set the text
note this will work if using jQuery, my bad!

div won't display on click of an image

No idea where the problem lies, tried various things and I'm not having any luck. I've done this successfully before in the past but now it won't work, any help would be great...
HTML snippet:
<tr>
<td class="tableContent noBorderSides paddingAll"><img class="imgResize" src="images/emptyCircle.png" onclick="expandItem()"/>
<div id="Expand" class="hiddenDiv">
HELLO?
</div>
JavaScript:
function expandItem() {
if (document.getElementById("Expand").style.display == 'block') {
document.getElementById("Expand").style.display = 'none';
}
else if (document.getElementById("Expand").style.display == 'none') {
document.getElementById("Expand").style.display = 'block';
}
}
CSS:
.hiddenDiv {
display: none;
}
What am I doing wrong?
The initial display that is set in your CSS won't be reachable from the .style property.
Do it like this:
function expandItem() {
var expand = document.getElementById("Expand");
if (expand.style.display == '') {
expand.style.display = 'block';
}
else if (expand.style.display == 'block') {
expand.style.display = '';
}
}
Or a little shorter like this:
function expandItem() {
var expand = document.getElementById("Expand");
expand.style.display = (expand.style.display == '') ? 'none' : '';
}
Use .getComputedStyle() to get any style attributes associated with a given element. Notice, that the object returned is read only, so you'll want to use this for the initial if statement, and then set the style as you were doing above.
You could just remove the class from the element that defines the hidden property and add when you want to hide:
if (document.getElementById("Expand").className == '') {
document.getElementById("Expand").className = 'hiddenDiv';
}
else if (document.getElementById("Expand").className == 'hiddenDiv') {
document.getElementById("Expand").className = '';
}
Do note that if you have other classes on that element you will need to do a little string manip rather than just a straight check and remove.
//Temporary solution
//Replace your javascript code with following code
if (document.getElementById("Expand").style.display == 'block') {
document.getElementById("Expand").style.display = 'none';
}
else{
document.getElementById("Expand").style.display = 'block';
}
//Note :- Javascript detect '' (empty) when it try to search display property for expand block
#user1689607's answer is right if you need to just use javascript. If you have access to jQuery you can do it like so
$("#Expand").toggle();
And a simple jsfiddle to demonstrate: http://jsfiddle.net/P36YA/

Categories