PDA

View Full Version : Yet Another Code Challenge


beetle
01-31-2003, 03:54 PM
Ok folks, you asked for it! A code challenge that could be a cool widgety thing, possibly be useful and NOT a string-based problem!

The only downside is that I'm not totally sure if this is even possible. With that being said, the guidelines here will be pretty loose, I'll set the initial deadline at 1 week from the date/time of this post.

The challenge
Create a script that will allow "click and drag to check" functionality for checkboxes. If you don't get what I mean by that, consider this scenario...

Hotmail, or any other web-mail product, usually has a checkbox next to each message that can be checked for deletion or moving or whatever action the user decides. However, you pretty much have two choices to get all those checkboxes checked, either clicking them one by one, or using the "Check All" button and then unchecking what you don't want to move/delete/whatever.

So, I propose an interface that would let the user click one box, hold the button down, and drag down the list, checking each box that the mouse passes over, until the mouse button is let up. If you have used Photoshop, then you will recognize this interface being similar to the layer linking or visibility toggles in the layers palette.

Note that if the solution for this is IE only or other, then it should degrade, sniff, whatever for other browsers.

Good luck, and have at it!

A1ien51
01-31-2003, 05:24 PM
This was whipped up in jiff,
Tested in Netscape 7(passed), IE 6(Passed), Opera 6(Did not work, but did not effect performance)

Works with the shift key pressed down and the ablitiy for toggle to be turned on/off in the script's settings


<html>
<head>
<script>
//A1ien51 Submission
//Settings
var Toggle = true; //Toggle between selected and unselected durning highlight

var Highlight=false;
function handleKeyPress(evt) {
var nbr;
if (window.Event) nbr = evt.which;
else nbr = event.keyCode;
if(nbr==16)Highlight=true;
return true;
}

function MakeFalse(){Highlight=false;}

function SelectIt(X){
if(Highlight){
if(X.checked && Toggle)X.checked=false;
else X.checked=true;
}
}

document.onkeydown= handleKeyPress
document.onkeyup= MakeFalse;

</script>
</head>
<body>
<form name="A">
Hold Shift Key Down to Toggle Boxes onmouseover<br><hr>
<input type="checkbox" name="C1" onmouseover="SelectIt(this)"><br>
<input type="checkbox" name="C2" onmouseover="SelectIt(this)"><br>
<input type="checkbox" name="C3" onmouseover="SelectIt(this)"><br>
<input type="checkbox" name="C4" onmouseover="SelectIt(this)"><br>
<input type="checkbox" name="C5" onmouseover="SelectIt(this)"><br>
<input type="checkbox" name="C6" onmouseover="SelectIt(this)"><br>
<input type="checkbox" name="C7" onmouseover="SelectIt(this)"><br>
<input type="checkbox" name="C8" onmouseover="SelectIt(this)"><br>
</form>
</body>
</html>

beetle
01-31-2003, 05:37 PM
That's cool Alien51!!!

But, I'd much rather see

1) No shift key
2) Less global namespace use
3) Not having to attach an event to each checkbox

Whaddya say?

A1ien51
01-31-2003, 05:40 PM
lol....that script took me all but 2 minutes, copied from 2 other scripts of mine and attached the onmouseovers....I will play with it later on, time to get some real work done...lol

A1ien51

here is a link to see the above scriupt in action
http://www10.brinkster.com/a1ien51/Scripts/checkboxselect.htm

Oh and when you said hold the button down, I was not thinking mouse button....lol

Vladdy
01-31-2003, 06:14 PM
Something I whipped up during lunch hour (IE only for now - will have to change events for Gecko). Still far from perfect and would not work with the page scrolled - but these are details to work on later...
Group attribute for the checkbox has a potential to have separate groups of checkboxes affected by the drag-select....
Right now I did the "select range" type behaviour where mouse does not have to pass over every checkbox, which IMHO is a preferred mode in most applications (otherwise "hit or miss" is not much different from individual clicking)

<html>
<head>
<title>CB Test</title>
<style>
input
{ display:block;
}
</style>
<script>
cbSelect = false;
cbGroup = null;
cbFirst = null;
function initCB()
{ document.body.attachEvent('onmousemove',bodyMMove);
document.body.attachEvent('onmouseup',bodyMUp);
inputs = document.getElementsByTagName('input');
for(i=0; i<inputs.length; i++)
{ if(inputs[i].type == 'checkbox' && inputs[i].getAttribute('group'))
{ inputs[i].attachEvent('onmousedown',cbMDown);
inputs[i].attachEvent('onmouseup',cbMUp);
}
}
}

function bodyMMove(e)
{ if(cbSelect)
for(i=0; i<cbGroup.length; i++)
{ cbGroup[i].checked = e.clientY > cbFirst.offsetTop?(e.clientY>cbGroup[i].offsetTop && cbFirst.offsetTop<cbGroup[i].offsetTop) :(e.clientY<cbGroup[i].offsetTop && cbFirst.offsetTop>cbGroup[i].offsetTop) ;
}
}

function bodyMUp(e)
{ cbSelect=false;
cbGroup = null;
}

function cbMDown(e)
{ if(!e.srcElement.checked)
{ e.srcElement.checked = true;
cbSelect = true;
initCBSelect(e.srcElement);
}
}

function cbMUp(e)
{ if(e.srcElement.checked && cbSelect)
{ e.srcElement.checked = false;
}
cbSelect=false;
cbGroup = null;
}

function initCBSelect(start)
{ inputs = document.getElementsByTagName('input');
cbGroup = new Array();
for(i=0; i<inputs.length; i++)
{ if(inputs[i].type == 'checkbox' && inputs[i].getAttribute('group'))
{ if(inputs[i] == start) cbFirst = inputs[i];
else cbGroup[cbGroup.length]=inputs[i];
}
}
}


</script>
</head>
<body onload="initCB()">
<input type="checkbox" group="1" />
<input type="checkbox" group="1" />
<input type="checkbox" group="1" />
<input type="checkbox" group="1" />
<input type="checkbox" group="1" />
<input type="checkbox" group="1" />
<input type="checkbox" group="1" />
<input type="checkbox" group="1" />
<input type="checkbox" group="1" />
<input type="checkbox" group="1" />
<input type="checkbox" group="1" />
<input type="checkbox" group="1" />
<input type="checkbox" group="1" />
</body>
</html>

Borgtex
01-31-2003, 06:45 PM
Only tested with IE 5.5, that's the reason for document.all (but maybe it works on other browsers).

Click an unchecked box and drag to check a group
Click a checked box and drag to ungroup

<script>
var clkbox=false

function msmov()
{
e=event.srcElement
if (window.event.button == 1 && e.drag && clkbox) e.checked=chkval;
}

function click()
{
e=event.srcElement
if (e.drag) {clkbox=true; chkval=!e.checked}
}

function unclick()
{clkbox=false;}


if (document.all)
{
document.onmousemove=msmov
document.onmousedown=click
document.onmouseup=unclick
}

</script>
<body>
<form name="A">
<input type="checkbox" name="C1" drag="true"><br>
<input type="checkbox" name="C2" drag="true"><br>
<input type="checkbox" name="C3" drag="true"><br>
<input type="checkbox" name="C4" drag="true"><br>
<input type="checkbox" name="C5" drag="true"><br>
<input type="checkbox" name="C6" drag="true"><br>
<input type="checkbox" name="C7" drag="true"><br>
<input type="checkbox" name="C8" drag="true"><br>
</form>
</body>

beetle
01-31-2003, 06:52 PM
Hey guys, you better work hard on this one! I just finished mine and it's pretty darn good.

Good luck!

scroots
01-31-2003, 07:05 PM
I might make an entry if i have time this weekend. As i have to pick numbers and then finds stupid names on lists (data handling maths coursework, some names are stupid and i mean stupid, its all about weight/height etc. of a fictitious school but based on real data.)

scroots

beetle
02-03-2003, 04:13 PM
No more new entries? I may terminate this contest early

ca_redwards
02-05-2003, 11:55 PM
<script language=javascript type="text/javascript">
function jump()
{
e=event.srcElement;
if(d && e.drag && event.button)
e.checked=c
}
function up(){d=0}
function down()
{
e=event.srcElement;
if(e.drag){
d=1;
c=!e.checked
}
}
with(document)
{
onmousemove=jump;
onmouseup=up;
onmousedown=down
}
up()
</script>
<body>
<form>
<input type=checkbox drag=true>Jump<br>
<input type=checkbox drag=true>Up<br>
<input type=checkbox drag=true>&amp;<br>
<input type=checkbox drag=true>Down!
</form>
</body>

Borgtex
02-06-2003, 12:14 AM
me? ;)

beetle
02-06-2003, 04:31 PM
Great job Borgtex! You are the winner! :thumbsup:

Little did I realize after I posted this thread that this was indeed possible (I obviously didn't think about it much). Having known this beforehand, I would have added some additional requirements. Anyhow, here's my solution (http://www.peterbailey.net/dhtml/DragToCheck.htm)

I know, it's fairly verbose, but it doesn't take up any namespace or require any extra HTML attributes!

whammy
02-07-2003, 12:08 AM
beetle, your first solution doesn't work on my IE 6.0 browser, it only checks 4 either way.

But the second solution seems to work fine - and that's the way checkboxes should be handled anyway, since radios are supposed to be named the same, not checkboxes. ;)

Isn't that what select multiple is for? :D

beetle
02-07-2003, 01:03 AM
Originally posted by whammy
beetle, your first solution doesn't work on my IE 6.0 browser, it only checks 4 either way.

But the second solution seems to work fine - and that's the way checkboxes should be handled anyway, since radios are supposed to be named the same, not checkboxes. ;)

Isn't that what select multiple is for? :D Tsk tsk, whammy. And you're a server-side programmer too! :rolleyes:

What about, oh, a web-based email like hotmail. They use checkboxes for deletion or movement selection. I don't know about ASP, but PHP handles these as arrays

<input type="checkbox" name="email[]" />
<input type="checkbox" name="email[]" />
<input type="checkbox" name="email[]" />

The top version in my example (as labeled) doesn't allow checking across checkboxes with dissimilar names from the first checkbox clicked. And it's not really a "version". Its the same code with one parameter change.

Sorry, I happen to think this is how it should be

gsanbrook
02-07-2003, 10:37 PM
Originally posted by Borgtex

if (document.all)
{
document.onmousemove=msmov
document.onmousedown=click
document.onmouseup=unclick
}



Borgtex,
Love this script. Works very well. However, could you tell me what the

if(document.all)

is doing? I understand the rest of the script, but don't understand why this is necessary for it to run.

Thanks
Gsanbrook

whammy
02-07-2003, 11:56 PM
if(document.all) checks to see if it's an IE browser. The script won't be run in any other browsers, since document.all is proprietary to the Internet Explorer "Document Object Model".

whammy
02-07-2003, 11:58 PM
P.S. to beetle:

Of course, there are instances when you would use checkboxes as an array - but I generally avoid that unless it makes my job easier (which in some cases it does!).

I just wanted to let you know the first version didn't work in my browser. ;)

beetle
02-08-2003, 03:44 AM
Originally posted by whammy
P.S. to beetle:

Of course, there are instances when you would use checkboxes as an array - but I generally avoid that unless it makes my job easier (which in some cases it does!).

I just wanted to let you know the first version didn't work in my browser. ;) Whammy, you are confusing me. The first form SHOULD only let you check/uncheck the top 4 or bottom 4. That's how I designed it to work. Do you still think it's broken somehow?

Skyzyx
02-22-2003, 01:26 AM
beetle...

Opera 7 appears to return true for document.all, document.attachEvent, and document.addEventListener!

The odd thing is that when you enable your script, you have to double-click the checkboxes for them to even check at all in Opera 7. Single-clicking won't work, and the click-and-drag functionality doesn't work either (although this is not unexpected).

I dug through the script, and can't make heads or tails of it... any suggestions?

Skyzyx
02-22-2003, 03:06 AM
jkd, got any suggestions?

jkd
02-22-2003, 04:10 AM
hm? what? where?

Oh. Umm, about browser detection? If you're going to use object detection, make correct assertions.

if (document.all)

implies document.all exists, and does not imply document.attachEvent does. That's why object detection isn't always a good idea, as to be accurate, you should check for every object/method you're going to use. I prefer sniffing various navigator properties, or not bothering and at all and just use standards, then laugh at Javascript errors in people's browsers when it doesn't support DOM1 or whatever DOM2 interface.


Or are you wondering about the bizarre behavior in Opera? Opera is flaky, too flaky imho. It's CSS is great, but I keep running into severe DOM problems with it. I haven't actually looked at the script in question (if it's not my code, I hate looking at it ;)), but I'll get back to you on it.

beetle
02-22-2003, 04:18 AM
I think he's talking about this (http://www.peterbailey.net/dhtml/DragToCheck.htm)

I realize now a better sniff would be:

if ( !document.attachEvent || !document.addEventListener )
return;

jkd
02-22-2003, 04:39 AM
I suggest:

if (typeof window.opera != "undefined") {
runAndHide();
}

(btw, people should use typeof to check for the existance of objects. it doesn't cause Strict warnings in Gecko, unlike the classical method - which means typeof is a little faster too)

I think it might be a little more logical (and a little less standards-compliant) to implement this drag-over feature through a DHTML behavior and an XBL binding... or perhaps by intercepting events at the document level.

UI-wise, it isn't a great idea to provide different functionality to widgets that look identical. Using behaviors/bindings, or intercepting events at the root would provide a global behavior modification. Either that, or provide some sort of indication that the enhanced checkboxes are really "ubercheckboxes" :).

brothercake
02-22-2003, 04:48 AM
Originally posted by jkd
Either that, or provide some sort of indication that the enhanced checkboxes are really "ubercheckboxes" :).

What, like

input['type=checkbox'].ubercheckbox { display:blink; }


:D


fyi:

if(typeof document.all!="undefined" && typeof window.opera=="undefined") { ... is always IE and never opera ... }

opera *only* returns an object for document.all *if and only if* it's set to "identify as IE" - however since you can't control this, you should *never ever use document.all in opera*

beetle
02-22-2003, 04:49 AM
I think notifying the user of advanced functionality goes without saying (at least it does in my mind)

We are just working on getting it done the best way. :D

I didn't know that about the typeof/warnings thing in Gecko, thanks (too bad that clause it such a pain to type over and over...)

brothercake
02-22-2003, 04:51 AM
Originally posted by beetle
I didn't know that about the typeof/warnings thing in Gecko

I've found typeof generally more robust anyway; a notable exception being images in Konqueror - querying the typeof a non-existent image will return "undefined" for all except Konqueror, where it returns "null"

Oh, and filter properties in IE5.5 (first build only) where the filters array exists, but its members return the type "unknown"

jkd
02-22-2003, 04:57 AM
Originally posted by brothercake
I've found typeof generally more robust anyway; a notable exception being images in Konqueror - querying the typeof a non-existent image will return "undefined" for all except Konqueror, where it returns "null"

Oh, and filter properties in IE5.5 (first build only) where the filters array exists, but its members return the type "unknown"

"null" doesn't make sense...
typeof null == "object"

Oh well, browsers don't always make sense anyway.

http://devedge.netscape.com/library/manuals/2000/javascript/1.5/reference/ops.html#1042603

The JS 1.5 spec doesn't say what strings typeof returns, so I guess the vendor can do whatever they want.

typeof typeof == "silly" // in konq ;)