Wrox Programmer Forums
Go Back   Wrox Programmer Forums > Web Programming > JavaScript > Javascript How-To
|
Javascript How-To Ask your "How do I do this with Javascript?" questions here.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the Javascript How-To section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old June 24th, 2007, 03:30 PM
Registered User
 
Join Date: Jun 2007
Posts: 2
Thanks: 0
Thanked 0 Times in 0 Posts
Default Dynamic Table works in IE but not Firefox

I wrote this pretty slick DHTML table that lets you add/remove rows and show/hide columns on the fly. It works perfectly in IE7, but it doesn't behave in Firefox 2.0.0.4. You can see it in action here:

http://www.phreelancer.com/dyn_table/

If you start to add/remove rows and then show/hide columns a few times in FF, you'll see that some table cells are bundled together or that some hidden cells don't get collapsed (but are still empty). It's driving me insane. I've tried several approaches. Any advice would be great. Here's the code:

Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
<head>
<title>Todomo Admin Section</title>
<link rel="stylesheet" type="text/css" href="http://www.phreelancer.com/dyn_table/dyn_table.css"/>
<script type="text/javascript">
// these array values correspond to the current status of their checkboxes
var languages = new Array();
languages["English"] = true;
languages["Spanish"] = true;
languages["Portuguese"] = false;

document.getElementsByClassName = function(class_name) {
   var docList = this.all || this.getElementsByTagName("*");
   var matchArray = new Array();

   // create a regular expression object for class
   var re1 = new RegExp("\\b"+class_name+"\\b");

   // create regular expression to handle dashes in class name
   var re2 = new RegExp("[\S]"+class_name+"|"+class_name+"[\S]");

   for (var i = 0; i < docList.length; i++) {
      if (re1.test(docList[i].className) && !re2.test(docList[i].className) ) {
         matchArray[matchArray.length] = docList[i];
      }
   }
   return matchArray;
}

// add/remove table column for specified language
function dyn_table_change_language(language) {
   var cb = document.getElementById("cb"+language);

   languages[language] = cb.checked;

   // make sure at least one checkbox is checked
   if (!cb.checked) {
      var num_checked = 0;
      for (var key in languages) {
         if (languages[key]) {
            num_checked++;
         }
      }

      if (num_checked == 0) {
         languages[language] = true;
         cb.checked = true;
         alert("You must keep at least one language enabled.");
         return;
      }
   }

   var cells = document.getElementsByClassName(language);
   for (var i=0; i<cells.length; i++) {
      cells[i].style.display = cb.checked ? "block" : "none";
   }
}

// hide all table cells that are part of a disabled language/column
function dyn_table_hide_languages() {
   for (var language in languages) {
      if (!languages[language]) {
         var cells = document.getElementsByClassName(language);
         for (var i=0; i<cells.length; i++) {
            cells[i].style.display = "none";
         }
      }
   }
}

// add a new table row
function dyn_table_add_category() {
   var tbody = document.getElementById("dyn_table_categories");

   // count up all the existing categories on the screen
   var category_id = 1;
   while (true) {
      category_id++;
      var row = document.getElementById("category"+category_id);
      if (!row) {
         break;
      }
   }

   var tr = document.createElement("tr");
   tr.setAttribute("id", "category"+category_id);

   var td_label = document.createElement("td");
   td_label.appendChild(document.createTextNode("Category "+category_id+" Name:"));
   td_label.setAttribute("class", "left");
   td_label.setAttribute("className", "left");

   var td_English = document.createElement("td");
   td_English.setAttribute("class", "English");
   td_English.setAttribute("className", "English");

   var td_Spanish = document.createElement("td");
   td_Spanish.setAttribute("class", "Spanish");
   td_Spanish.setAttribute("className", "Spanish");

   var td_Portuguese = document.createElement("td");
   td_Portuguese.setAttribute("class", "Portuguese");
   td_Portuguese.setAttribute("className", "Portuguese");

   var td_del_link = document.createElement("td");
   var a_del_link = document.createElement("a");
   a_del_link.setAttribute("id", "del_category"+category_id);
   a_del_link.setAttribute("href", "javascript:dyn_table_del_category("+category_id+")");
   a_del_link.appendChild(document.createTextNode("Delete Category "+category_id));
   td_del_link.appendChild(a_del_link);

   var input_English = document.createElement("input");
   input_English.setAttribute("type", "text");
   input_English.setAttribute("name", "English"+category_id);
   input_English.setAttribute("id", "English"+category_id);

   var input_Spanish = document.createElement("input");
   input_Spanish.setAttribute("type", "text");
   input_Spanish.setAttribute("name", "Spanish"+category_id);
   input_Spanish.setAttribute("id", "Spanish"+category_id);

   var input_Portuguese = document.createElement("input");
   input_Portuguese.setAttribute("type", "text");
   input_Portuguese.setAttribute("name", "Portuguese"+category_id);
   input_Portuguese.setAttribute("id", "Portuguese"+category_id);

   td_English.appendChild(input_English);
   td_Spanish.appendChild(input_Spanish);
   td_Portuguese.appendChild(input_Portuguese);

   tr.appendChild(td_label);
   tr.appendChild(td_English);
   tr.appendChild(td_Spanish);
   tr.appendChild(td_Portuguese);
   tr.appendChild(td_del_link);

   tbody.appendChild(tr);

   dyn_table_hide_languages();
}

// remove specified category/row
function dyn_table_del_category(category_id) {
   var tr = document.getElementById("category"+category_id);
   if (!tr) {
      return;
   }
   tr.parentNode.removeChild(tr);

   // must decrement category_id value of all subsequent rows
   while (true) {
      category_id++;
      var new_category_id = category_id - 1;
      tr = document.getElementById("category"+category_id);
      if (!tr) {
         break;
      }
      var children = tr.childNodes;
      tr.setAttribute("id", "category"+new_category_id);

      // I tried avoiding 'innerHTML', but that didn't help

      //children[0].innerHTML = "";
      children[0].removeChild(children[0].childNodes[0]);
      children[0].appendChild(document.createTextNode("Category "+new_category_id+" Name:"));
      children[1].childNodes[0].setAttribute("name", "English"+new_category_id);
      children[1].childNodes[0].setAttribute("id", "English"+new_category_id);
      children[2].childNodes[0].setAttribute("name", "Spanish"+new_category_id);
      children[2].childNodes[0].setAttribute("id", "Spanish"+new_category_id);
      children[3].childNodes[0].setAttribute("name", "Portuguese"+new_category_id);
      children[3].childNodes[0].setAttribute("id", "Portuguese"+new_category_id);
      children[4].childNodes[0].setAttribute("id", "del_category"+new_category_id);
      children[4].childNodes[0].setAttribute("href", "javascript:dyn_table_del_category("+new_category_id+")");

      var a_del_link = document.createElement("a");
      a_del_link.setAttribute("id", "del_category"+new_category_id);
      a_del_link.setAttribute("href", "javascript:dyn_table_del_category("+new_category_id+")");
      a_del_link.appendChild(document.createTextNode("Delete Category "+new_category_id));

      //children[4].childNodes[0].innerHTML = "";
      children[4].removeChild(children[4].childNodes[0]);
      children[4].appendChild(a_del_link);
   }
}
</script>
</head>
<body>
<form method="post">
<div id="dyn_table" class="channel_fields">
   <div class="box dark">
      <div class="left">Languages:</div>
      <div class="right">
         <input type="checkbox" name="dyn_table[languages][]" id="cbEnglish" value="English" checked="checked" onclick="dyn_table_change_language('English')"/>English &nbsp;
         <input type="checkbox" name="dyn_table[languages][]" id="cbSpanish" value="Spanish" checked="checked" onclick="dyn_table_change_language('Spanish')"/>Spanish &nbsp;
         <input type="checkbox" name="dyn_table[languages][]" id="cbPortuguese" value="Portuguese" onclick="dyn_table_change_language('Portuguese')"/>Portuguese
      </div>
      <br clear="both"/><br/>
   </div>
   <div class="box dark">
      <table border="0" cellspacing="0">

      <tbody id="dyn_table_categories">
      <tr>
         <td class="left">&nbsp;</td>
         <td class="English">English</td>
         <td class="Spanish">Spanish</td>
         <td class="Portuguese" style="display:none">Portuguese</td>
         <td>&nbsp;</td>
      </tr>
      <tr id="category1">
         <td class="left">Category 1 Name:</td>
         <td class="English"><input type="text" name="English1" id="English1"/></td>
         <td class="Spanish"><input type="text" name="Spanish1" id="Spanish1"/></td>
         <td class="Portuguese" style="display:none"><input type="text" name="Portuguese1" id="Portuguese1"/></td>
         <td>&nbsp;</td>
      </tr>
      </tbody>
      </table>
      <div class="left"><a href="javascript:dyn_table_add_category()">Add New Category</a></div>
   </div>
</div>
</form>
</body>
</html>
 
Old June 24th, 2007, 03:47 PM
Registered User
 
Join Date: Jun 2007
Posts: 2
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Ah, I found the solution. All I had to do was use an empty string value for the 'display' CSS property instead of 'block' because display:block isn't valid CSS for tables and table elements:

Code:
cells[i].style.display = cb.checked ? "" : "none";
rather than

Code:
cells[i].style.display = cb.checked ? "block" : "none";





Similar Threads
Thread Thread Starter Forum Replies Last Post
Problem in Firefox with table in centered page Europom CSS Cascading Style Sheets 2 March 12th, 2008 07:43 AM
help writing dynamic form data to dynamic table ublend SQL Server ASP 1 June 1st, 2007 08:09 AM
help writing dynamic form data to dynamic table ublend Classic ASP Professional 1 June 1st, 2007 08:08 AM
zxml.js exception in Firefox but works fine in IE lgarc BOOK: Professional Ajax ISBN: 978-0-471-77778-6 6 January 29th, 2007 05:25 AM
PHP code - works in Firefox, fails in IE gingerbraid Beginning PHP 13 October 6th, 2005 06:33 PM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.