diff --git a/lang/en/scheduler.php b/lang/en/scheduler.php
index 3ce2f063..f0bd7a62 100644
--- a/lang/en/scheduler.php
+++ b/lang/en/scheduler.php
@@ -55,7 +55,8 @@
$string['addappointment'] = 'Add another student';
$string['addcommands'] = 'Add slots';
$string['addondays'] = 'Add appointments on';
-$string['addsession'] = 'Add repeated slots';
+$string['addaperiodsession'] = 'Add repeated slots (via calendar)';
+$string['addsession'] = 'Add repeated slots (by weekdays)';
$string['addsingleslot'] = 'Add single slot';
$string['addslot'] = 'You can add additional appointment slots at any time.';
$string['addstudenttogroup'] = 'Add this student to appointment group';
diff --git a/slotforms.php b/slotforms.php
index 56d1538b..3b80296c 100644
--- a/slotforms.php
+++ b/slotforms.php
@@ -539,3 +539,113 @@ public function validation($data, $files) {
return $errors;
}
}
+
+class scheduler_addaperiodsession_form extends scheduler_slotform_base {
+
+ protected function definition() {
+
+ global $DB, $CFG, $COURSE;
+
+ $mform = $this->_form;
+
+ $listdates = "";
+ $mform->addElement('hidden', 'getlistdates', $listdates);
+
+ // Define Calendar panel
+ $mform->addElement('html', '
');
+ $mform->addElement('html', '
');
+ $mform->addElement('html', '
');
+ // Start and end time
+ $hours = array();
+ $minutes = array();
+ for ($i=0; $i<=23; $i++) {
+ $hours[$i] = sprintf("%02d", $i);
+ }
+ for ($i=0; $i<60; $i+=5) {
+ $minutes[$i] = sprintf("%02d", $i);
+ }
+
+ $timegroup = array();
+ $timegroup[] = $mform->createElement('static', 'timefrom', '', get_string('timefrom', 'scheduler'));
+ $timegroup[] = $mform->createElement('select', 'starthour', get_string('hour', 'form'), $hours);
+ $timegroup[] = $mform->createElement('select', 'startminute', get_string('minute', 'form'), $minutes);
+ $timegroup[] = $mform->createElement('static', 'timeto', '', get_string('timeto', 'scheduler'));
+ $timegroup[] = $mform->createElement('select', 'endhour', get_string('hour', 'form'), $hours);
+ $timegroup[] = $mform->createElement('select', 'endminute', get_string('minute', 'form'), $minutes);
+ $mform->addGroup($timegroup, 'timerange', get_string('timerange', 'scheduler'), null, false);
+
+ // Divide into slots?
+ $mform->addElement('selectyesno', 'divide', get_string('divide', 'scheduler'));
+ $mform->setDefault('divide', 1);
+
+ // Duration of the slot
+ $this->add_duration_field('minutesperslot');
+
+ // Break between slots
+ $this->add_minutes_field('break', 'break', 0, 'minutes');
+
+ // Force when overlap?
+ $mform->addElement('selectyesno', 'forcewhenoverlap', get_string('forcewhenoverlap', 'scheduler'));
+
+ // Ignore conflict checkbox
+ $mform->addElement('checkbox', 'ignoreconflicts', get_string('ignoreconflicts', 'scheduler'));
+ $mform->setDefault('ignoreconflicts', false);
+ $mform->addHelpButton('ignoreconflicts', 'ignoreconflicts', 'scheduler');
+
+ // Common fields
+ $this->add_base_fields();
+
+ // Display slot from date - relative
+ $hideuntilsel = array();
+ $hideuntilsel[0] = get_string('now', 'scheduler');
+ $hideuntilsel[DAYSECS] = get_string('onedaybefore', 'scheduler');
+ for ($i = 2; $i < 7; $i++) {
+ $hideuntilsel[DAYSECS*$i] = get_string('xdaysbefore', 'scheduler', $i);
+ }
+ $hideuntilsel[WEEKSECS] = get_string('oneweekbefore', 'scheduler');
+ for ($i = 2; $i < 7; $i++) {
+ $hideuntilsel[WEEKSECS*$i] = get_string('xweeksbefore', 'scheduler', $i);
+ }
+ $mform->addElement('select', 'hideuntilrel', get_string('displayfrom', 'scheduler'), $hideuntilsel);
+ $mform->setDefault('hideuntilsel', 0);
+
+ // E-mail reminder from
+ $remindersel = array();
+ $remindersel[-1] = get_string('never', 'scheduler');
+ $remindersel[0] = get_string('onthemorningofappointment', 'scheduler');
+ $remindersel[DAYSECS] = get_string('onedaybefore', 'scheduler');
+ for ($i = 2; $i < 7; $i++) {
+ $remindersel[DAYSECS * $i] = get_string('xdaysbefore', 'scheduler', $i);
+ }
+ $remindersel[WEEKSECS] = get_string('oneweekbefore', 'scheduler');
+ for ($i = 2; $i < 7; $i++) {
+ $remindersel[WEEKSECS*$i] = get_string('xweeksbefore', 'scheduler', $i);
+ }
+
+ $mform->addElement('select', 'emaildaterel', get_string('emailreminder', 'scheduler'), $remindersel);
+ $mform->setDefault('remindersel', -1);
+
+ $this->add_action_buttons();
+
+ }
+
+ public function validation($data, $files) {
+ $errors = parent::validation($data, $files);
+
+ // Time range is negative
+ $starttime = $data['starthour']*60+$data['startminute'];
+ $endtime = $data['endhour']*60+$data['endminute'];
+ if ($starttime > $endtime) {
+ $errors['endtime'] = get_string('negativerange', 'scheduler');
+ }
+
+ // Break must be nonnegative
+ if ($data['break'] < 0) {
+ $errors['breakgroup'] = get_string('breaknotnegative', 'scheduler');
+ }
+
+ // Conflict checks are now being done after submitting the form.
+
+ return $errors;
+ }
+}
diff --git a/styles.css b/styles.css
index 8c8aece9..e9fe3e6e 100644
--- a/styles.css
+++ b/styles.css
@@ -212,3 +212,7 @@ body.path-mod-scheduler.jsenabled input.studentselectsubmit {
.path-mod-scheduler #id_datafieldhdr fieldset.fgroup span label {
margin-left: 0.4em;
}
+
+.yui3-skin-sam .redtext {
+ color:#ff0000;
+}
diff --git a/teacherview.controller.php b/teacherview.controller.php
index e72e6f05..ac5aedf7 100644
--- a/teacherview.controller.php
+++ b/teacherview.controller.php
@@ -176,6 +176,104 @@ function scheduler_delete_slots_from_ui(array $slots, $action) {
echo $output->action_message($msg);
}
+function scheduler_action_doaddaperiodsession($scheduler, $formdata) {
+
+ global $DB, $output;
+
+ $data = (object) $formdata;
+
+ $listdatesarr = json_decode($data->getlistdates, true);
+
+ // Create as many slots of $duration on the given dates list $listdates and that do not conflict.
+ $countslots = 0;
+ $couldnotcreateslots = '';
+ $slot = new stdClass();
+ $slot->schedulerid = $scheduler->id;
+ $slot->teacherid = $data->teacherid;
+ $slot->appointmentlocation = $data->appointmentlocation;
+ $slot->exclusivity = $data->exclusivityenable ? $data->exclusivity : 0;
+ if ($data->divide) {
+ $slot->duration = $data->duration;
+ } else {
+ $slot->duration = $data->endhour * 60 + $data->endminute - $data->starthour * 60 - $data->startminute;
+ };
+ $slot->notes = '';
+ $slot->notesformat = FORMAT_HTML;
+ $slot->timemodified = time();
+
+ for ($d = 0; $d <= count($listdatesarr[0])-1; $d ++){
+ $year = date("Y", strtotime($listdatesarr[0][$d]));
+ $month = date("m", strtotime($listdatesarr[0][$d]));
+ $day = date("d", strtotime($listdatesarr[0][$d]));
+ $slot->starttime = make_timestamp($year, $month, $day, $data->starthour, $data->startminute);
+ $eventdate = usergetdate($slot->starttime);
+ $data->timestart = $slot->starttime;
+ $data->timeend = make_timestamp(date('Y',$data->timestart), date('m',$data->timestart), date('d',$data->timestart), $data->endhour, $data->endminute);
+
+ // this corrects around midnight bug
+ if ($data->timestart > $data->timeend){
+ $data->timeend += DAYSECS;
+ }
+ if ($data->hideuntilrel == 0) {
+ $slot->hideuntil = time();
+ } else {
+ $slot->hideuntil = make_timestamp($eventdate['year'], $eventdate['mon'], $eventdate['mday'], 6, 0) - $data->hideuntilrel;
+ }
+ if ($data->emaildaterel == -1) {
+ $slot->emaildate = 0;
+ } else {
+ $slot->emaildate = make_timestamp($eventdate['year'], $eventdate['mon'], $eventdate['mday'], 0, 0) - $data->emaildaterel;
+ }
+
+ while ($slot->starttime <= $data->timeend - $data->duration * 60) {
+ if (!isset($data->ignoreconflicts)) {
+ //check against ALL conflicts
+ $conflicts = $scheduler->get_conflicts($data->timestart, $data->timestart + $slot->duration * 60,
+ $data->teacherid, 0, SCHEDULER_ALL);
+ }
+ else {
+ //check against LOCAL conflicts only
+ $conflicts = $scheduler->get_conflicts($data->timestart, $data->timestart + $slot->duration * 60,
+ $data->teacherid, 0, SCHEDULER_SELF);
+ }
+ $resolvable = (boolean) $data->forcewhenoverlap;
+ foreach ($conflicts as $conflict) {
+ $resolvable = $resolvable
+ && $conflict->isself == 1 // Do not delete slots outside the current scheduler.
+ && $conflict->numstudents == 0; // Do not delete slots with bookings.
+ }
+
+ if ($conflicts) {
+ $cl = new scheduler_conflict_list();
+ $cl->add_conflicts($conflicts);
+ if (!$resolvable) {
+ print_string('conflictingslots', 'scheduler', userdate($data->timestart));
+ echo $output->doc_link('mod/scheduler/conflict', '', true);
+ echo $output->render($cl);
+ } else { // We force, so delete all conflicting before inserting.
+ foreach ($conflicts as $conflict) {
+ $cslot = $scheduler->get_slot($conflict->id);
+ \mod_scheduler\event\slot_deleted::create_from_slot($cslot, 'addsession-conflict')->trigger();
+ $cslot->delete();
+ }
+ print_string('deletedconflictingslots', 'scheduler', userdate($data->timestart));
+ echo $output->doc_link('mod/scheduler/conflict', '', true);
+ echo $output->render($cl);
+ }
+ }
+ if (!$conflicts || $resolvable) {
+ $slotid = $DB->insert_record('scheduler_slots', $slot, true, true);
+ $slotobj = $scheduler->get_slot($slotid);
+ \mod_scheduler\event\slot_added::create_from_slot($slotobj)->trigger();
+ $countslots++;
+ }
+ $slot->starttime += ($data->duration + $data->break) * 60;
+ $data->timestart += ($data->duration + $data->break) * 60;
+ }
+ }
+ echo $output->action_message(get_string('slotsadded', 'scheduler', $countslots));
+}
+
// Require valid session key for all actions.
require_sesskey();
diff --git a/teacherview.php b/teacherview.php
index 0fd77936..2ee63ba2 100644
--- a/teacherview.php
+++ b/teacherview.php
@@ -163,7 +163,7 @@ function scheduler_print_schedulebox(scheduler_instance $scheduler, $studentid,
}
}
-/************************************ Add session multiple slots form ****************************************/
+/************************************ Add session multiple slots (by weekdays) form ****************************************/
if ($action == 'addsession') {
$actionurl = new moodle_url('/mod/scheduler/view.php',
@@ -189,6 +189,41 @@ function scheduler_print_schedulebox(scheduler_instance $scheduler, $studentid,
}
}
+/************************************ Add session multiple slots (via YUI calendar) form ************************************/
+if ($action == 'addaperiodsession') {
+
+ $courselang = substr($COURSE->lang, 0, 2); //need to localization option
+
+ $actionurl = new moodle_url('/mod/scheduler/view.php',
+ array('what' => 'addaperiodsession', 'id' => $cm->id, 'subpage' => $subpage));
+ $returnurl = new moodle_url('/mod/scheduler/view.php',
+ array('what' => 'view', 'id' => $cm->id, 'subpage' => $subpage));
+
+ if (!$scheduler->has_available_teachers()) {
+ print_error('needteachers', 'scheduler', $returnurl);
+ }
+
+ $mform = new scheduler_addaperiodsession_form($actionurl, $scheduler, $cm, $usergroups);
+
+ //process form response
+ if ($mform->is_cancelled()) {
+ redirect($returnurl);
+ } else if ($formdata = $mform->get_data()) {
+ scheduler_action_doaddaperiodsession($scheduler, $formdata);
+ } else {
+ //prepare and load the YUI module
+ $calconfig=array($courselang);
+ $calfunction ='M.mod_scheduler.calpane.init';
+ $calmodule = 'moodle-mod_scheduler-calpane';
+ $PAGE->requires->yui_module($calmodule, $calfunction, $calconfig);
+ //display form
+ echo $output->heading(get_string('addaperiodsession', 'scheduler'));
+ $mform->display();
+ echo $output->footer($course);
+ die;
+ }
+}
+
/************************************ Schedule a student form ***********************************************/
if ($action == 'schedule') {
if ($subaction == 'dochooseslot') {
@@ -404,6 +439,7 @@ function scheduler_print_schedulebox(scheduler_instance $scheduler, $studentid,
$addbuttons = array();
$addbuttons[] = $commandbar->action_link(new moodle_url($actionurl, array('what' => 'addsession')), 'addsession', 't/add');
+$addbuttons[] = $commandbar->action_link(new moodle_url($actionurl, array('what' => 'addaperiodsession')), 'addaperiodsession', 't/add');
$addbuttons[] = $commandbar->action_link(new moodle_url($actionurl, array('what' => 'addslot')), 'addsingleslot', 't/add');
$commandbar->add_group(get_string('addcommands', 'scheduler'), $addbuttons);
diff --git a/version.php b/version.php
index 44b882b2..3a777d4d 100644
--- a/version.php
+++ b/version.php
@@ -15,7 +15,7 @@
*/
$plugin->component = 'mod_scheduler'; // Full name of the plugin (used for diagnostics).
-$plugin->version = 2016100500; // The current module version (Date: YYYYMMDDXX).
+$plugin->version = 2016103000; // The current module version (Date: YYYYMMDDXX).
$plugin->release = '3.x dev'; // Human-friendly version name.
$plugin->requires = 2016052300; // Requires Moodle 3.1.
$plugin->maturity = MATURITY_ALPHA; // Alpha development code - not for production sites!
diff --git a/yui/build/moodle-mod_scheduler-calpane/moodle-mod_scheduler-calpane-coverage.js b/yui/build/moodle-mod_scheduler-calpane/moodle-mod_scheduler-calpane-coverage.js
new file mode 100644
index 00000000..dcadbd0c
--- /dev/null
+++ b/yui/build/moodle-mod_scheduler-calpane/moodle-mod_scheduler-calpane-coverage.js
@@ -0,0 +1,6 @@
+if (typeof __coverage__ === 'undefined') { __coverage__ = {}; }
+if (!__coverage__['build/moodle-mod_scheduler-calpane/moodle-mod_scheduler-calpane.js']) {
+ __coverage__['build/moodle-mod_scheduler-calpane/moodle-mod_scheduler-calpane.js'] = {"path":"build/moodle-mod_scheduler-calpane/moodle-mod_scheduler-calpane.js","s":{"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0},"b":{"1":[0,0],"2":[0,0],"3":[0,0],"4":[0,0],"5":[0,0],"6":[0,0],"7":[0,0]},"f":{"1":0,"2":0,"3":0,"4":0,"5":0},"fnMap":{"1":{"name":"(anonymous_1)","line":1,"loc":{"start":{"line":1,"column":40},"end":{"line":1,"column":59}}},"2":{"name":"(anonymous_2)","line":8,"loc":{"start":{"line":8,"column":11},"end":{"line":8,"column":30}}},"3":{"name":"(anonymous_3)","line":54,"loc":{"start":{"line":54,"column":24},"end":{"line":54,"column":53}}},"4":{"name":"(anonymous_4)","line":61,"loc":{"start":{"line":61,"column":33},"end":{"line":61,"column":52}}},"5":{"name":"(anonymous_5)","line":73,"loc":{"start":{"line":73,"column":33},"end":{"line":73,"column":47}}}},"statementMap":{"1":{"start":{"line":1,"column":0},"end":{"line":86,"column":109}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":8}},"3":{"start":{"line":5,"column":0},"end":{"line":5,"column":40}},"4":{"start":{"line":6,"column":0},"end":{"line":6,"column":35}},"5":{"start":{"line":8,"column":0},"end":{"line":84,"column":4}},"6":{"start":{"line":9,"column":4},"end":{"line":12,"column":7}},"7":{"start":{"line":13,"column":4},"end":{"line":16,"column":7}},"8":{"start":{"line":17,"column":4},"end":{"line":17,"column":73}},"9":{"start":{"line":19,"column":4},"end":{"line":26,"column":27}},"10":{"start":{"line":28,"column":4},"end":{"line":38,"column":5}},"11":{"start":{"line":29,"column":8},"end":{"line":29,"column":56}},"12":{"start":{"line":31,"column":8},"end":{"line":31,"column":88}},"13":{"start":{"line":33,"column":8},"end":{"line":37,"column":9}},"14":{"start":{"line":34,"column":12},"end":{"line":34,"column":92}},"15":{"start":{"line":35,"column":15},"end":{"line":37,"column":9}},"16":{"start":{"line":36,"column":12},"end":{"line":36,"column":92}},"17":{"start":{"line":40,"column":4},"end":{"line":40,"column":20}},"18":{"start":{"line":42,"column":4},"end":{"line":50,"column":6}},"19":{"start":{"line":52,"column":4},"end":{"line":59,"column":7}},"20":{"start":{"line":55,"column":12},"end":{"line":57,"column":13}},"21":{"start":{"line":56,"column":16},"end":{"line":56,"column":41}},"22":{"start":{"line":61,"column":4},"end":{"line":71,"column":7}},"23":{"start":{"line":62,"column":8},"end":{"line":69,"column":15}},"24":{"start":{"line":70,"column":8},"end":{"line":70,"column":22}},"25":{"start":{"line":73,"column":4},"end":{"line":83,"column":7}},"26":{"start":{"line":74,"column":8},"end":{"line":74,"column":37}},"27":{"start":{"line":75,"column":8},"end":{"line":75,"column":29}},"28":{"start":{"line":77,"column":8},"end":{"line":79,"column":3}},"29":{"start":{"line":78,"column":12},"end":{"line":78,"column":101}},"30":{"start":{"line":80,"column":8},"end":{"line":80,"column":26}},"31":{"start":{"line":82,"column":8},"end":{"line":82,"column":85}}},"branchMap":{"1":{"line":5,"type":"binary-expr","locations":[{"start":{"line":5,"column":18},"end":{"line":5,"column":33}},{"start":{"line":5,"column":37},"end":{"line":5,"column":39}}]},"2":{"line":28,"type":"if","locations":[{"start":{"line":28,"column":4},"end":{"line":28,"column":4}},{"start":{"line":28,"column":4},"end":{"line":28,"column":4}}]},"3":{"line":28,"type":"binary-expr","locations":[{"start":{"line":28,"column":8},"end":{"line":28,"column":26}},{"start":{"line":28,"column":30},"end":{"line":28,"column":47}}]},"4":{"line":33,"type":"if","locations":[{"start":{"line":33,"column":8},"end":{"line":33,"column":8}},{"start":{"line":33,"column":8},"end":{"line":33,"column":8}}]},"5":{"line":35,"type":"if","locations":[{"start":{"line":35,"column":15},"end":{"line":35,"column":15}},{"start":{"line":35,"column":15},"end":{"line":35,"column":15}}]},"6":{"line":55,"type":"if","locations":[{"start":{"line":55,"column":12},"end":{"line":55,"column":12}},{"start":{"line":55,"column":12},"end":{"line":55,"column":12}}]},"7":{"line":78,"type":"cond-expr","locations":[{"start":{"line":78,"column":36},"end":{"line":78,"column":38}},{"start":{"line":78,"column":41},"end":{"line":78,"column":44}}]}},"code":["(function () { YUI.add('moodle-mod_scheduler-calpane', function (Y, NAME) {","","var MOD;\r","\r","M.mod_scheduler = M.mod_scheduler || {};\r","MOD = M.mod_scheduler.calpane = {};\r","\r","MOD.init = function(langconf) {\r"," Y.Intl.add(\"datatype-date-format\", \"uk-UK\", {\r"," \"A\":[\"Неділя\",\"Понеділок\",\"Вівторк\",\"Середа\",\"Четвер\",\"П'ятниця\",\"Субота\"],\r"," \"B\":[\"Січень\",\"Лютий\",\"Березень\",\"Квітень\",\"Травень\",\"Червень\",\"Липень\",\"Серпень\",\"Вересень\",\"Жовтень\",\"Листопад\",\"Грудень\"]\r"," });\r"," Y.Intl.add(\"datatype-date-format\", \"ru-RU\", {\r"," \"A\":[\"Воскресенье\",\"Понедельник\",\"Вторник\",\"Среда\",\"Четверг\",\"Пятница\",\"Суббота\"],\r"," \"B\":[\"Январь\",\"Февраль\",\"Март\",\"Апрель\",\"Май\",\"Июнь\",\"Июль\",\"Август\",\"Сентябрь\",\"Октябрь\",\"Ноябрь\",\"Декабрь\"]\r"," });\r"," Y.CalendarBase.CONTENT_TEMPLATE = Y.CalendarBase.THREE_PANE_TEMPLATE;\r"," // Setup basic calendar parameters\r"," var calend = new Y.Calendar({\r"," contentBox: \"#calContainer\",\r"," width:'760px',\r"," showPrevMonth: true,\r"," showNextMonth: true,\r"," selectionMode: 'multiple-sticky',\r"," minimumDate: new Date(),\r"," date: new Date()});\r"," //Set localization options\r"," if (langconf === false || langconf === \"en\") {\r"," Y.Intl.setLang(\"datatype-date-format\", \"en-US\");\r"," } else {\r"," Y.Intl.setLang(\"datatype-date-format\", langconf + \"-\" + langconf.toUpperCase());\r"," //set additional calendar options for the Ukrainian and Russian\r"," if (langconf === \"uk\") {\r"," calend.set(\"strings.very_short_weekdays\", [\"Нд\",\"Пн\",\"Вт\",\"Ср\",\"Чт\",\"Пт\",\"Сб\"]);\r"," } else if (langconf === \"ru\") {\r"," calend.set(\"strings.very_short_weekdays\", [\"Вс\",\"Пн\",\"Вт\",\"Ср\",\"Чт\",\"Пт\",\"Сб\"]);\r"," }\r"," }\r"," // Draw calendar instance\r"," calend.render();\r"," // Create a set of rules to match specific dates. In this case, the \"all_weekends\" rule will match any Saturday or Sunday.\r"," var rules = {\r"," \"all\": {\r"," \"all\": {\r"," \"all\": {\r"," \"0,6\": \"all_weekends\"\r"," }\r"," }\r"," }\r"," };\r"," // Set the calendar customRenderer, provides the rules defined above.\r"," calend.set(\"customRenderer\", {\r"," rules: rules,\r"," filterFunction: function (date, node, rules) {\r"," if (Y.Array.indexOf(rules, 'all_weekends') >= 0) {\r"," node.addClass(\"redtext\");\r"," }\r"," }\r"," });\r"," // Set a custom header renderer with a callback function, which receives the current date and outputs a string.\r"," calend.set(\"headerRenderer\", function (curDate) {\r"," var ydate = Y.DataType.Date,\r"," output = ydate.format(curDate, {\r"," format: \"%B %Y\"\r"," }) + \" — \" + ydate.format(ydate.addMonths(curDate, 1), {\r"," format: \"%B %Y\"\r"," })+ \" — \" + ydate.format(ydate.addMonths(curDate, 2), {\r"," format: \"%B %Y\"\r"," });\r"," return output;\r"," });\r"," // Listen to calendar's selectionChange event.\r"," calend.on(\"selectionChange\", function (ev) {\r"," var dtdate = Y.DataType.Date;\r"," var listdates = '[{';\r"," // Collect dates from selection\r"," for (var i = 0; i < ev.newSelection.length; i++) {\r"," listdates += (i === 0 ? \"\" : \",\") + '\"'+ i +'\":\"'+ dtdate.format(ev.newSelection[i])+'\"';\r","\t\t}\r"," listdates += \"}]\";\r"," //set dates to HTML control\r"," Y.one(document.getElementsByName('getlistdates')[0]).set('value', listdates);\r"," });\r"," };","","}, '@VERSION@', {\"requires\": [\"base\", \"calendar\", \"datatype-date\", \"datatype-date-format\", \"node\", \"intl\"]});","","}());"]};
+}
+var __cov_VfNixH5rFGHdVHAfsTIltg = __coverage__['build/moodle-mod_scheduler-calpane/moodle-mod_scheduler-calpane.js'];
+__cov_VfNixH5rFGHdVHAfsTIltg.s['1']++;YUI.add('moodle-mod_scheduler-calpane',function(Y,NAME){__cov_VfNixH5rFGHdVHAfsTIltg.f['1']++;__cov_VfNixH5rFGHdVHAfsTIltg.s['2']++;var MOD;__cov_VfNixH5rFGHdVHAfsTIltg.s['3']++;M.mod_scheduler=(__cov_VfNixH5rFGHdVHAfsTIltg.b['1'][0]++,M.mod_scheduler)||(__cov_VfNixH5rFGHdVHAfsTIltg.b['1'][1]++,{});__cov_VfNixH5rFGHdVHAfsTIltg.s['4']++;MOD=M.mod_scheduler.calpane={};__cov_VfNixH5rFGHdVHAfsTIltg.s['5']++;MOD.init=function(langconf){__cov_VfNixH5rFGHdVHAfsTIltg.f['2']++;__cov_VfNixH5rFGHdVHAfsTIltg.s['6']++;Y.Intl.add('datatype-date-format','uk-UK',{'A':['\u041d\u0435\u0434\u0456\u043b\u044f','\u041f\u043e\u043d\u0435\u0434\u0456\u043b\u043e\u043a','\u0412\u0456\u0432\u0442\u043e\u0440\u043a','\u0421\u0435\u0440\u0435\u0434\u0430','\u0427\u0435\u0442\u0432\u0435\u0440','\u041f\'\u044f\u0442\u043d\u0438\u0446\u044f','\u0421\u0443\u0431\u043e\u0442\u0430'],'B':['\u0421\u0456\u0447\u0435\u043d\u044c','\u041b\u044e\u0442\u0438\u0439','\u0411\u0435\u0440\u0435\u0437\u0435\u043d\u044c','\u041a\u0432\u0456\u0442\u0435\u043d\u044c','\u0422\u0440\u0430\u0432\u0435\u043d\u044c','\u0427\u0435\u0440\u0432\u0435\u043d\u044c','\u041b\u0438\u043f\u0435\u043d\u044c','\u0421\u0435\u0440\u043f\u0435\u043d\u044c','\u0412\u0435\u0440\u0435\u0441\u0435\u043d\u044c','\u0416\u043e\u0432\u0442\u0435\u043d\u044c','\u041b\u0438\u0441\u0442\u043e\u043f\u0430\u0434','\u0413\u0440\u0443\u0434\u0435\u043d\u044c']});__cov_VfNixH5rFGHdVHAfsTIltg.s['7']++;Y.Intl.add('datatype-date-format','ru-RU',{'A':['\u0412\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435','\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a','\u0412\u0442\u043e\u0440\u043d\u0438\u043a','\u0421\u0440\u0435\u0434\u0430','\u0427\u0435\u0442\u0432\u0435\u0440\u0433','\u041f\u044f\u0442\u043d\u0438\u0446\u0430','\u0421\u0443\u0431\u0431\u043e\u0442\u0430'],'B':['\u042f\u043d\u0432\u0430\u0440\u044c','\u0424\u0435\u0432\u0440\u0430\u043b\u044c','\u041c\u0430\u0440\u0442','\u0410\u043f\u0440\u0435\u043b\u044c','\u041c\u0430\u0439','\u0418\u044e\u043d\u044c','\u0418\u044e\u043b\u044c','\u0410\u0432\u0433\u0443\u0441\u0442','\u0421\u0435\u043d\u0442\u044f\u0431\u0440\u044c','\u041e\u043a\u0442\u044f\u0431\u0440\u044c','\u041d\u043e\u044f\u0431\u0440\u044c','\u0414\u0435\u043a\u0430\u0431\u0440\u044c']});__cov_VfNixH5rFGHdVHAfsTIltg.s['8']++;Y.CalendarBase.CONTENT_TEMPLATE=Y.CalendarBase.THREE_PANE_TEMPLATE;__cov_VfNixH5rFGHdVHAfsTIltg.s['9']++;var calend=new Y.Calendar({contentBox:'#calContainer',width:'760px',showPrevMonth:true,showNextMonth:true,selectionMode:'multiple-sticky',minimumDate:new Date(),date:new Date()});__cov_VfNixH5rFGHdVHAfsTIltg.s['10']++;if((__cov_VfNixH5rFGHdVHAfsTIltg.b['3'][0]++,langconf===false)||(__cov_VfNixH5rFGHdVHAfsTIltg.b['3'][1]++,langconf==='en')){__cov_VfNixH5rFGHdVHAfsTIltg.b['2'][0]++;__cov_VfNixH5rFGHdVHAfsTIltg.s['11']++;Y.Intl.setLang('datatype-date-format','en-US');}else{__cov_VfNixH5rFGHdVHAfsTIltg.b['2'][1]++;__cov_VfNixH5rFGHdVHAfsTIltg.s['12']++;Y.Intl.setLang('datatype-date-format',langconf+'-'+langconf.toUpperCase());__cov_VfNixH5rFGHdVHAfsTIltg.s['13']++;if(langconf==='uk'){__cov_VfNixH5rFGHdVHAfsTIltg.b['4'][0]++;__cov_VfNixH5rFGHdVHAfsTIltg.s['14']++;calend.set('strings.very_short_weekdays',['\u041d\u0434','\u041f\u043d','\u0412\u0442','\u0421\u0440','\u0427\u0442','\u041f\u0442','\u0421\u0431']);}else{__cov_VfNixH5rFGHdVHAfsTIltg.b['4'][1]++;__cov_VfNixH5rFGHdVHAfsTIltg.s['15']++;if(langconf==='ru'){__cov_VfNixH5rFGHdVHAfsTIltg.b['5'][0]++;__cov_VfNixH5rFGHdVHAfsTIltg.s['16']++;calend.set('strings.very_short_weekdays',['\u0412\u0441','\u041f\u043d','\u0412\u0442','\u0421\u0440','\u0427\u0442','\u041f\u0442','\u0421\u0431']);}else{__cov_VfNixH5rFGHdVHAfsTIltg.b['5'][1]++;}}}__cov_VfNixH5rFGHdVHAfsTIltg.s['17']++;calend.render();__cov_VfNixH5rFGHdVHAfsTIltg.s['18']++;var rules={'all':{'all':{'all':{'0,6':'all_weekends'}}}};__cov_VfNixH5rFGHdVHAfsTIltg.s['19']++;calend.set('customRenderer',{rules:rules,filterFunction:function(date,node,rules){__cov_VfNixH5rFGHdVHAfsTIltg.f['3']++;__cov_VfNixH5rFGHdVHAfsTIltg.s['20']++;if(Y.Array.indexOf(rules,'all_weekends')>=0){__cov_VfNixH5rFGHdVHAfsTIltg.b['6'][0]++;__cov_VfNixH5rFGHdVHAfsTIltg.s['21']++;node.addClass('redtext');}else{__cov_VfNixH5rFGHdVHAfsTIltg.b['6'][1]++;}}});__cov_VfNixH5rFGHdVHAfsTIltg.s['22']++;calend.set('headerRenderer',function(curDate){__cov_VfNixH5rFGHdVHAfsTIltg.f['4']++;__cov_VfNixH5rFGHdVHAfsTIltg.s['23']++;var ydate=Y.DataType.Date,output=ydate.format(curDate,{format:'%B %Y'})+' — '+ydate.format(ydate.addMonths(curDate,1),{format:'%B %Y'})+' — '+ydate.format(ydate.addMonths(curDate,2),{format:'%B %Y'});__cov_VfNixH5rFGHdVHAfsTIltg.s['24']++;return output;});__cov_VfNixH5rFGHdVHAfsTIltg.s['25']++;calend.on('selectionChange',function(ev){__cov_VfNixH5rFGHdVHAfsTIltg.f['5']++;__cov_VfNixH5rFGHdVHAfsTIltg.s['26']++;var dtdate=Y.DataType.Date;__cov_VfNixH5rFGHdVHAfsTIltg.s['27']++;var listdates='[{';__cov_VfNixH5rFGHdVHAfsTIltg.s['28']++;for(var i=0;i= 0) {
+ node.addClass("redtext");
+ }
+ }
+ });
+ // Set a custom header renderer with a callback function, which receives the current date and outputs a string.
+ calend.set("headerRenderer", function (curDate) {
+ var ydate = Y.DataType.Date,
+ output = ydate.format(curDate, {
+ format: "%B %Y"
+ }) + " — " + ydate.format(ydate.addMonths(curDate, 1), {
+ format: "%B %Y"
+ })+ " — " + ydate.format(ydate.addMonths(curDate, 2), {
+ format: "%B %Y"
+ });
+ return output;
+ });
+ // Listen to calendar's selectionChange event.
+ calend.on("selectionChange", function (ev) {
+ var dtdate = Y.DataType.Date;
+ var listdates = '[{';
+ // Collect dates from selection
+ for (var i = 0; i < ev.newSelection.length; i++) {
+ listdates += (i === 0 ? "" : ",") + '"'+ i +'":"'+ dtdate.format(ev.newSelection[i])+'"';
+ }
+ listdates += "}]";
+ //set dates to HTML control
+ Y.one(document.getElementsByName('getlistdates')[0]).set('value', listdates);
+ });
+ };
+
+}, '@VERSION@', {"requires": ["base", "calendar", "datatype-date", "datatype-date-format", "node", "intl"]});
diff --git a/yui/build/moodle-mod_scheduler-calpane/moodle-mod_scheduler-calpane-min.js b/yui/build/moodle-mod_scheduler-calpane/moodle-mod_scheduler-calpane-min.js
new file mode 100644
index 00000000..9363e877
--- /dev/null
+++ b/yui/build/moodle-mod_scheduler-calpane/moodle-mod_scheduler-calpane-min.js
@@ -0,0 +1 @@
+YUI.add("moodle-mod_scheduler-calpane",function(e,t){var n;M.mod_scheduler=M.mod_scheduler||{},n=M.mod_scheduler.calpane={},n.init=function(t){e.Intl.add("datatype-date-format","uk-UK",{A:["\u041d\u0435\u0434\u0456\u043b\u044f","\u041f\u043e\u043d\u0435\u0434\u0456\u043b\u043e\u043a","\u0412\u0456\u0432\u0442\u043e\u0440\u043a","\u0421\u0435\u0440\u0435\u0434\u0430","\u0427\u0435\u0442\u0432\u0435\u0440","\u041f'\u044f\u0442\u043d\u0438\u0446\u044f","\u0421\u0443\u0431\u043e\u0442\u0430"],B:["\u0421\u0456\u0447\u0435\u043d\u044c","\u041b\u044e\u0442\u0438\u0439","\u0411\u0435\u0440\u0435\u0437\u0435\u043d\u044c","\u041a\u0432\u0456\u0442\u0435\u043d\u044c","\u0422\u0440\u0430\u0432\u0435\u043d\u044c","\u0427\u0435\u0440\u0432\u0435\u043d\u044c","\u041b\u0438\u043f\u0435\u043d\u044c","\u0421\u0435\u0440\u043f\u0435\u043d\u044c","\u0412\u0435\u0440\u0435\u0441\u0435\u043d\u044c","\u0416\u043e\u0432\u0442\u0435\u043d\u044c","\u041b\u0438\u0441\u0442\u043e\u043f\u0430\u0434","\u0413\u0440\u0443\u0434\u0435\u043d\u044c"]}),e.Intl.add("datatype-date-format","ru-RU",{A:["\u0412\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435","\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a","\u0412\u0442\u043e\u0440\u043d\u0438\u043a","\u0421\u0440\u0435\u0434\u0430","\u0427\u0435\u0442\u0432\u0435\u0440\u0433","\u041f\u044f\u0442\u043d\u0438\u0446\u0430","\u0421\u0443\u0431\u0431\u043e\u0442\u0430"],B:["\u042f\u043d\u0432\u0430\u0440\u044c","\u0424\u0435\u0432\u0440\u0430\u043b\u044c","\u041c\u0430\u0440\u0442","\u0410\u043f\u0440\u0435\u043b\u044c","\u041c\u0430\u0439","\u0418\u044e\u043d\u044c","\u0418\u044e\u043b\u044c","\u0410\u0432\u0433\u0443\u0441\u0442","\u0421\u0435\u043d\u0442\u044f\u0431\u0440\u044c","\u041e\u043a\u0442\u044f\u0431\u0440\u044c","\u041d\u043e\u044f\u0431\u0440\u044c","\u0414\u0435\u043a\u0430\u0431\u0440\u044c"]}),e.CalendarBase.CONTENT_TEMPLATE=e.CalendarBase.THREE_PANE_TEMPLATE;var n=new e.Calendar({contentBox:"#calContainer",width:"760px",showPrevMonth:!0,showNextMonth:!0,selectionMode:"multiple-sticky",minimumDate:new Date,date:new Date});t===!1||t==="en"?e.Intl.setLang("datatype-date-format","en-US"):(e.Intl.setLang("datatype-date-format",t+"-"+t.toUpperCase()),t==="uk"?n.set("strings.very_short_weekdays",["\u041d\u0434","\u041f\u043d","\u0412\u0442","\u0421\u0440","\u0427\u0442","\u041f\u0442","\u0421\u0431"]):t==="ru"&&n.set("strings.very_short_weekdays",["\u0412\u0441","\u041f\u043d","\u0412\u0442","\u0421\u0440","\u0427\u0442","\u041f\u0442","\u0421\u0431"])),n.render();var r={all:{all:{all:{"0,6":"all_weekends"}}}};n.set("customRenderer",{rules:r,filterFunction:function(t,n,r){e.Array.indexOf(r,"all_weekends")>=0&&n.addClass("redtext")}}),n.set("headerRenderer",function(t){var n=e.DataType.Date,r=n.format(t,{format:"%B %Y"})+" — "+n.format(n.addMonths(t,1),{format:"%B %Y"})+" — "+n.format(n.addMonths(t,2),{format:"%B %Y"});return r}),n.on("selectionChange",function(t){var n=e.DataType.Date,r="[{";for(var i=0;i= 0) {
+ node.addClass("redtext");
+ }
+ }
+ });
+ // Set a custom header renderer with a callback function, which receives the current date and outputs a string.
+ calend.set("headerRenderer", function (curDate) {
+ var ydate = Y.DataType.Date,
+ output = ydate.format(curDate, {
+ format: "%B %Y"
+ }) + " — " + ydate.format(ydate.addMonths(curDate, 1), {
+ format: "%B %Y"
+ })+ " — " + ydate.format(ydate.addMonths(curDate, 2), {
+ format: "%B %Y"
+ });
+ return output;
+ });
+ // Listen to calendar's selectionChange event.
+ calend.on("selectionChange", function (ev) {
+ var dtdate = Y.DataType.Date;
+ var listdates = '[{';
+ // Collect dates from selection
+ for (var i = 0; i < ev.newSelection.length; i++) {
+ listdates += (i === 0 ? "" : ",") + '"'+ i +'":"'+ dtdate.format(ev.newSelection[i])+'"';
+ }
+ listdates += "}]";
+ //set dates to HTML control
+ Y.one(document.getElementsByName('getlistdates')[0]).set('value', listdates);
+ });
+ };
+
+}, '@VERSION@', {"requires": ["base", "calendar", "datatype-date", "datatype-date-format", "node", "intl"]});
diff --git a/yui/src/calpane/build.json b/yui/src/calpane/build.json
new file mode 100644
index 00000000..a791f4c5
--- /dev/null
+++ b/yui/src/calpane/build.json
@@ -0,0 +1,10 @@
+{
+ "name": "moodle-mod_scheduler-calpane",
+ "builds": {
+ "moodle-mod_scheduler-calpane": {
+ "jsfiles": [
+ "calpane.js"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/yui/src/calpane/js/calpane.js b/yui/src/calpane/js/calpane.js
new file mode 100644
index 00000000..26872def
--- /dev/null
+++ b/yui/src/calpane/js/calpane.js
@@ -0,0 +1,82 @@
+var MOD;
+
+M.mod_scheduler = M.mod_scheduler || {};
+MOD = M.mod_scheduler.calpane = {};
+
+MOD.init = function(langconf) {
+ Y.Intl.add("datatype-date-format", "uk-UK", {
+ "A":["Неділя","Понеділок","Вівторк","Середа","Четвер","П'ятниця","Субота"],
+ "B":["Січень","Лютий","Березень","Квітень","Травень","Червень","Липень","Серпень","Вересень","Жовтень","Листопад","Грудень"]
+ });
+ Y.Intl.add("datatype-date-format", "ru-RU", {
+ "A":["Воскресенье","Понедельник","Вторник","Среда","Четверг","Пятница","Суббота"],
+ "B":["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"]
+ });
+ Y.CalendarBase.CONTENT_TEMPLATE = Y.CalendarBase.THREE_PANE_TEMPLATE;
+ // Setup basic calendar parameters
+ var calend = new Y.Calendar({
+ contentBox: "#calContainer",
+ width:'760px',
+ showPrevMonth: true,
+ showNextMonth: true,
+ selectionMode: 'multiple-sticky',
+ minimumDate: new Date(),
+ date: new Date()});
+ //Set localization options
+ if (langconf === false || langconf === "en") {
+ Y.Intl.setLang("datatype-date-format", "en-US");
+ } else {
+ Y.Intl.setLang("datatype-date-format", langconf + "-" + langconf.toUpperCase());
+ //set additional calendar options for the Ukrainian and Russian
+ if (langconf === "uk") {
+ calend.set("strings.very_short_weekdays", ["Нд","Пн","Вт","Ср","Чт","Пт","Сб"]);
+ } else if (langconf === "ru") {
+ calend.set("strings.very_short_weekdays", ["Вс","Пн","Вт","Ср","Чт","Пт","Сб"]);
+ }
+ }
+ // Draw calendar instance
+ calend.render();
+ // Create a set of rules to match specific dates. In this case, the "all_weekends" rule will match any Saturday or Sunday.
+ var rules = {
+ "all": {
+ "all": {
+ "all": {
+ "0,6": "all_weekends"
+ }
+ }
+ }
+ };
+ // Set the calendar customRenderer, provides the rules defined above.
+ calend.set("customRenderer", {
+ rules: rules,
+ filterFunction: function (date, node, rules) {
+ if (Y.Array.indexOf(rules, 'all_weekends') >= 0) {
+ node.addClass("redtext");
+ }
+ }
+ });
+ // Set a custom header renderer with a callback function, which receives the current date and outputs a string.
+ calend.set("headerRenderer", function (curDate) {
+ var ydate = Y.DataType.Date,
+ output = ydate.format(curDate, {
+ format: "%B %Y"
+ }) + " — " + ydate.format(ydate.addMonths(curDate, 1), {
+ format: "%B %Y"
+ })+ " — " + ydate.format(ydate.addMonths(curDate, 2), {
+ format: "%B %Y"
+ });
+ return output;
+ });
+ // Listen to calendar's selectionChange event.
+ calend.on("selectionChange", function (ev) {
+ var dtdate = Y.DataType.Date;
+ var listdates = '[{';
+ // Collect dates from selection
+ for (var i = 0; i < ev.newSelection.length; i++) {
+ listdates += (i === 0 ? "" : ",") + '"'+ i +'":"'+ dtdate.format(ev.newSelection[i])+'"';
+ }
+ listdates += "}]";
+ //set dates to HTML control
+ Y.one(document.getElementsByName('getlistdates')[0]).set('value', listdates);
+ });
+ };
\ No newline at end of file
diff --git a/yui/src/calpane/meta/calpane.json b/yui/src/calpane/meta/calpane.json
new file mode 100644
index 00000000..651b5b7d
--- /dev/null
+++ b/yui/src/calpane/meta/calpane.json
@@ -0,0 +1,12 @@
+{
+ "moodle-mod_scheduler-calpane": {
+ "requires": [
+ "base",
+ "calendar",
+ "datatype-date",
+ "datatype-date-format",
+ "node",
+ "intl"
+ ]
+ }
+}
\ No newline at end of file