Index: branches/RC/core/admin_templates/users/user_selector.tpl =================================================================== diff -u -N --- branches/RC/core/admin_templates/users/user_selector.tpl (revision 0) +++ branches/RC/core/admin_templates/users/user_selector.tpl (revision 10020) @@ -0,0 +1,47 @@ + + + + + + + + + + + + + +
+ + +
+ + + + \ No newline at end of file Index: branches/RC/core/admin_templates/users/admins_edit.tpl =================================================================== diff -u -N -r8929 -r10020 --- branches/RC/core/admin_templates/users/admins_edit.tpl (.../admins_edit.tpl) (revision 8929) +++ branches/RC/core/admin_templates/users/admins_edit.tpl (.../admins_edit.tpl) (revision 10020) @@ -1,6 +1,10 @@ - + + + + + Index: branches/RC/core/admin_templates/users/admins_edit_groups.tpl =================================================================== diff -u -N --- branches/RC/core/admin_templates/users/admins_edit_groups.tpl (revision 0) +++ branches/RC/core/admin_templates/users/admins_edit_groups.tpl (revision 10020) @@ -0,0 +1,100 @@ + + + + + +
+ + + + + +
+ + +
+ + + + + + + + + + + + +" /> + + \ No newline at end of file Index: branches/RC/core/admin_templates/users/Attic/group_selector.tpl =================================================================== diff -u -N --- branches/RC/core/admin_templates/users/Attic/group_selector.tpl (revision 0) +++ branches/RC/core/admin_templates/users/Attic/group_selector.tpl (revision 10020) @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + +
+ + +
+ + + + \ No newline at end of file Index: branches/RC/core/admin_templates/users/admins_edit_tabs.tpl =================================================================== diff -u -N --- branches/RC/core/admin_templates/users/admins_edit_tabs.tpl (revision 0) +++ branches/RC/core/admin_templates/users/admins_edit_tabs.tpl (revision 10020) @@ -0,0 +1,12 @@ + + + + +
+ + + + + +
+
\ No newline at end of file Index: branches/RC/core/admin_templates/js/form_controls.js =================================================================== diff -u -N --- branches/RC/core/admin_templates/js/form_controls.js (revision 0) +++ branches/RC/core/admin_templates/js/form_controls.js (revision 10020) @@ -0,0 +1,471 @@ +function MultiInputControl($field_name, $field_mask, $field_labels, $result_mask) { + this.FieldName = $field_name; + this.ValidateURL = ''; + + this.FieldMask = $field_mask; + this.FieldLabels = $field_labels; + this.ResultMask = $result_mask; // format of record in list + + this.Permissions = new Array (); // action groups allowed + this.Messages = new Array (); // various phrase (errors, confirmations, button titles) + this.Controls = new Array (); // controls used for editing list content + this.Records = new Array (); // data to be submitted (needs to be parsed using formatters) + this.Errors = new Array (); // error messages in fields + this.InEditing = false; +} + +MultiInputControl.prototype.registerControl = function($field_name, $type, $required) { + this.Controls[$field_name] = {'type' : $type, 'required' : $required}; +} + +MultiInputControl.prototype.getControl = function ($field, $appendix) { + $appendix = isset($appendix) ? '_' + $appendix : ''; + return document.getElementById( this.FieldMask.replace('#FIELD_NAME#', $field) + $appendix ); +} + +MultiInputControl.prototype.getControlValue = function ($field) { + var $value = ''; + + switch (this.Controls[$field]['type']) { + case 'select': + var $control = this.getControl($field); + $value = $control.options[$control.selectedIndex].value; + break; + + /*case 'datetime': + $value = this.getControl($field + '_date').value + ' ' + this.getControl($field + '_time').value; + break;*/ + + default: + $value = this.getControl($field).value; + break; + } + + return $value; +} + +MultiInputControl.prototype.setControlValue = function ($field, $value) { + switch (this.Controls[$field]['type']) { + case 'select': + var $i = 0; + var $control = this.getControl($field); + if ($value === null) { + $control.selectedIndex = 0; + } + while ($i < $control.options.length) { + if ($control.options[$i].value == $value) { + $control.selectedIndex = $i; + break; + } + $i++; + } + break; + + /*case 'datetime': + $value = $value.split(' '); + this.getControl($field + '_date').value = $value[0]; + this.getControl($field + '_time').value = $value[1]; + break;*/ + + default: + this.getControl($field).value = ($value === null) ? '' : $value; + break; + } +} + +MultiInputControl.prototype.formatValue = function ($field, $value) { + if (this.Controls[$field]['type'] == 'select') { + var $i = 0; + var $control = this.getControl($field); + while ($i < $control.options.length) { + if ($control.options[$i].value == $value) { + $value = $control.options[$i].innerHTML; + break; + } + $i++; + } + + } + + return $value; +} + +MultiInputControl.prototype.formatLine = function($record_index) { + var $ret = this.ResultMask; + + for (var $field_name in this.Controls) { + var $value = this.Records[$record_index][$field_name]; + $ret = $ret.replace('#' + $field_name + '#', this.formatValue($field_name, $value)); + } + + return $ret; +} + +MultiInputControl.prototype.makeRequest = function($request_type, $record, $skip_index) { + var $url = this.ValidateURL; + for (var $field_name in $record) { + $url += '&' + this.FieldMask.replace('#FIELD_NAME#', $field_name) + '=' + escape($record[$field_name]); + } + + Request.makeRequest($url, this.BusyRequest, '', this.successCallback, this.errorCallback, [$request_type, $record, $skip_index], this); +} + +MultiInputControl.prototype.AddRecord = function() { + var $record = this.prepareRecord(); + + if (this.InEditing) { + // already in editing + var $record_index = this.getControl(this.FieldName, 'minput').selectedIndex; + this.makeRequest('SaveRecord', $record, $record_index); + return ; + } + + if (this.hasPermission('add')) { + this.makeRequest('AddRecord', $record, false); + } +} + +MultiInputControl.prototype.EditRecord = function() { + var $record_index = this.getControl(this.FieldName, 'minput').selectedIndex; + if ($record_index == -1 || this.InEditing) { + // no record selected + return ; + } + + this.InEditing = true; + var $edit_record = this.Records[$record_index]; + + for (var $field_name in $edit_record) { + this.setControlValue($field_name, $edit_record[$field_name]); + } + + this.getControl(this.FieldName, 'add_button').value = this.Messages['save_button']; + this.getControl(this.FieldName, 'minput').disabled = true; + + this.SetButtonState('edit', false); + this.SetButtonState('delete', false); +} + + +MultiInputControl.prototype.ResetControls = function() { + for (var $field_name in this.Controls) { + this.setControlValue($field_name, null); + } + + this.Errors = new Array (); +} + +MultiInputControl.prototype.CancelEditing = function() { + this.ResetControls(); + + this.getControl(this.FieldName, 'add_button').value = this.Messages['add_button']; + this.getControl(this.FieldName, 'minput').disabled = false; + + this.SetButtonState('edit', true); + this.SetButtonState('delete', true); + this.InEditing = false; +} + +MultiInputControl.prototype.ShowRecord = function($record_index) { + var $options = this.getControl(this.FieldName, 'minput').options; + + if ($record_index < $options.length) { + // update existing record + $options[$record_index].innerHTML = this.formatLine($record_index); + } + else { + // create new record + var $new_option = document.createElement('OPTION'); + $options.add($new_option, $options.length); + $new_option.value = $record_index; // will be used in move up/down & sorting (if any) + $new_option.innerHTML = this.formatLine($record_index); + } +} + +MultiInputControl.prototype.DeleteRecords = function() { + if (!confirm(this.Messages['delete_confirm'])) { + return ; + } + + var $control = this.getControl(this.FieldName, 'minput'); + var $i = $control.length - 1; + while ($i >= 0) { + if ($control.options[$i].selected == true) { + this.Records.splice($i, 1); + $control.remove($i); + } + $i--; + } + + this.SaveValues(); +} + +MultiInputControl.prototype.AddFromXML = function($xml) { + var $document = getDocumentFromXML($xml); + this.ProcessXMLNode($document); +} + +MultiInputControl.prototype.ProcessXMLNode = function($node, $root_name) { + for (var $i = 0; $i < $node.childNodes.length; $i++) { + var $child = $node.childNodes.item($i); + if ($child.tagName == 'record') { + this.Records[this.Records.length] = new Array (); + this.ProcessXMLNode($child, $root_name); + this.ShowRecord(this.Records.length - 1); + } + else if ($child.tagName == 'field') { + if ($root_name == 'records') { + this.Records[this.Records.length - 1][$child.getAttribute('name')] = $child.firstChild.nodeValue; + } + else if ($root_name == 'errors') { + this.Errors[$child.getAttribute('name')] = $child.firstChild.nodeValue; + } + } + else if ($child.tagName == 'records') { + this.ProcessXMLNode($child, $child.tagName); + } + else if ($child.tagName == 'errors') { + this.Errors = new Array (); + this.ProcessXMLNode($child, $child.tagName); + } + } +} + +MultiInputControl.prototype.LoadValues = function() { + var $current_value = this.getControl(this.FieldName).value; + if ($current_value) { + this.AddFromXML($current_value); + } +} + +MultiInputControl.prototype.SaveValues = function() { + var $i = 0; + var $xml = ''; + while ($i < this.Records.length) { + $xml += ''; + for (var $field_name in this.Controls) { + $xml += '' + this.Records[$i][$field_name] + ''; + } + $xml += ''; + $i++; + } + + this.getControl(this.FieldName).value = $xml ? '' + $xml + '' : ''; +} + +MultiInputControl.prototype.prepareRecord = function() { + var $record = new Array (); + for (var $field_name in this.Controls) { + $record[$field_name] = this.getControlValue($field_name); + } + return $record; +} + +MultiInputControl.prototype.ValidateRecord = function($record, $skip_index) { + var $valid = true; + + $valid = $valid && this.ValidateRequired($record); + $valid = $valid && this.ValidateUnique($record, $skip_index); + + return $valid; +} + +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; + } + } + return true; +} + +MultiInputControl.prototype.compareRecords = function($record_a, $record_b) { + var $equals = true; + + for (var $field_name in $record_a) { + if ($record_a[$field_name] !== $record_b[$field_name]) { + return false; + } + } + + return $equals; +} + +MultiInputControl.prototype.ValidateUnique = function($record, $skip_index) { + var $i = 0; + if (!isset($skip_index)) { + $skip_index = -1; + } + + while ($i < this.Records.length) { + if ($i != $skip_index && this.compareRecords($record, this.Records[$i])) { + alert(this.Messages['unique_error']); + return false; + } + $i++; + } + + return true; +} + +MultiInputControl.prototype.displayErrors = function() { + var $has_errors = false; + var $field_label = ''; + for (var $field_name in this.Errors) { + $has_errors = true; + alert(this.FieldLabels[$field_name] + ': ' + this.Errors[$field_name]); + } + + return $has_errors; +} + +MultiInputControl.prototype.successCallback = function($request, $params, $object) { + if (Request.processRedirect($request) === true) { + return ; + } + + var $document = getDocumentFromXML($request.responseText); + $object.ProcessXMLNode($document); + + if ($object.displayErrors()) { + return ; + } + + switch ($params[0]) { + case 'AddRecord': + if (!$object.ValidateRecord($params[1])) { + return ; + } + $object.Records.push($params[1]); + + $object.ShowRecord($object.Records.length - 1); + $object.ResetControls(); + break; + + case 'SaveRecord': + if (!$object.ValidateRecord($params[1], $params[2])) { + return ; + } + + $object.Records[$params[2]] = $params[1]; + $object.ShowRecord($params[2]); + + $object.CancelEditing(); + break; + } + + $object.SaveValues(); +} + +MultiInputControl.prototype.errorCallback = function($request, $params, $object) { + alert('AJAX Error; class: MultiInputControl; ' + Request.getErrorHtml($request)); +} + +MultiInputControl.prototype.SetMessage = function($pseudo, $message) { + this.Messages[$pseudo] = $message; +} + +MultiInputControl.prototype.InitEvents = function() { + var $button = null; + var $var_name = this.FieldName; + + $button = this.getControl(this.FieldName, 'add_button'); + $button.onclick = function() { eval($var_name).AddRecord() }; + + if (this.hasPermission('add') || this.hasPermission('edit')) { + $button = this.getControl(this.FieldName, 'cancel_button'); + $button.onclick = function() { eval($var_name).CancelEditing() }; + } + + if (this.hasPermission('edit')) { + $button = this.getControl(this.FieldName, 'edit_button'); + $button.onclick = function() { eval($var_name).EditRecord() }; + + $button = this.getControl(this.FieldName, 'minput'); + $button.ondblclick = function() { eval($var_name).EditRecord() }; + } + + if (this.hasPermission('delete')) { + $button = this.getControl(this.FieldName, 'delete_button'); + $button.onclick = function() { eval($var_name).DeleteRecords() }; + } +} + +MultiInputControl.prototype.hasPermission = function ($perm_name) { + return in_array($perm_name, this.Permissions); +} + +MultiInputControl.prototype.SetPermission = function ($perm_name, $perm_value) { + var $perm_index = array_search($perm_name, this.Permissions); + + if ($perm_index != -1) { + // permission found + if (!$perm_value) { + this.Permissions = this.Permissions.splice($perm_index, 1); + } + } + else if ($perm_value) { + // permission not found + this.Permissions.push($perm_name); + } +} + +MultiInputControl.prototype.SetButtonState = function ($button, $mode) { + if (!this.hasPermission($button)) { + return ; + } + + var $button = this.getControl(this.FieldName, $button + '_button'); + + $button.disabled = !$mode; + $button.className = $mode ? 'button' : 'button-disabled'; +} + + +// ======================================================================================= + +function EditPickerControl($field_name, $field_mask) { + this.FieldName = $field_name; + this.FieldMask = $field_mask; + this.Messages = new Array (); + + this.InitEvents(); + select_sort( this.getControl('available') ); +} + +EditPickerControl.prototype.getControl = function ($type) { + var $control_id = this.FieldMask + (isset($type) ? '_' + $type : ''); + return document.getElementById($control_id); +} + +EditPickerControl.prototype.SetMessage = function ($pseudo, $message) { + this.Messages[$pseudo] = $message; +} + +EditPickerControl.prototype.SaveValues = function () { + this.getControl().value = select_to_string(this.getControl('selected')); + this.getControl('available_field').value = select_to_string(this.getControl('available')); +} + +EditPickerControl.prototype.MoveLeft = function () { + move_selected(this.getControl('available'), this.getControl('selected'), this.Messages['nothing_selected']); + this.SaveValues(); +} + +EditPickerControl.prototype.MoveRight = function () { + move_selected(this.getControl('selected'), this.getControl('available'), this.Messages['nothing_selected']); + select_sort( this.getControl('available') ); + this.SaveValues(); +} + +EditPickerControl.prototype.InitEvents = function() { + var $button = null; + var $var_name = this.FieldName; + + $button = this.getControl('move_left_button'); + $button.onclick = function() { eval($var_name).MoveLeft() }; + + $button = this.getControl('move_right_button'); + $button.onclick = function() { eval($var_name).MoveRight() }; +} \ No newline at end of file