A list of paragraphs (<p>
) is given. As soon as the user clicks on paragraph A the class of paragraph A changes to "activated". Now the user selects paragraph B and all the paragraphs between A and B change their class to "activated".
By clicking on B again, only A remains with the class "active".
By clicking on A the class "active" gets removed on all paragraphs between A and B (including A and B).
It shouldn't be possible to "deactivate" any paragraph between A and B. The selection between A and B should always be a uninterrupted list of selected paragraphs.
Can anyone give me a hint on how to realize this with Prototype/Scriptaculous? The application is implemented in Rails, so any hint in RJS would even be more appreciated!
OK, in the meantime and with the help of a coworker I came up with an own answer to this problem:
<script type="text/javascript">
// holds paragraph A (first selected paragraph)
var a_selected = null;
// holds paragraph B (second selected paragraph)
var b_selected = null;
// holds all 'active' paragraphs
var selected_paras = [];
function class_flipper_init() {
// reset paragraphs A and B
a_selected = null;
b_selected = null;
var paragraphs = $$("#foobar p");
paragraphs.each(function(paragraph, index) {
// if user clicks on a paragraph
paragraph.observe("click", function(event) {
// if A and B are 'active': reset everything.
if(b_selected != null) {
selected_paras.each(function(i) {
toggleStyle(i);
})
a_selected = null
b_selected = null
return
}
// if A is 'active'
if(a_selected != null) {
// if A is 'active' and selected B is below A:
// select all paragraphs between A and B
if(a_selected < index) {
b_selected = index;
for (var i = a_selected + 1; i <= index; i++ ) {
toggleStyle(paragraphs[i])
}
}
// if A is 'active' and selected B is above A:
// select all paragraphs between A and B
else if(a_selected > index) {
b_selected = index;
for (var i = a_selected - 1; i >= index; i-- ) {
toggleStyle(paragraphs[i])
}
}
// if A == B
else {
toggleStyle(paragraph)
a_selected = null
}
}
// if A is selected
else {
a_selected = index;
toggleStyle(paragraph)
}
});
});
}
function toggleStyle(paragraph) {
// remove active class
if (paragraph.hasClassName("active")) {
paragraph.removeClassName("active");
selected_paras = selected_paras.without(paragraph)
}
// set active class
else {
paragraph.addClassName("active");
selected_paras.push(paragraph)
}
}
</script>
class_flipper_init()
is called everytime the page (or in my case a certain partial) is loaded.
Please don't hesitate to submit a solution written in "pure" RJS or something more elegant. :-)