How to get Javascript's "getElementsByClassName()" to work? - javascript

When I do this, everything works just fine:
function openTab(tabName)
{
document.getElementById("divUsers").className = "invisible";
document.getElementById("divGroups").className = "invisible";
document.getElementById("divZFSPools").className = "invisible";
document.getElementById("divShares").className = "invisible";
document.getElementById(tabName).className = "visible";
}
But when I do this, nothing happens:
function openTab(tabName)
{
var targetTab, activeTab;
// Get the div:
targetTab = document.getElementById(tabName);
// If it is the active tab, return:
if(targetTab.style.display.className == "visible");
return;
// No, it is not the active tab:
document.getElementsByClassName("visible")[0].className = "invisible";
// Make the target tab visible:
document.getElementById(tabName).className = "visible";
}
FYI: "visible" and "invisible" are two CSS class names.
Does anyone have idea why? How can I achieve the desktop tab control behaviour using HTML and Javascript?

If I don't misunderstood you question just remove the ; after your if condition because a simple typo (;) can make huge difference to your code.
Assume,
if (0 === 1); { alert("Hello World") }
// equivalent to:
if (0 === 1) /*do nothing*/ ;
alert ("Hello World");
This code will alert "Hello World", but not because 0 equals 1, but
because of the semicolon. It makes JavaScript think that you have an
empty statement there, and everything to the right of it is treated as
no longer belonging to the if conditional and thus independent of it.
Source : https://www.codecademy.com/en/forum_questions/507f6dd09266b70200000d7e
So on your code it will be like this,
//If it is the active tab, return:
if(targetTab.style.display.className == "visible");
return; //^^ remove this semicolon

Related

Ideas for a correct function on my webpage?

I am having problems with a javascript function. I want to replace an icon by changing the class.
On my page, I have the following element:
<i class="wait icon" alt="{webui_botstatenotavailable}" title="{webui_botstatenotavailable}" id="{botname}"></i>
The following javascript should change the class, but it does not work:
function incomingBotStatusList(http_request, statusOff, statusOn)
{
if (http_request.readyState == 4)
{
if (http_request.status == 200)
{
if (http_request.responseText.length < 7)
{
// Error
}
else
{
var botStatusList = JSON.parse(http_request.responseText);
for (var key in botStatusList)
{
if (botStatusList.hasOwnProperty(key))
{
var botStatusImage = document.getElementById(key);
if (botStatusImage != null)
{
if (botStatusList[key] == 0)
{
botStatusImage.class.innerHTML = "images/bullet_red.png";
botStatusImage.title = statusOff;
botStatusImage.alt = statusOff;
}
else if (botStatusList[key] == 1)
{
botStatusImage.class.innerHTML = "<i class=\"checkmark green icon\">";
botStatusImage.alt = statusOn;
botStatusImage.title = statusOn;
}
}
}
}
}
}
}
}
Did someone from you know how it will work?
Thanks for your help!
Best Regards
Pierre
I see a couple of problems with your code. First, the <i> element is used to apply italic formatting to text. It is not the HTML code for an icon or an image.
Secondly, you write botStatusImage.class.innerHTML, but the Element.class does not exist, and Element.className is a string. It does not have an innerHTML attribute. So, you could write botStatusImage.className = "new_class_name"; and this would be more correct.
You should then change the image source by calling botStatusImage.setAttribute('src', new_url), where you have set new_url to the new image location.
Check out the javascript reference for the Element class that is returned from document.getElementById: check this link
My recommendation, start simple, then make it complex.
First, try to get the icon to change without the AJAX request. Try writing a function like this:
function changeIcon( imageId, newUrl ){
var element = document.getElementById( imageId );
element.setAttribute( "src", newUrl );
}
Then test this function in the console by passing calling it with the URL's manually.
Once that works, don't change it! Next add the AJAX call, and when you have the Icon url from your server response, all you do is call the function that you already wrote and tested. That way you separate the AJAX code from the image update code and you can test them separately.
The key is smaller functions. Build the easy stuff first, and then call those easy functions from the harder functions. Once you know the easy function works well, it becomes much easier to find problems in the harder functions.

getElementById not working within if statement - Troubleshooting

I have a simple JS script to swap out elements containing Flash and replace them with other formats for users who don't have Flash installed.
var hideclass="hidden"
var showclass="empty"
function flashFixMain(){
if (swfobject.hasFlashPlayerVersion("7.0.0")) {
document.getElementById('logoflash').className=showclass;
document.getElementById('logononflash').className=hideclass;
} else {
document.getElementById('logoflash').className=hideclass;
document.getElementById('logononflash').className=showclass;
}
}
And put simply, it doesn't work.
The if statement works fine - putting an alert in the appropriate place pops up fine.
I've checked the source of the appropriate page(s) online, and the element name pops up exactly as written (and only once!).
The class names work fine, as they are used as defaults on the page at the start.
So does anyone have any ideas what I might have missed?
change
document.getElementById('logoflash').class=showclass;
to
document.getElementById('logoflash').className = showclass;
it's className, not class
Instead of using .class you need to use the .className property; for instance:
document.getElementById('logoflash').className = showclass;
In modern browsers you can also use .classList to add a class rather than replace all existing classes:
document.getElementById('logoflash').classList.add(showclass);
As an aside, you could consider moving a few statements around like this:
var hasFlash = swfobject.hasFlashPlayerVersion("7.0.0"),
logoFlash = document.getElementById('logoflash'),
logoNonFlash = document.getElementById('logononflash');
logoFlash.className = hasFlash ? showclass : hideclass;
logoNonFlash.className = hasFlash ? hideclass : showclass;
I wrote up a quick test scenario and without seeing more of your environment, do not see anything that should keep this from working as expected.
The one thing I did notice while doing a write up w/o using jQuery (which I guess you are NOT using?) is that your 'addClass' is really a 'REPLACE' class value. You are simply setting it to a single class.
This makes me think, not having seen your environment, that some OTHER classes might be already assigned to your elements that are getting wiped out. This could be causing unexpected behaviour if some of your display is dependent on these other classes...
Without seeing more of your scenario, that is the only thing that seems like it might be an issue.
Anyway, here is my test setup. You might find something in this useful.
<div id="logoflash" class='something'>
Logoflash
</div>
<div id="logononflash" class='else' >
logononflash
</div>
<script>
var swfobject = {FlashPlayerVersion: '7.0.1', hasFlashPlayerVersion: function(v) {if(v == this.FlashPlayerVersion) return true; else return false;}, myName: 'fakeSWObject' };
console.log(swfobject)
var hideclass = "hidden"
var showclass = "empty"
var getById = function(sID) { return document.getElementById(sID); };
var addClass = function(sID, sClass) { getById(sID).className += ' ' + sClass };
function toggleEl(sID, bState){
console.log('begin toggleEl')
console.log('bState: ' + bState)
try {
if(bState == undefined) {
console.log('Toggling by element state');
getById(sID).style.display = getById(sID).style.display == 'none' ? 'block' : 'none';
} else {
console.log('Toggling by argument');
getById(sID).style.display = !!bState ? 'block' : 'none';
}
} catch (err) {
console.log(err);
}
}
function flashFixMain(){
if (swfobject.hasFlashPlayerVersion("7.0.0")) {
console.log('Is Flash 7.0.0');
toggleEl('logoflash', true);
toggleEl('logononflash', false);
addClass('logoflash', hideclass);
addClass('logononflash', showclass);
} else {
console.log('Is NOT Flash 7.0.0');
toggleEl('logoflash', true)
toggleEl('logononflash', false)
addClass('logoflash', showclass);
addClass('logononflash', hideclass);
}
}
$(function(){ // Yes, this is jQuery to fire after doc is ready
flashFixMain();
})
</script>
use Jquery:
$("#logoflash").addClass(hideclass);
or
$('#logoflash').toggleClass(hideclass, swfobject.hasFlashPlayerVersion("7.0.0"));

Javascript in jsp page outputs 'true' when var is defined in function

I have a webpage using a javascript. The code sample:
<script type="text/javascript">
var shown = 0;
function showOrHidePanel()
{
var isComplete = '<h:outputText value="#{general.sessionCompleted}" />';
if (isComplete == true){
if (shown==0) {
Richfaces.showModalPanel('pnl',{width:550, top:200});
}
shown = 1;
} else {
if (shown == 1) {
Richfaces.hideModalPanel('pnl');
}
shown = 0;
}
return;
}
</script>
<a4j:region>
<h:form>
<a4j:poll id="poll" interval="10000" reRender="pnl" action="#{general.checkOnDrcSession}"
oncomplete="showOrHidePanel()" />
</h:form>
</a4j:region>
The effect i'm trying to achieve is to make the modalpanel be shown by the polling component only once whenever sessionCompleted becomes true (So it wont show the flickering page effect on every re-show of the modalpanel.
But i'm a javascript newb and i'm afraid that, in addition to this not working correctly, I get a 'true' text at the top of the page.
When i take down the var isComplete = '<h:output... declaration, the 'true' text disappears.
Thanks for the help...
Get rid of those singlequotes.
var isComplete = <h:outputText value="#{general.sessionCompleted}" />;
You want to end up with
var isComplete = true; // or false
and not with
var isComplete = 'true'; // or 'false'
in the generated output.
Alternatively, you can also just do
if (<h:outputText value="#{general.sessionCompleted}" />) {
Try changing isComplete to just:
var isComplete = Boolean("#{general.sessionCompleted}");
This should (in theory) create a boolean value based on the text that is rendered by the server.

Resolving a JavaScript conflict

On a website, http://imgthis.com/blog/?p=34, I have two JavaScripts that load inside an iframe with an image gallery, one is lytebox which is a Light Box 2 slimmed down clone for image gallery pop ups and the other is a show only one div in a stack of divs. The lytebox script works until the show only one is invoked, from that point on it's broken in IE FF and Opera (Chrome and Safari do not throw an error) with this error:
Uncaught exception: TypeError: Cannot convert 'window.parent.frames[window.name]' to object Error thrown at line 223, column 1 in (imageLink, doSlide, doFrame) in [url to script]:
var anchors = (this.isFrame) ? window.parent.frames[window.name].document.getElementsByTagName('a') : document.getElementsByTagName('a');
called from line 204, column 56 in () in [url to script]:
myLytebox.start(this, false, false);
After it breaks you have to reload the page to get anything working again.
I'm assuming that it's a conflict, since it's only occurring after the other script has been invoked. Before the show only one is invoked it works perfectly.
This is the show only one code which is embedded into the page:
function showonlyone(thechosenone) {
var newboxes = document.getElementsByTagName('div');
for(var x=0; x<newboxes.length; x++) {
name = newboxes[x].getAttribute('name');
if (name == 'newboxes') {
if (newboxes[x].id == thechosenone) {
newboxes[x].style.display = 'block';
}
else {
newboxes[x].style.display = 'none';
}
}
}
}
I'm pretty lost as to how they could be conflicting since they are looking for different elements, though my JavaScript isn't that strong so maybe it makes all the difference in the world.
find line 223 of lytebox.js and make the following changes:
var anchors = (this.isFrame) ? window.parent.frames[window.name].document.getElementsByTagName('a') : document.getElementsByTagName('a');
to this:
var anchors = (this.isFrame && window.parent.frames[window.name].document) ? window.parent.frames[window.name].document.getElementsByTagName('a') : document.getElementsByTagName('a');
My lytebox.js had 2 occurrences
Suggestion: Find (this.isFrame) ? and replace with (this.isFrame && window.parent.frames[window.name].document) ?

Get control properties with javascript in firefox

I'm trying to access control's properties and although it works great in IE6, in FF3, it fails. I'm doing:
alert(document.getElementById(gridViewCtlId).style.display);
alert(document.getElementById(gridViewCtlId).style);
And the first one shows a blank popup while the second shows 'undefined'.
I do
alert(document.getElementById(gridViewCtlId).id);
and I get the proper ID of the box along with:
alert(document.getElementById(gridViewCtlId));
and I get that in an HTML table.
This works perfectly in IE but not FF. What do I need to do to get this functioning?
Edit: gridViewCtlId is defined as:
var gridViewCtlId = '<%=GridView.ClientID%>';
Here is the full code:
var itemVisible= '<%=ItemVisible.ClientID%>';
function onGridViewRowSelected(rowIdx)
{
alert(document.getElementById(gridViewCtlId).style.display);
alert(document.getElementById(gridViewCtlId).style);
if (document.getElementById(gridViewCtlId).disabled == false)
{
alert("hi1");
var selRowCCA = getSelectedRow(rowIdx);
if (curSelRow != null)
{
alert("hi2");
var previousRow = getSelectedRow(previousRowIndx);
var CountIdx = previousRowIndx % 2;
if (document.getElementById(itemVisible) == null)
{
if (CountIdx == 0)
{
alert("hi");
previousRow.style.backgroundColor = 'Silver';
}
else
{
previousRow.style.backgroundColor = 'White';
}
}
}
if (null != selRow)
{
alert("new");
previousRowIndx = rowIdx;
curSelRow = selRow;
selRow.style.backgroundColor = 'Red';
}
}
}
It's pretty much an onClick where I have to call that function to turn it back to its original color (using alternating color rows). IE, this works fine. If i do the first alert
alert(document.getElementById(gridViewCtlId).disabled);
I would get either true or false.
The reason it's like this is because someone is going to enter something in a text box and the first gridview is going to populate depending on whats in that textbox. Then when someone selected something in the first gridview, that gridview is going to become disabled and then populate a second. So i'm having an issue checking for the disabled part of the gridview.
<div id="test">
</div>
<script type="text/javascript">
var gridViewCtlIdCCA = 'test';
alert(document.getElementById(gridViewCtlIdCCA).style);
</script>
Alerts [object CSSStyleDefintion] in Firefox 2 and 3.
If .style where undefined, .style.display would produce an error, not alert an empty dialog (unless you are capturing window.onerror).
Can you create an SSCCE that demonstrates the problem. More information about SSCCE available here.

Categories