Skip to content

Commit

Permalink
MDL-38367 course dndupload - various tweaks to the UI
Browse files Browse the repository at this point in the history
Switched to Moodle-style dialog boxes (thanks Andrew for the pointer)
Enter button now submits the form (from within the 'name' field)
Upload button is disabled when the name is empty (if the name is required for the selected handler)
Dialog now has 'What do you want to do with this text?' and 'Name' for the text
Entire course section now has a class added when you drag over it (to enable it to be styled in the future)
  • Loading branch information
davosmith committed Mar 11, 2013
1 parent 8673a98 commit 66079e2
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 94 deletions.
208 changes: 123 additions & 85 deletions course/dndupload.js
Expand Up @@ -239,7 +239,7 @@ M.course_dndupload = {
* Look through the event data, checking it against the registered data types
* (in order of priority) and return details of the first matching data type
* @param e the event details
* @return mixed false if not found or an object {
* @return object|false - false if not found or an object {
* realtype: the type as given by the browser
* addmessage: the message to show to the user during dragging
* namemessage: the message for requesting a name for the resource from the user
Expand Down Expand Up @@ -284,6 +284,7 @@ M.course_dndupload = {
realtype: dttypes[j],
addmessage: types[i].addmessage,
namemessage: types[i].namemessage,
handlermessage: types[i].handlermessage,
type: types[i].identifier,
handlers: types[i].handlers
};
Expand Down Expand Up @@ -417,7 +418,7 @@ M.course_dndupload = {
var modsel = section.one(this.modslistselector);
if (!modsel) {
// Create the above 'ul' if it doesn't exist
var modsel = document.createElement('ul');
modsel = document.createElement('ul');
modsel.className = 'section img-text';
var contentel = section.get('children').pop();
var brel = contentel.get('children').pop();
Expand Down Expand Up @@ -489,6 +490,7 @@ M.course_dndupload = {
*/
hide_preview_element: function() {
this.Y.all('li.dndupload-preview').addClass('dndupload-hidden');
this.Y.all('.dndupload-over').removeClass('dndupload-over');
},

/**
Expand All @@ -500,6 +502,7 @@ M.course_dndupload = {
show_preview_element: function(section, type) {
this.hide_preview_element();
var preview = section.one('li.dndupload-preview').removeClass('dndupload-hidden');
section.addClass('dndupload-over');
preview.one('span').setContent(type.addmessage);
},

Expand Down Expand Up @@ -616,44 +619,16 @@ M.course_dndupload = {

var Y = this.Y;
var self = this;
var panel = new Y.Panel({
var panel = new M.core.dialogue({
bodyContent: content,
width: 350,
zIndex: 5,
centered: true,
width: '350px',
modal: true,
visible: true,
render: true,
buttons: [{
value: M.util.get_string('upload', 'moodle'),
action: function(e) {
e.preventDefault();
// Find out which module was selected
var module = false;
var div = Y.one('#dndupload_handlers'+uploadid);
div.all('input').each(function(input) {
if (input.get('checked')) {
module = input.get('value');
}
});
if (!module) {
return;
}
panel.hide();
// Remember this selection for next time
self.lastselected[extension] = module;
// Do the upload
self.upload_file(file, section, sectionnumber, module);
},
section: Y.WidgetStdMod.FOOTER
},{
value: M.util.get_string('cancel', 'moodle'),
action: function(e) {
e.preventDefault();
panel.hide();
},
section: Y.WidgetStdMod.FOOTER
}]
align: {
node: null,
points: [Y.WidgetPositionAlign.CC, Y.WidgetPositionAlign.CC]
}
});
// When the panel is hidden - destroy it and then check for other pending uploads
panel.after("visibleChange", function(e) {
Expand All @@ -662,6 +637,39 @@ M.course_dndupload = {
self.check_upload_queue();
}
});

// Add the submit/cancel buttons to the bottom of the dialog.
panel.addButton({
label: M.util.get_string('upload', 'moodle'),
action: function(e) {
e.preventDefault();
// Find out which module was selected
var module = false;
var div = Y.one('#dndupload_handlers'+uploadid);
div.all('input').each(function(input) {
if (input.get('checked')) {
module = input.get('value');
}
});
if (!module) {
return;
}
panel.hide();
// Remember this selection for next time
self.lastselected[extension] = module;
// Do the upload
self.upload_file(file, section, sectionnumber, module);
},
section: Y.WidgetStdMod.FOOTER
});
panel.addButton({
label: M.util.get_string('cancel', 'moodle'),
action: function(e) {
e.preventDefault();
panel.hide();
},
section: Y.WidgetStdMod.FOOTER
});
},

/**
Expand Down Expand Up @@ -822,6 +830,7 @@ M.course_dndupload = {
var nameid = 'dndupload_handler_name'+uploadid;
var content = '';
if (type.handlers.length > 1) {
content += '<p>'+type.handlermessage+'</p>';
content += '<div id="dndupload_handlers'+uploadid+'">';
var sel = type.handlers[0].module;
for (var i=0; i<type.handlers.length; i++) {
Expand All @@ -840,76 +849,105 @@ M.course_dndupload = {

var Y = this.Y;
var self = this;
var panel = new Y.Panel({
var panel = new M.core.dialogue({
bodyContent: content,
width: 350,
zIndex: 5,
centered: true,
width: '350px',
modal: true,
visible: true,
render: true,
buttons: [{
value: M.util.get_string('upload', 'moodle'),
action: function(e) {
e.preventDefault();
var name = Y.one('#dndupload_handler_name'+uploadid).get('value');
name = name.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); // Trim
var module = false;
var noname = false;
if (type.handlers.length > 1) {
// Find out which module was selected
var div = Y.one('#dndupload_handlers'+uploadid);
div.all('input').each(function(input) {
if (input.get('checked')) {
var idx = input.get('value');
module = type.handlers[idx].module;
noname = type.handlers[idx].noname;
}
});
if (!module) {
return;
}
} else {
module = type.handlers[0].module;
noname = type.handlers[0].noname;
}
if (name == '' && !noname) {
return;
}
panel.hide();
// Do the upload
self.upload_item(name, type.type, contents, section, sectionnumber, module);
},
section: Y.WidgetStdMod.FOOTER
},{
value: M.util.get_string('cancel', 'moodle'),
action: function(e) {
e.preventDefault();
panel.hide();
},
section: Y.WidgetStdMod.FOOTER
}]
align: {
node: null,
points: [Y.WidgetPositionAlign.CC, Y.WidgetPositionAlign.CC]
}
});

// When the panel is hidden - destroy it and then check for other pending uploads
panel.after("visibleChange", function(e) {
if (!panel.get('visible')) {
panel.destroy(true);
self.check_upload_queue();
}
});
// Focus on the 'name' box
Y.one('#'+nameid).focus();

var namefield = Y.one('#'+nameid);
var submit = function(e) {
e.preventDefault();
var name = Y.Lang.trim(namefield.get('value'));
var module = false;
var noname = false;
if (type.handlers.length > 1) {
// Find out which module was selected
var div = Y.one('#dndupload_handlers'+uploadid);
div.all('input').each(function(input) {
if (input.get('checked')) {
var idx = input.get('value');
module = type.handlers[idx].module;
noname = type.handlers[idx].noname;
}
});
if (!module) {
return;
}
} else {
module = type.handlers[0].module;
noname = type.handlers[0].noname;
}
if (name == '' && !noname) {
return;
}
if (noname) {
name = '';
}
panel.hide();
// Do the upload
self.upload_item(name, type.type, contents, section, sectionnumber, module);
};

// Add the submit/cancel buttons to the bottom of the dialog.
panel.addButton({
label: M.util.get_string('upload', 'moodle'),
action: submit,
section: Y.WidgetStdMod.FOOTER,
name: 'submit'
});
panel.addButton({
label: M.util.get_string('cancel', 'moodle'),
action: function(e) {
e.preventDefault();
panel.hide();
},
section: Y.WidgetStdMod.FOOTER
});
var submitbutton = panel.getButton('submit').button;
namefield.on('key', submit, 'enter'); // Submit the form if 'enter' pressed
namefield.after('keyup', function() {
if (Y.Lang.trim(namefield.get('value')) == '') {
submitbutton.disable();
} else {
submitbutton.enable();
}
});

// Enable / disable the 'name' box, depending on the handler selected.
for (i=0; i<type.handlers.length; i++) {
if (type.handlers[i].noname) {
Y.one('#dndupload_handler'+uploadid+type.handlers[i].module).on('click', function (e) {
Y.one('#'+nameid).set('disabled', 'disabled');
namefield.set('disabled', 'disabled');
submitbutton.enable();
});
} else {
Y.one('#dndupload_handler'+uploadid+type.handlers[i].module).on('click', function (e) {
Y.one('#'+nameid).removeAttribute('disabled');
namefield.removeAttribute('disabled');
namefield.focus();
if (Y.Lang.trim(namefield.get('value')) == '') {
submitbutton.disable();
}
});
}
}

// Focus on the 'name' box
Y.one('#'+nameid).focus();
},

/**
Expand Down
17 changes: 11 additions & 6 deletions course/dnduploadlib.php
Expand Up @@ -67,7 +67,7 @@ function dndupload_add_to_course($course, $modnames) {
array('upload', 'moodle'),
array('cancel', 'moodle')
),
'requires' => array('node', 'event', 'panel', 'json', 'anim')
'requires' => array('node', 'event', 'json', 'anim')
);
$vars = array(
array('courseid' => $course->id,
Expand Down Expand Up @@ -113,11 +113,11 @@ public function __construct($course, $modnames = null) {
// Note: 'Files' type is hard-coded into the Javascript as this needs to be ...
// ... treated a little differently.
$this->add_type('url', array('url', 'text/uri-list', 'text/x-moz-url'), get_string('addlinkhere', 'moodle'),
get_string('nameforlink', 'moodle'), 10);
get_string('nameforlink', 'moodle'), get_string('whatforlink', 'moodle'), 10);
$this->add_type('text/html', array('text/html'), get_string('addpagehere', 'moodle'),
get_string('nameforpage', 'moodle'), 20);
get_string('nameforpage', 'moodle'), get_string('whatforpage', 'moodle'), 20);
$this->add_type('text', array('text', 'text/plain'), get_string('addpagehere', 'moodle'),
get_string('nameforpage', 'moodle'), 30);
get_string('nameforpage', 'moodle'), get_string('whatforpage', 'moodle'), 30);

// Loop through all modules to find handlers.
$mods = get_plugin_list_with_function('mod', 'dndupload_register');
Expand Down Expand Up @@ -145,8 +145,11 @@ public function __construct($course, $modnames = null) {
} else {
$priority = 100;
}
if (!isset($type['handlermessage'])) {
$type['handlermessage'] = '';
}
$this->add_type($type['identifier'], $type['datatransfertypes'],
$type['addmessage'], $type['namemessage'], $priority);
$type['addmessage'], $type['namemessage'], $type['handlermessage'], $priority);
}
}
if (isset($resp['types'])) {
Expand All @@ -169,10 +172,11 @@ public function __construct($course, $modnames = null) {
* dragged onto the page
* @param string $namemessage The message to pop up when asking for the name to give the
* course module instance when it is created
* @param string $handlermessage The message to pop up when asking which module should handle this type
* @param int $priority Controls the order in which types are checked by the browser (mainly
* needed to check for 'text' last as that is usually given as fallback)
*/
public function add_type($identifier, $datatransfertypes, $addmessage, $namemessage, $priority=100) {
public function add_type($identifier, $datatransfertypes, $addmessage, $namemessage, $handlermessage, $priority=100) {
if ($this->is_known_type($identifier)) {
throw new coding_exception("Type $identifier is already registered");
}
Expand All @@ -182,6 +186,7 @@ public function add_type($identifier, $datatransfertypes, $addmessage, $namemess
$add->datatransfertypes = $datatransfertypes;
$add->addmessage = $addmessage;
$add->namemessage = $namemessage;
$add->handlermessage = $handlermessage;
$add->priority = $priority;
$add->handlers = array();

Expand Down
4 changes: 3 additions & 1 deletion lang/en/moodle.php
Expand Up @@ -1097,7 +1097,7 @@
$string['myprofile'] = 'My profile';
$string['name'] = 'Name';
$string['nameforlink'] = 'What do you want to call this link?';
$string['nameforpage'] = 'What do you want to call this text?';
$string['nameforpage'] = 'Name';
$string['navigation'] = 'Navigation';
$string['needed'] = 'Needed';
$string['never'] = 'Never';
Expand Down Expand Up @@ -1806,6 +1806,8 @@
If you have not done so already, you should edit your profile page so that we can learn more about you:
{$a->profileurl}';
$string['whatforlink'] = 'What do you want to do with the link?';
$string['whatforpage'] = 'What do you want to do with the text?';
$string['whattocallzip'] = 'What do you want to call the zip file?';
$string['whattodo'] = 'What to do';
$string['windowclosing'] = 'This window should close automatically. If not, please close it now.';
Expand Down
2 changes: 1 addition & 1 deletion mod/label/lang/en/label.php
Expand Up @@ -31,7 +31,7 @@
$string['dndresizeheight'] = 'Resize drag and drop height';
$string['dndresizewidth'] = 'Resize drag and drop width';
$string['dnduploadlabel'] = 'Add image to course page';
$string['dnduploadlabeltext'] = 'Add text to course page';
$string['dnduploadlabeltext'] = 'Add a label to the course page';
$string['label:addinstance'] = 'Add a new label';
$string['labeltext'] = 'Label text';
$string['modulename'] = 'Label';
Expand Down
2 changes: 1 addition & 1 deletion mod/page/lang/en/page.php
Expand Up @@ -26,7 +26,7 @@
$string['configdisplayoptions'] = 'Select all options that should be available, existing settings are not modified. Hold CTRL key to select multiple fields.';
$string['content'] = 'Page content';
$string['contentheader'] = 'Content';
$string['createpage'] = 'Create a new page';
$string['createpage'] = 'Create a new page resource';
$string['displayoptions'] = 'Available display options';
$string['displayselect'] = 'Display';
$string['displayselectexplain'] = 'Select display type.';
Expand Down

0 comments on commit 66079e2

Please sign in to comment.