Does anyone know if there is a way to do either of the 2 things? And if so, can you provide any info you might have?

1. Give users the ability to collapse a forum container. So they don't have to keep scrolling past forums they don't care about.

2. Have the sub-forums of a forum show up on a second page, but not the main forum page? For instance, in the below example, 'Cars' would be the only forum listed on the main forum list page. When clicked, you would then see the 3 sub-forums

Cars
|--Sports Cars
|--Sedans
|--SUVs

Comments

Kirk’s picture

Just FYI, I came across this in the handbook http://drupal.org/node/199071 which does some neat stuff.

sameh’s picture

This is the same that I wanted for my forums, so , I made these steps :

  1. I created a Java script file, gave it the name elwardah.js using the following code, and I put it in the /misc folder :

    " Note that I have 11 containers , count the containers in your forum and place the corresponding definitions after the first line "var containers = { };" of the Java script code "

    var containers = { };
    containers["container_1"] = { "show" : 1 };
    containers["container_2"] = { "show" : 1 };
    containers["container_3"] = { "show" : 1 };
    containers["container_4"] = { "show" : 1 };
    containers["container_5"] = { "show" : 1 };
    containers["container_6"] = { "show" : 1 };
    containers["container_7"] = { "show" : 1 };
    containers["container_8"] = { "show" : 1 };
    containers["container_9"] = { "show" : 1 };
    containers["container_10"] = { "show" : 1 };
    containers["container_11"] = { "show" : 1 };
    
    function elwardah_forum_class_filter(r, m) {
      m = " " + m + " ";
      var tmp = [];
      for (var i = 0; r[i]; i++) {
        var pass = (" " + r[i].className + " ").indexOf(m) >= 0;
        if (pass) {
          tmp.push(r[i]);
        }
      }
      return tmp;
    }
    
    function elwardah_forum_toggle_display(m) {
      containers[m]["show"] = !containers[m]["show"];
    
      elwardah_forum_render(m);
    
      elwardah_forum_store_preferences();
    };
    
    function elwardah_forum_render(m) {
      var rows = document.getElementsByTagName("tr");
      rows = elwardah_forum_class_filter(rows, m);
    
      for ( var i = 0; rows[i]; i++ ) {
        if (containers[m]["show"]) {
          elwardah_forum_show(rows[i]);
        } else {
          elwardah_forum_hide(rows[i]);
        }
      }
    
      var c = document.getElementById(m);
      var e = c.getElementsByTagName("span");
      e = elwardah_forum_class_filter(e, "show_hide_message");
      e[0].innerHTML = containers[m]["show"] ? "Hide" : "Show";
    }
    
    function elwardah_forum_hide(e) {
      e.oldblock = e.oldblock || e.style.display;
      if (e.oldblock == "none") {
        e.oldblock = "block";
      }
      e.style.display = "none";
    }
    
    function elwardah_forum_show(e) {
      e.style.display = e.oldblock ? e.oldblock : "";
      if (e.style.display == "none") {
        e.style.display = "block";
      }
    }
    
    function elwardah_forum_store_preferences() {
      var data = [];
      for (var c in containers) {
        data.push(c + ":" + Number(containers[c]["show"]));
      }
      data = escape(data.join(";"));
    
      var date = new Date();
      date.setTime(date.getTime() + (365*24*60*60*1000));
      var expires = "; expires=" + date.toGMTString();
      document.cookie = "forumprefs=" + data + expires + "; path=/";
    }
    
    function elwardah_forum_load_preferences() {
      var cookieName = "forumprefs=";
      var ca = document.cookie.split(";");
      for(var i = 0; i < ca.length; i++) {
        var c = unescape(ca[i].replace(/^\s+|\s+$/g, ""));
        if (c.indexOf(cookieName) == 0) {
          var data = c.substring(cookieName.length, c.length);
          data = data.split(";");
          for (var k = 0; data[k]; k++) {
            var pair = data[k].split(":");
            if (containers[pair[0]]) {
              containers[pair[0]]["show"] = Number(pair[1]);
            }
          }
        }
      }
    
      for (var c in containers) {
        elwardah_forum_render(c);
      }
    }
    
    function elwardah_stop_bubble(e) {
      if (e.stopPropagation) e.stopPropagation(); e.cancelBubble = true;
    }
    
  2. The following code is in my forum_list.tpl.php file that is in the theme folder :
    <?php
    /**
    * This snippet generates the forum_list layout.
    * This works with Drupal 4.7 and Drupal 5.x
    * For use with a custom forum_list.tpl.php file.
    *
    */
    
      global $user; // checks the current user so later the snippet can determine what permissions they have
     
      if ($forums) { // check if there is forums.
    
    	  drupal_add_js("misc/elwardah.js");  // include the Java script file in the pages that has forums
    
              $container_flag = 0;                   
     
        foreach ($forums as $key=>$forum) { // this is the start of the forum list routine that generates the containers and forum list.
    
          if ($forum->container) {          // If the forum is a container
    
              
    	      if ($container_flag) {  // I wanted each container to be in a separate table
    		          print theme('table', $header, $rows);
    			  $rows = $nrows;
    	      }
    	        $container_flag += 1;
    	
            $description  = "<div>\n";
            $description .= ' <div class="name">'. l($forum->name, "forum/$forum->tid/container") ."</div>\n";
            if ($forum->description) {
              $description .= " <div class=\"description\">$forum->description</div>\n" ;
            }
    
            $description .= "<span class=\"show_hide_message\">Show</span>"."</div>\n";
    	$rows[] = array( 'class' => 'container', 'data' => array('data' => array( 'data' => $description,'colspan' =>4)), 'id'=>'container_'.$container_flag, 'onclick'=>"elwardah_forum_toggle_display(this.id);" );
    	
    	// this sets the column titls and style sheet class names
            $rows[] = array('class' => 'container_'.$container_flag, 'data' =>array(
            array('data' => t('Subject'), 'class' => 'f-subject'), 
            array('data' => t('Topics'), 'class' => 'f-topics'),
            array('data' => t('Posts'),'class' => 'f-posts'),
            array('data' => t('Last post'),'class' => 'f-last-reply')
            ));
    
    
          }
          else {                     // If the forum is not a container
            $forum->old_topics = _forum_topics_unread($forum->tid, $user->uid);
            if ($user->uid) {
              $new_topics = _forum_topics_unread($forum->tid, $user->uid);
            }
            else {
              $new_topics = 0;
            }
            $description  = '<div>';
            $description .= ' <div class="name">'. l($forum->name, "forum/$forum->tid") ."</div>\n";
            if ($forum->description) {
              $description .= " <div class=\"description\">$forum->description</div>\n";
            }
            $description .= "</div>\n";
            $rows[] = array( 'class' => 'container_'.$container_flag, 'data' =>array(
              array('data' => $description, 'class' => 'forum'),
              array('data' => $forum->num_topics . ($new_topics ? '<br>'. l(format_plural($new_topics, '1 new', '@count new'), "forum/$forum->tid", NULL, NULL, 'new') : ''), 'class' => 'topics'),
              array('data' => $forum->num_posts, 'class' => 'posts'),
              array('data' => _forum_format($forum->last_post), 'class' => 'last-reply')));
          }
        }
        /**
         * Only set the table header if page is a container with listing of forums
         */
        if(in_array(arg(1), variable_get('forum_containers', array()))){
                // reverse array
                $nrows = array_reverse($rows,true);
                //get the container description
                $container = taxonomy_get_term(arg(1));
                //add to output
                $rows = $nrows;
                $rows[] = array( 'class' => 'container_'.$container_flag, 'data' =>array(
                    array('data' => t('Subject'), 'class' => 'f-subject'),
                    array('data' => t('Topics'), 'class' => 'f-topics'),
                    array('data' => t('Posts'),'class' => 'f-posts'),
                    array('data' => t('Last post'),'class' => 'f-last-reply')
                    ));
                $rows[] = array( 'class' => 'container', 'data' => array('data' => array( 'data' => $description,'colspan' =>4)), 'id'=>'container_'.$container_flag, 'onclick'=>"elwardah_forum_toggle_display(this.id);" );
                //reverse again to output
                $nrows = array_reverse($rows,true);
                $rows = $nrows;
            }      
        print theme('table', $header, $rows);
       
      }
    ?>
    
  3. I made the following addition to my css file :
    show_hide_message {
                                float: left;
                                color:#fff;
                                font-size:1.6em;
                                font-weight:bold;
                                }
    

You can see the result in my site :

http://www.elwardah.com/forum

Note: I did not test it for nested containers ...

vm’s picture

nicely done Sameh

you should create handbook page and add your snippets to it. It would be a welcome contribution and wont get lost as easily as it will in the forums.

_____________________________________________________________________
My posts & comments are usually dripping with sarcasm.
If you ask nicely I'll give you a towel : )

Dalsor’s picture

Is there something you have to do after adding these files? I've followed the steps, but when I click the container names it simply forwards to a page listing the forums under the container instead of collapsing the container.

Thanks for any help.

if ( bad() && possible() )
happen();

grn’s picture

Hello, is it possible to port this to Drupal 6.2? Any hints?

/grn

grn’s picture

This is being developed for advanced forum (http://drupal.org/node/291084).

/grn