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 2019/01/20 19:22:24 UTC

[roller] branch bootstrap-ui updated: More polish of web UI.

This is an automated email from the ASF dual-hosted git repository.

snoopdave pushed a commit to branch bootstrap-ui
in repository https://gitbox.apache.org/repos/asf/roller.git


The following commit(s) were added to refs/heads/bootstrap-ui by this push:
     new 3e531ef  More polish of web UI.
3e531ef is described below

commit 3e531efe151cfa50ef5fdde2a14d7b19c6f68c01
Author: Dave Johnson <sn...@gmail.com>
AuthorDate: Sun Jan 20 14:22:16 2019 -0500

    More polish of web UI.
---
 .../roller/weblogger/pojos/WeblogEntryComment.java |  5 +-
 .../weblogger/ui/struts2/editor/Comments.java      | 73 ++++++++--------------
 .../main/resources/ApplicationResources.properties |  2 +-
 .../webapp/WEB-INF/jsps/admin/GlobalConfig.jsp     |  2 +-
 .../main/webapp/WEB-INF/jsps/core/CreateWeblog.jsp | 30 ++++-----
 app/src/main/webapp/WEB-INF/jsps/core/Profile.jsp  | 31 ++++-----
 app/src/main/webapp/WEB-INF/jsps/core/Register.jsp |  7 +++
 .../main/webapp/WEB-INF/jsps/editor/Categories.jsp |  4 +-
 .../main/webapp/WEB-INF/jsps/editor/Comments.jsp   | 27 ++++----
 .../WEB-INF/jsps/editor/MediaFileSidebar.jsp       | 25 +++++---
 app/src/main/webapp/theme/scripts/roller.js        |  5 ++
 11 files changed, 99 insertions(+), 112 deletions(-)

diff --git a/app/src/main/java/org/apache/roller/weblogger/pojos/WeblogEntryComment.java b/app/src/main/java/org/apache/roller/weblogger/pojos/WeblogEntryComment.java
index b28dc52..1138ae9 100644
--- a/app/src/main/java/org/apache/roller/weblogger/pojos/WeblogEntryComment.java
+++ b/app/src/main/java/org/apache/roller/weblogger/pojos/WeblogEntryComment.java
@@ -50,7 +50,6 @@ public class WeblogEntryComment implements Serializable {
     private String    plugins = null;
     private String    contentType = "text/plain";
 
-    
     // associations
     private WeblogEntry weblogEntry = null;
     
@@ -292,6 +291,10 @@ public class WeblogEntryComment implements Serializable {
     public Boolean getApproved() {
         return ApprovalStatus.APPROVED.equals(getStatus());
     }
+
+    public String getEmptyString() {
+        return "";
+    }
     
     
     /**
diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Comments.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Comments.java
index 10c663a..3aee5df 100644
--- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Comments.java
+++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Comments.java
@@ -105,14 +105,7 @@ public class Comments extends UIAction {
                 setQueryEntry(wmgr.getWeblogEntry(getBean().getEntryId()));
             }
 
-            CommentSearchCriteria csc = new CommentSearchCriteria();
-            csc.setWeblog(getActionWeblog());
-            csc.setEntry(getQueryEntry());
-            csc.setSearchText(getBean().getSearchString());
-            csc.setStartDate(getBean().getStartDate());
-            csc.setEndDate(getBean().getEndDate());
-            csc.setStatus(getBean().getStatus());
-            csc.setReverseChrono(true);
+            CommentSearchCriteria csc = getCommentSearchCriteria();
             csc.setOffset(getBean().getPage() * COUNT);
             csc.setMaxResults(COUNT + 1);
 
@@ -162,11 +155,8 @@ public class Comments extends UIAction {
             params.put("bean.approvedString", getBean().getApprovedString());
         }
 
-        return WebloggerFactory
-                .getWeblogger()
-                .getUrlStrategy()
-                .getActionURL("comments", "/roller-ui/authoring",
-                        getActionWeblog().getHandle(), params, false);
+        return WebloggerFactory.getWeblogger().getUrlStrategy()
+            .getActionURL("comments", "/roller-ui/authoring", getActionWeblog().getHandle(), params, false);
     }
 
     public String execute() {
@@ -192,16 +182,9 @@ public class Comments extends UIAction {
         getBean().loadCheckboxes(getPager().getItems());
 
         try {
-            WeblogEntryManager wmgr = WebloggerFactory.getWeblogger()
-                    .getWeblogEntryManager();
+            WeblogEntryManager wmgr = WebloggerFactory.getWeblogger().getWeblogEntryManager();
 
-            CommentSearchCriteria csc = new CommentSearchCriteria();
-            csc.setWeblog(getActionWeblog());
-            csc.setSearchText(getBean().getSearchString());
-            csc.setStartDate(getBean().getStartDate());
-            csc.setEndDate(getBean().getEndDate());
-            csc.setStatus(getBean().getStatus());
-            csc.setReverseChrono(true);
+            CommentSearchCriteria csc = getCommentSearchCriteria();
 
             List<WeblogEntryComment> allMatchingComments = wmgr.getComments(csc);
             if (allMatchingComments.size() > COUNT) {
@@ -216,28 +199,33 @@ public class Comments extends UIAction {
         return LIST;
     }
 
+    private CommentSearchCriteria getCommentSearchCriteria() {
+        CommentSearchCriteria commentSearchCriteria = new CommentSearchCriteria();
+        commentSearchCriteria.setWeblog(getActionWeblog());
+        commentSearchCriteria.setEntry(getQueryEntry());
+        commentSearchCriteria.setSearchText(getBean().getSearchString());
+        commentSearchCriteria.setStartDate(getBean().getStartDate());
+        commentSearchCriteria.setEndDate(getBean().getEndDate());
+        commentSearchCriteria.setStatus(getBean().getStatus());
+        commentSearchCriteria.setReverseChrono(true);
+        return commentSearchCriteria;
+    }
+
+
     /**
      * Bulk delete all comments matching query criteria.
      */
     public String delete() {
 
         try {
-            WeblogEntryManager wmgr = WebloggerFactory.getWeblogger()
-                    .getWeblogEntryManager();
+            WeblogEntryManager wmgr = WebloggerFactory.getWeblogger().getWeblogEntryManager();
 
             // if search is enabled, we will need to re-index all entries with
             // comments that have been deleted, so build a list of those entries
             Set<WeblogEntry> reindexEntries = new HashSet<WeblogEntry>();
             if (WebloggerConfig.getBooleanProperty("search.enabled")) {
 
-                CommentSearchCriteria csc = new CommentSearchCriteria();
-                csc.setWeblog(getActionWeblog());
-                csc.setEntry(getQueryEntry());
-                csc.setSearchText(getBean().getSearchString());
-                csc.setStartDate(getBean().getStartDate());
-                csc.setEndDate(getBean().getEndDate());
-                csc.setStatus(getBean().getStatus());
-                csc.setReverseChrono(true);
+                CommentSearchCriteria csc = getCommentSearchCriteria();
 
                 List<WeblogEntryComment> targetted = wmgr.getComments(csc);
                 for (WeblogEntryComment comment : targetted) {
@@ -251,8 +239,7 @@ public class Comments extends UIAction {
 
             // if we've got entries to reindex then do so
             if (!reindexEntries.isEmpty()) {
-                IndexManager imgr = WebloggerFactory.getWeblogger()
-                        .getIndexManager();
+                IndexManager imgr = WebloggerFactory.getWeblogger().getIndexManager();
                 for (WeblogEntry entry : reindexEntries) {
                     imgr.addEntryReIndexOperation(entry);
                 }
@@ -280,8 +267,7 @@ public class Comments extends UIAction {
     public String update() {
 
         try {
-            WeblogEntryManager wmgr = WebloggerFactory.getWeblogger()
-                    .getWeblogEntryManager();
+            WeblogEntryManager wmgr = WebloggerFactory.getWeblogger().getWeblogEntryManager();
 
             List<WeblogEntryComment> flushList = new ArrayList<WeblogEntryComment>();
 
@@ -310,8 +296,7 @@ public class Comments extends UIAction {
             }
 
             // loop through IDs of all comments displayed on page
-            List<String> approvedIds = Arrays.asList(getBean()
-                    .getApprovedComments());
+            List<String> approvedIds = Arrays.asList(getBean().getApprovedComments());
             List<String> spamIds = Arrays.asList(getBean().getSpamComments());
             log.debug(spamIds.size() + " comments marked as spam");
 
@@ -426,14 +411,10 @@ public class Comments extends UIAction {
         List<KeyValueObject> opts = new ArrayList<KeyValueObject>();
 
         opts.add(new KeyValueObject("ALL", getText("generic.all")));
-        opts.add(new KeyValueObject("ONLY_PENDING",
-                getText("commentManagement.onlyPending")));
-        opts.add(new KeyValueObject("ONLY_APPROVED",
-                getText("commentManagement.onlyApproved")));
-        opts.add(new KeyValueObject("ONLY_DISAPPROVED",
-                getText("commentManagement.onlyDisapproved")));
-        opts.add(new KeyValueObject("ONLY_SPAM",
-                getText("commentManagement.onlySpam")));
+        opts.add(new KeyValueObject("ONLY_PENDING", getText("commentManagement.onlyPending")));
+        opts.add(new KeyValueObject("ONLY_APPROVED", getText("commentManagement.onlyApproved")));
+        opts.add(new KeyValueObject("ONLY_DISAPPROVED", getText("commentManagement.onlyDisapproved")));
+        opts.add(new KeyValueObject("ONLY_SPAM", getText("commentManagement.onlySpam")));
 
         return opts;
     }
diff --git a/app/src/main/resources/ApplicationResources.properties b/app/src/main/resources/ApplicationResources.properties
index 054edaf..ca6fbe3 100644
--- a/app/src/main/resources/ApplicationResources.properties
+++ b/app/src/main/resources/ApplicationResources.properties
@@ -401,7 +401,7 @@ customize it to your liking.
 createWebsite.handle=Handle
 createWebsite.emailAddress=Email Address
 createWebsite.locale=Locale
-createWebsite.timeZone=Timezone
+createWebsite.timezone=Timezone
 createWebsite.theme=Theme
 createWebsite.weblogUrl=URL
 createWebsite.button.save=Create Weblog
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 d5c68ea..10a91fc 100644
--- a/app/src/main/webapp/WEB-INF/jsps/admin/GlobalConfig.jsp
+++ b/app/src/main/webapp/WEB-INF/jsps/admin/GlobalConfig.jsp
@@ -114,7 +114,7 @@
 
     </s:iterator>
 
-    <input id="saveButton" class="btn" type="submit" value="<s:text name="generic.save"/>"/>
+    <input id="saveButton" class="btn btn-default" type="submit" value="<s:text name="generic.save"/>"/>
 
 </s:form>
 
diff --git a/app/src/main/webapp/WEB-INF/jsps/core/CreateWeblog.jsp b/app/src/main/webapp/WEB-INF/jsps/core/CreateWeblog.jsp
index 2c0b92d..919cf0f 100644
--- a/app/src/main/webapp/WEB-INF/jsps/core/CreateWeblog.jsp
+++ b/app/src/main/webapp/WEB-INF/jsps/core/CreateWeblog.jsp
@@ -48,19 +48,21 @@
     </div>
 
     <s:textfield label="%{getText('createWebsite.emailAddress')}"
-                 tooltip="%{getText('createWebsite.tip.emailAddress')}" onkeyup="formChanged()"
+                 tooltip="%{getText('createWebsite.tip.email')}" onkeyup="formChanged()"
                  name="bean.emailAddress" size="40" maxlength="50"/>
 
     <s:select label="%{getText('createWebsite.locale')}"
               tooltip="%{getText('createWebsite.tip.locale')}"
               name="bean.locale" size="1" list="localesList" listValue="displayName"/>
 
-    <s:select label="%{getText('createWebsite.timeZone')}"
-              tooltip="%{getText('createWebsite.tip.timeZone')}"
+    <s:select label="%{getText('createWebsite.timezone')}"
+              tooltip="%{getText('createWebsite.tip.timezone')}"
               name="bean.timeZone" size="1" list="timeZonesList"/>
 
     <div class="form-group" ng-app="themeSelectModule" ng-controller="themeController">
-        <label class="col-sm-3 control-label" for="createWeblog_bean_timeZone">Timezone</label>
+        <label class="col-sm-3 control-label" for="createWeblog_bean_timeZone">
+            <s:text name="createWebsite.theme" />
+        </label>
         <div class="col-sm-9 controls">
             <s:select name="bean.theme" size="1" list="themes" listKey="id" listValue="name"
                       onchange="previewImage(this[selectedIndex].value)"/>
@@ -77,6 +79,8 @@
 
 </s:form>
 
+<%-- ============================================================================== --%>
+
 <script>
 
     document.forms[0].elements[0].focus();
@@ -104,29 +108,17 @@
         var handle = $("#createWeblog_bean_handle:first").val();
         var email  = $("#createWeblog_bean_emailAddress:first").val();
 
-        if (    name      && name.trim().length > 0
-                && handle && handle.trim().length > 0
-                && email  && email.trim().length > 0   && validateEmail(email) ) {
-            valid = true;
-
-        } else {
-            valid = false;
-        }
+        valid = !!(name && name.trim().length > 0
+            && handle && handle.trim().length > 0
+            && email && email.trim().length > 0 && validateEmail(email));
 
         if ( valid ) {
             saveButton.attr("disabled", false);
-            saveButton.removeClass("btn-danger");
         } else {
             saveButton.attr("disabled", true);
-            saveButton.addClass("btn-danger");
         }
     }
 
-    function validateEmail(email) {
-        var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
-        return re.test(email);
-    }
-
     function handlePreview(handle) {
         previewSpan = document.getElementById("handlePreview");
         var n1 = previewSpan.childNodes[0];
diff --git a/app/src/main/webapp/WEB-INF/jsps/core/Profile.jsp b/app/src/main/webapp/WEB-INF/jsps/core/Profile.jsp
index fa8287a..7d9b9f9 100644
--- a/app/src/main/webapp/WEB-INF/jsps/core/Profile.jsp
+++ b/app/src/main/webapp/WEB-INF/jsps/core/Profile.jsp
@@ -32,7 +32,7 @@
     <s:textfield label="%{getText('userSettings.username')}"
                  tooltip="%{getText('userRegister.tip.userName')}"
                  onchange="formChanged()" onkeyup="formChanged()"
-                 name="bean.userName" size="30" maxlength="30" readonly="true" />
+                 name="bean.userName" size="30" maxlength="30" readonly="true"/>
 
     <s:textfield label="%{getText('userSettings.screenname')}"
                  tooltip="%{getText('userRegister.tip.screenName')}"
@@ -90,7 +90,7 @@
 
     var saveButton;
 
-    $( document ).ready(function() {
+    $(document).ready(function () {
         saveButton = $("#profile_0");
         formChanged();
     });
@@ -98,40 +98,33 @@
     function formChanged() {
         var valid = false;
 
-        var screenName      = $("#profile_bean_screenName:first").val();
-        var fullName        = $("#profile_bean_fullName:first").val();
-        var email           = $("#profile_bean_emailAddress:first").val();
-        var password        = $("#profile_bean_passwordText:first").val();
+        var screenName = $("#profile_bean_screenName:first").val();
+        var fullName = $("#profile_bean_fullName:first").val();
+        var email = $("#profile_bean_emailAddress:first").val();
+        var password = $("#profile_bean_passwordText:first").val();
         var passwordConfirm = $("#profile_bean_passwordConfirm:first").val();
 
-        if (    screenName && screenName.trim().length > 0
-             && fullName   && fullName.trim().length > 0
-             && email      && email.trim().length > 0 && validateEmail(email) ) {
+        if (screenName && screenName.trim().length > 0
+            && fullName && fullName.trim().length > 0
+            && email && email.trim().length > 0 && validateEmail(email)) {
             valid = true;
 
         } else {
             valid = false;
         }
 
-        if ( (password && password.trim().length) || (passwordConfirm && passwordConfirm.trim().length > 0 )) {
-            if ( password !== passwordConfirm ) {
+        if ((password && password.trim().length) || (passwordConfirm && passwordConfirm.trim().length > 0)) {
+            if (password !== passwordConfirm) {
                 valid = false;
             }
         }
 
-        if ( valid ) {
+        if (valid) {
             saveButton.attr("disabled", false);
-            saveButton.removeClass("btn-danger");
         } else {
             saveButton.attr("disabled", true);
-            saveButton.addClass("btn-danger");
         }
 
     }
 
-    function validateEmail(email) {
-        var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
-        return re.test(email);
-    }
-
 </script>
diff --git a/app/src/main/webapp/WEB-INF/jsps/core/Register.jsp b/app/src/main/webapp/WEB-INF/jsps/core/Register.jsp
index 5b0f99a..6f8fcef 100644
--- a/app/src/main/webapp/WEB-INF/jsps/core/Register.jsp
+++ b/app/src/main/webapp/WEB-INF/jsps/core/Register.jsp
@@ -137,6 +137,8 @@
 
 </s:form>
 
+<%-- ============================================================================== --%>
+
 <script type="text/javascript">
 
     function onChange() {
@@ -145,6 +147,11 @@
         var emailAddress    = document.register['bean.emailAddress'].value;
         var userName = passwordText = passwordConfirm = openIdUrl = "";
 
+        if (!validateEmail(emailAddress)) {
+            document.getElementById('submit').disabled = true;
+            return;
+        }
+
         if (authMethod === 'LDAP') {
             userName = '<s:property value="bean.userName" />';
         } else {
diff --git a/app/src/main/webapp/WEB-INF/jsps/editor/Categories.jsp b/app/src/main/webapp/WEB-INF/jsps/editor/Categories.jsp
index bf4761b..4d9ca17 100644
--- a/app/src/main/webapp/WEB-INF/jsps/editor/Categories.jsp
+++ b/app/src/main/webapp/WEB-INF/jsps/editor/Categories.jsp
@@ -268,8 +268,8 @@
                 </div>
 
                 <div class="modal-footer">
-                    <s:submit cssClass="btn" value="%{getText('generic.yes')}"/>&nbsp;
-                    <button type="button" class="btn btn-default btn-primary" data-dismiss="modal">
+                    <s:submit cssClass="btn btn-danger" value="%{getText('generic.yes')}"/>&nbsp;
+                    <button type="button" class="btn btn-default" data-dismiss="modal">
                         <s:text name="generic.no" />
                     </button>
                 </div>
diff --git a/app/src/main/webapp/WEB-INF/jsps/editor/Comments.jsp b/app/src/main/webapp/WEB-INF/jsps/editor/Comments.jsp
index 1b0afe8..7a329b9 100644
--- a/app/src/main/webapp/WEB-INF/jsps/editor/Comments.jsp
+++ b/app/src/main/webapp/WEB-INF/jsps/editor/Comments.jsp
@@ -210,17 +210,17 @@
                     <s:if test="actionName == 'comments'">
                         <%-- only blog admins (not the global admin) can approve blog comments --%>
                         <td>
-                            <s:checkboxlist name="bean.approvedComments" theme="simple" cssClass="comment-select"
-                                            list="{#comment}" listKey="id" listValue="name"/>
+                            <s:checkboxlist name="bean.approvedComments" cssClass="comment-select"
+                                            list="#comment" listKey="id" listValue="emptyString" />
                         </td>
                     </s:if>
                     <td>
-                        <s:checkboxlist name="bean.spamComments" label="" theme="simple" cssClass="comment-select" 
-                                        list="{#comment}" listKey="id" listValue="name"/>
+                        <s:checkboxlist name="bean.spamComments" cssClass="comment-select"
+                                        list="#comment" listKey="id" listValue="emptyString"  />
                     </td>
                     <td>
-                        <s:checkboxlist name="bean.deleteComments" label="" theme="simple" cssClass="comment-select" 
-                                        list="{#comment}" listKey="id" listValue="name"/>
+                        <s:checkboxlist name="bean.deleteComments" cssClass="comment-select"
+                                        list="#comment" listKey="id" listValue="emptyString"  />
                     </td>
 
                         <%-- ======================================================== --%>
@@ -324,8 +324,8 @@
                                                    <a onclick='saveComment("<s:property value="#comment.id"/>")'><s:text
                                                            name="generic.save"/></a> &nbsp;|&nbsp;
                                               </span>
-                                              <span id="cancellink-<s:property value="#comment.id"/>"
-                                                    style="display: none">
+                                                <span id="cancellink-<s:property value="#comment.id"/>"
+                                                      style="display: none">
                                                    <a onclick='editCommentCancel("<s:property
                                                            value="#comment.id"/>")'><s:text name="generic.cancel"/></a>
                                               </span>
@@ -360,10 +360,10 @@
                 </s:if>
             </ul>
         </nav>
-        
+
         <%-- ========================================================= --%>
         <%-- Save changes and cancel buttons --%>
-        
+
         <hr size="1" noshade="noshade"/>
         <s:submit cssClass="btn btn-primary" value="%{getText('commentManagement.update')}"/>
 
@@ -373,7 +373,7 @@
 
 
 <script>
-    
+
     <%-- setup check all/none checkbox controls --%>
     <s:if test="pager.items != null">
     $(document).ready(function () {
@@ -399,13 +399,14 @@
     </s:if>
 
     <%-- TODO: hook this up; it is currently not working in Roller trunk either --%>
+
     function bulkDelete() {
         if (window.confirm('<s:text name="commentManagement.confirmBulkDelete"><s:param value="bulkDeleteCount" /></s:text>')) {
             document.commentQueryForm.method.value = "bulkDelete";
             document.commentQueryForm.submit();
         }
     }
-    
+
     var comments = {};
 
     function editComment(id) {
@@ -469,5 +470,5 @@
             }
         });
     }
-    
+
 </script>
diff --git a/app/src/main/webapp/WEB-INF/jsps/editor/MediaFileSidebar.jsp b/app/src/main/webapp/WEB-INF/jsps/editor/MediaFileSidebar.jsp
index 4d1df58..eb43df0 100644
--- a/app/src/main/webapp/WEB-INF/jsps/editor/MediaFileSidebar.jsp
+++ b/app/src/main/webapp/WEB-INF/jsps/editor/MediaFileSidebar.jsp
@@ -25,7 +25,7 @@
                 <h3><s:text name="mediaFileSidebar.actions"/></h3>
 
                 <div style="clear:right">
-                    <span class="glyphicon glyphicon-folder-open"></span>
+                    <span class="glyphicon glyphicon-picture"></span>
                     <s:url var="mediaFileAddURL" action="mediaFileAdd">
                         <s:param name="weblog" value="%{actionWeblog.handle}"/>
                         <s:param name="directoryName" value="%{directoryName}"/>
@@ -38,15 +38,20 @@
 
                 <s:if test="!pager">
                     <%-- Only show Create New Directory control when NOT showing search results --%>
+
                     <div style="clear:right; margin-top: 1em">
-                        <span class="glyphicon glyphicon-picture"></span>
-                        <s:text name="mediaFileView.addDirectory"/><br/>
-                        <div style="padding-left:2em; padding-top:1em">
+
+                        <span class="glyphicon glyphicon-folder-open"></span>
+                        <s:text name="mediaFileView.addDirectory"/> <br />
+
+                        <label for="newDirectoryName">
                             <s:text name="mediaFileView.directoryName"/>
-                            <input type="text" id="newDirectoryName" name="newDirectoryName" size="10" maxlength="25"/>
-                            <input type="button" id="newDirectoryButton" class="btn btn-primary"
-                                   value='<s:text name="mediaFileView.create" />' onclick="onCreateDirectory()"/>
-                        </div>
+                        </label>
+                        <input type="text" id="newDirectoryName" name="newDirectoryName" size="8" maxlength="25"/>
+
+                        <input type="button" id="newDirectoryButton" class="btn btn-primary" style="clear:left"
+                               value='<s:text name="mediaFileView.create" />' onclick="onCreateDirectory()"/>
+
                     </div>
                 </s:if>
 
@@ -71,9 +76,9 @@
                               list="sizeFilterTypes" listKey="key" listValue="value"
                               label="%{getText('mediaFileView.size')}"/>
 
-                    <s:textfield id="beanSize" name="bean.size" size="3" maxlength="10" />
+                    <s:textfield id="beanSize" name="bean.size" size="3" maxlength="10"/>
 
-                    <s:select name="bean.sizeUnit" list="sizeUnits" listKey="key" listValue="value" />
+                    <s:select name="bean.sizeUnit" list="sizeUnits" listKey="key" listValue="value"/>
 
                     <s:textfield id="beanTags" name="bean.tags" size="20" maxlength="50"
                                  label="%{getText('mediaFileView.tags')}"/>
diff --git a/app/src/main/webapp/theme/scripts/roller.js b/app/src/main/webapp/theme/scripts/roller.js
index bc1a1e7..b60ca42 100644
--- a/app/src/main/webapp/theme/scripts/roller.js
+++ b/app/src/main/webapp/theme/scripts/roller.js
@@ -205,3 +205,8 @@ function toggleFunction(toggle,name) {;
 function isValidUrl(url) {
     return /^(http|https|ftp):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/i.test(url);
 }
+
+function validateEmail(email) {
+    var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
+    return re.test(email);
+}