MDL-5583 mod_data: Improve required fields

Fix accidental <tr> in some field modify screens
Update mod_data version
Change required asterisk to image
Improve required error message
Fix required icon positions
Remove required code from date field
Add name in labels for fields
Add required field option for multimenu
Remove old required field title text modifier
Add multimenu to behat
Add more comprehensive behat tests
Reload old input when an input error occurs
Behat grammar fixes
Allow location of 0, 0
Use html_writer
Fix existing mod_data behat tests
This commit is contained in:
John Okely 2015-02-17 13:30:45 +08:00
parent b89cca197e
commit 1c3b2058c8
27 changed files with 303 additions and 169 deletions

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="mod/data/db" VERSION="20141001" COMMENT="XMLDB file for Moodle mod/data"
<XMLDB PATH="mod/data/db" VERSION="20150205" COMMENT="XMLDB file for Moodle mod/data"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
>
@ -54,7 +54,7 @@
<FIELD NAME="type" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="description" TYPE="text" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="required" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Private fields are only visible or editable by users with additional capabilities"/>
<FIELD NAME="required" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Required fields must have a value when inserted by a user"/>
<FIELD NAME="param1" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="param2" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="param3" TYPE="text" NOTNULL="false" SEQUENCE="false"/>

View File

@ -133,7 +133,11 @@ function xmldb_data_upgrade($oldversion) {
// Moodle v2.7.0 release upgrade line.
// Put any upgrade step following this.
if ($oldversion < 2014051201) {
// Moodle v2.8.0 release upgrade line.
// Put any upgrade step following this.
if ($oldversion < 2015022600) {
// Define field required to be added to data_fields.
$table = new xmldb_table('data_fields');
$field = new xmldb_field('required', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'description');
@ -143,11 +147,8 @@ function xmldb_data_upgrade($oldversion) {
$dbman->add_field($table, $field);
}
upgrade_mod_savepoint(true, 2014051201, 'data');
upgrade_mod_savepoint(true, 2015022600, 'data');
}
// Moodle v2.8.0 release upgrade line.
// Put any upgrade step following this.
return true;
}

View File

@ -330,7 +330,7 @@ if ($data->addtemplate){
$errors .= $OUTPUT->notification($notification);
}
}
$replacements[] = $errors . $field->display_add_field($rid);
$replacements[] = $errors . $field->display_add_field($rid, $datarecord);
}
// Replace the field id tag.

View File

@ -266,11 +266,11 @@ if (($mode == 'new') && (!empty($newtype)) && confirm_sesskey()) { ///
$table = new html_table();
$table->head = array(
get_string('fieldname','data'),
get_string('fieldname', 'data'),
get_string('type', 'data'),
get_string('required', 'data'),
get_string('fielddescription', 'data'),
get_string('action','data'),
get_string('action', 'data'),
);
$table->align = array('left','left','left', 'center');
$table->wrap = array(false,false,false,false);

View File

@ -27,7 +27,7 @@ class data_field_checkbox extends data_field_base {
var $type = 'checkbox';
function display_add_field($recordid = 0, $formdata = null) {
global $CFG, $DB;
global $CFG, $DB, $OUTPUT;
$content = array();
@ -41,13 +41,18 @@ class data_field_checkbox extends data_field_base {
$content = array();
}
$str = '';
$str = '<div title="' . s($this->field->description) . '">';
$str .= '<fieldset><legend><span class="accesshide">'.$this->field->name;
if ($this->field->required) {
$str .= '<div title="' . get_string('requiredfieldhint', 'data', s($this->field->description)) . '">';
$str .= '$nbsp;' . get_string('requiredelement', 'form');
$str .= '</span></legend>';
$str .= '<div>';
$str .= html_writer::img($OUTPUT->pix_url('req'), get_string('requiredelement', 'form'),
array('class' => 'req', 'title' => get_string('requiredelement', 'form')));
$str .= '</div>';
} else {
$str .= '<div title="' . s($this->field->description) . '">';
$str .= '</span></legend>';
}
$str .= '<fieldset><legend><span class="accesshide">'.$this->field->name.'</span></legend>';
$i = 0;
foreach (explode("\n", $this->field->param1) as $checkbox) {

View File

@ -51,12 +51,7 @@ class data_field_date extends data_field_base {
$content = time();
}
$str = '';
if ($this->field->required) {
$str .= '<div title="' . get_string('requiredfieldhint', 'data', s($this->field->description)) . '">';
} else {
$str .= '<div title="' . s($this->field->description) . '">';
}
$str = '<div title="'.s($this->field->description).'">';
$dayselector = html_writer::select_time('days', 'field_'.$this->field->id.'_day', $content);
$monthselector = html_writer::select_time('months', 'field_'.$this->field->id.'_month', $content);
$yearselector = html_writer::select_time('years', 'field_'.$this->field->id.'_year', $content);

View File

@ -39,7 +39,7 @@ class data_field_file extends data_field_base {
if ($formdata) {
$fieldname = 'field_' . $this->field->id . '_file';
$itemid = $formdata->$fieldname;
} else if ($recordid){
} else if ($recordid) {
if ($content = $DB->get_record('data_content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid))) {
file_prepare_draft_area($itemid, $this->context->id, 'mod_data', 'content', $content->id);
@ -65,14 +65,18 @@ class data_field_file extends data_field_base {
$itemid = file_get_unused_draft_itemid();
}
$html = '';
// database entry label
$html = '<div title="' . s($this->field->description) . '">';
$html .= '<fieldset><legend><span class="accesshide">'.$this->field->name;
if ($this->field->required) {
$html .= '<div title="' . get_string('requiredfieldhint', 'data', s($this->field->description)) . '">';
$html .= '&nbsp;' . get_string('requiredelement', 'form') . '</span></legend>';
$image = html_writer::img($OUTPUT->pix_url('req'), get_string('requiredelement', 'form'),
array('class' => 'req', 'title' => get_string('requiredelement', 'form')));
$html .= html_writer::div($image);
} else {
$html .= '<div title="' . s($this->field->description) . '">';
$html .= '</span></legend>';
}
$html .= '<fieldset><legend><span class="accesshide">'.$this->field->name.'</span></legend>';
// itemid element
$html .= '<input type="hidden" name="field_'.$this->field->id.'_file" value="'.$itemid.'" />';
@ -90,10 +94,6 @@ class data_field_file extends data_field_base {
$output = $PAGE->get_renderer('core', 'files');
$html .= $output->render($fm);
if ($this->field->required) {
$html .= '<span class="requiredfield">' . get_string('requiredfieldshort', 'data') . '</span>';
}
$html .= '</fieldset>';
$html .= '</div>';

View File

@ -44,7 +44,7 @@ class data_field_latlong extends data_field_base {
// Other map sources listed at http://kvaleberg.com/extensions/mapsources/index.php?params=51_30.4167_N_0_7.65_W_region:earth
function display_add_field($recordid = 0, $formdata = null) {
global $CFG, $DB;
global $CFG, $DB, $OUTPUT;
$lat = '';
$long = '';
@ -59,25 +59,26 @@ class data_field_latlong extends data_field_base {
$long = $content->content1;
}
}
$str = '';
if ($this->field->required) {
$str .= '<div title="' . get_string('requiredfieldhint', 'data', s($this->field->description)) . '">';
} else {
$str .= '<div title="' . s($this->field->description) . '">';
}
$str = '<div title="'.s($this->field->description).'">';
$str .= '<fieldset><legend><span class="accesshide">'.$this->field->name.'</span></legend>';
$str .= '<table><tr><td align="right">';
$str .= '<label for="field_'.$this->field->id.'_0">' . get_string('latitude', 'data') . '</label></td><td><input type="text" name="field_'.$this->field->id.'_0" id="field_'.$this->field->id.'_0" value="'.s($lat).'" size="10" />°N</td></tr>';
$str .= '<tr><td align="right"><label for="field_'.$this->field->id.'_1">' . get_string('longitude', 'data') . '</label></td><td><input type="text" name="field_'.$this->field->id.'_1" id="field_'.$this->field->id.'_1" value="'.s($long).'" size="10" />°E</td>';
$str .= '<label for="field_'.$this->field->id.'_0">' . get_string('latitude', 'data');
if ($this->field->required) {
$str .= '<td><span class="requiredfield">' . get_string('requiredfieldshort', 'data') . '</span></td>';
$str .= html_writer::img($OUTPUT->pix_url('req'), get_string('requiredelement', 'form'),
array('class' => 'req', 'title' => get_string('requiredelement', 'form')));
}
$str .= '</label></td><td><input type="text" name="field_'.$this->field->id.'_0" id="field_'.$this->field->id.'_0" value="';
$str .= s($lat).'" size="10" />°N</td></tr>';
$str .= '<tr><td align="right"><label for="field_'.$this->field->id.'_1">' . get_string('longitude', 'data');
if ($this->field->required) {
$str .= html_writer::img($OUTPUT->pix_url('req'), get_string('requiredelement', 'form'),
array('class' => 'req', 'title' => get_string('requiredelement', 'form')));
}
$str .= '</label></td><td><input type="text" name="field_'.$this->field->id.'_1" id="field_'.$this->field->id.'_1" value="';
$str .= s($long).'" size="10" />°E</td>';
$str .= '</tr>';
$str .= '</table>';
$str .= '</fieldset>';
if ($this->field->required) {
$str .= get_string('requiredfieldhint', 'data', s($this->field->description));
}
$str .= '</div>';
return $str;
}
@ -240,4 +241,15 @@ class data_field_latlong extends data_field_base {
return sprintf('%01.4f', $record->content) . ' ' . sprintf('%01.4f', $record->content1);
}
/**
* Check if a field from an add form is empty
*
* @param mixed $value
* @param mixed $name
* @return bool
*/
function notemptyfield($value, $name) {
return isset($value) && !($value == '');
}
}

View File

@ -32,18 +32,13 @@ class data_field_menu extends data_field_base {
if ($formdata) {
$fieldname = 'field_' . $this->field->id;
$content = $formdata->$fieldname;
} else if ($recordid){
} else if ($recordid) {
$content = $DB->get_field('data_content', 'content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid));
$content = trim($content);
} else {
$content = '';
}
$str = '';
if ($this->field->required) {
$str .= '<div title="' . get_string('requiredfieldhint', 'data', s($this->field->description)) . '">';
} else {
$str .= '<div title="' . s($this->field->description) . '">';
}
$str = '<div title="' . s($this->field->description) . '">';
$options = array();
$rawoptions = explode("\n",$this->field->param1);
@ -54,11 +49,15 @@ class data_field_menu extends data_field_base {
}
}
$str .= html_writer::label(get_string('menuchoose', 'data'), 'field_'.$this->field->id, false, array('class' => 'accesshide'));
$str .= html_writer::select($options, 'field_'.$this->field->id, $content, array(''=>get_string('menuchoose', 'data')), array('id'=>'field_'.$this->field->id));
$str .= '<label for="' . 'field_' . $this->field->id . '">';
$str .= html_writer::span($this->field->name, 'accesshide');
if ($this->field->required) {
$str .= '<span class="requiredfield">' . get_string('requiredfieldshort', 'data') . '</span>';
$image = html_writer::img($OUTPUT->pix_url('req'), get_string('requiredelement', 'form'),
array('class' => 'req', 'title' => get_string('requiredelement', 'form')));
$str .= html_writer::div($image);
}
$str .= '</label>';
$str .= html_writer::select($options, 'field_'.$this->field->id, $content, array(''=>get_string('menuchoose', 'data')), array('id'=>'field_'.$this->field->id));
$str .= '</div>';

View File

@ -7,7 +7,6 @@
<td class="c0"><label for="description"><?php echo get_string('fielddescription', 'data'); ?></label></td>
<td class="c1"><input class="fielddescription" type="text" name="description" id="description" value="<?php p($this->field->description);?>" /></td>
</tr>
<tr>
<tr>
<td class="c0"><label for="required"><?php echo get_string('requiredfield', 'data'); ?></label></td>
<td class="c1"><input class="requiredfield" type="checkbox" name="required" id="required" <?php p($this->field->required?"checked=\"checked\"":""); ?>/></td>

View File

@ -27,12 +27,16 @@ class data_field_multimenu extends data_field_base {
var $type = 'multimenu';
function display_add_field($recordid = 0, $formdata = null) {
global $DB;
global $DB, $OUTPUT;
if ($formdata) {
$fieldname = 'field_' . $this->field->id;
$content = $formdata->$fieldname;
} else if ($recordid){
if (isset($formdata->$fieldname)) {
$content = $formdata->$fieldname;
} else {
$content = array();
}
} else if ($recordid) {
$content = $DB->get_field('data_content', 'content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid));
$content = explode('##', $content);
} else {
@ -41,10 +45,19 @@ class data_field_multimenu extends data_field_base {
$str = '<div title="'.s($this->field->description).'">';
$str .= '<input name="field_' . $this->field->id . '[xxx]" type="hidden" value="xxx"/>'; // hidden field - needed for empty selection
$str .= '<label class="accesshide" for="field_' . $this->field->id . '">' . $this->field->name. '</label>';
$str .= '<label for="field_' . $this->field->id . '">';
$str .= html_writer::span($this->field->name, 'accesshide');
if ($this->field->required) {
$str .= '<div>';
$str .= html_writer::img($OUTPUT->pix_url('req'), get_string('requiredelement', 'form'),
array('class' => 'req', 'title' => get_string('requiredelement', 'form')));
$str .= '</div>';
}
$str .= '</label>';
$str .= '<select name="field_' . $this->field->id . '[]" id="field_' . $this->field->id . '" multiple="multiple">';
foreach (explode("\n",$this->field->param1) as $option) {
foreach (explode("\n", $this->field->param1) as $option) {
$option = trim($option);
$str .= '<option value="' . s($option) . '"';
@ -241,4 +254,16 @@ class data_field_multimenu extends data_field_base {
}
return false;
}
/**
* Check if a field from an add form is empty
*
* @param mixed $value
* @param mixed $name
* @return bool
*/
function notemptyfield($value, $name) {
unset($value['xxx']);
return !empty($value);
}
}

View File

@ -7,6 +7,10 @@
<td class="c0"><label for="description"><?php echo get_string('fielddescription', 'data'); ?></label></td>
<td class="c1"><input class="fielddescription" type="text" name="description" id="description" value="<?php p($this->field->description); ?>" /></td>
</tr>
<tr>
<td class="c0"><label for="required"><?php echo get_string('requiredfield', 'data'); ?></label></td>
<td class="c1"><input class="requiredfield" type="checkbox" name="required" id="required" <?php p($this->field->required?"checked=\"checked\"":""); ?>/></td>
</tr>
<tr>
<td class="c0" valign="top"><label for="param1"><?php echo get_string('fieldoptions', 'data'); ?></label></td>
<td class="c1"><textarea class="optionstextarea" name="param1" id="param1" cols="80" rows="10"><?php if($this->field->param1) {p($this->field->param1);} ?></textarea></td>

View File

@ -40,6 +40,10 @@ class data_field_picture extends data_field_base {
if ($formdata) {
$fieldname = 'field_' . $this->field->id . '_file';
$itemid = $formdata->$fieldname;
$fieldname = 'field_' . $this->field->id . '_alttext';
if (isset($formdata->$fieldname)) {
$alttext = $formdata->$fieldname;
}
} else if ($recordid) {
if ($content = $DB->get_record('data_content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid))) {
file_prepare_draft_area($itemid, $this->context->id, 'mod_data', 'content', $content->id);
@ -67,13 +71,17 @@ class data_field_picture extends data_field_base {
} else {
$itemid = file_get_unused_draft_itemid();
}
$str = '';
$str = '<div title="' . s($this->field->description) . '">';
$str .= '<fieldset><legend><span class="accesshide">'.$this->field->name;
if ($this->field->required) {
$str .= '<div title="' . get_string('requiredfieldhint', 'data', s($this->field->description)) . '">';
$str .= '&nbsp;' . get_string('requiredelement', 'form') . '</span></legend>';
$image = html_writer::img($OUTPUT->pix_url('req'), get_string('requiredelement', 'form'),
array('class' => 'req', 'title' => get_string('requiredelement', 'form')));
$str .= html_writer::div($image);
} else {
$str .= '<div title="' . s($this->field->description) . '">';
$str .= '</span></legend>';
}
$str .= '<fieldset><legend><span class="accesshide">'.$this->field->name.'</span></legend>';
$str .= '<noscript>';
if ($file) {
$src = file_encode_url($CFG->wwwroot.'/pluginfile.php/', $this->context->id.'/mod_data/content/'.$content->id.'/'.$file->get_filename());
@ -103,9 +111,6 @@ class data_field_picture extends data_field_base {
$str .= '<input type="hidden" name="field_'.$this->field->id.'_file" value="'.$itemid.'" />';
$str .= '<label for="field_'.$this->field->id.'_alttext">'.get_string('alttext','data') .'</label>&nbsp;<input type="text" name="field_'
.$this->field->id.'_alttext" id="field_'.$this->field->id.'_alttext" value="'.s($alttext).'" />';
if ($this->field->required) {
$str .= '<span class="requiredfield">' . get_string('requiredfieldshort', 'data') . '</span>';
}
$str .= '</div>';
$str .= '</fieldset>';
@ -311,12 +316,12 @@ class data_field_picture extends data_field_base {
function notemptyfield($value, $name) {
global $USER;
$names = explode('_',$name);
$names = explode('_', $name);
if ($names[2] == 'file') {
$usercontext = context_user::instance($USER->id);
$fs = get_file_storage();
$files = $fs->get_area_files($usercontext->id, 'user', 'draft', $value);
return count($files)>=2;
return count($files) >= 2;
}
return false;
}

View File

@ -12,7 +12,6 @@
<input class="fielddescription" type="text" name="description" id="description" value="<?php p($this->field->description);?>" />
</td>
</tr>
<tr>
<tr>
<td class="c0"><label for="required"><?php echo get_string('requiredfield', 'data'); ?></label></td>
<td class="c1"><input class="requiredfield" type="checkbox" name="required" id="required" <?php p($this->field->required?"checked=\"checked\"":""); ?>/></td>

View File

@ -27,30 +27,36 @@ class data_field_radiobutton extends data_field_base {
var $type = 'radiobutton';
function display_add_field($recordid = 0, $formdata = null) {
global $CFG, $DB;
global $CFG, $DB, $OUTPUT;
if ($formdata) {
$fieldname = 'field_' . $this->field->id;
$content = $formdata->$fieldname;
} else if ($recordid){
if (isset($formdata->$fieldname)) {
$content = $formdata->$fieldname;
} else {
$content = '';
}
} else if ($recordid) {
$content = trim($DB->get_field('data_content', 'content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid)));
} else {
$content = '';
}
$str = '';
$str = '<div title="' . s($this->field->description) . '">';
$str .= '<fieldset><legend><span class="accesshide">' . $this->field->name;
if ($this->field->required) {
$str .= '<div title="' . get_string('requiredfieldhint', 'data', s($this->field->description)) . '">';
$str .= '&nbsp;' . get_string('requiredelement', 'form') . '</span></legend>';
$image = html_writer::img($OUTPUT->pix_url('req'), get_string('requiredelement', 'form'),
array('class' => 'req', 'title' => get_string('requiredelement', 'form')));
$str .= html_writer::div($image);
} else {
$str .= '<div title="' . s($this->field->description) . '">';
$str .= '</span></legend>';
}
$str .= '<fieldset><legend><span class="accesshide">'.$this->field->name.'</span></legend>';
$i = 0;
$requiredstr = '';
if ($this->field->required) {
$requiredstr = '<span class="requiredfield">' . get_string('requiredfieldshort', 'data') . '</span>';
}
$options = explode("\n",$this->field->param1);
$options = explode("\n", $this->field->param1);
foreach ($options as $radio) {
$radio = trim($radio);
if ($radio === '') {
@ -66,11 +72,7 @@ class data_field_radiobutton extends data_field_base {
$str .= '/>';
}
$str .= '<label for="field_'.$this->field->id.'_'.$i.'">'.$radio.'</label>';
if ($i == count($options) - 1) {
$str .= $requiredstr;
}
$str .= '<br />';
$str .= '<label for="field_'.$this->field->id.'_'.$i.'">'.$radio.'</label><br />';
$i++;
}
$str .= '</fieldset>';

View File

@ -7,7 +7,6 @@
<td class="c0"><label for="description"><?php echo get_string('fielddescription', 'data'); ?></label></td>
<td class="c1"><input class="fielddescription" type="text" name="description" id="description" value="<?php p($this->field->description); ?>" /></td>
</tr>
<tr>
<tr>
<td class="c0"><label for="required"><?php echo get_string('requiredfield', 'data'); ?></label></td>
<td class="c1"><input class="requiredfield" type="checkbox" name="required" id="required" <?php p($this->field->required?"checked=\"checked\"":""); ?>/></td>

View File

@ -7,7 +7,6 @@
<td class="c0"><label for="description"><?php echo get_string('fielddescription', 'data'); ?></label></td>
<td class="c1"><input class="fielddescription" type="text" name="description" id="description" value="<?php p($this->field->description); ?>" /></td>
</tr>
<tr>
<tr>
<td class="c0"><label for="required"><?php echo get_string('requiredfield', 'data'); ?></label></td>
<td class="c1"><input class="requiredfield" type="checkbox" name="required" id="required" <?php p($this->field->required?"checked=\"checked\"":""); ?>/></td>

View File

@ -54,12 +54,14 @@ class data_field_textarea extends data_field_base {
$text = '';
$format = 0;
$str = '';
$str = '<div title="' . s($this->field->description) . '">';
$str .= '<label for="field_' . $this->field->id . '">';
$str .= html_writer::span($this->field->name, "accesshide");
if ($this->field->required) {
$str .= '<div title="' . get_string('requiredfieldhint', 'data', s($this->field->description)) . '">';
} else {
$str .= '<div title="' . s($this->field->description) . '">';
$str .= html_writer::img($OUTPUT->pix_url('req'), get_string('requiredelement', 'form'),
array('class' => 'req', 'title' => get_string('requiredelement', 'form')));
}
$str .= '</label>';
editors_head_setup();
$options = $this->get_options();
@ -69,12 +71,23 @@ class data_field_textarea extends data_field_base {
if ($formdata) {
$fieldname = 'field_' . $this->field->id . '_content1';
$format = $formdata->$fieldname;
if (isset($formdata->$fieldname)) {
$format = $formdata->$fieldname;
} else {
$format = file_get_unused_draft_itemid();
}
$fieldname = 'field_' . $this->field->id . '_itemid';
$draftitemid = $formdata->$fieldname;
if (isset($formdata->$fieldname)) {
$draftitemid = $formdata->$fieldname;
} else {
$draftitemid = file_get_unused_draft_itemid();
}
$fieldname = 'field_' . $this->field->id;
$text = $formdata->$fieldname;
} else if ($recordid && $content = $DB->get_record('data_content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid))){
if (isset($formdata->$fieldname)) {
$text = $formdata->$fieldname;
}
} else if ($recordid &&
$content = $DB->get_record('data_content', array('fieldid' => $this->field->id, 'recordid' => $recordid))) {
$format = $content->content1;
$text = clean_text($content->content, $format);
$text = file_prepare_draft_area($draftitemid, $this->context->id, 'mod_data', 'content', $content->id, $options, $text);
@ -141,9 +154,6 @@ class data_field_textarea extends data_field_base {
}
$str .= '</select>';
if ($this->field->required) {
$str .= '<span class="requiredfield">' . get_string('requiredfieldshort', 'data') . '</span>';
}
$str .= '</div>';
$str .= '</div>';
return $str;
@ -253,8 +263,8 @@ class data_field_textarea extends data_field_base {
* @return bool
*/
function notemptyfield($value, $name) {
$names = explode('_',$name);
//clean first
$names = explode('_', $name);
// Clean first.
if (count($names) == 2) {
return !empty($value);
}

View File

@ -10,7 +10,6 @@
value="<?php p($this->field->description); ?>" />
</td>
</tr>
<tr>
<tr>
<td class="c0"><label for="required"><?php echo get_string('requiredfield', 'data'); ?></label></td>
<td class="c1"><input class="requiredfield" type="checkbox" name="required" id="required" <?php p($this->field->required?"checked=\"checked\"":""); ?>/></td>

View File

@ -56,23 +56,26 @@ class data_field_url extends data_field_base {
$text = $content->content1;
}
}
$str = '';
$str = '<div title="' . s($this->field->description) . '">';
$label = '<label for="' . $fieldid . '"><span class="accesshide">' . $this->field->name . '</span>';
if ($this->field->required) {
$str .= '<div title="' . get_string('requiredfieldhint', 'data', s($this->field->description)) . '">';
} else {
$str .= '<div title="' . s($this->field->description) . '">';
$label .= html_writer::img($OUTPUT->pix_url('req'), get_string('requiredelement', 'form'),
array('class' => 'req', 'title' => get_string('requiredelement', 'form')));
}
$label .= '</label>';
if (!empty($this->field->param1) and empty($this->field->param2)) {
$str .= '<table><tr><td align="right">';
$str .= get_string('url','data').':</td><td>';
$str .= '<label class="accesshide" for="' . $fieldid . '">'. $this->field->name .'</label>';
$str .= $label;
$str .= '<input type="text" name="field_'.$this->field->id.'_0" id="'.$fieldid.'" value="'.$url.'" size="60" />';
$str .= '<button id="filepicker-button-'.$options->client_id.'" style="display:none">'.$straddlink.'</button></td></tr>';
$str .= '<tr><td align="right">'.get_string('text','data').':</td><td><input type="text" name="field_'.$this->field->id.'_1" id="field_'.$this->field->id.'_1" value="'.s($text).'" size="60" /></td></tr>';
$str .= '</table>';
} else {
// Just the URL field
$str .= '<label class="accesshide" for="' . $fieldid . '">'. $this->field->name .'</label>';
$str .= $label;
$str .= '<input type="text" name="field_'.$this->field->id.'_0" id="'.$fieldid.'" value="'.s($url).'" size="60" />';
if (count($options->repositories) > 0) {
$str .= '<button id="filepicker-button-'.$options->client_id.'" class="visibleifjs">'.$straddlink.'</button>';
@ -84,10 +87,6 @@ class data_field_url extends data_field_base {
$module = array('name'=>'data_urlpicker', 'fullpath'=>'/mod/data/data.js', 'requires'=>array('core_filepicker'));
$PAGE->requires->js_init_call('M.data_urlpicker.init', array($options), true, $module);
if ($this->field->required) {
$str .= '<span class="requiredfield">' . get_string('requiredfieldshort', 'data') . '</span>';
}
$str .= '</div>';
return $str;
}

View File

@ -135,6 +135,7 @@ $string['entry'] = 'Entry';
$string['entrysaved'] = 'Your entry has been saved';
$string['errormustbeteacher'] = 'You need to be a teacher to use this page!';
$string['errorpresetexists'] = 'There is already a preset with the selected name';
$string['errormustsupplyvalue'] = 'You must supply a value here.';
$string['example'] = 'Database module example';
$string['excel'] = 'Excel';
$string['export'] = 'Export';
@ -310,8 +311,6 @@ $string['requiredentriestoview_help'] = 'The number of entries a student is requ
Note: If entries are required before viewing, the database auto-linking filter should be disabled. This is because the database auto-linking filter can\'t determine whether a user has submitted the required number of entries.';
$string['requiredfield'] = 'Required field';
$string['requiredfieldhint'] = '{$a} (required field)';
$string['requiredfieldshort'] = ' *';
$string['resetsettings'] = 'Reset filters';
$string['resettemplate'] = 'Reset template';
$string['resizingimages'] = 'Resizing image thumbnails...';

View File

@ -153,7 +153,7 @@ class data_field_base { // Base class for Database Field Types (see field/*/
$this->field->name = trim($data->name);
$this->field->description = trim($data->description);
$this->field->required = !empty($data->required)?1:0;
$this->field->required = !empty($data->required) ? 1 : 0;
if (isset($data->param1)) {
$this->field->param1 = trim($data->param1);
@ -270,13 +270,13 @@ class data_field_base { // Base class for Database Field Types (see field/*/
* @param int $recordid
* @return string
*/
function display_add_field($recordid=0, $formdata=null){
global $DB;
function display_add_field($recordid=0, $formdata=null) {
global $DB, $OUTPUT;
if ($formdata) {
$fieldname = 'field_' . $this->field->id;
$content = $formdata->$fieldname;
} else if ($recordid){
} else if ($recordid) {
$content = $DB->get_field('data_content', 'content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid));
} else {
$content = '';
@ -287,17 +287,14 @@ class data_field_base { // Base class for Database Field Types (see field/*/
$content='';
}
$str = '';
$str = '<div title="' . s($this->field->description) . '">';
$str .= '<label for="field_'.$this->field->id.'"><span class="accesshide">'.$this->field->name.'</span>';
if ($this->field->required) {
$str .= '<div title="' . get_string('requiredfieldhint', 'data', s($this->field->description)) . '">';
} else {
$str .= '<div title="' . s($this->field->description) . '">';
}
$str .= '<label class="accesshide" for="field_'.$this->field->id.'">'.$this->field->description.'</label>';
$str .= '<input class="basefieldinput" type="text" name="field_'.$this->field->id.'" id="field_'.$this->field->id.'" value="'.s($content).'" />';
if ($this->field->required) {
$str .= '<span class="requiredfield">' . get_string('requiredfieldshort', 'data') . '</span>';
$str .= html_writer::img($OUTPUT->pix_url('req'), get_string('requiredelement', 'form'),
array('class' => 'req', 'title' => get_string('requiredelement', 'form')));
}
$str .= '</label><input class="basefieldinput" type="text" name="field_'.$this->field->id.'" id="field_'.$this->field->id;
$str .= '" value="'.s($content).'" />';
$str .= '</div>';
return $str;
@ -3835,7 +3832,7 @@ function data_process_submission(stdClass $mod, $fields, stdClass $datarecord) {
if (!isset($result->fieldnotifications[$field->field->name])) {
$result->fieldnotifications[$field->field->name] = array();
}
$result->fieldnotifications[$field->field->name][] = get_string('required');
$result->fieldnotifications[$field->field->name][] = get_string('errormustsupplyvalue', 'data');
$requiredfieldsfilled = false;
}
@ -3849,7 +3846,7 @@ function data_process_submission(stdClass $mod, $fields, stdClass $datarecord) {
if ($emptyform) {
// The form is empty.
$result->generalnotifications[] = get_string('emptyaddform','data');
$result->generalnotifications[] = get_string('emptyaddform', 'data');
}
$result->validated = $requiredfieldsfilled && !$emptyform;

View File

@ -69,13 +69,6 @@
.dir-rtl .mod-data-default-template .template-token {text-align:right;}
.dir-rtl .mod-data-default-template searchcontrols {text-align:left;}
#page-mod-data-edit .privatefieldlocked {
font-style: italic;
color: #888888;
}
#page-mod-data-view .privatefieldhidden {
display: none;
}
#page-mod-data-edit .requiredfield {
color: #ff0000;
#page-mod-data-edit .req {
cursor: help;
}

View File

@ -31,19 +31,19 @@ Feature: Users can add entries to database activities
When I log in as "student1"
And I follow "Course 1"
And I add an entry to "Test database name" database with:
| Test field description | Student original entry |
| Test field name | Student original entry |
And I press "Save and view"
Then I should see "Student original entry"
And I follow "Edit"
And I set the following fields to these values:
| Test field description | Student edited entry |
| Test field name | Student edited entry |
And I press "Save and view"
And I should see "Student edited entry"
And I add an entry to "Test database name" database with:
| Test field description | Student second entry |
| Test field name | Student second entry |
And I press "Save and add another"
And I add an entry to "Test database name" database with:
| Test field description | Student third entry |
| Test field name | Student third entry |
And I press "Save and view"
And I follow "View list"
And I should see "Student edited entry"

View File

@ -1,10 +1,10 @@
@mod @mod_data
Feature: Users can be required to specify certain fields when adding entries to database activities
In order to populate databases
As a user
I need to specify certain fields when I add entries to databases
In order to constrain user input
As a teacher
I need to specify certain fields as required when I add entries to databases
Scenario: Students can add entries to a database
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| student1 | Student | 1 | student1@asd.com |
@ -23,12 +23,26 @@ Feature: Users can be required to specify certain fields when adding entries to
And I follow "Course 1"
And I add a "Text input" field to "Test database name" database and I fill the form with:
| Field name | Base Text input |
| Required | yes |
| Field description | Base Text input |
And I add a "Checkbox" field to "Test database name" database and I fill the form with:
| Field name | Required Checkbox |
| Field description | Required Checkbox |
| Required | yes |
| Options | Option 1 |
| Options | Required Checkbox Option 1 |
And I follow "Fields"
And I set the field "newtype" to "Checkbox"
And I click on "Go" "button" in the ".fieldadd" "css_element"
And I set the following fields to these values:
| Field name | Required Two-Option Checkbox |
| Field description | Required Two-Option Checkbox |
| Required | yes |
And I set the field "Options" to multiline
"""
RTOC Option 1
RTOC Option 2
"""
And I press "Add"
And I add a "Latlong" field to "Test database name" database and I fill the form with:
| Field name | Required Latlong |
| Field description | Required Latlong |
@ -46,7 +60,7 @@ Feature: Users can be required to specify certain fields when adding entries to
| Field name | Required Radio |
| Field description | Required Radio |
| Required | yes |
| Options | Option 1 |
| Options | Required Radio Option 1 |
And I add a "Text input" field to "Test database name" database and I fill the form with:
| Field name | Required Text input |
| Field description | Required Text input |
@ -59,10 +73,28 @@ Feature: Users can be required to specify certain fields when adding entries to
| Field name | Required URL |
| Field description | Required URL |
| Required | yes |
And I add a "Multimenu" field to "Test database name" database and I fill the form with:
| Field name | Required Multimenu |
| Field description | Required Multimenu |
| Required | yes |
| Options | Option 1 |
And I follow "Fields"
And I set the field "newtype" to "Multimenu"
And I click on "Go" "button" in the ".fieldadd" "css_element"
And I set the following fields to these values:
| Field name | Required Two-Option Multimenu |
| Field description | Required Two-Option Multimenu |
| Required | yes |
And I set the field "Options" to multiline
"""
Option 1
Option 2
"""
And I press "Add"
And I add a "Checkbox" field to "Test database name" database and I fill the form with:
| Field name | Not required Checkbox |
| Field description | Not required Checkbox |
| Options | Option 1 |
| Options | Not required Checkbox Option 1 |
And I add a "Latlong" field to "Test database name" database and I fill the form with:
| Field name | Not required Latlong |
| Field description | Not required Latlong |
@ -76,7 +108,7 @@ Feature: Users can be required to specify certain fields when adding entries to
And I add a "Radio button" field to "Test database name" database and I fill the form with:
| Field name | Not required Radio |
| Field description | Not required Radio |
| Options | Option 1 |
| Options | Not required Radio Option 1 |
And I add a "Text input" field to "Test database name" database and I fill the form with:
| Field name | Not required Text input |
| Field description | Not required Text input |
@ -86,28 +118,89 @@ Feature: Users can be required to specify certain fields when adding entries to
And I add a "URL" field to "Test database name" database and I fill the form with:
| Field name | Not required URL |
| Field description | Not required URL |
And I add a "Multimenu" field to "Test database name" database and I fill the form with:
| Field name | Not required Multimenu |
| Field description | Not required Multimenu |
| Options | Option 1 |
And I follow "Templates"
And I log out
Scenario: Students receive errors for empty required fields but not for optional fields
When I log in as "student1"
And I follow "Course 1"
And I add an entry to "Test database name" database with:
| Base Text input | Some input to allow us to submit the for otherwise empty |
| Base Text input | Some input to allow us to submit the otherwise empty form |
And I press "Save and view"
Then ".alert.alert-error" "css_element" should exist in the "Required Checkbox" "table_row"
Then ".alert.alert-error" "css_element" should exist in the "Required Latlong" "table_row"
Then ".alert.alert-error" "css_element" should exist in the "Required Menu" "table_row"
Then ".alert.alert-error" "css_element" should exist in the "Required Number" "table_row"
Then ".alert.alert-error" "css_element" should exist in the "Required Radio" "table_row"
Then ".alert.alert-error" "css_element" should exist in the "Required Text input" "table_row"
Then ".alert.alert-error" "css_element" should exist in the "Required Text area" "table_row"
Then ".alert.alert-error" "css_element" should exist in the "Required URL" "table_row"
Then ".alert.alert-error" "css_element" should not exist in the "Not required Checkbox" "table_row"
Then ".alert.alert-error" "css_element" should not exist in the "Not required Latlong" "table_row"
Then ".alert.alert-error" "css_element" should not exist in the "Not required Menu" "table_row"
Then ".alert.alert-error" "css_element" should not exist in the "Not required Number" "table_row"
Then ".alert.alert-error" "css_element" should not exist in the "Not required Radio" "table_row"
Then ".alert.alert-error" "css_element" should not exist in the "Not required Text input" "table_row"
Then ".alert.alert-error" "css_element" should not exist in the "Not required Text area" "table_row"
Then ".alert.alert-error" "css_element" should not exist in the "Not required URL" "table_row"
And ".alert.alert-error" "css_element" should exist in the "Required Two-Option Checkbox" "table_row"
And ".alert.alert-error" "css_element" should exist in the "Required Latlong" "table_row"
And ".alert.alert-error" "css_element" should exist in the "Required Menu" "table_row"
And ".alert.alert-error" "css_element" should exist in the "Required Number" "table_row"
And ".alert.alert-error" "css_element" should exist in the "Required Radio" "table_row"
And ".alert.alert-error" "css_element" should exist in the "Required Text input" "table_row"
And ".alert.alert-error" "css_element" should exist in the "Required Text area" "table_row"
And ".alert.alert-error" "css_element" should exist in the "Required URL" "table_row"
And ".alert.alert-error" "css_element" should exist in the "Required Multimenu" "table_row"
And ".alert.alert-error" "css_element" should exist in the "Required Two-Option Multimenu" "table_row"
And ".alert.alert-error" "css_element" should not exist in the "Not required Checkbox" "table_row"
And ".alert.alert-error" "css_element" should not exist in the "Not required Latlong" "table_row"
And ".alert.alert-error" "css_element" should not exist in the "Not required Menu" "table_row"
And ".alert.alert-error" "css_element" should not exist in the "Not required Number" "table_row"
And ".alert.alert-error" "css_element" should not exist in the "Not required Radio" "table_row"
And ".alert.alert-error" "css_element" should not exist in the "Not required Text input" "table_row"
And ".alert.alert-error" "css_element" should not exist in the "Not required Text area" "table_row"
And ".alert.alert-error" "css_element" should not exist in the "Not required URL" "table_row"
And ".alert.alert-error" "css_element" should not exist in the "Not required Multimenu" "table_row"
And I follow "View list"
And I should see "No entries in database"
Scenario: Students recieve no error for filled in required fields
When I log in as "student1"
And I follow "Course 1"
And I add an entry to "Test database name" database with:
| Base Text input | Some input to allow us to submit the otherwise empty form |
| Required Checkbox Option 1 | 1 |
| RTOC Option 1 | 1 |
| Latitude | 0 |
| Longitude | 0 |
| Required Menu | 1 |
| Required Number | 1 |
| Required Radio Option 1 | 1 |
| Required Text input | New entry text |
| Required Text area | More text |
| Required URL | http://example.com/ |
| Required Multimenu | 1 |
| Required Two-Option Multimenu | 1 |
And I press "Save and view"
And I follow "View list"
Then I should not see "No entries in database"
And I should see "New entry text"
Scenario: Fields refill with data after having an error
When I log in as "student1"
And I follow "Course 1"
And I add an entry to "Test database name" database with:
| RTOC Option 1 | 1 |
| Latitude | 0 |
| Longitude | 0 |
| Required Menu | 1 |
| Required Number | 1 |
| Required Radio Option 1 | 1 |
| Required Text input | New entry text |
| Required Text area | More text |
| Required URL | http://example.com/ |
| Required Multimenu | 1 |
| Required Two-Option Multimenu | 1 |
And I press "Save and view"
Then the following fields match these values:
| Base Text input | |
| Latitude | 0 |
| Longitude | 0 |
| Required Menu | Option 1 |
| Required Number | 1 |
| Required Radio Option 1 | 1 |
| Required Text input | New entry text |
| Required Text area | More text |
| Required URL | http://example.com/ |
| Required Multimenu | Option 1 |
| Required Two-Option Multimenu | Option 1 |

View File

@ -27,13 +27,13 @@ Feature: Users can view and search database entries
# To generate the default templates.
And I follow "Templates"
And I add an entry to "Test database name" database with:
| Test field description | Teacher entry 1 |
| Test field name | Teacher entry 1 |
And I press "Save and add another"
And I add an entry to "Test database name" database with:
| Test field description | Teacher entry 2 |
| Test field name | Teacher entry 2 |
And I press "Save and add another"
And I add an entry to "Test database name" database with:
| Test field description | Teacher entry 3 |
| Test field name | Teacher entry 3 |
And I press "Save and view"
And I log out
When I log in as "student1"

View File

@ -24,7 +24,7 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2014111001; // The current module version (Date: YYYYMMDDXX)
$plugin->version = 2015022600; // The current module version (Date: YYYYMMDDXX)
$plugin->requires = 2014110400; // Requires this Moodle version
$plugin->component = 'mod_data'; // Full name of the plugin (used for diagnostics)
$plugin->cron = 0;