0

I have some tables here, and using this javascript below, I made them hide and show every time a user click on their buttons. What I want to add in to this script, is when someone click on a table's button to show-up, all the other to be hidden. Any idea how can I do this? Thank you in advance!

This is my html code:

<table id="SC1_TH_" class="header_op"><tr><td>
<div id="SC1_BSH_" onClick="SC[1]();" class="hide_button">*</div>OPTION ONE
</td></tr></table>
<div id="SC1_BO_" style="display:dlock;">BLAH BLAH</div>

<table id="SC2_TH_" class="header_cl"><tr><td>
<div id="SC2_BSH_" onClick="SC[2]();" class="show_button">*</div>OPTION ONE
</td></tr></table>
<div id="SC2_BO_" style="display:none;">BLAH BLAH</div>

<table id="SC3_TH_" class="header_cl"><tr><td>
<div id="SC3_BSH_" onClick="SC[3]();" class="show_button">*</div>OPTION ONE
</td></tr></table>
<div id="SC3_BO_" style="display:none;">BLAH BLAH</div>

This is my javascript:

<script type="text/javascript">

var SC = [];

for (var i = 1; i < 10; i++) {

SC[i] = (function(i){

return function(){

var SC_TH  = document.getElementById('SC'+i+'_TH_');
var SC_BSH = document.getElementById('SC'+i+'_BSH_');    
var SC_BO  = document.getElementById('SC'+i+'_BO_');

  if (SC_BO.style.display == 'block' || SC_BO.style.display == ''){
      SC_TH.className      = 'header_cl';
      SC_BSH.className     = 'show_button';
      SC_BO.style.display  = 'none';}
else {SC_TH.className      = 'header_op';
      SC_BSH.className     = 'hide_button';
      SC_BO.style.display  = 'block';}
     }})(i);}       
</script>

EDIT: In other words, I need something to say, if this button that clicking right now is something all the other to be hidden!!!

10
  • 2
    Is there a particular reason you're not using for example jQuery, etc? "Accordion" style showing and hiding is a solved problem with most js libraries: See here Commented Jan 20, 2013 at 10:50
  • Yes my friend cause I should make my own!!! Orders you see... Commented Jan 20, 2013 at 10:54
  • 1
    Somebody ordered you to use inline Javascript instead of a framework like JQuery? Commented Jan 20, 2013 at 10:57
  • Oh yes!!! :) If you have to do with people that can't understand... You know!!! Commented Jan 20, 2013 at 10:59
  • Yikes, that's too bad. Do they realise that jquery is javascript? And that they are asking you to literally re-invent the wheel? Commented Jan 20, 2013 at 11:48

3 Answers 3

1

Here's a working example with some very simple jQuery (recommended) code.

HTML:

<table><tr><td>
<div class="toggle-button">*</div>OPTION ONE
</td></tr></table>
<div class="toggle">BLAH BLAH</div>

<table><tr><td>
<div class="toggle-button">*</div>OPTION ONE
</td></tr></table>
<div class="toggle">BLAH BLAH</div>

<table><tr><td>
<div class="toggle-button">*</div>OPTION ONE
</td></tr></table>
<div class="toggle">BLAH BLAH</div>

JS:

$(function() {
    $('div.toggle').hide();
    $('.toggle-button').click(function(){
        $('div.toggle').hide();
        $(this).closest('table').next('div.toggle').show();
    });
});

As @StephenByrne mentioned, I also strongly recommend using an existing component such as jQuery Accordian. It takes minutes to implement and comes with a whole host of themes to chose from and is fully customisable. You could spend hours or days writing your own. Unless it's a learning exercise, it's simply a waste of time. No need to reinvent the wheel.

As you have indicated a strong push towards js-only, here's a working js-only solution.

HTML:

<table id="SC1_TH_" class="header_op"><tr><td>
<div id="SC1_BSH_" onclick="toggle(this);" class="hide_button">*</div>OPTION ONE
</td></tr></table>
<div id="SC1_BO_" style="display:block;">BLAH BLAH</div>

<table id="SC2_TH_" class="header_cl"><tr><td>
<div id="SC2_BSH_" onclick="toggle(this);" class="show_button">*</div>OPTION ONE
</td></tr></table>
<div id="SC2_BO_" style="display:none;">BLAH BLAH</div>

<table id="SC3_TH_" class="header_cl"><tr><td>
<div id="SC3_BSH_" onclick="toggle(this);" class="show_button">*</div>OPTION ONE
</td></tr></table>
<div id="SC3_BO_" style="display:none;">BLAH BLAH</div>

JS:

function toggle(src) {
    var id =  src.id;
    var index = id.substring(2, 3);

    var i = 1;
    var toggleItem = document.getElementById('SC' + i.toString() + '_BO_');

    while (toggleItem != null) {
        var bShow = index == i;
        var button = document.getElementById('SC' + i.toString() + '_BSH_');
        var table = document.getElementById('SC' + i.toString() + '_TH_');

        if (bShow) {
            toggleItem.style.display = 'block';
            toggleItem.className = 'setitemclassname';
            button.className = 'setbuttonclassname';
            table.className = 'settableclassname';
        }
        else {
            toggleItem.style.display = 'none';
            toggleItem.className = 'setitemclassname';
            button.className = 'setbuttonclassname';
            table.className = 'settableclassname';
        }
        toggleItem = document.getElementById('SC' + (++i).toString() + '_BO_');
    }
}

Inside the while loop when index == i evaluates to true, you know you have the item to show. Add extra logic there to change your class names.

Sign up to request clarification or add additional context in comments.

7 Comments

@ATOzTOA This is a recommendation and adds value to a community that may be looking for the same solution without a JS-only dependency. It's not always best to give the OP exactly what they want but also to propose better solutions.
Your example is very good my friend and thank you for your answer and you time!!! But I need something that will patch on my javascript code above...
@DNA180 See updated answer with inclusion of JS-only approach.
Your second example is working for me!!! I just need to do some corrections on how it looks when clicked or not. Thank you very much for your help!!!
@flem: Well, I don't have the knowledge to do what I said as it is now. If you have the kindness, please tell me this... How I'll "say" to this script you wrote, that if display is block take this class and if is not take the other class??? As it is now I can't imagine the syntax!!! Really thank you for your time!!!
|
1

A cleaner solution involves altering your HTML a bit as well - getting rid of the onclick and replacing it with a class (toggleItem) that will allow the javascript to identify the items to be toggled. I also make sure that all the buttons have the class button so they can be identified.

<table id="SC1_TH_" class="header">
  <tr>
    <td>
      <div id="SC1_BSH_" class="button">*</div>OPTION ONE</td>
  </tr>
</table>
<div id="SC1_BO_" class="toggleItem">BLAH BLAH</div>
<table id="SC2_TH_" class="header">
  <tr>
    <td>
      <div id="SC2_BSH_" class="button">*</div>OPTION ONE</td>
  </tr>
</table>
<div id="SC2_BO_" class="toggleItem">BLAH BLAH</div>
<table id="SC3_TH_" class="header">
  <tr>
    <td>
      <div id="SC3_BSH_" class="button">*</div>OPTION ONE</td>
  </tr>
</table>
<div id="SC3_BO_" class="toggleItem">BLAH BLAH</div>

Then in the javascript:

var buttons = document.getElementsByClassName('button'),
  toggleItems = document.getElementsByClassName('toggleItem'),
  tables = document.getElementsByClassName('header');
for (var i = 0; i < buttons.length; i++) {
    buttons[i].onclick = getFunction(toggle, i);
}
// getFunction is needed for reasons to do with variable scope
function getFunction(f, p) {return function() {f(p)}}
function toggle(selected) {
    for (var i = 0; i < toggleItems.length; i++) {
        toggleItems[i].style.display = i == selected ? '' : 'none';
        tables[i].className = i == selected ? 'header open' : 'header closed';
        buttons[i].className = i == selected ? 'button show' : 'button hide';
    }
}
toggle(0);  // initially show only the first one

(This does assume that the buttons and toggle items will be in the same order. If that is not the case you will have to revert to checking their IDs or find some other way to associate the items and buttons.)

(EDITED to include changing class of tables and buttons)

Comments

1

Just hide all of them, then show the one that should become toggled open. This script is not the elegantest solution, but integrates directly in your coding style:

for (var i = 1; i < 10; i++) {
    SC[i] = (function(i){
        var SC_TH  = document.getElementById('SC'+i+'_TH_'),
            SC_BSH = document.getElementById('SC'+i+'_BSH_'),
            SC_BO  = document.getElementById('SC'+i+'_BO_');

        return function(action) {
            if (!action) action = SC_BO.style.display=="none" ? "show" : "hide";

            if (action == "show") { 
                for (var i=0; i<SC.length; i++)
                    SC[i]("hide");
                SC_TH.className      = 'header_op';
                SC_BSH.className     = 'hide_button';
                SC_BO.style.display  = '';
            } else {
                SC_TH.className      = 'header_cl';
                SC_BSH.className     = 'show_button';
                SC_BO.style.display  = 'none';
            }
        };
    })(i);
}

4 Comments

@Bergi "not the elegantest solution". That's the understatement of the year. We shouldn't be promoting illegible code.
@flem: Don't blame him :) He just tried to make it close to my coding style as he said!!!
@DNA180. There's no blame here, just my opinion that the code (no matter who wrote it) is not well written. This is not meant to cause offense but rather meant as constructive criticism. If you revisit this code in a year from now, you'll have no idea what it means. Those of us with more experience should not be promoting this style of coding. It's not good for us, OP, or the community. It's especially bad for those who have to support the code in the future.
@flem: I don't think the code is illegible. Correctly indented, it is quite clear what happens in the closure. The array of functions is a bit weird - at least if this is a standalone functionality - but might integrate well into some data model (which the OP might have hidden from us to make the example self-contained). Of course you are right that this type of code should not be chosen over a cleaner solution if the goal is just a simple accordion functionality.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.