MDL-36990 - first try of a dragdrop version
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
if (!defined('AJAX_SCRIPT')) {
|
||||
define('AJAX_SCRIPT', true);
|
||||
}
|
||||
|
||||
require_once(dirname(dirname(dirname(__FILE__))).'/config.php');
|
||||
|
||||
$id = required_param('id', PARAM_INT);
|
||||
$action = optional_param('action', '', PARAM_ALPHA);
|
||||
$sesskey = optional_param('sesskey', false, PARAM_TEXT);
|
||||
$itemorder = optional_param('itemorder', false, PARAM_SEQUENCE);
|
||||
|
||||
$cm = get_coursemodule_from_id('feedback', $id, 0, false, MUST_EXIST);
|
||||
$course = $DB->get_record("course", array("id"=>$cm->course), '*', MUST_EXIST);
|
||||
$feedback = $DB->get_record("feedback", array("id"=>$cm->instance), '*', MUST_EXIST);
|
||||
|
||||
confirm_sesskey();
|
||||
|
||||
$context = context_module::instance($cm->id);
|
||||
require_login($course, true, $cm);
|
||||
require_capability('mod/feedback:edititems', $context);
|
||||
|
||||
$return = false;
|
||||
|
||||
switch ($action) {
|
||||
case 'saveitemorder':
|
||||
$itemlist = explode(',', trim($itemorder, ','));
|
||||
if (count($itemlist) > 0) {
|
||||
$return = feedback_ajax_saveitemorder($itemlist, $feedback);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
echo json_encode($return);
|
||||
die;
|
||||
|
||||
////////////////////////////////////////
|
||||
|
||||
function feedback_ajax_saveitemorder($itemlist, $feedback) {
|
||||
global $DB;
|
||||
|
||||
$result = true;
|
||||
$position = 0;
|
||||
foreach ($itemlist as $itemid) {
|
||||
$position++;
|
||||
$result = $result && $DB->set_field('feedback_item',
|
||||
'position',
|
||||
$position,
|
||||
array('id'=>$itemid, 'feedback'=>$feedback->id));
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
+33
-2
@@ -157,6 +157,28 @@ $strfeedback = get_string("modulename", "feedback");
|
||||
$PAGE->set_url('/mod/feedback/edit.php', array('id'=>$cm->id, 'do_show'=>$do_show));
|
||||
$PAGE->set_heading(format_string($course->fullname));
|
||||
$PAGE->set_title(format_string($feedback->name));
|
||||
|
||||
// Adding the javascript module for the items dragdrop
|
||||
if ($do_show == 'edit') {
|
||||
$jsmodule = array(
|
||||
'name' => 'mod_feedback',
|
||||
'fullpath' => '/mod/feedback/module.js',
|
||||
'requires' => array('io', 'json-parse', 'dd-constrain', 'dd-proxy', 'dd-drop'),
|
||||
'strings' => array(array('pluginname', 'feedback'),
|
||||
array('move_item', 'feedback'))
|
||||
);
|
||||
|
||||
$yuibase = $CFG->httpswwwroot.'/lib/yuilib/'.$CFG->yui3version . '/build/';
|
||||
$ajaxscript = $CFG->httpswwwroot.'/mod/feedback/ajax.php';
|
||||
$PAGE->requires->js_init_call('M.mod_feedback.init', array($cm->id,
|
||||
sesskey(),
|
||||
$yuibase,
|
||||
$ajaxscript,
|
||||
$CFG->httpswwwroot),
|
||||
false,
|
||||
$jsmodule);
|
||||
}
|
||||
|
||||
echo $OUTPUT->header();
|
||||
|
||||
/// print the tabs
|
||||
@@ -265,6 +287,8 @@ if ($do_show == 'edit') {
|
||||
}
|
||||
//print the inserted items
|
||||
$itempos = 0;
|
||||
echo '<div id="feedback_dragarea">'; //The container for the dragging area
|
||||
echo '<ul id="feedback_draglist">'; //the list what includes the draggable items
|
||||
foreach ($feedbackitems as $feedbackitem) {
|
||||
$itempos++;
|
||||
//hiding the item to move
|
||||
@@ -273,12 +297,16 @@ if ($do_show == 'edit') {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//here come the draggable items, each one in a single li-element
|
||||
echo '<li class="feedback_itemlist generalbox" id="feedback_item_'.$feedbackitem->id.'">';
|
||||
echo '<span class="spinnertest"> </span>';
|
||||
if ($feedbackitem->dependitem > 0) {
|
||||
$dependstyle = ' feedback_depend';
|
||||
} else {
|
||||
$dependstyle = '';
|
||||
}
|
||||
echo $OUTPUT->box_start('feedback_item_box_'.$align.$dependstyle);
|
||||
echo $OUTPUT->box_start('feedback_item_box_'.$align.$dependstyle,
|
||||
'feedback_item_box_'.$feedbackitem->id);
|
||||
//items without value only are labels
|
||||
if ($feedbackitem->hasvalue == 1 AND $feedback->autonumbering) {
|
||||
$itemnr++;
|
||||
@@ -286,7 +314,7 @@ if ($do_show == 'edit') {
|
||||
echo $itemnr;
|
||||
echo $OUTPUT->box_end();
|
||||
}
|
||||
echo $OUTPUT->box_start('box generalbox boxalign_'.$align);
|
||||
echo $OUTPUT->box_start('box boxalign_'.$align);
|
||||
echo $OUTPUT->box_start('feedback_item_commands_'.$align);
|
||||
echo '<span class="feedback_item_commands">';
|
||||
echo '('.get_string('position', 'feedback').':'.$itempos .')';
|
||||
@@ -401,8 +429,11 @@ if ($do_show == 'edit') {
|
||||
echo $OUTPUT->box_end();
|
||||
}
|
||||
echo '<div class="clearer"> </div>';
|
||||
echo '</li>';
|
||||
}
|
||||
echo $OUTPUT->box_end();
|
||||
echo '</ul>';
|
||||
echo '</div>';
|
||||
} else {
|
||||
echo $OUTPUT->box(get_string('no_items_available_yet', 'feedback'),
|
||||
'generalbox boxaligncenter');
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
M.mod_feedback = {};
|
||||
M.mod_feedback.init = function(Y, id, sesskey, yuibase, ajaxscript, moodlebase) {
|
||||
//Listen for all drop:over events
|
||||
Y.DD.DDM.on('drop:over', function(e) {
|
||||
//Get a reference to our drag and drop nodes
|
||||
var drag = e.drag.get('node'),
|
||||
drop = e.drop.get('node');
|
||||
|
||||
//Are we dropping on a li node?
|
||||
if (drop.get('tagName').toLowerCase() === 'li') {
|
||||
//Are we not going up?
|
||||
if (!goingUp) {
|
||||
drop = drop.get('nextSibling');
|
||||
}
|
||||
//Add the node to this list
|
||||
e.drop.get('node').get('parentNode').insertBefore(drag, drop);
|
||||
//Resize this nodes shim, so we can drop on it later.
|
||||
e.drop.sizeShim();
|
||||
}
|
||||
});
|
||||
//Listen for all drag:drag events
|
||||
Y.DD.DDM.on('drag:drag', function(e) {
|
||||
//Get the last y point
|
||||
var y = e.target.lastXY[1];
|
||||
//is it greater than the lastY var?
|
||||
if (y < lastY) {
|
||||
//We are going up
|
||||
goingUp = true;
|
||||
} else {
|
||||
//We are going down.
|
||||
goingUp = false;
|
||||
}
|
||||
//Cache for next check
|
||||
lastY = y;
|
||||
});
|
||||
//Listen for all drag:start events
|
||||
Y.DD.DDM.on('drag:start', function(e) {
|
||||
//Get our drag object
|
||||
var drag = e.target;
|
||||
//Set some styles here
|
||||
drag.get('node').setStyle('opacity', '.25');
|
||||
drag.get('dragNode').set('innerHTML', drag.get('node').get('innerHTML'));
|
||||
drag.get('dragNode').setStyles({
|
||||
opacity: '.5',
|
||||
borderColor: drag.get('node').getStyle('borderColor'),
|
||||
backgroundColor: drag.get('node').getStyle('backgroundColor')
|
||||
});
|
||||
});
|
||||
//Listen for a drag:end events
|
||||
Y.DD.DDM.on('drag:end', function(e) {
|
||||
var drag = e.target;
|
||||
//Put our styles back
|
||||
drag.get('node').setStyles({
|
||||
visibility: '',
|
||||
opacity: '1'
|
||||
});
|
||||
|
||||
});
|
||||
//Listen for all drag:drophit events
|
||||
Y.DD.DDM.on('drag:drophit', function(e) {
|
||||
var drop = e.drop.get('node'),
|
||||
drag = e.drag.get('node');
|
||||
dragnode = Y.one(drag);
|
||||
//if we are not on an li, we must have been dropped on a ul
|
||||
if (drop.get('tagName').toLowerCase() !== 'li') {
|
||||
if (!drop.contains(drag)) {
|
||||
drop.appendChild(drag);
|
||||
}
|
||||
myElements = '';
|
||||
drop.get('children').each(function(v, k) {
|
||||
myElements = myElements + ',' + get_node_id(v.get('id'));
|
||||
});
|
||||
var spinner = M.util.add_spinner(Y, dragnode);
|
||||
saveposition(Y, this, id, myElements, sesskey, spinner);
|
||||
}
|
||||
});
|
||||
|
||||
//Static Vars
|
||||
var goingUp = false, lastY = 0;
|
||||
|
||||
//Get the list of li's in the lists and make them draggable
|
||||
var listitems = Y.Node.all('#feedback_dragarea ul li.feedback_itemlist');
|
||||
listitems.each(function(v, k) { //make each item draggable
|
||||
var dd = new Y.DD.Drag({
|
||||
node: v,
|
||||
target: {
|
||||
padding: '0 0 0 20'
|
||||
}
|
||||
}).plug(Y.Plugin.DDProxy, {
|
||||
moveOnEnd: false
|
||||
}).plug(Y.Plugin.DDConstrained, {
|
||||
constrain2node: '#feedback_dragarea' //prevent dragging outside the dragarea
|
||||
});
|
||||
|
||||
item_id = get_node_id(v.get('id')); //get the id of the feedback item
|
||||
item_box = Y.Node.one('#feedback_item_box_' + item_id); //get the current item box so we can add the drag handle
|
||||
handletitle = M.util.get_string('move_item', 'feedback');
|
||||
mydraghandle = get_drag_handle(handletitle, 'itemhandle');
|
||||
v.insert(mydraghandle, item_box); //insert the new handle into the item box
|
||||
dd.addHandle(mydraghandle); //now we add the handle to the drag object, so the box only can be moved with this handle
|
||||
});
|
||||
// remove all legacy move icons
|
||||
Y.Node.all('span.feedback_item_command_moveup').each(function(v, k) {
|
||||
v.remove();
|
||||
});;
|
||||
Y.Node.all('span.feedback_item_command_movedown').each(function(v, k) {
|
||||
v.remove();
|
||||
});;
|
||||
Y.Node.all('span.feedback_item_command_move').each(function(v, k) {
|
||||
v.remove();
|
||||
});;
|
||||
|
||||
//Create targets for drop.
|
||||
var droparea = Y.Node.one('#feedback_dragarea ul#feedback_draglist');
|
||||
var tar = new Y.DD.Drop({
|
||||
node: droparea
|
||||
});
|
||||
|
||||
// here we save the new itemorder
|
||||
function saveposition(Y, objekt, id, itemorder, sesskey, spinner){
|
||||
|
||||
Y.io(ajaxscript, {
|
||||
//the needed paramaters
|
||||
data: {action: 'saveitemorder',
|
||||
id: id,
|
||||
itemorder: itemorder,
|
||||
sesskey: sesskey
|
||||
},
|
||||
|
||||
timeout: 5000, //5 seconds for timeout I think it is enough
|
||||
|
||||
//define the events
|
||||
on: {
|
||||
start : function(transactionid) {
|
||||
spinner.show();
|
||||
},
|
||||
success: function(transactionid, xhr) {
|
||||
var response = xhr.response;
|
||||
var ergebnis = Y.JSON.parse(response);
|
||||
window.setTimeout(function(e) {
|
||||
spinner.hide();
|
||||
}, 250);
|
||||
},
|
||||
failure: function() {
|
||||
window.setTimeout(function(e) {
|
||||
spinner.hide();
|
||||
}, 250);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//this returns the numeric id from the dom id
|
||||
function get_node_id(id) {
|
||||
return Number(id.replace(/feedback_item_/i, ''));
|
||||
};
|
||||
|
||||
//this creates a new drag handle and return it as a new node
|
||||
function get_drag_handle(title, handleclass) {
|
||||
var MOVEICON = {
|
||||
pix: "i/move_2d",
|
||||
largepix: "i/dragdrop",
|
||||
component: 'moodle'
|
||||
};
|
||||
|
||||
|
||||
var iconname = MOVEICON.pix;
|
||||
var dragicon = Y.Node.create('<img />')
|
||||
.setStyle('cursor', 'move')
|
||||
.setAttrs({
|
||||
'src' : M.util.image_url(iconname, MOVEICON.component),
|
||||
'alt' : title,
|
||||
'class' : handleclass
|
||||
});
|
||||
|
||||
var dragelement = Y.Node.create('<span></span>')
|
||||
.setAttribute('title', title)
|
||||
dragelement.appendChild(dragicon);
|
||||
return dragelement;
|
||||
};
|
||||
|
||||
};
|
||||
@@ -82,3 +82,9 @@ hr.feedback_pagebreak {
|
||||
background-color:#aaaaaa;
|
||||
border:0px;
|
||||
}
|
||||
|
||||
ul#feedback_draglist {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user