SitePoint Sponsor

User Tag List

Results 1 to 12 of 12
  1. #1
    SitePoint Wizard bronze trophy cydewaze's Avatar
    Join Date
    Jan 2006
    Location
    Merry Land, USA
    Posts
    1,096
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)

    Using Javascript to apply CSS styles

    I'm working on a page that was created by someone else, and which uses Javascript to apply CSS style changes to certain elements on the page. Basically we have a home-built CMS that lets you browse the web directory and edit files. You select a file be ticking a checkbox next to the filename, and the aforementioned Javascript "unhides" the buttons to edit, rename, or delete a file.

    The Javascript is written in a way that if you select only one file, you have all options (edit, rename, and delete) but if you select more than one, you can only delete. It works very well, EXCEPT when there is only one item (file or subdirectory) in a directory, in which case you can't unhide any buttons. Here's the script in question.

    Code JavaScript:
        <script type="text/javascript">
     
        function hideButtons()
        {
                        document.getElementById('edit').style.visibility="hidden";
                        document.getElementById('rename').style.visibility="hidden";
                        document.getElementById('delete').style.visibility="hidden";
        }
     
     
     
        function showOptions()
        {
                        var thisItemChecked = 0;
                        if (document.getElementsByName('thisItem').length==1)
                        {
                                        if (document.getElementById('thisItem').checked==true)
                                        {
                                                        thisItemChecked++;
                                        }
                        } else if (document.getElementsByName('thisItem').length>1) {
                                        for (var i=0; i<document.editTopic.thisItem.length; i++)
                                        {
                                                        if (document.editTopic.thisItem[i].checked==true)
                                                        {
                                                                        thisItemChecked++;
                                                        }
                                        }
                        }
                        if (thisItemChecked==1)
                        {
                                        document.getElementById('edit').style.visibility="visible";
                                        document.getElementById('rename').style.visibility="visible";
                        } else {
                                        document.getElementById('edit').style.visibility="hidden";
                                        document.getElementById('rename').style.visibility="hidden";
                        }
                        if (thisItemChecked>=1)
                        {
                                        document.getElementById('delete').style.visibility="visible";
                        } else {
                                        document.getElementById('delete').style.visibility="hidden";
                        }
        }
        </script>

    The HTML (all three buttons are like this):

    Code HTML4Strict:
    <input type="image" name="edit" id="edit" src="images/edit_30x30.png" alt="Edit" title="Edit" />

    And the checkbox that triggers the Javascript is like this:

    Code HTML4Strict:
    <input type="checkbox" name="thisItem" id="thisItem#name#" value="#showDir##name#?type=#thisType#" onclick="showOptions();" />

    (the funny #things# are ColdFusion variables, so you can ignore them)

    The first function hides the buttons, and the other function does the rest. But why oh why won't it work when there's only one item in the directory?
    <cfset myblog = "http://cydewaze.org/">

  2. #2
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,712
    Mentioned
    102 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by cydewaze View Post
    The first function hides the buttons, and the other function does the rest. But why oh why won't it work when there's only one item in the directory?
    What is the value of thisItemChecked when there is only one item in the directory?
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  3. #3
    SitePoint Wizard bronze trophy cydewaze's Avatar
    Join Date
    Jan 2006
    Location
    Merry Land, USA
    Posts
    1,096
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by paul_wilkins View Post
    What is the value of thisItemChecked when there is only one item in the directory?
    Well I have to admit I'm not great with Javascript, so the only way I knew how to check this was to put an alert(thisItemChecked); in the JS code. If I put it up where it tests for zero, it returns zero. If I put it anywhere else, it doesn't pop up.

    If I leave it in the latter spot and browse to a directory with many items, it returns 1.
    <cfset myblog = "http://cydewaze.org/">

  4. #4
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,712
    Mentioned
    102 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by cydewaze View Post
    Well I have to admit I'm not great with Javascript, so the only way I knew how to check this was to put an alert(thisItemChecked); in the JS code. If I put it up where it tests for zero, it returns zero. If I put it anywhere else, it doesn't pop up.

    If I leave it in the latter spot and browse to a directory with many items, it returns 1.
    Let's get more eyes on to this then. Link us to a page that allows us to experience the same problem.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  5. #5
    SitePoint Wizard bronze trophy cydewaze's Avatar
    Join Date
    Jan 2006
    Location
    Merry Land, USA
    Posts
    1,096
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by paul_wilkins View Post
    Let's get more eyes on to this then. Link us to a page that allows us to experience the same problem.
    This is in our CMS, so I'll have to figure out a way to build a page that simulates the problem, because you have to be inside our building and on our network to get to the actual page in question. I think I can probably build a static version of the same page though, and stick it up on the web.
    <cfset myblog = "http://cydewaze.org/">

  6. #6
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,712
    Mentioned
    102 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by cydewaze View Post
    This is in our CMS, so I'll have to figure out a way to build a page that simulates the problem, because you have to be inside our building and on our network to get to the actual page in question. I think I can probably build a static version of the same page though, and stick it up on the web.
    jsfiddle.net is a good place to put up a test page.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  7. #7
    SitePoint Wizard bronze trophy cydewaze's Avatar
    Join Date
    Jan 2006
    Location
    Merry Land, USA
    Posts
    1,096
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Here we go!

    http://jsfiddle.net/4XHJL/1/

    Hopefully it works!
    <cfset myblog = "http://cydewaze.org/">

  8. #8
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,712
    Mentioned
    102 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by cydewaze View Post
    Here we go!

    http://jsfiddle.net/4XHJL/1/

    Hopefully it works!
    Okay, thanks. Now the code can be examined in context to ther HTML code that it's working with, an understanding of the problems can be arrived at.

    It's this part of the code that's the cause of the matter, but there are several reasons and solutions to it.

    Code:
    var thisItemChecked = 0;
    if (document.getElementsByName('thisItem').length==1) {
        if (document.getElementById('thisItem').checked==true) {
            thisItemChecked++;
        }
    } else if (document.getElementsByName('thisItem').length>1) {
        for (var i=0; i<document.editTopic.thisItem.length; i++) {
            if (document.editTopic.thisItem[i].checked==true) {
                thisItemChecked++;
            }
        }
    }
    The first issue is that there are no elements with an id of "thisItem"

    Code:
    if ([document.getElementById('thisItem').checked==true) {
    So we'll remove that first if section, and just use the lower one if the number of items is more than or equal to 1. That equality change is something that you have already attempted on your test page too.

    Code:
    var thisItemChecked = 0;
    if (document.getElementsByName('thisItem').length==1) {
        if (document.getElementById('thisItem').checked==true) {
            thisItemChecked++;
        }
    } else if (document.getElementsByName('thisItem').length >= 1) {
    The next issue is that document.editTopic can have some troubles, so when accessing a form, it's better to access it via the id attribute on the form.
    This allows us to then to easily access the named elements of the form via the form.elements collection.

    Code:
    var thisItemChecked = 0,
        form = document.getElementById('thisItem'),
        items = form.elements.thisItem;
    if (document.getElementsByName('thisItem')items.length >= 1) {
        for (var i = 0; i < document.editTopic.thisItemitems.length; i += 1) {
            if (document.editTopic.thisItemitems[i].checked === true) {
                thisItemChecked += 1;
            }
        }
    }
    And finally, the loop won't occur if there are 0 items, so the if condition around the loop can now be removed.

    Code:
    var thisItemChecked = 0,
        form = document.getElementById('thisItem'),
        items = form.elements.thisItem;
    if (document.getElementsByName('thisItem')items.length >= 1) {
        for (var i = 0; i < items.length; i += 1) {
            if (items[i].checked === true) {
                thisItemChecked += 1;
            }
        }
    }
    Which leaves us with the following working code:

    Code:
    var thisItemChecked = 0,
        form = document.getElementById('thisItem'),
        items = form.elements.thisItem;
    for (var i = 0; i < items.length; i += 1) {
        if (items[i].checked === true) {
            thisItemChecked += 1;
        }
    }
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  9. #9
    SitePoint Wizard bronze trophy cydewaze's Avatar
    Join Date
    Jan 2006
    Location
    Merry Land, USA
    Posts
    1,096
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by paul_wilkins View Post
    Okay, thanks. Now the code can be examined in context to ther HTML code that it's working with, an understanding of the problems can be arrived at.
    At least by one of us!



    Quote Originally Posted by paul_wilkins View Post
    The first issue is that there are no elements with an id of "thisItem"
    You're right. It's always "thisitem" with a variable appended to it, and that variable is the filename associated with the checkbox. In this case, that's index.cfm.



    Quote Originally Posted by paul_wilkins View Post
    The next issue is that document.editTopic can have some troubles, so when accessing a form, it's better to access it via the id attribute on the form.
    This allows us to then to easily access the named elements of the form via the form.elements collection.


    Code:
    var thisItemChecked = 0,
       form = document.getElementById('thisItem'),
       items = form.elements.thisItem;
    if (document.getElementsByName('thisItem')items.length >= 1) {
       for (var i = 0; i < document.editTopic.thisItemitems.length; i += 1) {
           if (document.editTopic.thisItemitems[i].checked === true) {
               thisItemChecked += 1;
           }
       }
    }
    But the first green line contains "getElementById('thisItem')" and we just established that there isn't an element with the ID "thisItem". I'm confused.



    Quote Originally Posted by paul_wilkins View Post
    Which leaves us with the following working code:


    Code:
    var thisItemChecked = 0,
       form = document.getElementById('thisItem'),
       items = form.elements.thisItem;
    for (var i = 0; i < items.length; i += 1) {
       if (items[i].checked === true) {
           thisItemChecked += 1;
       }
    }
    I haven't had success getting this to work, so I tried changing document.getElementById('thisItem') to document.getElementByName('thisItem') without any luck.
    Last edited by paul_wilkins; Mar 21, 2012 at 08:55. Reason: revert accidental edit
    <cfset myblog = "http://cydewaze.org/">

  10. #10
    SitePoint Wizard bronze trophy cydewaze's Avatar
    Join Date
    Jan 2006
    Location
    Merry Land, USA
    Posts
    1,096
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Oh weird! My reply is gone, but it looks like Paul's answer is there as if it was posted by me. VERY strange!

    Anyway, that did the trick! It needed to be the form's ID. Works like a charm now! Thanks Paul.
    <cfset myblog = "http://cydewaze.org/">

  11. #11
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,712
    Mentioned
    102 Post(s)
    Tagged
    4 Thread(s)
    My apologies on that. I chose edit instead of reply with quote, and at this late hour didn't notice until too late. In reply to post #9:

    Quote Originally Posted by cydewaze View Post
    But the first green line contains "getElementById('thisItem')" and we just established that there isn't an element with the ID "thisItem". I'm confused.
    That should be the id attribute of the form, which is editTopic instead.

    I've set the jsfiddle to use nowrap and no library, and the following code is tested to work with the HTML code that you have there.

    The array check with the items is due to a fun web browser inconsistancy, where if there's only one item then that item is given, whereas with multiple items it's an array-like collection that's returned instead.

    Code:
    var thisItemChecked = 0,
        form = document.getElementById('editTopic'),
        items = form.elements.thisItem;
    if (!items.length) {
        items = [items];
    }
    for (var i = 0; i < items.length; i += 1) {
        if (items[i].checked === true) {
            thisItemChecked += 1;
        }
    }
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  12. #12
    SitePoint Wizard bronze trophy cydewaze's Avatar
    Join Date
    Jan 2006
    Location
    Merry Land, USA
    Posts
    1,096
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Thanks again Paul, and again, it works perfectly (and I can almost make sense of it now!). It's no wonder my usual "edit and hope" method of trying to get it to work wasn't getting me anywhere.

    I had actually considered putting a hidden form item on the page with the same name as a workaround to ensure there were always at least two items in the directory. But it's better go get it working the right way.
    <cfset myblog = "http://cydewaze.org/">


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •