Google Answers Logo
View Question
 
Q: Toggle & Aggregate with CSS and JavaScript ( Answered 4 out of 5 stars,   0 Comments )
Question  
Subject: Toggle & Aggregate with CSS and JavaScript
Category: Computers > Programming
Asked by: nosneb-ga
List Price: $50.00
Posted: 09 Feb 2004 07:26 PST
Expires: 10 Mar 2004 07:26 PST
Question ID: 304970
I am tyring to simulate an application on the Web. I am trying to
aggregate table cell values when the user clicks on a cell into a
single form field (which will be hidden). I can get close but I don't
know how to unset the table cell color or how to keep repetitions of
the same day out of my field (if the user clicks a table cell more
than once - the table cells should toggle).

I have a simple table of days of the week. What I would like it to do
are the following:
 a) hover over text changes text color and weight (using CSS)
 b) click on table cell text:
        1. changes the table cell text to the highlight color (not weight)
        2. sets a field on the form to be the cell's text
        3. OK to click one, multiple, all table cells and their 
           values will aggregate in the form field (separated by 
           carriage returns):
               Mon
               Tues
        4. If a field is clicked, and is clicked again:
            a) the table text reverts to default
            b) the value is removed from the form field

Code follows:

<TABLE BORDER=0 CELLPADDING=5 CELLSPACING=0>
<TR>
	<TD class="date" WIDTH=34>Mon</TD>
	<TD class="date" WIDTH=34>Tue</TD>
	<TD class="date" WIDTH=34>Wed</TD>
</TR>
<TR>
	<TD class="date">Thu</TD>
	<TD class="date">Fri<</TD>
	<TD class="date">Sat</TD>
</TR>
<TR>
	<TD class="date">Sun/TD>
	<TD>&nbsp;</TD>
	<TD>&nbsp;</TD>
</TR>
</TABLE>

I have tried using this with onClick in the table cells but using the
A properties I can't toggle the cell formatting ( defualt = gray,
first click = blue, second click = gray, etc.)
<style rel="stylesheet" type="text/css">
.date {border: inset 0.01em; 
       filter: progid:DXImageTransform.Microsoft.Gradient(gradientType=0,startColorStr=Gainsboro,endColorStr=white);
       float: left;
       text-align: center; }
.date A:link {	font-family:verdana, arial, helvetica; 
		font-size:xx-small; 
		text-decoration: none; 
		color: gray; }
.date A:visited { font-family:verdana, arial, helvetica;
                text-decoration: none;
		font-size:xx-small; 
		color: blue; }
.date A:hover {	text-decoration: none;
		font-weight: bold; 
		color: blue; }
</style>

I am open to any solution that works with CSS and JS. I have spent
some time looking on the Web, so I am looking for working code not
links. Thank you.
Answer  
Subject: Re: Toggle & Aggregate with CSS and JavaScript
Answered By: eiffel-ga on 09 Feb 2004 12:57 PST
Rated:4 out of 5 stars
 
Hi nosneb,

Here is some code that, as far as I can tell, does what you want.

However: I have only been able to test it with the Mozilla browser. If
there is any problem using it with Internet Explorer, let me know and
I will adapt it tomorrow when I have access to a Windows machine.

Here is the stylesheet. Put it in a file "index.css".

===

table {
	border: 1px solid black; 
	text-align: center;
	}

td {
	border: 1px solid black;
	}

td.date {
	color: gray;
	}

td.hovering {
	color: black;
	font-weight: bold;
	}

td.selected {
	color: red;
	}

td.hoveringselected {
	color: red;
	font-weight: bold;
	}

===

Here is the HTML file. Put it in a file "index.html".

===

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
  <meta http-equiv="content-type"
 content="text/html; charset=ISO-8859-1">
  <title>Toggle & Aggregate Demo</title>
  <link rel="stylesheet" type="text/css" href="index.css" title="standard">

<script type="text/javascript">

   // Associative array to record which days are currently selected
   var days = new Object();

   // Return the current table cell in a browser-independent way
   function cell(d) {
      if (document.getElementById)
         return document.getElementById(d);
      else
         return document.all[d];
   }

   // Highlight the text when the mouse hovers over it
   function entered(d) {
      if (days[d])
	 cell(d).className = 'hoveringselected';
      else
	 cell(d).className = 'hovering';
   }

   // Unhighlight the text when the mouse moves away
   function exited(d) {
      if (days[d])
	 cell(d).className = 'selected';
      else
	 cell(d).className = 'date';
   }

   // Update things when the user clicks on some day
   function clicked(d) {
      // Toggle this day's entry in the associative array
      days[d] = !days[d];
      // Set the color to show whether the day is selected
      if (days[d])
	 cell(d).className = 'hoveringselected';
      else
	 cell(d).className = 'hovering';
      // Update the field that shows the cell's text
      document.forms['report'].elements['current'].value = d;
      // Update the multi-line list of selected days
      var selected = document.forms['report'].elements['selected'];
      selected.value = '';
      if (days['Mon']) selected.value += 'Monday\n';
      if (days['Tue']) selected.value += 'Tuesday\n';
      if (days['Wed']) selected.value += 'Wednesday\n';
      if (days['Thu']) selected.value += 'Thursday\n';
      if (days['Fri']) selected.value += 'Friday\n';
      if (days['Sat']) selected.value += 'Saturday\n';
      if (days['Sun']) selected.value += 'Sunday\n';  
   }

</script>

</head>
<body>
<h1>Toggle & Aggregate Demo</h1>

<h2>Click on the day names:</h2>
<TABLE BORDER=0 CELLPADDING=5 CELLSPACING=0>
<TR>
	<TD class="date" id="Mon" WIDTH=34
	  onmouseover="entered('Mon');"
	  onmouseout="exited('Mon');"
	  onmousedown="clicked('Mon');"
	  >
	  Mon</TD>
	<TD class="date" id="Tue" WIDTH=34
	  onmouseover="entered('Tue');"
	  onmouseout="exited('Tue');"
	  onmousedown="clicked('Tue');"
	  >
	  Tue</TD>
	<TD class="date" id="Wed" WIDTH=34
	  onmouseover="entered('Wed');"
	  onmouseout="exited('Wed');"
	  onmousedown="clicked('Wed');"
	  >
	  Wed</TD>
</TR>
<TR>
	<TD class="date" id="Thu"
	  onmouseover="entered('Thu');"
	  onmouseout="exited('Thu');"
	  onmousedown="clicked('Thu');"
	  >
	  Thu</TD>
	<TD class="date" id="Fri"
	  onmouseover="entered('Fri');"
	  onmouseout="exited('Fri');"
	  onmousedown="clicked('Fri');"
	  >
	  Fri</TD>
	<TD class="date" id="Sat"
	  onmouseover="entered('Sat');"
	  onmouseout="exited('Sat');"
	  onmousedown="clicked('Sat');"
	  >
	  Sat</TD>
</TR>
<TR>
	<TD class="date" id="Sun"
	  onmouseover="entered('Sun');"
	  onmouseout="exited('Sun');"
	  onmousedown="clicked('Sun');"
	  >
	  Sun</TD>
	<TD>&nbsp;</TD>
	<TD>&nbsp;</TD>
</TR>
</TABLE>

<form name="report">
<h2>Most recently clicked:</h2>
<input name="current">
<h2>Days currently selected:</h2>
<textarea name="selected" rows=7 cols=10></textarea>
</form>

</body>
</html>

===

Please let me know if this meets your needs, or if there are any
problems (in which case I will work on it further).


Google search strategy:

css reference
://www.google.com/search?q=css+reference

javascript reference
://www.google.com/search?q=javascript+reference


Regards,
eiffel-ga

Request for Answer Clarification by nosneb-ga on 09 Feb 2004 17:01 PST
This is excellent. It is exactly what I asked for. How do you control
the sorting: you have it working for days of the week (which I asked
for). I would also like to extend it to months of the year, and days
of the month. The sorting in the selected field isn't alphabetic, how
can I get it so that other lists will sort? Also, to expand to say
days of the month, can I also use the variable passed to the function
(e.g., Mon is passed and Mon is updated to the selected field) or do I
need 31 lines of this? Thank you very much.

Clarification of Answer by eiffel-ga on 10 Feb 2004 03:54 PST
Hi nosneb,

You can sort the list of selected items however you want, just by
changing the order of the tests. For example, to sort the weekdays
alphabetically, you could change the code to this:

      if (days['Fri']) selected.value += 'Friday\n';
      if (days['Mon']) selected.value += 'Monday\n';
      if (days['Sat']) selected.value += 'Saturday\n';
      if (days['Sun']) selected.value += 'Sunday\n';  
      if (days['Thu']) selected.value += 'Thursday\n';
      if (days['Tue']) selected.value += 'Tuesday\n';
      if (days['Wed']) selected.value += 'Wednesday\n';

Whatever order you put those 7 lines of code in, is the order that the
days will appear in the list.

If you extend this system to cater for days, then yes you will need 31
lines of tests. That's because every time you change any entry on the
list, the whole list is regenerated (not just the entry that you
clicked on).

Whilst there are other approaches that would result in more compact
code (such as using numerically-indexed arrays), I think this approach
is straightforward, flexible and maintainable.

To extend this system to months and days of the month, you will need
to duplicate some of the functions. As an example, I've shown how you
could add processing for the first few months.

===

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
  <meta http-equiv="content-type"
 content="text/html; charset=ISO-8859-1">
  <title>Toggle & Aggregate Demo</title>
  <link rel="stylesheet" type="text/css" href="index.css" title="standard">

<script type="text/javascript">

   // Associative arrays to record which days and months are currently selected
   var days = new Object();
   var months = new Object();

   // Return the current table cell in a browser-independent way
   function cell(d) {
      if (document.getElementById)
         return document.getElementById(d);
      else
         return document.all[d];
   }

   // Highlight the text when the mouse hovers over it
   function dayEntered(d) {
      if (days[d])
	 cell(d).className = 'hoveringselected';
      else
	 cell(d).className = 'hovering';
   }

   // Unhighlight the day when the mouse moves away
   function dayExited(d) {
      if (days[d])
	 cell(d).className = 'selected';
      else
	 cell(d).className = 'date';
   }

   // Update things when the user clicks on some day
   function dayClicked(d) {
      // Toggle this day's entry in the associative array
      days[d] = !days[d];
      // Set the color to show whether the day is selected
      if (days[d])
	 cell(d).className = 'hoveringselected';
      else
	 cell(d).className = 'hovering';
      // Update the field that shows the cell's text
      document.forms['report'].elements['currentDay'].value = d;
      // Update the multi-line list of selected days
      var selected = document.forms['report'].elements['daysSelected'];
      selected.value = '';
      if (days['Fri']) selected.value += 'Friday\n';
      if (days['Mon']) selected.value += 'Monday\n';
      if (days['Sat']) selected.value += 'Saturday\n';
      if (days['Sun']) selected.value += 'Sunday\n';  
      if (days['Thu']) selected.value += 'Thursday\n';
      if (days['Tue']) selected.value += 'Tuesday\n';
      if (days['Wed']) selected.value += 'Wednesday\n';
   }

   // Highlight the month when the mouse hovers over it
   function monthEntered(d) {
      if (months[d])
	 cell(d).className = 'hoveringselected';
      else
	 cell(d).className = 'hovering';
   }

   // Unhighlight the month when the mouse moves away
   function monthExited(d) {
      if (months[d])
	 cell(d).className = 'selected';
      else
	 cell(d).className = 'date';
   }

   // Update things when the user clicks on some month
   function monthClicked(d) {
      // Toggle this day's entry in the associative array
      months[d] = !months[d];
      // Set the color to show whether the day is selected
      if (months[d])
	 cell(d).className = 'hoveringselected';
      else
	 cell(d).className = 'hovering';
      // Update the field that shows the cell's text
      document.forms['report'].elements['currentMonth'].value = d;
      // Update the multi-line list of selected days
      var selected = document.forms['report'].elements['monthsSelected'];
      selected.value = '';
      if (months['Jan']) selected.value += 'January\n';
      if (months['Feb']) selected.value += 'February\n';
      if (months['Mar']) selected.value += 'March\n';
   }

</script>

</head>
<body>
<h1>Toggle & Aggregate Demo</h1>

<h2>Click on the day names:</h2>

<TABLE BORDER=0 CELLPADDING=5 CELLSPACING=0>
<TR>
	<TD class="date" id="Mon" WIDTH=34
	  onmouseover="dayEntered('Mon');"
	  onmouseout="dayExited('Mon');"
	  onmousedown="dayClicked('Mon');"
	  >
	  Mon</TD>
	<TD class="date" id="Tue" WIDTH=34
	  onmouseover="dayEntered('Tue');"
	  onmouseout="dayExited('Tue');"
	  onmousedown="dayClicked('Tue');"
	  >
	  Tue</TD>
	<TD class="date" id="Wed" WIDTH=34
	  onmouseover="dayEntered('Wed');"
	  onmouseout="dayExited('Wed');"
	  onmousedown="dayClicked('Wed');"
	  >
	  Wed</TD>
</TR>
<TR>
	<TD class="date" id="Thu"
	  onmouseover="dayEntered('Thu');"
	  onmouseout="dayExited('Thu');"
	  onmousedown="dayClicked('Thu');"
	  >
	  Thu</TD>
	<TD class="date" id="Fri"
	  onmouseover="dayEntered('Fri');"
	  onmouseout="dayExited('Fri');"
	  onmousedown="dayClicked('Fri');"
	  >
	  Fri</TD>
	<TD class="date" id="Sat"
	  onmouseover="dayEntered('Sat');"
	  onmouseout="dayExited('Sat');"
	  onmousedown="dayClicked('Sat');"
	  >
	  Sat</TD>
</TR>
<TR>
	<TD class="date" id="Sun"
	  onmouseover="dayEntered('Sun');"
	  onmouseout="dayExited('Sun');"
	  onmousedown="dayClicked('Sun');"
	  >
	  Sun</TD>
	<TD>&nbsp;</TD>
	<TD>&nbsp;</TD>
</TR>
</TABLE>

<h2>Click on the month names:</h2>

<TABLE BORDER=0 CELLPADDING=5 CELLSPACING=0>
<TR>
	<TD class="date" id="Jan" WIDTH=34
	  onmouseover="monthEntered('Jan');"
	  onmouseout="monthExited('Jan');"
	  onmousedown="monthClicked('Jan');"
	  >
	  Jan</TD>
	<TD class="date" id="Feb" WIDTH=34
	  onmouseover="monthEntered('Feb');"
	  onmouseout="monthExited('Feb');"
	  onmousedown="monthClicked('Feb');"
	  >
	  Feb</TD>
	<TD class="date" id="Mar" WIDTH=34
	  onmouseover="monthEntered('Mar');"
	  onmouseout="monthExited('Mar');"
	  onmousedown="monthClicked('Mar');"
	  >
	  Mar</TD>
</TR>
</TABLE>

<form name="report">
<h2>Most recently clicked:</h2>
Day: <input name="currentDay"><br>
Month: <input name="currentMonth">
<h2>Days currently selected:</h2>
<textarea name="daysSelected" rows=7 cols=10></textarea>
<h2>Months currently selected:</h2>
<textarea name="monthsSelected" rows=7 cols=10></textarea>
</form>

</body>
</html>

===

One word of caution: in this design the text of each entry needs to be
different. So it's fine to have "Jan" and "1" for the 1st of January,
but if you wanted to represent January as "1" instead of "Jan" we
would need to consider a different design as the two uses of "1" would
get mixed up (due to the way JavaScript processes the "getElementById"
function).

Regards,
eiffel-ga
nosneb-ga rated this answer:4 out of 5 stars
This was excellent and answered my question. This was really the best
reasonable response time.

Comments  
There are no comments at this time.

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy