From fc71a984bf06182d7a41d2d6bb95e3f5667e3f80 Mon Sep 17 00:00:00 2001 From: Roland Gruber Date: Sat, 20 Oct 2018 19:41:18 +0200 Subject: [PATCH] added multi-value field functions for self service --- lam/lib/baseModule.inc | 111 +++++++++++++++++++++++++ lam/style/responsive/105_normalize.css | 1 + lam/templates/lib/500_lam.js | 52 ++++++++++++ 3 files changed, 164 insertions(+) diff --git a/lam/lib/baseModule.inc b/lam/lib/baseModule.inc index 2f2bd6af..a1f38af2 100644 --- a/lam/lib/baseModule.inc +++ b/lam/lib/baseModule.inc @@ -1558,6 +1558,117 @@ abstract class baseModule { } } + /** + * Adds a simple text input field for the self service. + * The field name will be the same as the class name plus "_" plus attribute name (e.g. posixAccount_cn). + * + * @param array $container array that is used as return value for getSelfServiceOptions() + * @param String $name attribute name (== field name) + * @param String $label label to display in front of input field + * @param array $fields list of active fields + * @param array $attributes attributes of LDAP account + * @param array $readOnlyFields list of read-only fields + * @param boolean $required field is required + * @param boolean $isTextArea display as text area + */ + protected function addMultiValueSelfServiceTextField(&$container, $name, $label, &$fields, &$attributes, &$readOnlyFields, $required = false, $isTextArea = false) { + $values = array(); + if (isset($attributes[$name][0])) { + $values = $attributes[$name]; + } + $readOnly = in_array($name, $readOnlyFields); + $field = new htmlResponsiveRow(); + if (!$readOnly) { + if (empty($values)) { + $values[] = ''; + } + $fieldNamePrefix = get_class($this) . '_' . $name . '_'; + for ($i = 0; $i < sizeof($values); $i++) { + $fieldRow = new htmlResponsiveRow(); + $value = $values[$i]; + if (!$isTextArea) { + $inputField = new htmlInputField($fieldNamePrefix . $i, $value); + $inputField->setRequired($required); + $inputField->setFieldSize(null); + } + else { + $inputField = new htmlInputTextarea($fieldNamePrefix . $i, $value, null, null); + } + $fieldRow->add($inputField, 9); + if (!empty($value)) { + $linkGroup = new htmlGroup(); + $delLink = new htmlLink(null, '#', '../../graphics/del.png'); + $delLink->setOnClick('window.lam.selfservice.delMultiValue(\'' . $fieldNamePrefix . '\', this); return false;'); + $delLink->setCSSClasses(array('del-link')); + $linkGroup->addElement($delLink); + if ($i === (sizeof($values) - 1)) { + $addLink = new htmlLink(null, '#', '../../graphics/add.png'); + $addLink->setOnClick('window.lam.selfservice.addMultiValue(\'' . $fieldNamePrefix . '\', this); return false;'); + $addLink->setCSSClasses(array('add-link', 'margin-left5')); + $linkGroup->addElement($addLink); + } + $fieldRow->add($linkGroup, 3); + } + $field->add($fieldRow, 12); + } + } + else { + foreach ($values as $value) { + if (!$isTextArea) { + $inputField = new htmlOutputText($value); + } + else { + $inputField = new htmlOutputText($value); + $inputField->setPreformatted(true); + } + $field->add($inputField, 12); + } + } + $row = new htmlResponsiveRow(); + $label = new htmlOutputText($this->getSelfServiceLabel($name, $label)); + $label->setMarkAsRequired($required); + $row->addLabel($label); + $row->addField($field); + $container[$name] = $row; + } + + /** + * Checks the input value of a self service multi-value text field. + * The field name must be the same as the class name plus "_" plus attribute name (e.g. posixAccount_cn). + * If validation is used then there must exist a message named [{attribute name}][0] (e.g. $this->messages['street'][0]). + * + * @param array $container return value of checkSelfServiceOptions() + * @param String $name attribute name + * @param array $attributes LDAP attributes + * @param string $fields input fields + * @param array $readOnlyFields list of read-only fields + * @param String $validationID validation ID for get_preg() + */ + protected function checkMultiValueSelfServiceTextField(&$container, $name, &$attributes, $fields, &$readOnlyFields, $validationID = null) { + if (in_array($name, $fields) && !in_array($name, $readOnlyFields)) { + $fieldName = get_class($this) . '_' . $name; + $valuesNew = array(); + foreach ($_POST as $postKey => $postValue) { + if (strpos($postKey, $fieldName) === false) { + continue; + } + if (empty($postValue)) { + continue; + } + if (($validationID != null) && !get_preg($postValue, $validationID)) { + $container['messages'][] = $this->messages[$name][0]; + return; + } + $valuesNew[] = $postValue; + } + $valuesOld = isset($attributes[$name]) ? $attributes[$name] : array(); + $intersect = array_intersect($valuesOld, $valuesNew); + if ((sizeof($valuesOld) != sizeof($valuesNew)) || (sizeof($intersect) != sizeof($valuesOld))) { + $container['mod'][$name] = $valuesNew; + } + } + } + /** * Returns a list of managed object classes for this module. * diff --git a/lam/style/responsive/105_normalize.css b/lam/style/responsive/105_normalize.css index 47b010e4..e624df56 100644 --- a/lam/style/responsive/105_normalize.css +++ b/lam/style/responsive/105_normalize.css @@ -56,6 +56,7 @@ hr { pre { font-family: monospace, monospace; /* 1 */ font-size: 1em; /* 2 */ + margin: 0em; } /* Text-level semantics diff --git a/lam/templates/lib/500_lam.js b/lam/templates/lib/500_lam.js index 9a1ed75f..d6ac8351 100644 --- a/lam/templates/lib/500_lam.js +++ b/lam/templates/lib/500_lam.js @@ -1105,6 +1105,58 @@ window.lam.html.updateDnSelection = function(el, fieldId, tokenName, tokenValue) }); } +window.lam.selfservice = window.lam.selfservice || {}; + +/** + * Deletes a value of a multi-value field. + * + * @param fieldNamePrefix prefix of input field name + * @param delButton delete button that was clicked + */ +window.lam.selfservice.delMultiValue = function(fieldNamePrefix, delButton) { + var fields = jQuery("input[name^='" + fieldNamePrefix + "']"); + var isOnlyOneField = (fields.length === 1); + if (!isOnlyOneField) { + // move add button if present + var addButton = jQuery(delButton).siblings('.add-link'); + if (addButton.length === 1) { + var lastLastDelLink = jQuery(fields[fields.length - 2]).parent().parent().find('.del-link'); + var lastLastDelLinkParent = jQuery(lastLastDelLink[0]).parent(); + jQuery(addButton[0]).appendTo(lastLastDelLinkParent[0]); + } + // delete row + var row = jQuery(delButton).closest(".row").parent(); + row.remove(); + } + else { + fields[0].value = ''; + } +}; + +/** + * Adds a value to a multi-value field. + * + * @param fieldNamePrefix prefix of input field name + * @param addButton add button that was clicked + */ +window.lam.selfservice.addMultiValue = function(fieldNamePrefix, addButton) { + var fields = jQuery("input[name^='" + fieldNamePrefix + "']"); + // get next field number + var lastFieldName = fields[fields.length - 1].name; + var lastFieldNameIndex = lastFieldName.substring(fieldNamePrefix.length); + var newFieldNameIndex = parseInt(lastFieldNameIndex) + 1; + // copy row + var row = jQuery(addButton).closest(".row").parent(); + var clone = row.clone(); + clone = clone.appendTo(row.parent()); + var cloneInput = clone.find("input[name^='" + fieldNamePrefix + "']"); + cloneInput[0].name = fieldNamePrefix + newFieldNameIndex; + cloneInput[0].id = fieldNamePrefix + newFieldNameIndex; + cloneInput[0].value = ''; + // delete add link from old row + jQuery(addButton).remove(); +}; + jQuery(document).ready(function() { window.lam.gui.equalHeight(); window.lam.form.autoTrim();