Index: core/admin_templates/incs/form_blocks.tpl
===================================================================
--- core/admin_templates/incs/form_blocks.tpl (revision 13557)
+++ core/admin_templates/incs/form_blocks.tpl (working copy)
@@ -720,6 +720,22 @@
</inp2:m_if>
</inp2:m_DefineElement>
+<inp2:m_DefineElement name="js_option_item">
+ '<inp2:m_Param name="key" js_escape="1"/>': '<inp2:m_Param name="option" js_escape="1"/>'<inp2:m_ifnot check="m_Param" name="is_last">, </inp2:m_ifnot>
+</inp2:m_DefineElement>
+
+<inp2:m_DefineElement name="js_option_phrase">
+ '<inp2:m_Param name="key" js_escape="1"/>': '<inp2:m_Phrase name="$option" js_escape="1"/>'<inp2:m_ifnot check="m_Param" name="is_last">, </inp2:m_ifnot>
+</inp2:m_DefineElement>
+
+<inp2:m_DefineElement name="inp_json_options">
+ <inp2:m_if check="{$prefix}_FieldOption" field="$field" option="use_phrases">
+ {<inp2:{$prefix}_PredefinedOptions field="$field" block="js_option_phrase" selected="selected"/>}
+ <inp2:m_else />
+ {<inp2:{$prefix}_PredefinedOptions field="$field" block="js_option_item" selected="selected"/>}
+ </inp2:m_if>
+</inp2:m_DefineElement>
+
<inp2:m_DefineElement name="inp_edit_checkbox" caption_render_as="default_field_caption_element" is_last="" field_class="" onchange="" hint_label="" onclick="">
<inp2:m_if check="{$prefix}_FieldVisible" field="$field">
<tr class="<inp2:m_odd_even odd='edit-form-odd' even='edit-form-even'/>" id="<inp2:$prefix_InputName field='$field'/>_row">
@@ -860,7 +876,7 @@
</inp2:m_if>
<inp2:m_Param name="field"/>.InitEvents();
- <inp2:m_Param name="field"/>.SetMessage('required_error', '<inp2:m_Phrase name="la_error_required" escape="1"/>');
+ <inp2:m_Param name="field"/>.SetMessage('required_error', '<inp2:m_Phrase name="la_err_required" escape="1"/>');
<inp2:m_Param name="field"/>.SetMessage('unique_error', '<inp2:m_Phrase name="la_error_unique" escape="1"/>');
<inp2:m_Param name="field"/>.SetMessage('delete_confirm', '<inp2:m_Phrase label="la_Delete_Confirm" escape="1"/>');
<inp2:m_Param name="field"/>.SetMessage('add_button', '<inp2:m_Phrase name="la_btn_Add" escape="1"/>');
Index: core/admin_templates/js/form_controls.js
===================================================================
--- core/admin_templates/js/form_controls.js (revision 13557)
+++ core/admin_templates/js/form_controls.js (working copy)
@@ -15,7 +15,23 @@
}
MultiInputControl.prototype.registerControl = function($field_name, $type, $required, $options) {
- this.Controls[$field_name] = {'type' : $type, 'required' : $required, 'options' : $options};
+ if (Object.prototype.toString.call($type) === "[object String]") {
+ this.Controls[$field_name] = {
+ 'type' : $type,
+ 'required' : $required,
+ 'options' : $options,
+ };
+ }
+ else {
+ if ($required === undefined || $required === false) {
+ // type, required, options, default
+ this.Controls[$field_name] = $type;
+ }
+ else {
+ // upgrade control
+ $.extend(this.Controls[$field_name], $type);
+ }
+ }
}
MultiInputControl.prototype.getControl = function ($field, $appendix, $prepend) {
@@ -34,6 +50,10 @@
$value = $control.options[$control.selectedIndex].value;
break;
+ case 'radio':
+ $value = $("input[name='" + jq(this.FieldMask.replace('#FIELD_NAME#', $field)) + "']:checked").val();
+ break;
+
/*case 'datetime':
$value = this.getControl($field + '_date').value + ' ' + this.getControl($field + '_time').value;
break;*/
@@ -47,6 +67,10 @@
}
MultiInputControl.prototype.setControlValue = function ($field, $value) {
+ if ($value === null && this.Controls[$field]['default'] !== undefined) {
+ $value = this.Controls[$field]['default'];
+ }
+
switch (this.Controls[$field]['type']) {
case 'select':
var $i = 0;
@@ -54,12 +78,8 @@
if ($value === null) {
$control.selectedIndex = 0;
}
- while ($i < $control.options.length) {
- if ($control.options[$i].value == $value) {
- $control.selectedIndex = $i;
- break;
- }
- $i++;
+ else {
+ $($control).val($value).change();
}
break;
@@ -68,6 +88,15 @@
this.getControl($field, null, '_cb').checked = parseInt($value) == 1;
break;
+ case 'radio':
+ if ($value === null) {
+ $("input[name='" + jq(this.FieldMask.replace('#FIELD_NAME#', $field)) + "']:checked").attr('checked', '').change();
+ }
+ else {
+ $( this.getControl($field, $value) ).attr('checked', 'checked').change();
+ }
+ break;
+
/*case 'datetime':
$value = $value.split(' ');
this.getControl($field + '_date').value = $value[0];
@@ -75,7 +104,8 @@
break;*/
default:
- this.getControl($field).value = ($value === null) ? '' : $value;
+ var $control = this.getControl($field);
+ $($control).val($value === null ? '' : $value).change();
break;
}
}
@@ -101,14 +131,14 @@
}
}
- if (this.Controls[$field]['type'] == 'checkbox') {
- $value = this.Controls[$field]['options'][ parseInt($value) ];
+ if (this.Controls[$field]['type'] == 'checkbox' || this.Controls[$field]['type'] == 'radio') {
+ $value = this.Controls[$field]['options'][$value];
}
return $value;
}
-MultiInputControl.prototype.formatLine = function($record_index) {
+MultiInputControl.prototype.formatLine = function($record_index, $escape) {
var $ret = this.ResultMask;
for (var $field_name in this.Controls) {
@@ -116,9 +146,13 @@
$ret = $ret.replace('#' + $field_name + '#', this.formatValue($field_name, $value));
}
- return this.htmlspecialchars($ret);
+ return $escape === undefined || $escape ? this.htmlspecialchars($ret) : $ret;
}
+MultiInputControl.prototype.isReadOnly = function($record_index) {
+ return false;
+}
+
MultiInputControl.prototype._getRecordIndex = function ($selected_index) {
var $object = this.getControl(this.FieldName, 'minput');
@@ -130,9 +164,10 @@
}
MultiInputControl.prototype.makeRequest = function($request_type, $record, $skip_index) {
- var $url = this.ValidateURL;
+ var $url = this.ValidateURL + '&request_type=' + encodeURIComponent($request_type);
+
for (var $field_name in $record) {
- $url += '&' + this.FieldMask.replace('#FIELD_NAME#', $field_name) + '=' + escape($record[$field_name]);
+ $url += '&' + this.FieldMask.replace('#FIELD_NAME#', $field_name) + '=' + encodeURIComponent($record[$field_name]);
}
Request.makeRequest($url, this.BusyRequest, '', this.successCallback, this.errorCallback, [$request_type, $record, $skip_index], this);
@@ -200,6 +235,7 @@
if ($option_index < $options.length) {
// update existing record
$options[$option_index].innerHTML = this.formatLine( this._getRecordIndex($option_index) );
+ $options[$option_index].disabled = this.isReadOnly( this._getRecordIndex($option_index) );
}
else {
// create new record
@@ -207,6 +243,7 @@
$options.add($new_option, $options.length);
$new_option.value = $option_index; // will be used in move up/down & sorting (if any)
$new_option.innerHTML = this.formatLine(this.Records.length - 1);
+ $new_option.disabled = this.isReadOnly(this.Records.length - 1);
}
}
@@ -326,11 +363,11 @@
MultiInputControl.prototype.ValidateRequired = function($record) {
for (var $field_name in $record) {
if (this.Controls[$field_name]['required'] && !$record[$field_name]) {
- alert(this.Messages['required_error']);
- return false;
+ this.Errors[$field_name] = this.Messages['required_error'];
}
}
- return true;
+
+ return !this.displayErrors();
}
MultiInputControl.prototype.compareRecords = function($record_a, $record_b) {
@@ -369,14 +406,18 @@
}
MultiInputControl.prototype.displayErrors = function() {
- var $has_errors = false;
- var $field_label = '';
+ var $ret = [];
+
for (var $field_name in this.Errors) {
- $has_errors = true;
- alert(this.FieldLabels[$field_name] + ': ' + this.Errors[$field_name]);
+ $ret.push(this.FieldLabels[$field_name] + ': ' + this.Errors[$field_name]);
}
- return $has_errors;
+ if ($ret.length) {
+ alert( $ret.join("\n") );
+ return true;
+ }
+
+ return false;
}
MultiInputControl.prototype.successCallback = function($request, $params, $object) {
Index: core/kernel/db/db_tag_processor.php
===================================================================
--- core/kernel/db/db_tag_processor.php (revision 13557)
+++ core/kernel/db/db_tag_processor.php (working copy)
@@ -1141,6 +1141,9 @@
array_shift($options);
}
+ $index = 0;
+ $option_count = count($options);
+
if (strpos($value, '|') !== false) {
// multiple checkboxes OR multiselect
$value = explode('|', substr($value, 1, -1) );
@@ -1148,7 +1151,10 @@
$block_params['key'] = $key;
$block_params['option'] = $val;
$block_params[$selected_param_name] = ( in_array($key, $value) ? ' '.$selected : '');
+ $block_params['is_last'] = $index == $option_count - 1;
$o .= $this->Application->ParseBlock($block_params);
+
+ $index++;
}
}
else {
@@ -1157,7 +1163,10 @@
$block_params['key'] = $key;
$block_params['option'] = $val;
$block_params[$selected_param_name] = (strlen($key) == strlen($value) && ($key == $value) ? ' '.$selected : '');
+ $block_params['is_last'] = $index == $option_count - 1;
$o .= $this->Application->ParseBlock($block_params);
+
+ $index++;
}
}
return $o;
Index: core/units/helpers/controls/minput_helper.php
===================================================================
--- core/units/helpers/controls/minput_helper.php (revision 13557)
+++ core/units/helpers/controls/minput_helper.php (working copy)
@@ -46,17 +46,28 @@
return $xml ? '<records>'.$xml.'</records>' : '';
}
+ /**
+ * Returns validation errors in XML format
+ *
+ * @param kDBItem $object
+ * @param Array $fields_hash
+ * @return string
+ */
function prepareErrorsXML(&$object, $fields_hash)
{
$xml = '';
+ $errors = Array ();
+
foreach ($fields_hash as $field_name => $field_value) {
- $object->SetField($field_name, $field_value);
if (!$object->ValidateField($field_name)) {
- $xml .= '<field name="'.$field_name.'">'.$object->GetErrorMsg($field_name, false).'</field>';
+ $field_options = $object->GetFieldOptions($field_name);
+ $error_field = array_key_exists('error_field', $field_options) ? $field_options['error_field'] : $field_name;
+
+ $errors[$error_field] = '<field name="'.$error_field.'">'.$object->GetErrorMsg($error_field, false).'</field>';
}
}
- return '<errors>'.$xml.'</errors>';
+ return '<errors>'.implode('', $errors).'</errors>';
}
/**
@@ -73,6 +84,21 @@
if ($items_info) {
list ($id, $field_values) = each($items_info);
+ foreach ($field_values as $field_name => $field_value) {
+ $object->SetField($field_name, $field_value);
+ }
+
+ $event_mapping = Array (
+ 'AddRecord' => 'OnBeforeItemCreate',
+ 'SaveRecord' => 'OnBeforeItemUpdate',
+ );
+
+ $request_type = $this->Application->GetVar('request_type');
+
+ if (array_key_exists($request_type, $event_mapping)) {
+ $event->CallSubEvent($event_mapping[$request_type]);
+ }
+
echo $this->prepareErrorsXML($object, $field_values);
}