Hi everybody,

I have this expand/contract thing, whereby a button is situated below a label "Advanced Features".

And so when the user clicks on "Advanced Features", the button will drop below the whole expansion. The button should be situated BEFORE the label before clicking onto "Advanced Features".

Any ideas on how I can do this?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>

   <script language = "javascript" type = "text/javascript">
   var collapsable_parent_name = "collapseExpand"; 
var collapsable_parent_type = "div"; 
var collapsable_child_type = "div"; 

var collapsable_expand = "Advanced Features"; 
var collapsable_shrink = "Simple Features"; 

init = function() 
{ 
    if(document.getElementById && document.createTextNode) 
    { 
        var entries = document.getElementsByTagName(collapsable_parent_type); 
        for(i = 0; i < entries.length; i++) 
        if (entries[i].className == collapsable_parent_name) 
                assignCollapse(entries[i]);
    } 
} 

assignCollapse = function (div) 
{ 
    var button = document.createElement("collapse_add_adv_features");
    button.style.cursor = "pointer"; 
    button.setAttribute("expand", collapsable_expand); 
    button.setAttribute("shrink", collapsable_shrink); 
    button.setAttribute("state", -1); 
    div.insertBefore(button, div.getElementsByTagName(collapsable_child_type)[0]); 

    button.onclick=function()
    { 
        var state = -(1*this.getAttribute("state")); 
        this.setAttribute("state", state); 
        this.parentNode.getElementsByTagName(collapsable_child_type)[0].style.display=state==1?'none':'block'; 
        this.innerHTML = this.getAttribute(state==1?"expand":"shrink"); 
    };                    
    button.onclick(); 
} 


window.onload = init;
   
   </script>
    
</head>
<body>
    <table>

                        <label>
                            *First Name:</label>
                        <input id="Text16" type="text" name="First Name" onkeydown="return noSpace(event)" />
                        <br />
                        <br />
                        <label>
                            *Last Name:</label>
                        <input id="Text17" type="text" name="Last Name" onkeydown="return noSpace(event)" /><br />
                        <br />

                        <div class="collapseExpand">
                            <div>
                                <br />
                                <ul id="mailboxTabs" class="shadetabs">
                                    <li><a class="selected" href="#" rel="mailbox1">1</a></li>
                                    <li><a class="" href="#" rel="mailbox2">2</a></li>
                                    <li><a class="" href="#" rel="mailbox3">3</a></li>
                                </ul>
                                <div class="contentBox">
                                    <div style="display: block;" id="mailbox1" class="tabcontent">

                                    </div>                                
                                
                                
                                    
                                    <div style="display: none;" id="mailbox2" class="tabcontent">
                                    </div>
                                
                                
                                
                                
                                    <div style="display: none;" id="mailbox3" class="tabcontent">

                                    </div>
                                    
                                    
                                    <div style="display: none;" id="mailbox4" class="tabcontent">
                                        </form> 
                                                               
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

                    <script type="text/javascript">
                        var switchMBTabs=new ddtabcontent("mailboxTabs")
                        switchMBTabs.setpersist(true)
                        switchMBTabs.setselectedClassTarget("link") //"link" or "linkparent"
                        switchMBTabs.init()
                    </script>

                <input id="Submit17" type="submit" value="Submit" onclick="return check()"/>
                </td>
            </tr>
    </table>
</body>
</html>

Dani AI

Generated

Short answer: keep one real <button> (do not invent custom tags) and move that node in the DOM when the panel opens or closes. As correctly pointed out, the core is show/hide; the missing piece for is moving the same button between the header and the end of the expanded content (use insertBefore / appendChild), plus a few small accessibility and form-related fixes.

Common pitfalls to avoid: creating nonstandard elements (your createElement("collapse_add_adv_features")) is unnecessary and may behave oddly in XHTML; use createElement('button') and give it type="button" so it doesn't submit the form. Keep one toggle node, update aria-expanded, and move the node rather than creating/destroying copies.

A minimal pattern you can drop into your page (replace the IDs/classes to match your markup):

<div id="advWrap">
  <button id="advBtn" type="button">Show Advanced</button>

  <div id="advPanel" class="collapseExpand">
    <div id="advLabel" role="button" tabindex="0" aria-controls="advContent" aria-expanded="false">
      Advanced Features
    </div>

    <div id="advContent" style="display:none">
      <!-- existing tabs/content (mailboxTabs / tabcontent) go here -->
    </div>
  </div>
</div>

<script>
(function(){
  var wrap = document.getElementById('advWrap');
  var btn = document.getElementById('advBtn');
  var label = document.getElementById('advLabel');
  var content = document.getElementById('advContent');

  function placeBeforeLabel(){ wrap.insertBefore(btn, label); }
  function placeAfterContent(){ wrap.appendChild(btn); }

  function setCollapsed(collapsed){
    content.style.display = collapsed ? 'none' : 'block';
    btn.textContent = collapsed ? 'Show Advanced' : 'Hide Advanced';
    label.setAttribute('aria-expanded', String(!collapsed));
    if(collapsed) placeBeforeLabel(); else placeAfterContent();
  }

  function toggle(){ setCollapsed(content.style.display === 'block'); }

  var on = function(el, ev, fn){ if(el.addEventListener) el.addEventListener(ev, fn, false); else el.attachEvent('on'+ev, fn); };
  on(btn, 'click', toggle);
  on(label, 'click', toggle);
  on(label, 'keydown', function(e){ e=e||window.event; var k=e.which||e.keyCode; if(k===13||k===32){ if(e.preventDefault) e.preventDefault(); toggle(); }});

  setCollapsed(true); // initial: button before label
})();
</script>

Troubleshooting tips: ensure the script runs after the DOM (place before </body> or wrap in onload), check that the button and panel share the same parent when you call insertBefore/appendChild, and keep type="button" to avoid accidental form submits. If you have multiple expanders, loop over them with querySelectorAll and create one button per block.

Recommended Answers

All 4 Replies

The basic concept behind expand and collapse is to set the visibility of a div. Basically, you want your link to call a function to show or hide the div. You will need to do something like this:

<div id="advanced" style="display:none">Advanced Features Here</div>
<a onClick="showHide();return(false)" href="#">Advanced Features</a>
function showHide() {
div = document.getElementById('advanced');

	if (div.style.display != 'none') {
		div.style.display = 'none';
	}
	else {
		div.style.display = '';
	}
}

That's one way of doing it. Take a look here for more help:

Feel free to ask me questions.

Hi alipica,

this is not the way I want it to be. I want to show the button, not the "Advanced Features Here". Okay, if this is a substitution of the button, then it's alright apart from some problems.

Firstly, the button should be shown before the word "Advanced Features" at startup. And when the user clicks on the "Advanced Features", the button will be shown below the tabs of "1", "2", "3".

I'm not fully sure I understand what you're saying. Here's what I think you're saying: You have a set of options within a div. Underneath that div, you have a button that will display another div with options. The second div should appear between the button and the first div. The second div should display when the button is clicked and disappear if the button is clicked again.

Is this correct or have I got this all wrong?

Haha, I do not understand yours as well. Okay, I shall try to explain it simpler.

1) I have a form with a button and a div.
2) The button is situated above the div.
3) And when the user clicks on the word "Advanced Features" (div), the button will be shown at the bottom. This means that the button will be shown below everything within the Advanced Features (div).

Perhaps you can refer to my code and look at the GUI.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.