Drag and drop
Scriptaculous provides several objects for supporting drag-and-drop functionality:
Draggable
: an element that can be dragged
Draggables
: manages all Draggable
objects on the page
Droppables
: elements on which a Draggable
can be dropped
Sortable
: a list of items that can be reordered
new Draggable(element or id,
{ options }
);
- specifies an element as being able to be dragged
- options:
handle
,
revert
,
snap
,
zindex
,
constraint
,
ghosting
,
starteffect
,
reverteffect
,
endeffect
- event options:
onStart
,
onDrag
,
onEnd
- each handler function accepts two parameters: the
Draggable
object, and the mouse event
Draggable
example
<div id="draggabledemo1">Draggable demo. Default options.</div>
<div id="draggabledemo2">Draggable demo.
{snap: [40,40], revert: true}</div>
document.observe("dom:loaded", function() {
new Draggable("draggabledemo1");
new Draggable("draggabledemo2", {revert: true, snap: [40, 40]});
});
Draggable demo.
Default options.
Draggable demo.
{snap:[60, 60], revert:true}
- a global helper for accessing/managing all Draggable objects on a page
- (not needed for this course)
- properties:
drags
,
observers
- methods:
register
,
unregister
,
activate
,
deactivate
,
updateDrag
,
endDrag
,
keyPress
,
addObserver
,
removeObserver
,
notify
Droppables.add(element or id,
{ options }
);
- specifies an element as being able to be dragged
- options:
accept
,
containment
,
hoverclass
,
overlap
,
greedy
- event options:
onHover
,
onDrop
- each callback accepts three parameters: the
Draggable
, the Droppable
, and the event
- Shopping Cart demo
<img id="product1" src="images/shirt.png" alt="shirt" />
<img id="product2" src="images/cup.png" alt="cup" />
<div id="droptarget"></div>
document.observe("dom:loaded", function() {
new Draggable("product1");
new Draggable("product2");
Droppables.add("droptarget", {onDrop: productDrop});
});
function productDrop(drag, drop, event) {
alert("You dropped " + drag.id);
}
Sortable.create(element or id of list,
{ options }
);
- specifies a list (
ul
, ol
) as being able to be dragged into any order
- implemented internally using
Draggable
s and Droppable
s
- options:
tag
,
only
,
overlap
,
constraint
,
containment
,
format
,
handle
,
hoverclass
,
ghosting
,
dropOnEmpty
,
scroll
,
scrollSensitivity
,
scrollSpeed
,
tree
,
treeTag
- to make a list un-sortable again, call
Sortable.destroy
on it
Sortable
demo
<ol id="simpsons">
<li id="simpsons_0">Homer</li>
<li id="simpsons_1">Marge</li>
<li id="simpsons_2">Bart</li>
<li id="simpsons_3">Lisa</li>
<li id="simpsons_4">Maggie</li>
</ol>
document.observe("dom:loaded", function() {
Sortable.create("simpsons");
});
- Homer
- Marge
- Bart
- Lisa
- Maggie
Sortable
list events
event |
description |
onChange
|
when any list item hovers over a new position while dragging
|
onUpdate
|
when a list item is dropped into a new position (more useful)
|
document.observe("dom:loaded", function() {
Sortable.create("simpsons", {
onUpdate: listUpdate
});
});
onChange
handler function receives the dragging element as its parameter
onUpdate
handler function receives the list as its parameter
Sortable
list events example
document.observe("dom:loaded", function() {
Sortable.create("simpsons", {
onUpdate: listUpdate
});
});
function listUpdate(list) {
list.shake();
}
- Homer
- Marge
- Bart
- Lisa
- Maggie
Subtleties of Sortable
events
Auto-completing text fields
Scriptaculous offers ways to make a text box that auto-completes based on prefix strings:
new Autocompleter.Local(
element or id of text box,
element or id of div to show completions,
array of choices,
{ options }
);
- you must create an (initially empty)
div
to store the auto-completion matches
- it will be inserted as a
ul
that you can style with CSS
- the user can select items by pressing Up/Down arrows; selected item is given a
class
of selected
- pass the choices as an array of strings
- pass any extra options as a fourth parameter between
{
}
- options:
choices
, partialSearch
, fullSearch
, partialChars
, ignoreCase
Autocompleter.Local
demo
<input id="bands70s" size="40" type="text" />
<div id="bandlistarea"></div>
document.observe("dom:loaded", function() {
new Autocompleter.Local(
"bands70s",
"bandlistarea",
["ABBA", "AC/DC", "Aerosmith", "America", "Bay City Rollers", ...],
{}
);
});
Autocompleter styling
<input id="bands70s" size="40" type="text" />
<div id="bandlistarea"></div>
#bandlistarea {
border: 2px solid gray;
}
#bandlistarea .selected {
background-color: pink;
}
new Ajax.Autocompleter(
element or id of text box,
element or id of div to show completions,
url,
{ options }
);
- when you have too many choices to hold them all in an array, you can instead fetch subsets of choices from the server using Ajax
- instead of passing choices as an array, pass a URL from which to fetch them
- the choices are sent back from the server as an HTML
ul
with li
elements in it
- options:
paramName
,
tokens
,
frequency
,
minChars
,
indicator
,
updateElement
,
afterUpdateElement
,
callback
,
parameters
new Ajax.InPlaceEditor(element or id,
url,
{ options }
);
- options:
okButton
,
okText
,
cancelLink
,
cancelText
,
savingText
,
clickToEditText
,
formId
,
externalControl
,
rows
,
onComplete
,
onFailure
,
cols
,
size
,
highlightcolor
,
highlightendcolor
,
formClassName
,
hoverClassName
,
loadTextURL
,
loadingText
,
callback
,
submitOnBlur
,
ajaxOptions
- event options:
onEnterHover
,
onLeaveHover
,
onEnterEditMode
,
onLeaveEditMode
new Ajax.InPlaceCollectionEditor(element or id,
url,
{
collection: array of choices,
options
}
);
- a variation of
Ajax.InPlaceEditor
that gives a collection of choices
- requires
collection
option whose value is an array of strings to choose from
- all other options are the same as
Ajax.InPlaceEditor
Playing sounds (API)
method |
description |
Sound.play("url");
|
plays a sound/music file
|
Sound.disable();
|
stops future sounds from playing (doesn't mute any sound in progress)
|
Sound.enable();
|
re-enables sounds to be playable after a call to Sound.disable()
|
Sound.play("music/java_rap.mp3");
Sound.play("music/wazzaaaaaap.wav");
-
to silence a sound playing in progress, use
Sound.play('', {replace: true});
-
cannot play sounds from a local computer (must be uploaded to a web site)
Other neat features
-
slider control:
new Control.Slider("id of knob", "id of track", {options});
-
Builder
- convenience class to replace document.createElement
:
var img = Builder.node("img", {
src: "images/lolcat.jpg",
width: 100, height: 100,
alt: "I can haz Scriptaculous?"
});
$("main").appendChild(img);
-
Tabbed UIs
11.1: Event-Handling
-
11.1: Event-Handling
- 11.1.1 The Event Object
- 11.1.2 Mouse Events
- 11.1.3 Keyboard and Text Events
- 11.1.4 Form Events
- 11.1.5 Page Events
- 11.1.6 Timer Events
-
11.2: Case Study: Multiplication Quiz
- very instructive example
- easy to understand (I hope!)
- you should read it
- ask questions in next class meetingif there is anyhing that you don't understand
JavaScript events
-
the
click
event (onclick
) is just one of many events that can be handled
-
problem: events are tricky and have incompatibilities across browsers
-
reasons: fuzzy W3C event specs; IE disobeying web standards; etc.
-
solution: Prototype includes many event-related features and fixes
Attaching event handlers the Prototype way
element.onevent = function;
element.observe("event", function);
$("play").observe("click", playNewGame);
-
to use Prototype's event features, you must attach the handler using the DOM element object's
observe
method (added by Prototype)
-
pass the event name as a string, and the function name to call
-
handlers must be attached this way for Prototype's event features to work
The event
object
function name(event) {
}
-
Event handlers can accept an optional parameter to represent the event that is occurring. Event objects have the following properties / methods:
method / property name
|
description
|
type
|
what kind of event, such as "click" or "mousedown"
|
element() *
|
the element on which the event occurred
|
stop() **
|
cancels an event
|
stopObserving()
|
removes an event handler
|
-
* replaces non-standard
srcElement
and which
properties
-
** replaces non-standard
return false;
, stopPropagation
, etc.
Mouse events
clicking
click
|
user presses/releases mouse button on the element
|
dblclick
|
user presses/releases mouse button twice on the element
|
mousedown
|
user presses down mouse button on the element
|
mouseup
|
user releases mouse button on the element
|
movement
mouseover
|
mouse cursor enters the element's box
|
mouseout
|
mouse cursor exits the element's box
|
mousemove
|
mouse cursor moves around within the element's box
|
Mouse event objects
The event
passed to a mouse handler has these properties:
property/method
|
description
|
clientX , clientY
|
coordinates in browser window
|
screenX , screenY
|
coordinates in screen
|
offsetX , offsetY
|
coordinates in element (non-standard)
|
pointerX() ,
pointerY() *
|
coordinates in entire web page
|
isLeftClick() **
|
true if left button was pressed
|
-
* replaces non-standard properties
pageX
and pageY
-
** replaces non-standard properties
button
and which
Mouse event example
<pre id="target">Move the mouse over me!</pre>
window.onload = function() {
$("target").observe("mousemove", showCoords);
};
function showCoords(event) {
$("target").innerHTML =
"pointer: (" + event.pointerX() + ", " + event.pointerY() + ")\n"
+ "screen : (" + event.screenX + ", " + event.screenY + ")\n"
+ "client : (" + event.clientX + ", " + event.clientY + ")";
}
Recap: The keyword this
this.fieldName
this.fieldName = value;
this.methodName(parameters);
-
all JavaScript code actually runs inside of an object
-
by default, code runs in the global
window
object (so this
=== window
)
-
all global variables and functions you declare become part of
window
-
the
this
keyword refers to the current object
Recap: Event handler binding
- event handlers attached unobtrusively are bound to the element
- inside the handler, that element becomes
this
(rather than the window
)
Fixing redundant code with this
<fieldset>
<label><input type="radio" name="ducks" value="Huey" /> Huey</label>
<label><input type="radio" name="ducks" value="Dewey" /> Dewey</label>
<label><input type="radio" name="ducks" value="Louie" /> Louie</label>
</fieldset>
function processDucks() {
if ($("huey").checked) {
alert("Huey is checked!");
} else if ($("dewey").checked) {
alert("Dewey is checked!");
} else {
alert("Louie is checked!");
}
alert(this.value + " is checked!");
}
- if the same function is assigned to multiple elements, each gets its own bound copy
Page/window events
name | description |
load ,
unload
|
the browser loads/exits the page
|
resize
|
the browser window is resized
|
error
|
an error occurs when loading a document or an image
|
contextmenu
|
the user right-clicks to pop up a context menu
|
-
The above can be handled on the
window
object. An alternative to window.onload
:
window.onload = function() { ... };
document.observe("dom:loaded", function() {
});
Keyboard/text events
name |
description |
keydown
|
user presses a key while this element has keyboard focus
|
keyup
|
user releases a key while this element has keyboard focus
|
keypress
|
user presses and releases a key while this element has keyboard focus
|
focus
|
this element gains keyboard focus
|
blur
|
this element loses keyboard focus
|
select
|
this element's text is selected or deselected)
|
-
focus: the attention of the user's keyboard (given to one element at a time)
Key event objects
property name
|
description
|
keyCode
|
ASCII integer value of key that was pressed
(convert to char with String.fromCharCode )
|
altKey , ctrlKey , shiftKey
|
true if Alt/Ctrl/Shift key is being held
|
Prototype's key code constants
Event.KEY_BACKSPACE
|
Event.KEY_DELETE
|
Event.KEY_DOWN
|
Event.KEY_END
|
Event.KEY_ESC
|
Event.KEY_HOME
|
Event.KEY_LEFT
|
Event.KEY_PAGEDOWN
|
Event.KEY_PAGEUP
|
Event.KEY_RETURN
|
Event.KEY_RIGHT
|
Event.KEY_TAB
|
Event.KEY_UP
|
|
|
|
-
issue: if the event you attach your listener to doesn't have the focus, you won't hear the event
-
possible solution: attach key listener to entire page body, outer element, etc.
Form events
event name
|
description
|
submit
|
form is being submitted
|
reset
|
form is being reset
|
change
|
the text or state of a form control has changed
|
-
Prototype adds the following methods to form controls' DOM objects:
Prototype form shortcuts
$F("formID")["name"]
-
gets parameter with given name from form with given id
$F("controlID")
Stopping an event
<form id="exampleform" action="http://foo.com/foo.php">...</form>
window.onload = function() {
$("exampleform").observe("submit", checkData);
};
function checkData(event) {
if ($F("city") == "" || $F("state").length != 2) {
alert("Error, invalid city/state.");
event.stop();
return false;
}
}
- to abort a form submit or other event, call Prototype's
stop
method on the event
Event-handling example
Use events to do some cool animations!
We use timer events,
with methods setInterval
and clearInterval
setInterval(code,millisec)
returns ID of timer event
clearInterval(id_of_setinterval)