Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #15 from marinaglancy/wip-renderer-rubric

MDL-29481: implemented rubrics renderer, improved rubrics UI
  • Loading branch information...
commit 6477706e9c0e60b458ce8d553da98f144bdb0915 2 parents 8168299 + ab15674
@mudrd8mz mudrd8mz authored
View
12 grade/grading/form/lib.php
@@ -289,6 +289,18 @@ public function validate_grading_element($elementvalue, $itemid) {
return true;
}
+ /**
+ * Returns the renderer for the current plugin
+ *
+ * @param string $subtype optional subtype
+ * @param string $target one of rendering target constants
+ * @return renderer_base
+ */
+ public function get_renderer($subtype = null, $target = null) {
+ global $PAGE;
+ return $PAGE->get_renderer('gradingform_'. $this->get_method_name(), $subtype, $target);
+ }
+
////////////////////////////////////////////////////////////////////////////
View
5 grade/grading/form/rubric/js/rubric.js
@@ -6,6 +6,11 @@ M.gradingform_rubric = {};
M.gradingform_rubric.init = function(Y, options) {
Y.on('click', M.gradingform_rubric.levelclick, '#rubric-'+options.name+' .level', null, Y, options.name);
Y.all('#rubric-'+options.name+' .radio').setStyle('display', 'none')
+ Y.all('#rubric-'+options.name+' .level').each(function (node) {
+ if (node.one('input[type=radio][checked]')) {
+ node.addClass('checked');
+ }
+ });
};
M.gradingform_rubric.levelclick = function(e, Y, name) {
View
79 grade/grading/form/rubric/js/rubriceditor.js
@@ -8,13 +8,82 @@ M.gradingform_rubriceditor.init = function(Y, options) {
'criterion' : options.criteriontemplate,
'level' : options.leveltemplate
}
- M.gradingform_rubriceditor.addhandlers(Y, options.name);
+ M.gradingform_rubriceditor.disablealleditors(null, Y, options.name)
+ M.gradingform_rubriceditor.addhandlers(Y, options.name)
};
// Adds handlers for clicking submit button. This function must be called each time JS adds new elements to html
M.gradingform_rubriceditor.addhandlers = function(Y, name) {
if (M.gradingform_rubriceditor.eventhandler) M.gradingform_rubriceditor.eventhandler.detach()
- M.gradingform_rubriceditor.eventhandler = Y.on('click', M.gradingform_rubriceditor.buttonclick, '#rubriceditor-'+name+' input[type=submit]', null, Y, name);
+ M.gradingform_rubriceditor.eventhandler = Y.on('click', M.gradingform_rubriceditor.clickanywhere, 'body', null, Y, name);
+ M.gradingform_rubriceditor.eventhandler = Y.on('click', M.gradingform_rubriceditor.buttonclick, '#rubric-'+name+' input[type=submit]', null, Y, name);
+}
+
+M.gradingform_rubriceditor.disablealleditors = function(e, Y, name) {
+ Y.all('#rubric-'+name+' .level').each( function(node) {M.gradingform_rubriceditor.editmode(node, false)} );
+ Y.all('#rubric-'+name+' .description').each( function(node) {M.gradingform_rubriceditor.editmode(node, false)} );
+}
+
+M.gradingform_rubriceditor.clickanywhere = function(e, Y, name) {
+ var el = e.target
+ // if clicked on button - disablecurrenteditor, continue
+ if (el.get('tagName') == 'INPUT' && el.get('type') == 'submit') {
+ M.gradingform_rubriceditor.disablealleditors(null, Y, name)
+ return
+ }
+ // else if clicked on level and this level is not enabled - enable it
+ // or if clicked on description and this description is not enabled - enable it
+ while (el && !(el.hasClass('level') || el.hasClass('description'))) el = el.get('parentNode')
+ if (el) {
+ if (el.one('textarea').getStyle('display') == 'none') {
+ M.gradingform_rubriceditor.disablealleditors(null, Y, name)
+ M.gradingform_rubriceditor.editmode(el, true)
+ }
+ return
+ }
+ // else disablecurrenteditor
+ M.gradingform_rubriceditor.disablealleditors(null, Y, name)
+}
+
+M.gradingform_rubriceditor.editmode = function(el, editmode) {
+ var ta = el.one('textarea')
+ if (!ta.get('parentNode').one('.plainvalue')) {
+ ta.get('parentNode').append('<div class="plainvalue"></div>')
+ }
+ var tb = el.one('input[type=text]')
+ if (tb && !tb.get('parentNode').one('.plainvalue')) {
+ tb.get('parentNode').append('<div class="plainvalue"></div>')
+ }
+ if (!editmode) {
+ var value = ta.get('value')
+ if (value.length) ta.get('parentNode').one('.plainvalue').removeClass('empty')
+ else {
+ value = (el.hasClass('level')) ? M.str.gradingform_rubric.levelempty : M.str.gradingform_rubric.criterionempty
+ ta.get('parentNode').one('.plainvalue').addClass('empty')
+ }
+ ta.get('parentNode').one('.plainvalue').set('innerHTML', value)
+ ta.get('parentNode').one('.plainvalue').setStyle('display', 'block')
+ ta.setStyle('display', 'none')
+ if (tb) {
+ tb.get('parentNode').one('.plainvalue').set('innerHTML', tb.get('value'))
+ tb.get('parentNode').one('.plainvalue').setStyle('display', 'inline-block')
+ tb.setStyle('display', 'none')
+ }
+ } else {
+ if (tb) {
+ tb.get('parentNode').one('.plainvalue').setStyle('display', 'none')
+ tb.setStyle('display', 'inline-block')
+ }
+ var width = ta.get('parentNode').getComputedStyle('width') // TODO min width
+ var height = ta.get('parentNode').getComputedStyle('height') // TODO min height
+ if (el.hasClass('level')) {
+ height = el.getComputedStyle('height') - el.one('.score').getComputedStyle('height')
+ } else if (el.hasClass('description')) {
+ height = el.get('parentNode').getComputedStyle('height')
+ }
+ ta.get('parentNode').one('.plainvalue').setStyle('display', 'none')
+ ta.setStyle('display', 'block').setStyle('width', width).setStyle('height', height)
+ }
}
// handler for clicking on submit buttons within rubriceditor element. Adds/deletes/rearranges criteria and/or levels on client side
@@ -25,9 +94,9 @@ M.gradingform_rubriceditor.buttonclick = function(e, Y, name, confirmed) {
if (chunks[0] != name) return;
var elements_str
if (chunks.length>3 || action == 'addlevel') {
- elements_str = '#rubriceditor-'+name+' #'+name+'-'+chunks[1]+'-levels .level'
+ elements_str = '#rubric-'+name+' #'+name+'-'+chunks[1]+'-levels .level'
} else {
- elements_str = '#rubriceditor-'+name+' .criterion'
+ elements_str = '#rubric-'+name+' .criterion'
}
// prepare the id of the next inserted level or criterion
var newid = 1
@@ -48,7 +117,7 @@ M.gradingform_rubriceditor.buttonclick = function(e, Y, name, confirmed) {
replace(/\{CRITERION-id\}/g, 'NEWID'+newid).replace(/\{.+?\}/g, '')
Y.one('#'+name+'-criteria').append(newcriterion)
M.gradingform_rubriceditor.addhandlers(Y, name);
- } else if (chunks.length == 3 && action == 'addlevel') {
+ } else if (chunks.length == 4 && action == 'addlevel') {
// ADD NEW LEVEL
var newlevel = M.gradingform_rubriceditor.templates[name]['level'].
replace(/\{CRITERION-id\}/g, chunks[1]).replace(/\{LEVEL-id\}/g, 'NEWID'+newid).replace(/\{.+?\}/g, '')
View
11 grade/grading/form/rubric/lang/en/gradingform_rubric.php
@@ -33,9 +33,12 @@
$string['name'] = 'Name';
$string['addcriterion'] = 'Add criterion';
-$string['criterionmoveup'] = 'Up';
-$string['criteriondelete'] = 'Delete';
-$string['criterionmovedown'] = 'Down';
+$string['criterionmoveup'] = 'Move up';
+$string['criteriondelete'] = 'Delete criterion';
+$string['criterionmovedown'] = 'Move down';
$string['criterionaddlevel'] = 'Add level';
$string['scorepostfix'] = ' pts';
-$string['leveldelete'] = 'Del';
+$string['leveldelete'] = 'Delete level';
+
+$string['criterionempty'] = 'Click to edit criterion';
+$string['levelempty'] = 'Click to edit level';
View
33 grade/grading/form/rubric/lib.php
@@ -32,6 +32,13 @@
* This controller encapsulates the rubric grading logic
*/
class gradingform_rubric_controller extends gradingform_controller {
+ // Modes of displaying the rubric (used in gradingform_rubric_renderer)
+ const DISPLAY_EDIT_FULL = 1; // For editing (moderator or teacher creates a rubric)
+ const DISPLAY_EDIT_FROZEN = 2; // Preview the rubric design with hidden fields
+ const DISPLAY_PREVIEW = 3; // Preview the rubric design
+ const DISPLAY_EVAL = 4; // For evaluation, enabled (teacher grades a student)
+ const DISPLAY_EVAL_FROZEN = 5; // For evaluation, with hidden fields
+ const DISPLAY_REVIEW = 6; // Dispaly filled rubric (i.e. students see their grades)
/**
* Extends the module settings navigation with the rubric grading settings
@@ -307,6 +314,32 @@ public function save_and_get_grade($raterid, $itemid, $formdata) {
*/
public function to_html($gradingformelement) {
global $PAGE, $USER;
+ if (!$gradingformelement->_flagFrozen) {
+ $module = array('name'=>'gradingform_rubric', 'fullpath'=>'/grade/grading/form/rubric/js/rubric.js');
+ $PAGE->requires->js_init_call('M.gradingform_rubric.init', array(array('name' => $gradingformelement->getName(), 'criteriontemplate' =>'', 'leveltemplate' => '')), true, $module);
+ $mode = self::DISPLAY_EVAL;
+ } else {
+ if ($this->_persistantFreeze) {
+ $mode = gradingform_rubric_controller::DISPLAY_EVAL_FROZEN;
+ } else {
+ $mode = gradingform_rubric_controller::DISPLAY_REVIEW;
+ }
+ }
+ $criteria = $this->definition->rubric_criteria;
+ $submissionid = $gradingformelement->get_grading_attribute('submissionid');
+ $raterid = $USER->id; // TODO - this is very strange!
+ $value = $gradingformelement->getValue();
+ if ($value === null) {
+ $value = $this->get_grading($raterid, $submissionid); // TODO maybe implement in form->set_data() ?
+ }
+ return $this->get_renderer()->display_rubric($criteria, $mode, $gradingformelement->getName(), $value);
+ }
+
+ /**
+ * Returns html for form element
+ */
+ public function to_html_old($gradingformelement) {
+ global $PAGE, $USER;
//TODO move to renderer
//$gradingrenderer = $this->prepare_renderer($PAGE);
View
186 grade/grading/form/rubric/renderer.php
@@ -28,7 +28,7 @@
/**
* Grading method plugin renderer
*/
-class gradingform_rubric_renderer extends gradingform_renderer {
+class gradingform_rubric_renderer {
/**
* Renders grading widget
@@ -43,4 +43,188 @@ protected function render_gradingform_rubric_widget(gradingform_rubric_widget $w
return $this->output->container($button.$span, 'gradingform_rubric-widget-wrapper', 1);
}
+
+ /**
+ *
+ * @param int $mode @see gradingform_rubric_controller
+ * @return string
+ */
+ public function criterion_template($mode, $elementname = '{NAME}', $criterion = null, $levels_str = '{LEVELS}') {
+ // TODO description format
+ if ($criterion === null || !is_array($criterion) || !array_key_exists('id', $criterion)) {
+ $criterion = array('id' => '{CRITERION-id}', 'description' => '{CRITERION-description}', 'sortorder' => '{CRITERION-sortorder}', 'class' => '{CRITERION-class}');
+ } else {
+ foreach (array('sortorder', 'description', 'class') as $key) {
+ // set missing array elements to empty strings to avoid warnings
+ if (!array_key_exists($key, $criterion)) {
+ $criterion[$key] = '';
+ }
+ }
+ }
+ $criterion_template = html_writer::start_tag('div', array('class' => 'clearfix criterion'. $criterion['class'], 'id' => '{NAME}-{CRITERION-id}'));
+ if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) {
+ $criterion_template .= html_writer::start_tag('div', array('class' => 'controls'));
+ foreach (array('moveup', 'delete', 'movedown') as $key) {
+ $value = get_string('criterion'.$key, 'gradingform_rubric');
+ $button = html_writer::empty_tag('input', array('type' => 'submit', 'name' => '{NAME}[{CRITERION-id}]['.$key.']',
+ 'id' => '{NAME}-{CRITERION-id}-'.$key, 'value' => $value, 'title' => $value));
+ $criterion_template .= html_writer::tag('div', $button, array('class' => $key));
+ }
+ $criterion_template .= html_writer::end_tag('div'); // .controls
+ $criterion_template .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[{CRITERION-id}][sortorder]', 'value' => $criterion['sortorder']));
+ $description = html_writer::tag('textarea', htmlspecialchars($criterion['description']), array('name' => '{NAME}[{CRITERION-id}][description]', 'cols' => '10', 'rows' => '5'));
+ } else {
+ if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FROZEN) {
+ $criterion_template .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[{CRITERION-id}][sortorder]', 'value' => $criterion['sortorder']));
+ $criterion_template .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[{CRITERION-id}][description]', 'value' => $criterion['description']));
+ }
+ $description = $criterion['description'];
+ }
+ $criterion_template .= html_writer::tag('div', $description, array('class' => 'description', 'id' => '{NAME}-{CRITERION-id}-description'));
+ $criterion_template .= html_writer::tag('div', $levels_str, array('class' => 'clearfix levels', 'id' => '{NAME}-{CRITERION-id}-levels'));
+ if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) {
+ $value = get_string('criterionaddlevel', 'gradingform_rubric');
+ $button = html_writer::empty_tag('input', array('type' => 'submit', 'name' => '{NAME}[{CRITERION-id}][levels][addlevel]',
+ 'id' => '{NAME}-{CRITERION-id}-levels-addlevel', 'value' => $value, 'title' => $value)); //TODO '{NAME}-{CRITERION-id}-levels-addlevel
+ $criterion_template .= html_writer::tag('div', $button, array('class' => 'addlevel'));
+ }
+ $criterion_template .= html_writer::end_tag('div'); // .criterion
+
+ $criterion_template = str_replace('{NAME}', $elementname, $criterion_template);
+ $criterion_template = str_replace('{CRITERION-id}', $criterion['id'], $criterion_template);
+ return $criterion_template;
+ }
+
+ public function level_template($mode, $elementname = '{NAME}', $criterionid = '{CRITERION-id}', $level = null) {
+ // TODO definition format
+ if ($level === null || !is_array($level) || !array_key_exists('id', $level)) {
+ $level = array('id' => '{LEVEL-id}', 'definition' => '{LEVEL-definition}', 'score' => '{LEVEL-score}', 'class' => '{LEVEL-class}', 'checked' => false);
+ } else {
+ foreach (array('score', 'definition', 'class', 'checked') as $key) {
+ // set missing array elements to empty strings to avoid warnings
+ if (!array_key_exists($key, $level)) {
+ $level[$key] = '';
+ }
+ }
+ }
+
+ // Template for one level within one criterion
+ $level_template = html_writer::start_tag('div', array('id' => '{NAME}-{CRITERION-id}-levels-{LEVEL-id}', 'class' => 'clearfix level'. $level['class']));
+ if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) {
+ $definition = html_writer::tag('textarea', htmlspecialchars($level['definition']), array('name' => '{NAME}[{CRITERION-id}][levels][{LEVEL-id}][definition]', 'cols' => '10', 'rows' => '4'));
+ $score = html_writer::empty_tag('input', array('type' => 'text', 'name' => '{NAME}[{CRITERION-id}][levels][{LEVEL-id}][score]', 'size' => '4', 'value' => $level['score']));
+ } else {
+ if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FROZEN) {
+ $level_template .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[{CRITERION-id}][levels][{LEVEL-id}][definition]', 'value' => $level['definition']));
+ $level_template .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[{CRITERION-id}][levels][{LEVEL-id}][score]', 'value' => $level['score']));
+ }
+ $definition = $level['definition'];
+ $score = $level['score'];
+ }
+ if ($mode == gradingform_rubric_controller::DISPLAY_EVAL) {
+ $input = html_writer::empty_tag('input', array('type' => 'radio', 'name' => '{NAME}[{CRITERION-id}]', 'value' => $level['id']) +
+ ($level['checked'] ? array('checked' => 'checked') : array()));
+ $level_template .= html_writer::tag('div', $input, array('class' => 'radio'));
+ }
+ if ($mode == gradingform_rubric_controller::DISPLAY_EVAL_FROZEN && $level['checked']) {
+ $html .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[{CRITERION-id}]', 'value' => $level['id']));
+ }
+ $score = html_writer::tag('span', $score, array('id' => '{NAME}-{CRITERION-id}-levels-{LEVEL-id}-score'));
+ $level_template .= html_writer::tag('div', $definition, array('class' => 'definition', 'id' => '{NAME}-{CRITERION-id}-levels-{LEVEL-id}-definition'));
+ $level_template .= html_writer::tag('div', $score. get_string('scorepostfix', 'gradingform_rubric'), array('class' => 'score'));
+ if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) {
+ $value = get_string('leveldelete', 'gradingform_rubric');
+ $button = html_writer::empty_tag('input', array('type' => 'submit', 'name' => '{NAME}[{CRITERION-id}][levels][{LEVEL-id}][delete]', 'id' => '{NAME}-{CRITERION-id}-levels-{LEVEL-id}-delete', 'value' => $value, 'title' => $value));
+ $level_template .= html_writer::tag('div', $button, array('class' => 'delete'));
+ }
+ $level_template .= html_writer::end_tag('div'); // .level
+
+ $level_template = str_replace('{NAME}', $elementname, $level_template);
+ $level_template = str_replace('{CRITERION-id}', $criterionid, $level_template);
+ $level_template = str_replace('{LEVEL-id}', $level['id'], $level_template);
+ return $level_template;
+ }
+
+ protected function rubric_template($mode, $elementname = '{NAME}', $criteria_str = '{CRITERIA}') {
+ $classsuffix = ''; // CSS suffix for class of the main div. Depends on the mode
+ switch ($mode) {
+ case gradingform_rubric_controller::DISPLAY_EDIT_FULL:
+ $classsuffix = ' editor editable'; break;
+ case gradingform_rubric_controller::DISPLAY_EDIT_FROZEN:
+ $classsuffix = ' editor frozen'; break;
+ case gradingform_rubric_controller::DISPLAY_PREVIEW:
+ $classsuffix = ' editor preview'; break;
+ case gradingform_rubric_controller::DISPLAY_EVAL:
+ $classsuffix = ' evaluate editable'; break;
+ case gradingform_rubric_controller::DISPLAY_EVAL_FROZEN:
+ $classsuffix = ' evaluate frozen'; break;
+ case gradingform_rubric_controller::DISPLAY_REVIEW:
+ $classsuffix = ' review'; break;
+ }
+
+ $rubric_template = html_writer::start_tag('div', array('id' => 'rubric-{NAME}', 'class' => 'clearfix form_rubric'.$classsuffix));
+ $rubric_template .= html_writer::tag('div', $criteria_str, array('class' => 'criteria', 'id' => '{NAME}-criteria'));
+ if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) {
+ $value = get_string('addcriterion', 'gradingform_rubric');
+ $input = html_writer::empty_tag('input', array('type' => 'submit', 'name' => '{NAME}[addcriterion]', 'id' => '{NAME}-addcriterion', 'value' => $value, 'title' => $value));
+ $rubric_template .= html_writer::tag('div', $input, array('class' => 'addcriterion'));
+ }
+ $rubric_template .= html_writer::end_tag('div');
+
+ return str_replace('{NAME}', $elementname, $rubric_template);
+ }
+
+ /**
+ * Returns html code for displaying the rubric in the specified mode
+ *
+ * @param array $criteria
+ * @param int $mode
+ * @param string $elementname
+ * @param array $values
+ * @return string
+ */
+ public function display_rubric($criteria, $mode, $elementname = null, $values = null) {
+ $criteria_str = '';
+ $cnt = 0;
+ foreach ($criteria as $id => $criterion) {
+ $criterion['class'] = $this->get_css_class_suffix($cnt++, sizeof($criteria) -1);
+ $levels_str = '';
+ $levelcnt = 0;
+ foreach ($criterion['levels'] as $levelid => $level) {
+ $level['score'] = (float)$level['score']; // otherwise the display will look like 1.00000
+ $level['class'] = $this->get_css_class_suffix($levelcnt++, sizeof($criterion['levels']) -1);
+ $level['checked'] = (is_array($values) && (array_key_exists($id, $values) && ((int)$values[$id] === $levelid)));
+ if ($level['checked'] && ($mode == gradingform_rubric_controller::DISPLAY_EVAL_FROZEN || $mode == gradingform_rubric_controller::DISPLAY_REVIEW)) {
+ $level['class'] .= ' checked';
+ //in mode DISPLAY_EVAL the class 'checked' will be added by JS if it is enabled. If it is not enabled, the 'checked' class will only confuse
+ }
+ $levels_str .= $this->level_template($mode, $elementname, $id, $level);
+ }
+ $criteria_str .= $this->criterion_template($mode, $elementname, $criterion, $levels_str);
+ }
+ return $this->rubric_template($mode, $elementname, $criteria_str);
+ }
+
+ /**
+ * Help function to return CSS class names for element (first/last/even/odd)
+ *
+ * @param <type> $cnt
+ * @param <type> $maxcnt
+ * @return string
+ */
+ private function get_css_class_suffix($cnt, $maxcnt) {
+ $class = '';
+ if ($cnt == 0) {
+ $class .= ' first';
+ }
+ if ($cnt == $maxcnt) {
+ $class .= ' last';
+ }
+ if ($cnt%2) {
+ $class .= ' odd';
+ } else {
+ $class .= ' even';
+ }
+ return $class;
+ }
}
View
120 grade/grading/form/rubric/rubriceditor.php
@@ -49,118 +49,30 @@ function getElementTemplateType() {
function toHtml() {
global $PAGE;
$html = $this->_getTabs();
-
- // Template for the whole rubric editor
- $classsuffix = $this->_flagFrozen ? 'frozen' : 'editable';
- $rubric_template = html_writer::start_tag('div', array('id' => 'rubriceditor-{NAME}', 'class' => 'clearfix form_rubric editor '.$classsuffix));
- $rubric_template .= html_writer::tag('div', '{CRITERIA}', array('class' => 'criteria', 'id' => '{NAME}-criteria'));
- if (!$this->_flagFrozen) {
- $rubric_template .= html_writer::empty_tag('input', array('type' => 'submit', 'name' => '{NAME}[addcriterion]', 'id' => '{NAME}-addcriterion', 'value' => get_string('addcriterion', 'gradingform_rubric')));
- }
- $rubric_template .= html_writer::end_tag('div');
-
- // Template for one criterion
- $criterion_template = html_writer::start_tag('div', array('class' => 'clearfix criterion{CRITERION-class}', 'id' => '{NAME}-{CRITERION-id}'));
- if (!$this->_flagFrozen) {
- $criterion_template .= html_writer::start_tag('div', array('class' => 'controls'));
- foreach (array('moveup', 'delete', 'movedown') as $key) {
- $button = html_writer::empty_tag('input', array('type' => 'submit', 'name' => '{NAME}[{CRITERION-id}]['.$key.']',
- 'id' => '{NAME}-{CRITERION-id}-'.$key, 'value' => get_string('criterion'.$key, 'gradingform_rubric')));
- $criterion_template .= html_writer::tag('div', $button, array('class' => $key));
- }
- $criterion_template .= html_writer::end_tag('div'); // .controls
- $criterion_template .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[{CRITERION-id}][sortorder]', 'value' => '{CRITERION-sortorder}'));
- $description = html_writer::tag('textarea', '{CRITERION-description}', array('name' => '{NAME}[{CRITERION-id}][description]', 'cols' => '10', 'rows' => '5'));
- } else {
- if ($this->_persistantFreeze) {
- $criterion_template .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[{CRITERION-id}][sortorder]', 'value' => '{CRITERION-sortorder}'));
- $criterion_template .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[{CRITERION-id}][description]', 'value' => '{CRITERION-description}'));
- }
- $description = '{CRITERION-description}';
- }
- $criterion_template .= html_writer::tag('div', $description, array('class' => 'description', 'id' => '{NAME}-{CRITERION-id}-description'));
- $criterion_template .= html_writer::tag('div', '{LEVELS}', array('class' => 'levels', 'id' => '{NAME}-{CRITERION-id}-levels'));
- if (!$this->_flagFrozen) {
- $button = html_writer::empty_tag('input', array('type' => 'submit', 'name' => '{NAME}[{CRITERION-id}][levels][addlevel]',
- 'id' => '{NAME}-{CRITERION-id}-addlevel', 'value' => get_string('criterionaddlevel', 'gradingform_rubric'))); //TODO '{NAME}-{CRITERION-id}-levels-addlevel
- $criterion_template .= html_writer::tag('div', $button, array('class' => 'addlevel'));
- }
- $criterion_template .= html_writer::end_tag('div'); // .criterion
-
- // Template for one level within one criterion
- $level_template = html_writer::start_tag('div', array('id' => '{NAME}-{CRITERION-id}-levels-{LEVEL-id}', 'class' => 'level{LEVEL-class}'));
+ $renderer = $PAGE->get_renderer('gradingform_rubric');
if (!$this->_flagFrozen) {
- $definition = html_writer::tag('textarea', '{LEVEL-definition}', array('name' => '{NAME}[{CRITERION-id}][levels][{LEVEL-id}][definition]', 'cols' => '10', 'rows' => '4'));
- $score = html_writer::empty_tag('input', array('type' => 'text', 'name' => '{NAME}[{CRITERION-id}][levels][{LEVEL-id}][score]', 'size' => '4', 'value' => '{LEVEL-score}'));
+ $mode = gradingform_rubric_controller::DISPLAY_EDIT_FULL;
+ $module = array('name'=>'gradingform_rubriceditor', 'fullpath'=>'/grade/grading/form/rubric/js/rubriceditor.js',
+ 'strings' => array(array('confirmdeletecriterion', 'gradingform_rubric'), array('confirmdeletelevel', 'gradingform_rubric'),
+ array('criterionempty', 'gradingform_rubric'), array('levelempty', 'gradingform_rubric')
+ ));
+ $PAGE->requires->js_init_call('M.gradingform_rubriceditor.init', array(
+ array('name' => $this->getName(),
+ 'criteriontemplate' => $renderer->criterion_template($mode, $this->getName()),
+ 'leveltemplate' => $renderer->level_template($mode, $this->getName())
+ )),
+ true, $module);
} else {
if ($this->_persistantFreeze) {
- $level_template .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[{CRITERION-id}][levels][{LEVEL-id}][definition]', 'value' => '{LEVEL-definition}'));
- $level_template .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[{CRITERION-id}][levels][{LEVEL-id}][score]', 'value' => '{LEVEL-score}'));
- }
- $definition = '{LEVEL-definition}';
- $score = '{LEVEL-score}';
- }
- $score = html_writer::tag('span', $score, array('id' => '{NAME}-{CRITERION-id}-levels-{LEVEL-id}-score'));
- $level_template .= html_writer::tag('div', $definition, array('class' => 'definition', 'id' => '{NAME}-{CRITERION-id}-levels-{LEVEL-id}-definition'));
- $level_template .= html_writer::tag('div', $score. get_string('scorepostfix', 'gradingform_rubric'), array('class' => 'score'));
- if (!$this->_flagFrozen) {
- $button = html_writer::empty_tag('input', array('type' => 'submit', 'name' => '{NAME}[{CRITERION-id}][levels][{LEVEL-id}][delete]', 'id' => '{NAME}-{CRITERION-id}-levels-{LEVEL-id}-delete', 'value' => get_string('leveldelete', 'gradingform_rubric')));
- $level_template .= html_writer::tag('div', $button, array('class' => 'delete'));
- }
- $level_template .= html_writer::end_tag('div'); // .level
-
- $criterion_template = str_replace('{NAME}', $this->getName(), $criterion_template);
- $level_template = str_replace('{NAME}', $this->getName(), $level_template);
- $rubric_template = str_replace('{NAME}', $this->getName(), $rubric_template);
-
- if (!$this->_flagFrozen) {
- $module = array('name'=>'gradingform_rubriceditor', 'fullpath'=>'/grade/grading/form/rubric/js/rubriceditor.js',
- 'strings' => array(array('confirmdeletecriterion', 'gradingform_rubric'), array('confirmdeletelevel', 'gradingform_rubric')));
- $PAGE->requires->js_init_call('M.gradingform_rubriceditor.init', array(array('name' => $this->getName(), 'criteriontemplate' => $criterion_template, 'leveltemplate' => $level_template)), true, $module);
- }
- $rubric_html = $rubric_template;
- $criteria = $this->prepare_non_js_data();
- $cnt = 0;
- foreach ($criteria as $id => $criterion) {
- $criterion_html = $criterion_template;
- $levelcnt = 0;
- foreach ($criterion['levels'] as $levelid => $level) {
- $cell_html = $level_template;
- $cell_html = str_replace('{LEVEL-id}', $levelid, $cell_html);
- $cell_html = str_replace('{LEVEL-definition}', htmlspecialchars($level['definition']), $cell_html);
- $cell_html = str_replace('{LEVEL-score}', htmlspecialchars($level['score']), $cell_html);
- $cell_html = str_replace('{LEVEL-class}', $this->get_css_class_suffix($levelcnt++, sizeof($criterion['levels']) -1), $cell_html);
- $criterion_html = str_replace('{LEVELS}', $cell_html.'{LEVELS}', $criterion_html);
+ $mode = gradingform_rubric_controller::DISPLAY_EDIT_FROZEN;
+ } else {
+ $mode = gradingform_rubric_controller::DISPLAY_PREVIEW;
}
- $criterion_html = str_replace('{LEVELS}', '', $criterion_html);
- $criterion_html = str_replace('{CRITERION-id}', $id, $criterion_html);
- $criterion_html = str_replace('{CRITERION-description}', htmlspecialchars($criterion['description']), $criterion_html);
- $criterion_html = str_replace('{CRITERION-sortorder}', htmlspecialchars($criterion['sortorder']), $criterion_html);
- $criterion_html = str_replace('{CRITERION-class}', $this->get_css_class_suffix($cnt++, sizeof($criteria) -1), $criterion_html);
- $rubric_html = str_replace('{CRITERIA}', $criterion_html.'{CRITERIA}', $rubric_html);
}
- $rubric_html = str_replace('{CRITERIA}', '', $rubric_html);
- $html .= $rubric_html;
-
+ $html .= $renderer->display_rubric($this->prepare_non_js_data(), $mode, $this->getName());
return $html;
}
- function get_css_class_suffix($cnt, $maxcnt) {
- $class = '';
- if ($cnt == 0) {
- $class .= ' first';
- }
- if ($cnt == $maxcnt) {
- $class .= ' last';
- }
- if ($cnt%2) {
- $class .= ' odd';
- } else {
- $class .= ' even';
- }
- return $class;
- }
-
function prepare_non_js_data() {
$return = array();
$criteria = $this->getValue();
View
69 grade/grading/form/rubric/styles.css
@@ -9,28 +9,30 @@
.movedown
[input type=submit]
.description
- .levels
- .level[.first][.last].odd/even
- .definition
- [textarea]
- .score
- span
- [input type=text]
- .delete
- [input type=submit]
- .addlevel
- [input type=submit]
+ .levels
+ .level[.first][.last].odd/even
+ .definition
+ [textarea]
+ .score
+ span
+ [input type=text]
+ .delete
+ [input type=submit]
+ .addlevel
+ [input type=submit]
.addcriterion
[input type=submit]
.form_rubric.evaluate
.criterion[.first][.last].odd/even
.description
- .levels
- .level[.first][.last].odd/even
- .definition
- .score
- span
+ .levels
+ .level[.first][.last].odd/even
+ .radio
+ input
+ .definition
+ .score
+ span
*/
@@ -39,23 +41,30 @@
.form_rubric .criterion .description,
.form_rubric .criterion .levels,
.form_rubric.editor .criterion .addlevel,
-.form_rubric .criterion .levels .level {display: inline-block; vertical-align: top;}
+.form_rubric .criterion .levels .level {display: inline-block; vertical-align: top;overflow: hidden;}
.form_rubric.editor .criterion .controls,
.form_rubric .criterion .description,
.form_rubric.editor .criterion .addlevel,
-.form_rubric .criterion .levels .level {padding:3px}
+.form_rubric .criterion .levels .level {padding:3px;}
+
+/* Those divs should extend vertically and fill 100% of parent element height */
+.form_rubric .criterion .levels .level,
+.form_rubric .criterion .description,
+.form_rubric .criterion .levels {padding-bottom: 32767px;margin-bottom: -32767px;}
-.form_rubric .criterion {border:1px solid #DDD;}
+.form_rubric .criterion {border:1px solid #DDD;overflow: hidden;}
.form_rubric .criterion.even {background:#F0F0F0;}
-.form_rubric .criterion .description {min-width:100px;font-weight:bold;}
+.form_rubric .criterion .description {width:150px;font-weight:bold;}
-.form_rubric .criterion .levels .level {border-left:1px solid #DDD;min-width:80px;}
+.form_rubric .criterion .levels .level {border-left:1px solid #DDD;min-width:80px;max-width:150px;position:relative;}
.form_rubric .criterion .levels .level.last {border-right:1px solid #DDD;}
-.form_rubric .criterion .levels .level .score {display:inline-block;}
-.form_rubric.editor .criterion .levels .level .delete {display:inline-block; padding-left: 5px;}
+.form_rubric .plainvalue.empty {font-style: italic; color: #AAA;}
+
+.form_rubric.editor .criterion .levels .level .delete {position:absolute;right:0px;bottom:32767px;}
+.form_rubric .criterion .levels .level .score {display:block;}
/* Make invisible the buttons 'Move up' for the first criterion and 'Move down' for the last, because those buttons will make no change */
.form_rubric.editor .criterion.first .controls .moveup input,
@@ -64,3 +73,17 @@
/* evaluation */
.form_rubric.evaluate .criterion .levels .level.checked {background:#d0ffd0;}
.form_rubric.evaluate .criterion .levels .level:hover {background:#30ff30;}
+
+/* replace buttons with images */
+.form_rubric.editor .delete input,
+.form_rubric.editor .moveup input,
+.form_rubric.editor .movedown input{text-indent: -1000em;cursor:pointer;border:none;}
+.form_rubric.editor .criterion .controls .delete input {width:20px;height:16px;background: transparent url([[pix:i/cross_red_big]]) no-repeat center top;}
+.form_rubric.editor .levels .level .delete input {width:20px;height:16px;background: transparent url([[pix:i/cross_red_small]]) no-repeat center top;}
+.form_rubric.editor .moveup input {width:20px;height:15px;background: transparent url([[pix:t/up]]) no-repeat center top;margin-top:4px;}
+.form_rubric.editor .movedown input {width:20px;height:15px;background: transparent url([[pix:t/down]]) no-repeat center top;margin-top:4px;}
+
+.form_rubric.editor .addcriterion input,
+.form_rubric.editor .addlevel input {background: transparent url([[pix:t/addgreen]]) no-repeat;display:block;color:#555555;font-weight:bold;text-decoration:none;}
+.form_rubric.editor .addcriterion input {background-position: 5px 8px;height:30px;line-height:29px;margin-bottom:14px;padding-left:20px;padding-right:10px;}
+.form_rubric.editor .addlevel input {background-position: 5px 6px;height:25px;line-height:24px;margin-bottom:10px;padding-left:18px;padding-right:8px;}
Please sign in to comment.
Something went wrong with that request. Please try again.