You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@roller.apache.org by sn...@apache.org on 2016/09/05 21:30:54 UTC
roller git commit: Bootstrapification of "Roller Configuration" or
GlobalConfig page.
Repository: roller
Updated Branches:
refs/heads/bootstrap-ui 2f4b2b3e1 -> 29adfd3f8
Bootstrapification of "Roller Configuration" or GlobalConfig page.
Project: http://git-wip-us.apache.org/repos/asf/roller/repo
Commit: http://git-wip-us.apache.org/repos/asf/roller/commit/29adfd3f
Tree: http://git-wip-us.apache.org/repos/asf/roller/tree/29adfd3f
Diff: http://git-wip-us.apache.org/repos/asf/roller/diff/29adfd3f
Branch: refs/heads/bootstrap-ui
Commit: 29adfd3f879998271de3d24b9bb8db225f828c87
Parents: 2f4b2b3
Author: Dave Johnson <sn...@gmail.com>
Authored: Mon Sep 5 17:30:10 2016 -0400
Committer: Dave Johnson <sn...@gmail.com>
Committed: Mon Sep 5 17:30:10 2016 -0400
----------------------------------------------------------------------
.../weblogger/config/runtime/ConfigDef.java | 29 ++-
.../weblogger/config/runtime/PropertyDef.java | 6 +-
.../ui/struts2/admin/GlobalConfig.java | 165 ++++++++-------
.../resources/ApplicationResources.properties | 8 +-
.../weblogger/config/runtimeConfigDefs.xml | 8 +-
app/src/main/resources/struts.xml | 1 +
.../webapp/WEB-INF/jsps/admin/GlobalConfig.jsp | 201 +++++++++++--------
7 files changed, 250 insertions(+), 168 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/roller/blob/29adfd3f/app/src/main/java/org/apache/roller/weblogger/config/runtime/ConfigDef.java
----------------------------------------------------------------------
diff --git a/app/src/main/java/org/apache/roller/weblogger/config/runtime/ConfigDef.java b/app/src/main/java/org/apache/roller/weblogger/config/runtime/ConfigDef.java
index 7a19408..f7b583d 100644
--- a/app/src/main/java/org/apache/roller/weblogger/config/runtime/ConfigDef.java
+++ b/app/src/main/java/org/apache/roller/weblogger/config/runtime/ConfigDef.java
@@ -15,27 +15,27 @@
* copyright in this work, please see the NOTICE file in the top level
* directory of this distribution.
*/
-/*
- * ConfigDef.java
- *
- * Created on June 4, 2005, 1:10 PM
- */
-
package org.apache.roller.weblogger.config.runtime;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+
/**
* Represents a logic grouping of runtime configuration properties.
* Each ConfigDef may contain 0 or more DisplayGroups.
*
+ * Created on June 4, 2005, 1:10 PM
* @author Allen Gilliland
*/
public class ConfigDef {
private List<DisplayGroup> displayGroups = null;
private String name = null;
+
+ Map<String, PropertyDef> propertyDefs = null;
public ConfigDef() {
@@ -53,8 +53,8 @@ public class ConfigDef {
public boolean removeDisplayGroup(DisplayGroup group) {
return this.displayGroups.remove(group);
}
-
-
+
+
public String toString() {
return name;
}
@@ -74,5 +74,16 @@ public class ConfigDef {
public void setName(String name) {
this.name = name;
}
-
+
+ public PropertyDef getPropertyDef( String name ) {
+ if ( propertyDefs == null ) {
+ propertyDefs = new HashMap<>();
+ for (DisplayGroup displayGroup : getDisplayGroups()) {
+ for (PropertyDef propertyDef : displayGroup.getPropertyDefs()) {
+ propertyDefs.put( propertyDef.getName(), propertyDef );
+ }
+ }
+ }
+ return propertyDefs.get( name );
+ }
}
http://git-wip-us.apache.org/repos/asf/roller/blob/29adfd3f/app/src/main/java/org/apache/roller/weblogger/config/runtime/PropertyDef.java
----------------------------------------------------------------------
diff --git a/app/src/main/java/org/apache/roller/weblogger/config/runtime/PropertyDef.java b/app/src/main/java/org/apache/roller/weblogger/config/runtime/PropertyDef.java
index 636d754..032bd15 100644
--- a/app/src/main/java/org/apache/roller/weblogger/config/runtime/PropertyDef.java
+++ b/app/src/main/java/org/apache/roller/weblogger/config/runtime/PropertyDef.java
@@ -52,11 +52,15 @@ public class PropertyDef {
public String toString() {
return "["+name+","+key+","+type+","+defaultValue+","+rows+","+cols+"]";
}
-
+
public String getName() {
return name;
}
+ public String getNameWithUnderbars() {
+ return name.replace(".", "_");
+ }
+
public void setName(String name) {
this.name = name;
}
http://git-wip-us.apache.org/repos/asf/roller/blob/29adfd3f/app/src/main/java/org/apache/roller/weblogger/ui/struts2/admin/GlobalConfig.java
----------------------------------------------------------------------
diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/admin/GlobalConfig.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/admin/GlobalConfig.java
index 6f474b7..9ab3d79 100644
--- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/admin/GlobalConfig.java
+++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/admin/GlobalConfig.java
@@ -18,11 +18,9 @@
package org.apache.roller.weblogger.ui.struts2.admin;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import javax.servlet.http.HttpServletRequest;
+
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -34,6 +32,7 @@ import org.apache.roller.weblogger.business.plugins.PluginManager;
import org.apache.roller.weblogger.business.plugins.comment.WeblogEntryCommentPlugin;
import org.apache.roller.weblogger.config.WebloggerRuntimeConfig;
import org.apache.roller.weblogger.config.runtime.ConfigDef;
+import org.apache.roller.weblogger.config.runtime.PropertyDef;
import org.apache.roller.weblogger.config.runtime.RuntimeConfigDefs;
import org.apache.roller.weblogger.pojos.GlobalPermission;
import org.apache.roller.weblogger.pojos.RuntimeConfigProperty;
@@ -47,21 +46,21 @@ import org.apache.struts2.interceptor.ServletRequestAware;
* Action which handles editing of global configuration.
*/
public class GlobalConfig extends UIAction implements ParameterAware, ServletRequestAware {
-
+
private static Log log = LogFactory.getLog(GlobalConfig.class);
-
+
// the request parameters
private Map<String, String[]> params = Collections.emptyMap();
-
+
// map of config properties
private Map<String, RuntimeConfigProperty> properties = Collections.emptyMap();
-
+
// the runtime config def used to populate the display
private ConfigDef globalConfigDef = null;
-
+
// list of comment plugins
private List<WeblogEntryCommentPlugin> pluginsList = Collections.emptyList();
-
+
// comment plugins that are enabled. this is what the html form submits to
private String[] commentPlugins = new String[0];
@@ -69,28 +68,30 @@ public class GlobalConfig extends UIAction implements ParameterAware, ServletReq
// GET on the GlobalConfig!save URL and thus sets all checkboxes to false
private String httpMethod = "GET";
+ private ResourceBundle bundle = ResourceBundle.getBundle("ApplicationResources");
+
// weblogs for frontpage blog chooser
private Collection<Weblog> weblogs;
-
+
public GlobalConfig() {
this.actionName = "globalConfig";
this.desiredMenu = "admin";
this.pageTitle = "configForm.title";
}
-
-
+
+
@Override
public boolean isWeblogRequired() {
return false;
}
-
+
@Override
public List<String> requiredGlobalPermissionActions() {
return Collections.singletonList(GlobalPermission.ADMIN);
}
-
-
+
+
/**
* Prepare action by loading runtime properties map.
*/
@@ -104,9 +105,9 @@ public class GlobalConfig extends UIAction implements ParameterAware, ServletReq
log.error("Error getting runtime properties map", ex);
addError("Unexpected error accessing Roller properties");
}
-
+
try {
- WeblogManager mgr = WebloggerFactory.getWeblogger().getWeblogManager();
+ WeblogManager mgr = WebloggerFactory.getWeblogger().getWeblogManager();
setWeblogs(mgr.getWeblogs(true, null, null, null, 0, -1));
} catch (WebloggerException ex) {
log.error("Error getting weblogs", ex);
@@ -121,28 +122,28 @@ public class GlobalConfig extends UIAction implements ParameterAware, ServletReq
setGlobalConfigDef(configDef);
}
}
-
+
// load plugins list
PluginManager pmgr = WebloggerFactory.getWeblogger().getPluginManager();
setPluginsList(pmgr.getCommentPlugins());
}
-
-
+
+
/**
* Display global properties editor form.
*/
@Override
public String execute() {
-
+
// setup array of configured plugins
if (!StringUtils.isEmpty(WebloggerRuntimeConfig.getProperty("users.comments.plugins"))) {
setCommentPlugins(StringUtils.split(WebloggerRuntimeConfig.getProperty("users.comments.plugins"), ","));
}
-
+
return SUCCESS;
}
-
-
+
+
/**
* Save global properties.
*/
@@ -150,71 +151,101 @@ public class GlobalConfig extends UIAction implements ParameterAware, ServletReq
if (!"POST".equals(httpMethod)) {
return ERROR;
}
-
+
// only set values for properties that are already defined
RuntimeConfigProperty updProp;
String incomingProp;
for (String propName : getProperties().keySet()) {
updProp = getProperties().get(propName);
incomingProp = this.getParameter(updProp.getName());
-
- log.debug("Checking property ["+propName+"]");
- log.debug("Request value is ["+incomingProp+"]");
-
- // some special treatment for booleans
- // this is a bit hacky since we are assuming that any prop
- // with a value of "true" or "false" is meant to be a boolean
- // it may not always be the case, but we should be okay for now
- // null check below needed w/Oracle
- if( updProp.getValue() != null
- && (updProp.getValue().equals("true") || updProp.getValue().equals("false"))) {
-
- if(incomingProp == null || !incomingProp.equals("on")) {
- incomingProp = "false";
+
+ log.debug("Checking property [" + propName + "]");
+ log.debug("Request value is [" + incomingProp + "]");
+
+ PropertyDef propertyDef = globalConfigDef.getPropertyDef( propName );
+ if ( propertyDef == null) {
+ // we're only processing defined properties, i.e. ones shown in the UI
+ continue;
+ }
+
+ if ( propertyDef.getType().equals("boolean") ) {
+
+ try {
+ Boolean.parseBoolean(incomingProp);
+ updProp.setValue(incomingProp);
+ } catch ( Exception nfe ) {
+ String propDesc = bundle.getString( propertyDef.getKey() );
+ addError("ConfigForm.invalidBooleanProperty",
+ Arrays.asList( new Object[] { propDesc, propName } ));
}
- else {
- incomingProp = "true";
+
+ } else if ( propertyDef.getType().equals("integer") ) {
+
+ try {
+ Integer.parseInt(incomingProp);
+ updProp.setValue(incomingProp);
+ } catch ( NumberFormatException nfe ) {
+ String propDesc = bundle.getString( propertyDef.getKey() );
+ addError("ConfigForm.invalidIntegerProperty",
+ Arrays.asList( new Object[] { propDesc, propName } ));
}
+
+ } else if ( propertyDef.getType().equals("float") ) {
+
+ try {
+ Float.parseFloat(incomingProp);
+ updProp.setValue(incomingProp);
+ } catch ( NumberFormatException nfe ) {
+ String propDesc = bundle.getString( propertyDef.getKey() );
+ addError("ConfigForm.invalidFloatProperty",
+ Arrays.asList( new Object[] { propDesc, propName } ));
+ }
+
+ } else if ( incomingProp != null ){
+ updProp.setValue( incomingProp.trim() );
+
+ } else if ( propertyDef.getName().equals("users.comments.plugins") ) {
+ // not a problem
+
+ } else {
+ addError("ConfigForm.invalidProperty", propName);
}
-
- // only work on props that were submitted with the request
- if(incomingProp != null) {
- log.debug("Setting new value for ["+propName+"]");
-
- // NOTE: the old way had some locale sensitive way to do this??
- updProp.setValue(incomingProp.trim());
- }
+
}
-
+
+ if ( this.hasActionErrors() ) {
+ return ERROR;
+ }
+
// special handling for comment plugins
String enabledPlugins = "";
- if(getCommentPlugins().length > 0) {
+ if (getCommentPlugins().length > 0) {
enabledPlugins = StringUtils.join(getCommentPlugins(), ",");
}
RuntimeConfigProperty prop = getProperties().get("users.comments.plugins");
prop.setValue(enabledPlugins);
-
+
try {
// save 'em and flush
PropertiesManager mgr = WebloggerFactory.getWeblogger().getPropertiesManager();
mgr.saveProperties(getProperties());
WebloggerFactory.getWeblogger().flush();
-
+
// notify user of our success
addMessage("generic.changes.saved");
-
+
} catch (WebloggerException ex) {
log.error("Error saving roller properties", ex);
addError("generic.error.check.logs");
}
-
+
return SUCCESS;
}
-
-
+
+
public void setParameters(Map<String, String[]> parameters) {
this.params = parameters;
-
+
if (log.isDebugEnabled()) {
log.debug("Parameter map:");
@@ -223,18 +254,18 @@ public class GlobalConfig extends UIAction implements ParameterAware, ServletReq
}
}
}
-
+
// convenience method for getting a single parameter as a String
private String getParameter(String key) {
-
+
String[] p = this.params.get(key);
- if(p != null && p.length > 0) {
+ if (p != null && p.length > 0) {
return p[0];
}
return null;
}
-
-
+
+
public Map<String, RuntimeConfigProperty> getProperties() {
return properties;
}
@@ -250,7 +281,7 @@ public class GlobalConfig extends UIAction implements ParameterAware, ServletReq
public void setGlobalConfigDef(ConfigDef globalConfigDef) {
this.globalConfigDef = globalConfigDef;
}
-
+
public List<WeblogEntryCommentPlugin> getPluginsList() {
return pluginsList;
}
@@ -258,7 +289,7 @@ public class GlobalConfig extends UIAction implements ParameterAware, ServletReq
public void setPluginsList(List<WeblogEntryCommentPlugin> pluginsList) {
this.pluginsList = pluginsList;
}
-
+
public String[] getCommentPlugins() {
return commentPlugins.clone();
}
@@ -270,7 +301,7 @@ public class GlobalConfig extends UIAction implements ParameterAware, ServletReq
public void setServletRequest(HttpServletRequest req) {
httpMethod = req.getMethod();
}
-
+
public Collection<Weblog> getWeblogs() {
return weblogs;
}
http://git-wip-us.apache.org/repos/asf/roller/blob/29adfd3f/app/src/main/resources/ApplicationResources.properties
----------------------------------------------------------------------
diff --git a/app/src/main/resources/ApplicationResources.properties b/app/src/main/resources/ApplicationResources.properties
index 4d7fdbb..c16d9aa 100644
--- a/app/src/main/resources/ApplicationResources.properties
+++ b/app/src/main/resources/ApplicationResources.properties
@@ -349,7 +349,7 @@ configForm.ignoreSpamComments=Don''t save comments thought to be spam
configForm.enableTrackbacks=Allow weblog trackbacks?
configForm.ignoreSpamTrackbacks=Don''t save trackbacks thought to be spam
configForm.commentHtmlAllowed=Allow html in comments?
-configForm.commentPlugins=Enabled/Disable comment formatting plugins
+configForm.commentPlugins=Enabled comment formatting plugins
configForm.emailComments=Allow email notification of comments?
configForm.moderationRequired=Require comment moderation for all weblogs
configForm.enableTrackbackValidation=Enable verification of trackback links?
@@ -1139,6 +1139,10 @@ ConfigForm.proxyPort=Proxy port for feed fetcher
ConfigForm.message.saveSucceeded=Saved Planet configuration
ConfigForm.error.saveFailed=Error saving Planet configuration
+ConfigForm.invalidBooleanProperty=Property {0} must be a boolean: {1}
+ConfigForm.invalidIntegerProperty=Property {0} must be an integer: {1}
+ConfigForm.invalidFloatProperty=Property {0} must be a float: {1}
+ConfigForm.invalidProperty=Property {0} is null
# ----------------------------------------------------- PlanetSubscriptions.jsp
@@ -1793,7 +1797,7 @@ yourWebsites.createWeblog=Create new weblog
yourWebsites.createWeblog.desc=\
Feel like you''ve got more to say? Maybe another weblog is what you need.
-yourWebsites.editProfile=Update your user info including password, email, locale and timezone.
+yourWebsites.editProfile=Your Profile
yourWebsites.editProfile.desc=Change user info, password, timezone
yourWebsites.oauthKeys=OAuth Credentials
http://git-wip-us.apache.org/repos/asf/roller/blob/29adfd3f/app/src/main/resources/org/apache/roller/weblogger/config/runtimeConfigDefs.xml
----------------------------------------------------------------------
diff --git a/app/src/main/resources/org/apache/roller/weblogger/config/runtimeConfigDefs.xml b/app/src/main/resources/org/apache/roller/weblogger/config/runtimeConfigDefs.xml
index 8c84ba6..a55f7f1 100644
--- a/app/src/main/resources/org/apache/roller/weblogger/config/runtimeConfigDefs.xml
+++ b/app/src/main/resources/org/apache/roller/weblogger/config/runtimeConfigDefs.xml
@@ -136,11 +136,11 @@
<display-group name="weblogSettings" key="configForm.weblogSettings" >
<property-def name="site.pages.maxEntries" key="configForm.pageMaxEntries">
- <type>string</type>
+ <type>integer</type>
<default-value>30</default-value>
</property-def>
<property-def name="site.newsfeeds.defaultEntries" key="configForm.newsfeedMaxEntries">
- <type>string</type>
+ <type>integer</type>
<default-value>30</default-value>
</property-def>
<property-def name="site.newsfeeds.styledFeeds" key="configForm.styledFeeds">
@@ -210,11 +210,11 @@
<default-value>exe</default-value>
</property-def>
<property-def name="uploads.file.maxsize" key="configForm.maxFileSize">
- <type>string</type>
+ <type>float</type>
<default-value>2.00</default-value>
</property-def>
<property-def name="uploads.dir.maxsize" key="configForm.maxDirSize">
- <type>string</type>
+ <type>float</type>
<default-value>20.00</default-value>
</property-def>
http://git-wip-us.apache.org/repos/asf/roller/blob/29adfd3f/app/src/main/resources/struts.xml
----------------------------------------------------------------------
diff --git a/app/src/main/resources/struts.xml b/app/src/main/resources/struts.xml
index fd24563..8020f7c 100644
--- a/app/src/main/resources/struts.xml
+++ b/app/src/main/resources/struts.xml
@@ -162,6 +162,7 @@
<action name="globalConfig!*" method="{1}"
class="org.apache.roller.weblogger.ui.struts2.admin.GlobalConfig">
<result name="success" type="tiles">.GlobalConfig</result>
+ <result name="error" type="tiles">.GlobalConfig</result>
</action>
<action name="userAdmin"
http://git-wip-us.apache.org/repos/asf/roller/blob/29adfd3f/app/src/main/webapp/WEB-INF/jsps/admin/GlobalConfig.jsp
----------------------------------------------------------------------
diff --git a/app/src/main/webapp/WEB-INF/jsps/admin/GlobalConfig.jsp b/app/src/main/webapp/WEB-INF/jsps/admin/GlobalConfig.jsp
index 6856b6b..af3e2fc 100644
--- a/app/src/main/webapp/WEB-INF/jsps/admin/GlobalConfig.jsp
+++ b/app/src/main/webapp/WEB-INF/jsps/admin/GlobalConfig.jsp
@@ -17,96 +17,127 @@
--%>
<%@ include file="/WEB-INF/jsps/taglibs-struts2.jsp" %>
-<p class="subtitle"><s:text name="configForm.subtitle" /></p>
-<p><s:text name="configForm.prompt" /></p>
+<p class="subtitle"><s:text name="configForm.subtitle"/></p>
+<p><s:text name="configForm.prompt"/></p>
-<s:form action="globalConfig!save">
- <s:hidden name="salt" />
- <table class="formtableNoDesc">
-
+<s:form action="globalConfig!save" theme="bootstrap" cssClass="form-horizontal">
+
+ <s:hidden name="salt"/>
+
<s:iterator id="dg" value="globalConfigDef.displayGroups">
-
- <tr>
- <td colspan="3"><h2><s:text name="%{#dg.key}" /></h2></td>
- </tr>
-
+
+ <h2><s:text name="%{#dg.key}"/></h2>
+
<s:iterator id="pd" value="#dg.propertyDefs">
-
- <tr>
- <td class="label"><s:text name="%{#pd.key}" /></td>
-
- <%-- special condition for comment plugins --%>
- <s:if test="#pd.name == 'users.comments.plugins'">
- <td class="field"><s:checkboxlist theme="roller" list="pluginsList"
- name="commentPlugins" listKey="id" listValue="name" /></td>
- </s:if>
-
- <%-- special condition for front page blog --%>
- <s:elseif test="#pd.name == 'site.frontpage.weblog.handle'">
- <td class="field">
- <select name='<s:property value="#pd.name"/>'>
- <option value=''>
- <s:text name="configForm.none" />
- </option> <s:iterator id="weblog" value="weblogs">
- <option value='<s:property value="#weblog.handle"/>'
- <s:if test='properties[#pd.name].value == #weblog.handle'>selected='true'</s:if> >
- <s:property value="#weblog.name"/>
- </option>
- </s:iterator>
- </select>
- </td>
- </s:elseif>
-
- <%-- "string" type means use a simple textbox --%>
- <s:elseif test="#pd.type == 'string'">
- <td class="field"><input type="text" name='<s:property value="#pd.name"/>'
- value='<s:property value="properties[#pd.name].value"/>' size="35" /></td>
- </s:elseif>
-
- <%-- "text" type means use a full textarea --%>
- <s:elseif test="#pd.type == 'text'">
- <td class="field">
- <textarea name='<s:property value="#pd.name"/>'
- rows="<s:property value="#pd.rows"/>"
- cols="<s:property value="#pd.cols"/>"><s:property value="properties[#pd.name].value"/>
- </textarea>
- </td>
- </s:elseif>
-
- <%-- "boolean" type means use a checkbox --%>
- <s:elseif test="#pd.type == 'boolean'">
- <s:if test="properties[#pd.name].value == 'true'">
- <td class="field"><input type="checkbox"
- name='<s:property value="#pd.name"/>' CHECKED></td>
- </s:if>
- <s:else>
- <td class="field"><input type="checkbox"
- name='<s:property value="#pd.name"/>'></td>
- </s:else>
- </s:elseif>
-
- <%-- if it's something we don't understand then use textbox --%>
- <s:else>
- <td class="field"><input type="text"
- name='<s:property value="#pd.name"/>' size="50" /></td>
- </s:else>
-
- <td class="description"><%-- <s:text name="" /> --%></td>
- </tr>
-
+
+ <%-- special condition for comment plugins --%>
+ <s:if test="#pd.name == 'users.comments.plugins'">
+ <s:checkboxlist label="%{getText(#pd.key)}" name="commentPlugins"
+ list="pluginsList" listKey="id" listValue="name"/>
+ </s:if>
+
+ <%-- special condition for front page blog --%>
+ <s:elseif test="#pd.name == 'site.frontpage.weblog.handle'">
+ <s:select name="%{#pd.name}" label="%{getText(#pd.key)}"
+ list="weblogs" listValue="name"/>
+ </s:elseif>
+
+ <%-- "string" type means use a simple textbox --%>
+ <s:elseif test="#pd.type == 'string'">
+ <s:textfield name="%{#pd.name}" label="%{getText(#pd.key)}" size="35"
+ value="%{properties[#pd.name].value}"/>
+ </s:elseif>
+
+ <%-- "text" type means use a full textarea --%>
+ <s:elseif test="#pd.type == 'text'">
+ <s:textarea name="%{#pd.name}" label="%{getText(#pd.key)}" rows="#pd.rows" cols="#pd.cols"
+ value="%{properties[#pd.name].value}"/>
+ </s:elseif>
+
+ <%-- "boolean" type means use a checkbox --%>
+ <s:elseif test="#pd.type == 'boolean'">
+ <s:if test="properties[#pd.name].value == 'true'">
+ <s:checkbox name="%{#pd.name}" label="%{getText(#pd.key)}" checked="checked" />
+ </s:if>
+ <s:if test="properties[#pd.name].value == 'false'">
+ <s:checkbox name="%{#pd.name}" label="%{getText(#pd.key)}" />
+ </s:if>
+ </s:elseif>
+
+ <s:elseif test="#pd.type == 'integer'">
+ <div class="form-group ">
+ <label class="col-sm-3 control-label"
+ for='globalConfig_<s:property value="#pd.nameWithUnderbars" />'>
+ <s:text name="%{#pd.key}"/>
+ </label>
+ <div class="col-sm-9 controls">
+ <input type="number" name='<s:property value="#pd.name" />'
+ size="35" value="30" id='globalConfig_<s:property value="#pd.nameWithUnderbars" />'
+ class="form-control integer" onkeyup="formChanged()" />
+ </div>
+ </div>
+ </s:elseif>
+
+ <s:elseif test="#pd.type == 'float'">
+ <div class="form-group ">
+ <label class="col-sm-3 control-label"
+ for='globalConfig_<s:property value="#pd.nameWithUnderbars" />'>
+ <s:text name="%{#pd.key}"/>
+ </label>
+ <div class="col-sm-9 controls">
+ <input type="number" name='<s:property value="#pd.name" />'
+ size="35" value="30" id='globalConfig_<s:property value="#pd.nameWithUnderbars" />'
+ class="form-control float" onkeyup="formChanged()" />
+ </div>
+ </div>
+ </s:elseif>
+
+ <%-- if it's something we don't understand then use textbox --%>
+ <s:else>
+ <s:textfield name="%{#pd.name}" label="%{getText(#pd.key)}" size="35"
+ value="%{properties[#pd.name].value}" />
+ </s:else>
+
</s:iterator>
-
- <tr>
- <td colspan="2"> </td>
- </tr>
-
</s:iterator>
- </table>
-
- <div class="control">
- <input class="buttonBox" type="submit" value="<s:text name="generic.save"/>"/>
- </div>
-
+ <input id="saveButton" class="btn" type="submit" value="<s:text name="generic.save"/>"/>
+
</s:form>
+
+
+<script type="text/javascript">
+
+ function formChanged() {
+
+ var saveBookmarkButton = $('#saveButton:first');
+
+ var error = false;
+
+ $("input").each( function() {
+
+ var isInteger = $(this).hasClass("integer");
+
+ if ( $(this).attr("type") == "number") {
+
+ if ( isNaN( this.valueAsNumber )) {
+ $(this).css("background", "#FBB")
+ error = true;
+
+ } else if ( isInteger && !Number.isInteger( this.valueAsNumber ) ) {
+ $(this).css("background", "#FBB")
+ error = true;
+
+ } else {
+ $(this).css("background", "white")
+ }
+ }
+
+ });
+
+ saveBookmarkButton.attr("disabled", error );
+ }
+
+</script>
+