SitePoint Sponsor

User Tag List

Results 1 to 9 of 9
  1. #1
    SitePoint Zealot AVdes's Avatar
    Join Date
    Jun 2005
    Location
    GA
    Posts
    106
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    must read div# not create/modify it.

    I have dynamically created div fields numbered, using primeBase which creates the fields from information pulled from a database. When a field is created the div is dynamically assigned div="attendee + #".

    Code HTML4Strict:
    <div>
      <div onclick="javascript:showAttendee('attendee1')"></div>		
      <div id="@attendee'+objectSetValue'('somethingSomething')"></div>
     
      <div onclick="javascript:showAttendee('attendee2')"></div>		
      <div id="@attendee'+objectSetValue'('somethingSomething')"></div>
    </div>

    The above is what it looks like.

    Code HTML4Strict:
    <div>
      <div onclick="javascript:showAttendee('attendee1')"></div>		
      <div id="attendee1"></div>
     
      <div onclick="javascript:showAttendee('attendee2')"></div>		
      <div id="attendee2"></div>
    </div>

    The above is how it looks if you view source.

    I need it to be able to open and close by clicking on the div directly above it.

    I found two options. The first will open as many as I want to open, in any order, and opening or closing it will not affect the others.

    This is what I want, But it doesn't work when the div's are numbered dynamically with PrimeBase. It has to read the number not create or modify it.

    Code JavaScript:
    function showAttendee(id) {
    	var myAttend = document.getElementById(id);
    	if(myAttend.style.display=="block" || myAttend.style.display=="") {
    		myAttend.style.display="none";
    		} else {
    		myAttend.style.display="block";
    		}
    	}

    This second option will work but when one is opened then the others close and vice versa so that only one can be open at a time.

    Code JavaScript:
    function showAttendee(id) {
    	var myAttend = document.getElementById(id); 
    	for (var b = 1; b<=10; b++) {
    		if (document.getElementById('attendee'+b)) {
    			document.getElementById('attendee'+b).style.display="none";
    			}
    		}
    	if (myAttend) {
    		myAttend.style.display="block";
    		}
    	}

    How can I make this work? I'm just learning JavaScript so any help is greatly appreciated.
    CSS Club mantra; "I hate IE6, I hate IE6, I hate IE6".
    http://www.avdes.com

  2. #2
    SitePoint Evangelist vikrantkorde's Avatar
    Join Date
    Jun 2004
    Location
    Mumbai, India
    Posts
    541
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hey AVdes,
    which one is not working?
    I checked the code given by u is working fine. I have wrote the HTML file as below. It is working fine
    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <HTML>
    <HEAD>
    <TITLE> New Document </TITLE>
    <META NAME="Generator" CONTENT="EditPlus">
    <META NAME="Author" CONTENT="Vikrant Korde">
    <META NAME="Keywords" CONTENT="Vikrant Korde, Vikrant, Korde">
    <META NAME="Description" CONTENT="">
    <script>
    function showAttendee(id) {
        var myAttend = document.getElementById(id);
        if(myAttend.style.display=="block" || myAttend.style.display=="") {
            myAttend.style.display="none";
            } else {
            myAttend.style.display="block";
            }
        }
    </script>
    </HEAD>
    
    <BODY>
    <div>
      <div onclick="javascript:showAttendee('attendee1')">click 1</div>       
      <div id="attendee1"> attendee1 data </div>
      <div onclick="javascript:showAttendee('attendee2')">click 2</div>       
      <div id="attendee2"> attendee2 data </div>
    </div>
    </BODY>
    </HTML>
    Vikrant Korde
    S Y S T I M E, Mhape,
    Mumbai, Maharashtra, India.

  3. #3
    SitePoint Zealot AVdes's Avatar
    Join Date
    Jun 2005
    Location
    GA
    Posts
    106
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes it does work but not in the way I need. The code only works if you hard code the id="attendee1". But when that number is created dynamically then it doesn't know what to do.

    The second sollution works, but then it will only open one at a time.
    CSS Club mantra; "I hate IE6, I hate IE6, I hate IE6".
    http://www.avdes.com

  4. #4
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    There is a way, and it involves walking through the dom.

    I'll place a top-level id on the containing div, so that we can use some traditional event registration techniques.

    Code html4strict:
    <div id="attendees">
      <div>click 1</div>       
      <div id="attendee1"> attendee1 data </div>
      <div>click 2</div>       
      <div id="attendee2"> attendee2 data </div>
    </div>

    It's going to take only one event assigned to the attendees div to capture all clicks that happen in there.

    Code javascript:
    document.getElementById('attendees').onclick = function () {
        // show attendee code
    };

    The showAttendee() function will find out the div that was clicked on, and if it has no id it will walk through them to the next div that has an id, to show/hide that particular one.

    So first, we find the element that was clicked on. If it was a normal link that was clicked, we should go no further.

    Code javascript:
    // get the element that fired the event
    evt = evt || window.event;
    targ = evt.target || evt.srcElement;
    // Exit if a link was clicked
    if (targ.nodeName === 'A') {
    	return;
    }

    If the div contains any elements, we may end up on one of those elements instead. Also, the Safari browser has a bug (or a feature) where the target element is the text itself and not the element that contains it.

    To resolve those issues, we will walk up the DOM until the parent is found to be "attendees", or until we reach the Body element itself.

    Code javascript:
    // If the elements parent is not "attendees", walk up
    // the DOM tree until it's found, or until we get to the body.
    while (targ.parentNode.id !== 'attendees' && targ.nodeName !== 'BODY') {
    	targ = targ.parentNode;
    }
    if (targ.nodeName === 'BODY') {
    	return; // "attendees" id wasn't found
    }

    When the element that says "click 1" has been clicked, we're going to go to the next element with an id attribute so that it can be toggled. This also means that clicking on the revealed information will hide it as well.

    Code javascript:
    // If this element has no id, walk forward through the DOM until one is found
    // The element with an id is the one that will be toggled off and on
    while (!targ.id && targ.nextSibling) {
    	targ = targ.nextSibling;
    }
    if (!targ.id) {
    	return;
    }

    And now that we have found the element that's going to be toggled, we can go ahead and do so.

    Code javascript:
    // toggle the state of the element
    if(targ.style.display == 'none') {
    	targ.style.display='';
    } else {
    	targ.style.display='none';
    }

    So in full, place this script at the bottom of the body, just before the </body> tag.

    Code javascript:
    document.getElementById('attendees').onclick = function (evt) {
        // get the element that fired the event
    	evt = evt || window.event;
    	targ = evt.target || evt.srcElement;
    	// Exit if a link was clicked
    	if (targ.nodeName === 'A') {
    		return;
    	}
    	// If the elements parent is not "attendees", walk up
    	// the DOM tree until it's found, or until we get to the body.
    	while (targ.parentNode.id !== 'attendees' && targ.nodeName !== 'BODY') {
    		targ = targ.parentNode;
    	}
    	if (targ.nodeName === 'BODY') {
    		return; // "attendees" id wasn't found
    	}
    	// If this element has no id, walk forward through the DOM until one is found
    	// The element with an id is the one that will be toggled off and on
    	while (!targ.id && targ.nextSibling) {
    		targ = targ.nextSibling;
    	}
    	if (!targ.id) {
    		return;
    	}
    	// toggle the state of the element
    	if(targ.style.display == 'none') {
    		targ.style.display='';
    	} else {
    		targ.style.display='none';
    	}
    };
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  5. #5
    SitePoint Zealot AVdes's Avatar
    Join Date
    Jun 2005
    Location
    GA
    Posts
    106
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This is a clever solution. thank You pmw57. But is there a way to do it so that the script is not contained in the html. I have to keep the javascript seperate. Also the divs cannot be placed inside another div. I cannot change the structure of the html.
    CSS Club mantra; "I hate IE6, I hate IE6, I hate IE6".
    http://www.avdes.com

  6. #6
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    The script code should be placed in an external file, and called from the end of the body, just before the </body> tag.

    As far as thecode structure is concerned, there is no change the structure itself. Just to the attributes on that structure.

    Here is the code that you posted:

    Code html4strict:
    <div>
      <div onclick="javascript:showAttendee('attendee1')"></div>       
      <div id="@attendee'+objectSetValue'('somethingSomething')"></div>
      <div onclick="javascript:showAttendee('attendee2')"></div>       
      <div id="@attendee'+objectSetValue'('somethingSomething')"></div>
    </div>

    And here is how you would change it

    Code html4strict:
    <div id="attendees">
      <div onclick="javascript:showAttendee('attendee1')"></div>       
      <div id="@attendee'+objectSetValue'('somethingSomething')"></div>
      <div onclick="javascript:showAttendee('attendee2')"></div>       
      <div id="@attendee'+objectSetValue'('somethingSomething')"></div>
    </div>

    It is the same structure, with an added id attribute from where the event will be attached.
    Last edited by paul_wilkins; Apr 30, 2008 at 16:53.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  7. #7
    SitePoint Zealot AVdes's Avatar
    Join Date
    Jun 2005
    Location
    GA
    Posts
    106
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm sorry. You are right. I tried to shorten my code so that it would be easyer to understand my dilema.

    Here is the actual code and structure:

    Code HTML4Strict:
    <body>
      <div>
        <ul>
          <li>
            <span class="title" onclick="javascript:showInfo('yourWeb')">Outer Shell</span>
            <div id="yourWeb">									
             <table>
               <tr>
                 <td>
    	    text text text
                 </td>
     
                <td>								
                  <ul>
                    <li>
                      text
                    </li>
     
                    <li>
                      text
                   </li>
     
                   <li>
                     <div class="attachTitle" onclick="javascript:showAttendee('myAttach1')">
                       <span class="titleText"><b>Attachments</b></span>
                     </div>
     
                     <div id="myAttach1">
                       <table class="myAttach">
                         <tr>
                           <td>
                             text text text
                           </td>
                         </tr>
                       </table>
                     </div>
                   </li>
                 </ul>
               </td>
     
               <td>
                 text text text
               </td>
             </tr>
           </table>
    <!-- Next one -->
           <table>
               <tr>
                 <td>
    	    text text text
                 </td>
     
                <td>								
                  <ul>
                    <li>
                      text
                    </li>
     
                    <li>
                      text
                    </li>
     
                    <li>
                      <div class="attachTitle" onclick="javascript:showAttendee('myAttach2')">
                        <span class="titleText"><b>Attachments</b></span>
                      </div>
     
                      <div id="myAttach2">
                        <table class="myAttach">
                          <tr>
                            <td>
                              text text text
                            </td>
                          </tr>
                        </table>
                      </div>
                    </li>
                  </ul>
                </td>
     
                <td>
                  text text text
                </td>
              </tr>
            </table>
          </li>
        </ul>
      </div>
    </body>

    What is actually happening here is I have an outer shell, of which there will be three of them on a single page, that can be opened and closed at will.

    Then inside each Outer Shell thre are sevral inner boxes can be as many as 100 or as few as one. inside each of these boxes exists a single inner shell (in the form of a table containied in a div contained in an unordered list). each small table is created and populated by a primeBase.lml assiging it an id#.

    See how complicated it is. I was afraid that if I showed the whole thing it would look to cumbersom. If I assigned the li containing the two divs for the inner shell an Id then each box would need a unique ID. then I have the same problem all over again. It looks hopeless.
    CSS Club mantra; "I hate IE6, I hate IE6, I hate IE6".
    http://www.avdes.com

  8. #8
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Thanks for the more complete code.

    The script can be attached on to the "yourWeb" identifier.

    When the click is processed the script can check if the element is a div, and if not walk up until it finds one.

    Code javascript:
    document.getElementById('yourWeb').onclick = function (evt) {
        // get the element that fired the event
        evt = evt || window.event;
        targ = evt.target || evt.srcElement;
        // Exit if a link was clicked
        if (targ.nodeName === 'A') {
            return;
        }
        // If the element is not a div, walk up the DOM tree
        // until it's found, or until we go too far and get to the body
        while (targ.nodeName !== 'DIV' && targ.nodeName !== 'BODY') {
            targ = targ.parentNode;
        }
        if (targ.nodeName === 'BODY') {
            return; // "attendees" id wasn't found
        }
        // If this element has no id, walk forward through the DOM until one is found
        // The element with an id is the one that will be toggled off and on
        // If this element is the "yourWeb" one then we shouldn't go any further.
        while (!targ.id && targ.nextSibling) {
            targ = targ.nextSibling;
        }
        if (targ.id === 'yourWeb' || !targ.id) {
            return;
        }
        // toggle the state of the element
        if(targ.style.display == 'none') {
            targ.style.display='';
        } else {
            targ.style.display='none';
        }
    };
    Last edited by paul_wilkins; Apr 30, 2008 at 16:26.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  9. #9
    SitePoint Zealot AVdes's Avatar
    Join Date
    Jun 2005
    Location
    GA
    Posts
    106
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hay that worked great. Thank you for being so patient. You Rock.
    CSS Club mantra; "I hate IE6, I hate IE6, I hate IE6".
    http://www.avdes.com


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
  •