Forum Moderators: open

Message Too Old, No Replies

Replacing checkboxes

         

kiwi1066

3:16 am on Sep 8, 2005 (gmt 0)

10+ Year Member



I have a form that has a number of checkboxes. I have used some Javascript that I found on google to hide the checkboxes and instead show an image ( a small grren square) that changes to orange when clicked. It all works but the trouble is that when using SSL the images load too slowly. Is it possible to do this using background color instead of images and if not is there another way? Each checkbox is in a table cell and I was wondering if you could somehow get rid of the checkboxes and instead assign a value to each cell and then use an onclick event to get that value. Thanks.

garann

8:18 pm on Sep 8, 2005 (gmt 0)

10+ Year Member



You should be able to do that pretty easily. If they're table cells, it might be something like this:


<script type="text/javascript">
toggleColor(obj,chkID) {
var chk = document.getElementById(chkID);
if (obj.style.backgroundColor == "orange") {
obj.style.backgroundColor = "green";
chk.value = "false";
} else {
obj.style.backgroundColor = "orange";
chk.value = "true";
}
}
</script>
...
<td style="background-color:green;" onclick="toggleColor(this,'hdnCheckValue')">
<input type="hidden" id="hdnCheckValue" name="hdnCheckValue" value="false"/>
</td>

kiwi1066

11:35 pm on Sep 8, 2005 (gmt 0)

10+ Year Member



Thanks for that but for some reason I keep getting an error on page message.
I currently am using

echo "<TD style='background:green; colour:white'>
<INPUT type='checkbox' name='book[$rm][]' value='$d' >
</TD>\n";

to get the values. Can I use that name and value in your code instead of "hdnCheckValue" and "false".

kiwi1066

9:58 am on Sep 9, 2005 (gmt 0)

10+ Year Member



OK I put the word function in before the words toggleColor and that got the changing colors part working but I don't get how you get a value from the table cell?

garann

3:43 pm on Sep 9, 2005 (gmt 0)

10+ Year Member



Oops. Sorry about the function thing. :)

That function is assigning the value the checkbox would send to the server to a hidden element when the box is checked, and setting the element's value to the empty string if it's unchecked.

For the code you posted, you'd probably want the td to look like this:

<td style="background-color:green;" onclick="toggleColor(this,'book[$rm][]','$d')">

And the function like this:

function toggleColor(obj,chkID,val) {
var chk = document.getElementById(chkID);
if (obj.style.backgroundColor == "orange") {
obj.style.backgroundColor = "green";
chk.value = "";
} else {
obj.style.backgroundColor = "orange";
chk.value = val;
}
}

The code above will make sure you get a value for the fake checkbox if it's been "checked" (turned orange), or the empty string if it hasn't. Will that work?

kiwi1066

8:10 pm on Sep 9, 2005 (gmt 0)

10+ Year Member



Thanks . I will give it a go and let you know how it goes.

kiwi1066

12:47 am on Sep 10, 2005 (gmt 0)

10+ Year Member



It appears that my problem is that I can't get the following to parse

echo '<td style="background-color:green;" onclick="toggleColor(this,'book[$rm][]','$d')"><INPUT type="hidden" name="book[$rm][]" value="$d" ></td>';

the ' around book[$rm[] and $d being the error. But if I create a table in HTML that is the only syntax that works eg

<td style="background-color:green;" onclick="toggleColor(this,'book[101][]','2005-09-14')"><INPUT type="hidden" name="book[101][]" value="2005-09-13" ></td>

Does that make sense?

Bernard Marx

1:50 am on Sep 10, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Couldn't you escape them?

\'banana\'

(or use a Heredoc statement)

kiwi1066

2:13 am on Sep 10, 2005 (gmt 0)

10+ Year Member



Thanks the escape thing worked.

kiwi1066

3:44 am on Sep 10, 2005 (gmt 0)

10+ Year Member



I have got the color toggle working but can't seem to get any values from what is selected eg the following is a test page where the cell changes color when clicked but the value doesn't echo.

<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<script type="text/javascript">
function toggleColor(obj,chkID,val) {
var chk = document.getElementById(chkID);
if (obj.style.backgroundColor == "orange") {
obj.style.backgroundColor = "green";
chk.value = "";
} else {
obj.style.backgroundColor = "orange";
chk.value = "val";
}
}
</script>

</head>

<body>
<form name="form1" id="form1" method="post" action="<?php echo $PHP_SELF;?>">
<table align='left'TABLE border='4' cellspacing='1' cellpadding='0'>
<TR><TH>Room</TH>

<TH width=20px>17</TH>
<TH width=20px>18</TH>
<TH width=20px>19</TH>
</TR>
<TR><TD>101</TD>

<td style="background-color:green;" onclick="toggleColor(this,'test','8')"><input name="test" type="hidden" value="8" /></td>
<td style="background-color:green;" onclick="toggleColor(this,'test','9')"><input name="test" type="hidden" value="9" /></td>
<td style="background-color:green;" onclick="toggleColor(this,'test','10')"><input name="test" type="hidden" value="10" /></td>
</TR>

</TABLE>
<input type="submit" name="Submit" value="Submit" />
</form>
<?php echo $_POST['test'];?>

</body>
</html>

kiwi1066

8:40 am on Sep 10, 2005 (gmt 0)

10+ Year Member



It has been suggested to me that when using
document.getElementById you need a unique ID and I was wondering if that was my problem as in the preceding example the inputs all have the same ID ie "test". I can't see a way around this though as I want to replace checkboxes that all have to have the same name.

Bernard Marx

10:55 am on Sep 10, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Try document.getElementsByName('_the_name_')[i]

Bernard Marx

11:00 am on Sep 10, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



W3C way:

document.getElementsByName('_the_name_')[index]

Old way:

document.forms.form1.elements['_the_name_'][index]

------

If there is only one such element, you will still need the [index] part with the W3C way, but not with the old.

kiwi1066

8:24 pm on Sep 10, 2005 (gmt 0)

10+ Year Member



I tried below and it didn't work

<script type="text/javascript">
function toggleColor(obj,chkID,val) {
var chk = document.getElementsByName('test')[index]
if (obj.style.backgroundColor == "orange") {
obj.style.backgroundColor = "green";
chk.value = "";
} else {
obj.style.backgroundColor = "orange";
chk.value = "val";
}
}
</script>

Bernard Marx

10:32 pm on Sep 10, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You don't literally use index. You put in the index of the actual element amongst elements of that name (in source order).

var chk = document.getElementsByName('test')[0]

kiwi1066

11:06 pm on Sep 10, 2005 (gmt 0)

10+ Year Member



You will have to excuse my ignorance but I don't understand what you mean by the index thing. I put in var chk = document.getElementsByName('test')[0] and the color change worked but I still got no value when echoed and will what you have suggested work where a user selects a number of values?

Bernard Marx

11:28 pm on Sep 10, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I'll try and piece together a test page from what you've posted so far, so I can work out what you're doing. If you fancy posting one yourself that'd be useful... but with all the PHP parsed out to give an example client-side output. We're dealing with the client-side here, which is why this statement has me confused:

I still got no value when echoed

--------

In fact, you'll have to excuse my ignorance. I just took the time to read your post #1 properly. Should have something for you in a mo'.

kiwi1066

12:04 am on Sep 11, 2005 (gmt 0)

10+ Year Member



Thanks

Have a look at my message #10 for a working example.

Bernard Marx

12:06 am on Sep 11, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Here's what I was thinking.

Trouble is... it won't work, or at least I don't think so. I have the feeling that the values of form inputs that are not displayed (ie CSS display: none, as opp. to type="hidden" ) are not posted.

I'm posting the code just for reference, and for something to amend in a moment.

<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style>
.scriptDisabled .chkCell input { display: none;}
.chkCell {background-color: green;}
</style>
<script type="text/javascript">

// set checkboxes to "display:none;"
document.getElementsByTagName('html')[0].className = 'scriptDisabled';

function toggleBox(cell)
{
var box = cell.getElementsByTagName('input')[0];
// Toggle check & get new state
var doCheck = (box.checked =!box.checked);
// empty --> green (via sheet)
cell.style.backgroundColor = doCheck? 'orange' : '';
}
</script>
</head>

<body>
<form name="form1" id="form1" method="post" action="<?php echo $PHP_SELF;?>">
<table align='left'TABLE border='4' cellspacing='1' cellpadding='0'>
<tr>
<th>Room</th>
<th width=20px>17</th>
<th width=20px>18</th>
<th width=20px>19</th>
</tr>
<tr>
<td>101</td>
<!-- (&nbsp;)s for some content, if inputs hidden by script -->
<td class="chkCell" onclick="toggleBox(this)">
&nbsp;<input name="test" type="checkbox" value="8"></td>
<td class="chkCell" onclick="toggleBox(this)">
&nbsp;<input name="test" type="checkbox" value="9"></td>
<td class="chkCell" onclick="toggleBox(this)">
&nbsp;<input name="test" type="checkbox" value="10"></td>
</tr>
</table>
<input type="submit" name="Submit" value="Submit" />
</form>
<?php echo $_POST['test'];?>

</body>
</html>

[edited by: jatar_k at 3:48 pm (utc) on Oct. 5, 2005]

Bernard Marx

12:37 am on Sep 11, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Here's a solution using proper hidden inputs.
The inputs look like this:

<input name="test" type="[blue]hidden[/blue]" value="8[blue]:0[/blue]">

The function is changed to this:

function toggleBox(cell)
{
var box = cell.getElementsByTagName('input')[0];
// get 'checked' state from last char (0¦1)
var doCheck =! Number(box.value.slice(-1));
// Switch last char
box.value = box.value.replace(/.$/, Number(doCheck));
// empty --> green (via sheet)
cell.style.backgroundColor = doCheck? 'orange' : '';
}

The idea is to signify checkedness by swapping the zero for a 1.
A couple of (possible) problems here.

1. This means you'll have to parse out the :0 or :1 at the server side. Not so tough really, but if this is beyond your control then the whole idea is a non-starter.

2. No fall-back for JS-disabled browsers. However, you could just throw the real checkboxes in there too, they will still be hidden normally via the CSS. You might get parallel postings back at the server though!

See how it goes.

Bernard Marx

12:51 am on Sep 11, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



..or just have a single hidden input, and, on submission, loop through the cells seing whether or not they're green; build an array of values and post that as a delimited string.

kiwi1066

1:09 am on Sep 11, 2005 (gmt 0)

10+ Year Member



Thanks.
I think I should point out that I have been learning php for 9 months and Javascript for 9 minutes.
The relevant part of the code that creates the calendar table is

echo "<TD style='background:green; colour:white'>
<INPUT type='checkbox' name='book[$rm][]' value='$d' ></TD>\n";

so when I run the page and view source in my browser I get

<table align='left'TABLE border='4' bordercolor='#A6A6D2' cellspacing='1' cellpadding='0'>
<TR><TH>Room</TH>
<TH width=20px>11</TH>
<TH width=20px>12</TH>
<TH width=20px>13</TH>
<TH width=20px>14</TH>
<TH width=20px>15</TH>
<TH width=20px>16</TH>
<TH width=20px>17</TH>
<TH width=20px>18</TH>
<TH width=20px>19</TH>
<TH width=20px>20</TH>
</TR>
<TR><TD>101</TD><TD style='background:green; colour:white'>
<INPUT type='checkbox' name='book[101][]' value='2005-09-11' >
</TD>
<TD style='background:green; colour:white'>
<INPUT type='checkbox' name='book[101][]' value='2005-09-12' >
</TD>
<TD style='background:green; colour:white'>
<INPUT type='checkbox' name='book[101][]' value='2005-09-13' >
</TD>
<TD style='background:green; colour:white'>
<INPUT type='checkbox' name='book[101][]' value='2005-09-14' >
</TD>
<TD style='background:green; colour:white'>
<INPUT type='checkbox' name='book[101][]' value='2005-09-15' >
</TD>
<TD style='background:green; colour:white'>
<INPUT type='checkbox' name='book[101][]' value='2005-09-16' >
</TD>
<TD style='background:green; colour:white'>
<INPUT type='checkbox' name='book[101][]' value='2005-09-17' >
</TD>
<TD style='background:green; colour:white'>
<INPUT type='checkbox' name='book[101][]' value='2005-09-18' >
</TD>
<TD style='background:green; colour:white'>
<INPUT type='checkbox' name='book[101][]' value='2005-09-19' >
</TD>
<TD style='background:green; colour:white'>
<INPUT type='checkbox' name='book[101][]' value='2005-09-20' >
</TD>
</TR>
</table>

so I don't know if what you have suggested will work or not....what do you think?

Bernard Marx

2:04 am on Sep 11, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I made two (+ a third in outline) suggestions, really. The first uses checkboxes. The others use <input type="hidden">.

The problem with using checkboxes is that setting them to display: none; may well (I'm fairly sure in fact) reseult in them not being posted (try it in a few browsers).

While writing, I've realised that this could be solved by using the CSS visibility property instead. So..

1) Take the code from my post (msg #:19).

2) Swap

"display: none;"
for
"visibility: hidden;"
in the stylesheet.
- add
"color: white;"
if you like

3) You can now remove the $nbsp;-s that I put in the cells too.

Moving the style attributes from the HTML into a stylesheet is, of course, a little more efficient on the server, and in download, and etc, but the main benefit is that it allows us that little trick that the checkboxes to only be hidden if Javascript is enabled in the browser (If it is, the HTML element gets a className added, "scriptEnabled", and this kicks the contextual CSS rule into action).

I think this'll work (as regards posting of form values). I'll test it myself later, but right now it's well past my bedtime.

kiwi1066

3:04 am on Sep 11, 2005 (gmt 0)

10+ Year Member



Thanks ..that works but I would prefer the method using "hidden" input as using the checkboxes mean that the cell has to be a certain size which I think is a bit cumbersome. What I was going to do if the user doesn't have javascript enabled is show a different link to take them to another page etc.

kiwi1066

3:38 am on Sep 11, 2005 (gmt 0)

10+ Year Member



I came back to edit my last post but there is a time limit on edit. I just wanted to thank you for all the work you have done on this.

kiwi1066

8:01 pm on Sep 20, 2005 (gmt 0)

10+ Year Member



I am still trying to set this up so that I do not use checkboxes at all and have got the following that nearly works. The problem with it is that you can only select one table cell at a time and it should be
getElementByTagName instead of
var eselected = document.getElementById("2005-09-20");
but I can't get that to work.
Can any one see how to remedy this or am I heading down the wrong track.
<html>
<head>
<title>

</title>
<style>
td.yes{
align:center;
width:158px;
height:40px;
background-color:orange;
font-size:14px;
font-family: Verdana Arial Helvetica sans-serif;
cursor:pointer;
}
td.no{
align:center;
width:158px;
height:40px;
background-color:green;
font-size:14px;
font-family: Verdana Arial Helvetica sans-serif;
cursor:pointer;
}
</style>
<script>

function doselection(cell)
{
var eselected = document.getElementById("2005-09-20");
var submission = document.getElementById("option");
eselected.setAttribute('className','no');
cell.setAttribute('className','yes');
eselected = cell;
submission.setAttribute('value',cell.getAttribute("id"));
}
</script></head>
<body >

<form action=Untitled-2.php method="post" name="form1" id="form1">
<input type=hidden id=option name=optval[] value="">
<?php
$d="2005-09-20";
$e="2005-09-21";
$f="2005-09-22";
$g="2005-09-27";
?>
<table border=2>
<tr>
<td id=<?php echo "$d"?> class=no onclick="doselection(this)">&nbsp;</td>
<td id=<?php echo "$e"?> class=no onclick="doselection(this)">&nbsp;</td>
<td id=<?php echo "$f"?> class=no onclick="doselection(this)">&nbsp;</td>
<td id=<?php echo "$g"?> class=no onclick="doselection(this)">&nbsp;</td>
</tr>
</table>
<input name="Submit" type=submit id="Submit" value="Submit">
</form>
<?php
if($Submit){
print_r($optval);
}
?>
</body></html>

Bernard Marx

9:14 pm on Sep 20, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hmm. I can't work out why you want to deselect another cell. I'm presuming that they act like checkboxes - ie that any or none of them may be selected at one time. This looks like you're trying to toggle one off when a new one comes on (like radio buttons).

On the server side of things, there is only one hidden input, this would be filled with some form of delimited string with all the selected values. It will be just one form value though, so you can therefor leave out the [].

Before I move on, am I getting the right end of the stick, ?

kiwi1066

9:26 pm on Sep 20, 2005 (gmt 0)

10+ Year Member



You are correct in describing the way it presently works but I don't want it to toggle on and off like that ie I want to be able to select multiple dates which is why I have the []. Do you think I am heading in the right direction with this?

Bernard Marx

10:27 pm on Sep 20, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Er.. dunno! I don't think there is just one right way.

1) Why is that cell (id="2005-09-20") being deselected when another is clicked.

2) (At present) there is only a single hidden input. I imagíne that using [] will only add an extra layer of confusion at the server. There are indeed multiple values being represented, but there is only a single value being sent.

Here's how I see it....

<html> 
<head>
<title>
</title>
<style>
#checkRow TD
{
align:center;
width:158px;
height:40px;
font-size:14px;
font-family: Verdana Arial Helvetica sans-serif;
cursor:pointer;
}

.yes{ background-color:orange;}
.no { background-color:green; }

</style>
<script>

/*
Avoid set/get attribute with classes, if possible
- IE: 'className', while W3C: 'class'
So we'll stick with dot syntax. */
function doselection(cell)
{
cell.className = (cell.className=="yes")?"no":"yes";
}

function getValues()
{
var cells = document.getElementById('checkRow')
.getElementsByTagName('td');

for(var k=0, cell, vals=[]; cell=cells[k++];)
{
if(cell.className=="yes")
vals[vals.length] = cell.id;
}
// join into ':' delimited string
// just split this single value in the PHP script.
document.getElementById('optval').value = vals.join(':');
}

</script></head>
<body >

<form action=receive.php method="post" name="form1" id="form1"
onsubmit="getValues()">
<input type=hidden id="optval" name="optval" value="">

<table border=2>
<tr id="checkRow">
<td id=2005-09-20 class=no onclick="doselection(this)">&nbsp;</td>
<td id=2005-09-21 class=no onclick="doselection(this)">&nbsp;</td>
<td id=2005-09-22 class=no onclick="doselection(this)">&nbsp;</td>
<td id=2005-09-27 class=no onclick="doselection(this)">&nbsp;</td>
</tr>
</table>
<input name="Submit" type=submit id="Submit" value="Submit">
</form>

</body></html>

kiwi1066

10:50 pm on Sep 20, 2005 (gmt 0)

10+ Year Member



Thanks
Could you please explain what you mean by
"just split this single value in the PHP script." as I couldn't get a value when using php to echo "optval"
This 49 message thread spans 2 pages: 49