Created a javascript "listSelector" class that can be used to select a list of items from an existing list.

Added a form in schoolschedule.php which uses that class to select students on a team
This commit is contained in:
jacob 2010-06-21 22:06:18 +00:00
parent e02e5ba687
commit 54f6a2e251
2 changed files with 530 additions and 112 deletions

232
js/listSelector.js Normal file
View File

@ -0,0 +1,232 @@
// a generic tool for doing list selection, passing elements between two divs 'left' and 'right'
// the styling needs to be cleaned up a bit, making some options more configurable and others less
function listSelector(left, right, globalName){
var name;
var wrapper;
var leftDiv, rightDiv, leftTitle, rightTitle, leftColours, rightColours;
var items;
var styleTags, boxStyle, itemStyle, rowStyle;
this.name = globalName;
this.leftColours = [];
this.rightColours = [];
this.rowStyle = "height:1.2em; margin-top:1px; width:100%;";
this.styleTags = {
'height' : '100%',
};
this.boxStyle = {
'position' : 'absolute',
'width' : '100%',
'height' : '100%',
'line-height' : '1.2em'
};
this.boxBackdropStyle = {
'position' : 'absolute',
'width' : '40%',
'height' : '90%',
'background' : '#FFF',
'border' : 'solid 1px',
'overflow' : 'hidden'
}
this.itemStyle = {
'margin-top' : '1px',
'height':'1.2em',
'width':'100%'
};
this.headerStyle = {
'width' : '50%',
'position' : 'absolute',
'text-align' : 'center',
'font-size' : '120%',
'font-weight' : 'bold'
};
this.highlightStyle = {
'background-color' : '#25BEFF'
};
this.unhighlightStyle = {
'background' : 'none'
};
this.drawLeftColumn = function(){
this.leftBackdrop = $('<div id="ls_leftBackdrop"></div>');
this.leftBackdrop.css(this.boxBackdropStyle);
this.leftBackdrop.css({
'top' : '5%',
'left' : '5%',
});
this.leftBackdrop.appendTo(this.wrapper);
this.leftHighlight = $('<div id="ls_leftHighlight"></div>');
this.leftHighlight.css(this.boxStyle);
this.leftHighlight.css({'overflow':'auto'});
this.leftHighlight.appendTo(this.leftBackdrop);
this.leftDiv = $('<div id="ls_leftItems"></div>');
this.leftDiv.css(this.boxStyle);
this.leftDiv.appendTo(this.leftHighlight);
if(this.leftTitle != undefined){
var pos = this.leftDiv.position();
var caption = $('<div>' + this.leftTitle + '</div>');
caption.appendTo(this.wrapper);
caption.css(this.headerStyle);
caption.css({
'left' : pos.left + 'px',
'top' : (pos.top - 15) + 'px'
});
}
// if any highlights were added, place them in the column now
var m = 0;
for(var n in this.leftColours){
while(m < n){
d = $('<div></div>');
d.css(this.itemStyle);
this.leftHighlight.append(d);
m++;
}
d = $('<div style="background-color:' + this.leftColours[n] + '"></div>');
d.css(this.itemStyle);
this.leftHighlight.append(d);
m = 1.0 * n + 1;
}
}
this.drawRightColumn = function(){
this.rightBackdrop = $('<div id="ls_rightBackdrop"></div>');
this.rightBackdrop.css(this.boxBackdropStyle);
this.rightBackdrop.css({
'top' : '5%',
'left' : '55%',
});
this.rightBackdrop.appendTo(this.wrapper);
this.rightHighlight = $('<div id="ls_rightHighlight"></div>');
this.rightHighlight.css(this.boxStyle);
this.rightHighlight.css({'overflow':'auto'});
this.rightHighlight.appendTo(this.rightBackdrop);
this.rightDiv = $('<div id="ls_rightItems"></div>');
this.rightDiv.css(this.boxStyle);
this.rightDiv.appendTo(this.rightHighlight);
if(this.rightTitle != undefined){
var pos = this.rightDiv.position();
var caption = $('<div>' + this.rightTitle + '</div>');
caption.appendTo(this.wrapper);
caption.css(this.headerStyle);
caption.css({
'left' : '50%',
'top' : (pos.top - 15) + 'px'
});
}
// if any highlights were added, place them in the column now
var m = 0, d;
for(var n in this.rightColours){
while(m < n){
d = $('<div></div>');
d.css(this.itemStyle);
this.rightHighlight.append(d);
m++;
}
d = $('<div style="background-color:' + this.rightColours[n] + '"></div>');
d.css(this.itemStyle);
this.rightHighlight.append(d);
m = 1.0 * n + 1;
}
}
this.draw = function(){
this.wrapper = $('<div id="ls_wrapper" style="position:relative"></div>');
this.wrapper.css(this.styleTags);
// create the columns
this.drawLeftColumn();
this.drawRightColumn();
// build our list of selectable items in each column
this.items = [];
for(id in left){
this.items[id] = $('<div id="ls_item_' + id + '">' + left[id] + '</div>');
eval(this.name + '.items[' + id + '].click(function(){' + this.name + '.switch(' + id + ');});');
eval(this.name + '.items[' + id + '].mouseenter(function(){' + this.name + '.highlight(' + id + ', true);});');
eval(this.name + '.items[' + id + '].mouseleave(function(){' + this.name + '.highlight(' + id + ', false);});');
this.items[id].css(this.itemStyle);
this.items[id].appendTo(this.leftDiv);
this.items[id].data('column', 'left');
}
for(id in right){
this.items[id] = $('<div id="ls_item_' + id + '">' + right[id] + '</div>');
eval(this.name + '.items[' + id + '].click(function(){' + this.name + '.switch(' + id + ');});');
eval(this.name + '.items[' + id + '].mouseenter(function(){' + this.name + '.highlight(' + id + ', true);});');
eval(this.name + '.items[' + id + '].mouseleave(function(){' + this.name + '.highlight(' + id + ', false);});');
this.items[id].css(this.itemStyle);
this.items[id].appendTo(this.rightDiv);
this.items[id].data('column', 'right');
}
return this.wrapper;
}
this.highlight = function(itemId, on){
if(on){
this.items[itemId].css(this.highlightStyle);
}else{
this.items[itemId].css(this.unhighlightStyle);
}
}
this.switch = function(itemId){
item = this.items[itemId];
if(item.data('column') == 'left'){
targetDiv = this.rightDiv;
item.data('column', 'right');
}else{
targetDiv = this.leftDiv;
item.data('column', 'left');
}
this.highlight(itemId, false);
this.items[itemId].appendTo(targetDiv);
}
this.setStyle = function(newTags){
for(var n in newTags){
this.styleTags[n] = newTags[n];
}
}
this.getLeftList = function(){
return this.getList('left');
}
this.getRightList = function(){
return this.getList('right');
}
this.getList = function(side){
var returnval = [];
var n = 0;
for(id in this.items){
if(this.items[id].data('column') == side){
returnval[n] = id;
n++;
}
}
return returnval;
}
}

View File

@ -114,7 +114,7 @@ if($_SESSION['schoolid'] && $_SESSION['schoolaccesscode']){
$maxteams=$r->somaxteams;
echo i18n("%1 of %2",array($regteams,$maxteams))."<br />";
$regq=mysql_query("SELECT so_teams.name
$regq=mysql_query("SELECT so_teams.name, schedule_registrations.id
FROM schedule_registrations
JOIN so_teams ON so_teams_id=so_teams.id
WHERE schedule_registrations.conferences_id='{$conference['id']}'
@ -122,7 +122,7 @@ if($_SESSION['schoolid'] && $_SESSION['schoolaccesscode']){
AND schedule_registrations.schedule_id='$r->id'");
echo mysql_error();
while($regr=mysql_fetch_object($regq)) {
echo "<div style=\"padding: 2px; border: 1px solid black; background-color: yellow;\">";
echo "<div style=\"padding: 2px; border: 1px solid black; background-color: yellow;\" onclick=\"handleTeamClick(event, {$regr->id}, {$r->events_id});\">";
echo $regr->name;
echo "</div>";
}
@ -135,19 +135,138 @@ if($_SESSION['schoolid'] && $_SESSION['schoolaccesscode']){
echo "<script type=\"text/javascript\">\n";
echo $js;
echo "</script>";
}else if($_GET['action']=="loadevent") {
}else if($_GET['action']=="saveevent") {
}else if($_GET['action'] == "saveteamlist"){
// print_r($_POST);
// get a list of all students that could be put on this team
$query = 'SELECT * FROM users_student';
$query .= ' JOIN users ON users_student.users_id = users.uid';
$query .= ' JOIN users_conferences_link ucl ON ucl.users_uid = users_student.users_id';
$query .= ' WHERE schools_id = ' . $_SESSION['schoolid'];
$query .= ' AND ucl.conferences_id=' . $conference['id'];
$query .= ' AND users.deleted = "no"';
$results = mysql_query($query);
$availList = array();
while($record = mysql_fetch_array($results)){
$availList[$record['uid']] = $record['firstname'] . ' ' . $record['lastname'];
}
else if($_GET['action']=="loadevent") {
// let's empty the current list of students for this team
$query = "DELETE FROM schedule_registrations_users_link";
$query .= " WHERE users_uid IN (";
$query .= implode(',', array_keys($availList)) . ')';
$query .= " AND schedule_registrations_id = " . (int)$_POST['regId'];
$results = mysql_query($query);
// and now we'll insert only those that were selected
$query = "INSERT INTO schedule_registrations_users_link (schedule_registrations_id, users_uid)";
$query .= " VALUES ";
$valueSet = array();
for($n = 0; $n < $_POST['numSelected']; $n++){
$valueSet[] = '(' . (int)$_POST['regId'] . ',' . (int)$_POST[$n] .')';
}
else if($_GET['action']=="saveevent") {
$query .= implode(',', $valueSet);
$results = mysql_query($query);
}else if($_GET['action'] == "getteamlist"){
// first we'll get the basic info, and do a quick check that the selected team is in this user's domain
if(!array_key_exists('regId', $_POST)){
echo "error code PEBKAC\n";
return;
}
else {
$query = "SELECT sr.* FROM schedule_registrations sr";
$query .= " JOIN so_teams ON so_teams.id = sr.so_teams_id";
$query .= " WHERE sr.id=" . $_POST['regId'];
$query .= " AND so_teams.schools_id = " . $_SESSION['schoolid'];
$results = mysql_query($query);
if(!$results){
echo 'team not found';
return;
}
$record = mysql_fetch_array($results);
// get a list of all students that could be put on this team
$query = 'SELECT * FROM users_student';
$query .= ' JOIN users ON users_student.users_id = users.uid';
$query .= ' JOIN users_conferences_link ucl ON ucl.users_uid = users_student.users_id';
$query .= ' WHERE schools_id = ' . $_SESSION['schoolid'];
$query .= ' AND ucl.conferences_id=' . $conference['id'];
$query .= ' AND users.deleted = "no"';
$results = mysql_query($query);
$availList = array();
while($record = mysql_fetch_array($results)){
$availList[$record['uid']] = $record['firstname'] . ' ' . $record['lastname'];
}
// now find out which of these students are already selected
$query = "SELECT * FROM schedule_registrations_users_link srul";
$query .= " WHERE users_uid IN (";
$query .= implode(',', array_keys($availList)) . ')';
$query .= " AND schedule_registrations_id = " . $_POST['regId'];
$results = mysql_query($query);
$selectedList = array();
if($results){
while($record = mysql_fetch_array($results)){
$idx = $record['users_uid'];
$selectedList[$idx] = $availList[$idx];
unset($availList[$idx]);
}
}
// get our minimum and maximum number of students for the event
$query = "SELECT sominteamsize, somaxteamsize FROM schedule JOIN"
. " schedule_registrations sr ON sr.schedule_id = schedule.id WHERE"
. " sr.id = " . $_POST['regId'];
$results = mysql_fetch_array(mysql_query($query));
$minTeamSize = $results['sominteamsize'];
$maxTeamSize = $results['somaxteamsize'];
echo '<script type="text/javascript">';
echo "minTeamSize = $minTeamSize;";
echo "maxTeamSize = $maxTeamSize;";
// build our student lists
echo "available={";
$n = 0;
foreach($availList as $id => $name){
if($n > 0) echo ',';
echo "$id:\"$name\"";
$n++;
}
echo '};';
echo "selected={";
$n = 0;
foreach($selectedList as $id => $name){
if($n > 0) echo ',';
echo "$id:\"$name\"";
$n++;
}
echo '};';
// pass the additional parameters
/*
$query = "SELECT default_min_team_size, default_max_team_size FROM events WHERE id=" . $_POST['eventId'];
$results = mysql_fetch_array(mysql_query($query));
echo "min_size=" . $results['default_min_team_size'] . ';';
echo "max_size=" . $results['default_max_team_size'] . ';';
*/
echo '</script>';
}else{
send_header("Event Registration",
array('School Home' => 'schoolaccess.php'),
"events_scheduling" );
echo "<br />";
?>
<script type="text/javascript" src="js/listSelector.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$(".date").datepicker({ dateFormat: 'yy-mm-dd' });
changeDate();
@ -170,6 +289,72 @@ if($_SESSION['schoolid'] && $_SESSION['schoolaccesscode']){
);
});
function handleTeamClick(event, regId, eventId){
var e = event || window.event;
e.stopPropagation();
params={
'regId' : regId,
'eventId' : eventId
};
$("#debug").load("schoolschedule.php?action=getteamlist", params, function(response){
// at this point, the arrays "available" and "selected" should be defined, giving
// us the corresponding selection elements for this scheduled event
// create a list selector that can use these lists
selector = new listSelector(selected, available, 'selector');
selector.setStyle({'height' : '70%', 'margin-top' : '10%'});
selector.leftTitle = '<?=i18n("assigned");?>';
selector.rightTitle = '<?=i18n("available");?>';
var n;
for(n = 0; n < minTeamSize; n++){
selector.leftColours[n] = '#AFA';
}
for(;n < maxTeamSize; n++){
selector.leftColours[n] = '#FFA';
}
var sdialog = $('<div></div>');
// sdialog.append('this is a test');
sdialog.append(selector.draw());
sdialog.dialog({
width : 600,
height : 400,
resizable: false,
draggable: false,
buttons: {
"<?=i18n("Save")?>": function() {
saveTeamList($(this), regId, eventId);
},
"<?=i18n('Close')?>": function() {
$(this).dialog("close");
changeDate();
}
}
});
});
}
function saveTeamList(ddiv, regId, eventId){
selectedList = selector.getLeftList();
//params = selector.getLeftList();
params = {
'regId' : regId,
'eventId' : eventId,
'numSelected' : selectedList.length
};
for(var n in selectedList){
params[n] = selectedList[n];
}
$("#debug").load("schoolschedule.php?action=saveteamlist", params, function(response){
ddiv.dialog("close");
});
}
function changeDate() {
$("#schedulediv").load("schoolschedule.php?action=loadschedule",{date:$("#date").val()},function() {
placeEvents();
@ -257,6 +442,7 @@ if($_SESSION['schoolid'] && $_SESSION['schoolaccesscode']){
<div id="event_dialog">
<? include "schoolschedule_event_dialog.php"; ?>
</div>
<div id="selector_dialog"></div>
<?
send_footer();