You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rave.apache.org by ca...@apache.org on 2011/07/27 17:59:41 UTC
svn commit: r1151514 - in /incubator/rave/trunk/rave-portal/src/main/webapp:
css/default.css script/rave.js
Author: carlucci
Date: Wed Jul 27 15:59:41 2011
New Revision: 1151514
URL: http://svn.apache.org/viewvc?rev=1151514&view=rev
Log:
RAVE-111: implement proper UI validation checking of user prefs that are marked required. This is a subtask of RAVE-27: Implement User Prefs.
https://issues.apache.org/jira/browse/RAVE-111
Modified:
incubator/rave/trunk/rave-portal/src/main/webapp/css/default.css
incubator/rave/trunk/rave-portal/src/main/webapp/script/rave.js
Modified: incubator/rave/trunk/rave-portal/src/main/webapp/css/default.css
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/webapp/css/default.css?rev=1151514&r1=1151513&r2=1151514&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/webapp/css/default.css (original)
+++ incubator/rave/trunk/rave-portal/src/main/webapp/css/default.css Wed Jul 27 15:59:41 2011
@@ -162,12 +162,42 @@ h1, h2, h3, h4, h5, h6 {
cursor: move;
}
+/*** various widget preference related classes ***/
.widget-prefs {
border: 1px solid #D3D3D3;
background-color: white;
display: none;
}
+.widget-prefs-required-text {
+ font-size: 0.8em;
+ margin-top: 5px;
+ margin-bottom: 5px;
+}
+
+.widget-prefs-label {
+ vertical-align: top;
+ font-size: 0.8em;
+ text-align: right;
+}
+
+.widget-prefs-label-required {
+
+}
+
+.widget-prefs-input {
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 0.8em;
+}
+
+.widget-prefs-input-required {
+
+}
+
+.widget-prefs-input-failed-validation {
+ background-color: yellow;
+}
+
.widget {
padding: 5px;
background-color: white;
Modified: incubator/rave/trunk/rave-portal/src/main/webapp/script/rave.js
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/webapp/script/rave.js?rev=1151514&r1=1151513&r2=1151514&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/webapp/script/rave.js (original)
+++ incubator/rave/trunk/rave-portal/src/main/webapp/script/rave.js Wed Jul 27 15:59:41 2011
@@ -29,17 +29,16 @@ var rave = rave || (function() {
* NOTE: The UI implementation has dependencies on jQuery and jQuery UI
*/
var ui = (function() {
- var TEXT_FIELD_TEMPLATE = "<tr><td>{displayName}</td><td><input type='text' id='{name}' name='{name}' value='{value}'></td></tr>";
- var CHECKBOX_TEMPLATE = "<tr><td>{displayName}</td><td><input type='checkbox' id='{name}' name='{name}' {checked}></td></tr>";
- var SELECT_FIELD_TEMPLATE = "<tr><td>{displayName}</td><td><select id='{name}' name='{name}'>{options}</select></td></tr>";
+ var TEXT_FIELD_TEMPLATE = "<tr>{prefLabelTemplate}<td><input type='text' id='{name}' name='{name}' value='{value}' class='{class}'></td></tr>";
+ var CHECKBOX_TEMPLATE = "<tr>{prefLabelTemplate}<td><input type='checkbox' id='{name}' name='{name}' class='{class}' {checked}></td></tr>";
+ var SELECT_FIELD_TEMPLATE = "<tr>{prefLabelTemplate}<td><select id='{name}' name='{name}' class='{class}'>{options}</select></td></tr>";
var SELECT_OPTION_TEMPLATE = "<option value='{value}' {selected}>{displayValue}</option>";
- var TEXTAREA_TEMPLATE = "<tr><td>{displayName}</td><td><textarea id='{name}' name='{name}' rows='5' cols='12'>{value}</textarea></td></tr>";
+ var TEXTAREA_TEMPLATE = "<tr>{prefLabelTemplate}<td><textarea id='{name}' name='{name}' rows='5' cols='12' class='{class}'>{value}</textarea></td></tr>";
var HIDDEN_FIELD_TEMPLATE = "<input type='hidden' id='{name}' name='{name}' value='{value}'>";
var PREFS_SAVE_BUTTON_TEMPLATE = "<button type='button' id='{elementId}'>Save</button>";
var PREFS_CANCEL_BUTTON_TEMPLATE = "<button type='button' id='{elementId}'>Cancel</button>";
- var NAME_REGEX = /{name}/g;
- var DISPLAY_NAME_REGEX = /{displayName}/g;
+ var NAME_REGEX = /{name}/g;
var VALUE_REGEX = /{value}/g;
var OPTIONS_REGEX = /{options}/g;
var SELECTED_REGEX = /{selected}/g;
@@ -47,6 +46,14 @@ var rave = rave || (function() {
var DISPLAY_VALUE_REGEX = /{displayValue}/g;
var PIPE_REGEX = /\|/g;
var ELEMENT_ID_REGEX = /{elementId}/g;
+ var PREF_LABEL_TEMPLATE_REGEX = /{prefLabelTemplate}/g;
+ var CLASS_REGEX = /{class}/g;
+
+ var WIDGET_PREFS_LABEL_CLASS = "widget-prefs-label";
+ var WIDGET_PREFS_LABEL_REQUIRED_CLASS = "widget-prefs-label-required";
+ var WIDGET_PREFS_INPUT_CLASS = "widget-prefs-input";
+ var WIDGET_PREFS_INPUT_REQUIRED_CLASS = "widget-prefs-input-required";
+ var WIDGET_PREFS_INPUT_FAILED_VALIDATION = "widget-prefs-input-failed-validation";
function WIDGET_PREFS_EDIT_BUTTON(regionWidgetId) {
return "widget-" + regionWidgetId + "-prefs";
@@ -162,21 +169,74 @@ var rave = rave || (function() {
});
}
}
+ /**
+ * Utility function to generate the html label for a userPref
+ * based on if it is required or not
+ */
+ function generatePrefLabelMarkup(userPref) {
+ var markup = [];
+ var prefLabel = (userPref.required) ? "* " + userPref.displayName : userPref.displayName;
+ markup.push("<td class='");
+ markup.push(WIDGET_PREFS_LABEL_CLASS);
+ if (userPref.required) {
+ markup.push(" ");
+ markup.push(WIDGET_PREFS_LABEL_REQUIRED_CLASS);
+ }
+ markup.push("'>");
+ markup.push(prefLabel);
+ markup.push("</td>");
+ return markup.join("");
+ }
+
+ /**
+ * Utility function to generate the css class(es) of a userPref input
+ * field based on if it is required or not
+ */
+ function generatePrefInputClassMarkup(userPref) {
+ var markup = [];
+ markup.push(WIDGET_PREFS_INPUT_CLASS);
+ if (userPref.required) {
+ markup.push(" ");
+ markup.push(WIDGET_PREFS_INPUT_REQUIRED_CLASS);
+ }
+ return markup.join("");
+ }
+
+ /**
+ * Utility function to validate a userPref input element
+ */
+ function validatePrefInput(element) {
+ var isValid = true;
+ var jqEl = $(element);
+ // if the input is required verify it's trimmed input length is > 0
+ if (jqEl.hasClass(WIDGET_PREFS_INPUT_REQUIRED_CLASS)) {
+ isValid = $.trim(jqEl.val()).length > 0;
+ }
+
+ return isValid;
+ }
function editPrefsAction(args) {
var regionWidget = getWidgetById(args.data.id);
var userPrefs = regionWidget.metadata.userPrefs;
-
+ var hasRequiredUserPrefs = false;
+
var prefsFormMarkup = [];
prefsFormMarkup.push("<table>");
for (var prefName in userPrefs) {
var userPref = userPrefs[prefName];
var currentPrefValue = regionWidget.userPrefs[userPref.name];
+ var prefLabelMarkup = generatePrefLabelMarkup(userPref);
+ var prefInputClassMarkup = generatePrefInputClassMarkup(userPref);
+ if (userPref.required) {
+ hasRequiredUserPrefs = true;
+ }
switch (userPref.dataType) {
case "STRING":
- prefsFormMarkup.push(TEXT_FIELD_TEMPLATE.replace(DISPLAY_NAME_REGEX, userPref.displayName)
+ prefsFormMarkup.push(TEXT_FIELD_TEMPLATE.replace(PREF_LABEL_TEMPLATE_REGEX, prefLabelMarkup)
+ .replace(CLASS_REGEX, prefInputClassMarkup)
.replace(NAME_REGEX, userPref.name)
.replace(VALUE_REGEX, typeof currentPrefValue != "undefined" ? currentPrefValue :
userPref.defaultValue));
@@ -186,7 +246,8 @@ var rave = rave || (function() {
currentPrefValue === 'true' || currentPrefValue === true :
userPref.defaultValue === 'true' || userPref.defaultValue === true;
- prefsFormMarkup.push(CHECKBOX_TEMPLATE.replace(DISPLAY_NAME_REGEX, userPref.displayName)
+ prefsFormMarkup.push(CHECKBOX_TEMPLATE.replace(PREF_LABEL_TEMPLATE_REGEX, prefLabelMarkup)
+ .replace(CLASS_REGEX, prefInputClassMarkup)
.replace(NAME_REGEX, userPref.name)
.replace(CHECKED_REGEX, checked ? "checked" : ""));
break;
@@ -202,14 +263,16 @@ var rave = rave || (function() {
.replace(SELECTED_REGEX, selected ? "selected" : ""));
}
- prefsFormMarkup.push(SELECT_FIELD_TEMPLATE.replace(DISPLAY_NAME_REGEX, userPref.displayName)
+ prefsFormMarkup.push(SELECT_FIELD_TEMPLATE.replace(PREF_LABEL_TEMPLATE_REGEX, prefLabelMarkup)
+ .replace(CLASS_REGEX, prefInputClassMarkup)
.replace(NAME_REGEX, userPref.name)
.replace(OPTIONS_REGEX, options.join("")));
break;
case "LIST":
var values = typeof currentPrefValue != "undefined" ? currentPrefValue : userPref.defaultValue;
values = values.replace(PIPE_REGEX, "\n");
- prefsFormMarkup.push(TEXTAREA_TEMPLATE.replace(DISPLAY_NAME_REGEX, userPref.displayName)
+ prefsFormMarkup.push(TEXTAREA_TEMPLATE.replace(PREF_LABEL_TEMPLATE_REGEX, prefLabelMarkup)
+ .replace(CLASS_REGEX, prefInputClassMarkup)
.replace(NAME_REGEX, userPref.name)
.replace(VALUE_REGEX, values));
break;
@@ -219,6 +282,11 @@ var rave = rave || (function() {
userPref.defaultValue));
}
}
+
+ // if this widget has one or more required inputs display the helper message
+ if (hasRequiredUserPrefs) {
+ prefsFormMarkup.push("<tr><td colspan='2' class='widget-prefs-required-text'>* indicates a required input</td></tr>");
+ }
prefsFormMarkup.push("<tr><td colspan='2'>");
prefsFormMarkup.push(PREFS_SAVE_BUTTON_TEMPLATE.replace(ELEMENT_ID_REGEX,
@@ -245,9 +313,21 @@ var rave = rave || (function() {
var prefsElement = $("#" + WIDGET_PREFS_CONTENT(regionWidget.regionWidgetId));
var updatedPrefs = {};
+ var hasValidationErrors = false;
+ // note that validation of "required" prefs is only done for text and
+ // textarea types, since those represent STRING and LIST inputs, and
+ // are the only inputs that could potentially contain empty data
prefsElement.find("*").filter(":input").each(function(index, element) {
switch (element.type) {
- case "text":
+ case "text":
+ if (!validatePrefInput(element)) {
+ hasValidationErrors = true;
+ $(element).addClass(WIDGET_PREFS_INPUT_FAILED_VALIDATION);
+ } else {
+ updatedPrefs[element.name] = $(element).val();
+ $(element).removeClass(WIDGET_PREFS_INPUT_FAILED_VALIDATION);
+ }
+ break;
case "select-one":
case "hidden":
updatedPrefs[element.name] = $(element).val();
@@ -256,25 +336,37 @@ var rave = rave || (function() {
updatedPrefs[element.name] = $(element).is(':checked').toString();
break;
case "textarea":
- var valuesToPersist = [];
- var textareaValues = $(element).val().split("\n");
- for (var i = 0; i < textareaValues.length; i++) {
- var value = $.trim(textareaValues[i]);
- if (value.length > 0) {
- valuesToPersist.push(value);
+ if (!validatePrefInput(element)) {
+ hasValidationErrors = true;
+ $(element).addClass(WIDGET_PREFS_INPUT_FAILED_VALIDATION);
+ } else {
+ var valuesToPersist = [];
+ var textareaValues = $(element).val().split("\n");
+ for (var i = 0; i < textareaValues.length; i++) {
+ var value = $.trim(textareaValues[i]);
+ if (value.length > 0) {
+ valuesToPersist.push(value);
+ }
}
+ updatedPrefs[element.name] = valuesToPersist.join("|");
+ $(element).removeClass(WIDGET_PREFS_INPUT_FAILED_VALIDATION);
}
- updatedPrefs[element.name] = valuesToPersist.join("|");
break;
}
});
- if(typeof regionWidget.savePreferences == "function") {
- regionWidget.savePreferences(updatedPrefs);
- }
+ // check to see if one or more input prefs had validation errors
+ if (hasValidationErrors) {
+ // focus on the first input that has validation errors
+ prefsElement.find("." + WIDGET_PREFS_INPUT_FAILED_VALIDATION).first().focus();
+ } else {
+ if(typeof regionWidget.savePreferences == "function") {
+ regionWidget.savePreferences(updatedPrefs);
+ }
- prefsElement.html("");
- prefsElement.hide();
+ prefsElement.html("");
+ prefsElement.hide();
+ }
}
function cancelEditPrefsAction(args) {