Anonymous avatar Anonymous committed 315aa6a

new xmlhttprequest-based client side javascript

git-svn-id: http://svn.opensymphony.com/svn/webwork/trunk@643 573baa09-0c28-0410-bef9-dab3c582ae83

Comments (0)

Files changed (5)

src/java/com/opensymphony/webwork/views/jsp/ui/FormTag.java

 
                 String result = UrlHelper.buildUrl(namespace + "/" + action + "." + Configuration.get("webwork.action.extension"), request, response, null);
                 addParameter("action", result);
+                addParameter("namespace", namespace);
 
                 // if the name isn't specified, use the action name
                 if (nameAttr == null) {

src/java/template/simple/form.vm

 <form
+#if ($parameters.namespace) namespace="$!parameters.namespace"                  #end
 #if ($parameters.id)        id="$!webwork.htmlEncode($parameters.id)"           #end
 #if ($parameters.name)      name="$!webwork.htmlEncode($parameters.name)"       #end
 #if ($parameters.action)    action="$!webwork.htmlEncode($parameters.action)"   #end

src/java/template/xhtml/controlheader.vm

 </tr>
 <tr>
 #end
+#if ($parameters.form.validate && $parameters.form.validate == true)
+    #if ($parameters.onblur)
+        #set ($parameters.onblur = "validate(this);${parameters.onblur}")
+    #else
+        #set ($parameters.onblur = "validate(this)")
+    #end
+#end
     <td>

src/java/template/xhtml/validation.vm

+<script>
+var xmlhttp=false;
+
+/*@cc_on @*/
+/*@if (@_jscript_version >= 5)
+// JScript gives us Conditional compilation, we can cope with old IE versions.
+// and security blocked creation of the objects.
+ try {
+  xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");  } catch (e) {
+  try {
+   xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
+  } catch (E) {
+   xmlhttp = false;
+  }
+ }
+@end @*/
+
+if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
+  xmlhttp = new XMLHttpRequest();
+}
+
+function validate(e) {
+    // mark the element as touch
+    e.touched = true;
+    xmlhttp.open("POST", "/validation", true);
+    xmlhttp.onreadystatechange = function() {
+        if (xmlhttp.readyState == 4) {
+            var xml = xmlhttp.responseXML;
+            clearErrorRows(e.parentNode.parentNode.parentNode);
+            clearErrorLabels(e.form);
+            var errors = xml.childNodes[0].getElementsByTagName("e");
+            for (var i = 0; i < errors.length; i++) {
+                var error = errors[i];
+                var errorName = error.getAttribute("n");
+                var errorText = error.childNodes[0].textContent;
+                // there was an error, report it
+                var element = e.form.elements[errorName];
+                if (element != null && element.touched && element.touched == true) {
+                    addError(element, errorText);
+                }
+            }
+        }
+    }
+
+    var req = getValidateXml(e.form);
+    xmlhttp.send(req);
+}
+
+function clearErrorRows(table) {
+    // clear out any rows with an "errorFor" attribute
+    var rows = table.rows;
+    var rowsToDelete = new Array();
+    for(var i = 0; i < rows.length; i++) {
+        var r = rows[i];
+        if (r.getAttribute("errorFor")) {
+            rowsToDelete.push(r);
+        }
+    }
+
+    // now delete the rows
+    for (var i = 0; i < rowsToDelete.length; i++) {
+        var r = rowsToDelete[i];
+        table.deleteRow(r.rowIndex);
+    }
+}
+
+function clearErrorLabels(form) {
+    // set all labels back to the normal class
+    var elements = form.elements;
+    for (var i = 0; i < elements.length; i++) {
+        var e = elements[i];
+        var cells = e.parentNode.parentNode.cells;
+        if (cells && cells.length >= 2) {
+            var label = cells[0].getElementsByTagName("label")[0];
+            if (label) {
+                label.setAttribute("class", "label");
+            }
+        }
+    }
+
+}
+
+function getValidateXml(f) {
+    var actionName = f.name;
+    var namespace = f.getAttribute("namespace");
+    var xml = '<r a="' + actionName + '" ns="' + namespace +'">\n';
+    for (var i = 0; i < f.elements.length; i++) {
+        var e = f.elements[i];
+        xml = xml + '<p n="' + e.name + '">' + e.value + '</p>\n';
+    }
+    xml = xml + '</r>\n';
+    return xml;
+}
+
+function addError(e, errorText) {
+    try {
+        // clear out any rows with an "errorFor" of e.id
+        var row = e.parentNode.parentNode;
+        var table = row.parentNode;
+        var error = document.createTextNode(errorText);
+        var tr = document.createElement("tr");
+        var td = document.createElement("td");
+        var span = document.createElement("span");
+        td.align = "center";
+        td.valign = "top";
+        td.colSpan = 2;
+        span.setAttribute("class", "errorMessage");
+        span.appendChild(error);
+        td.appendChild(span);
+        tr.appendChild(td);
+        tr.setAttribute("errorFor", e.id);;
+        table.insertBefore(tr, row);
+
+        // updat the label too
+        var label = row.cells[0].getElementsByTagName("label")[0];
+        label.setAttribute("class", "errorLabel");
+    } catch (e) {
+        alert(e);
+    }
+}
+</script>

src/webapp/javascript-input.jsp

 <html>
     <head>
         <title>JavaScript Validation Input</title>
+        <link rel="stylesheet" href="styles.css">
+        <ww:component template="'validation'"/>
     </head>
-    
+
     <body>
-        <ww:form name="'test'" action="'javascriptValidation'" validate="true" >
-            <ww:textfield label="'Required String'" name="'requiredString'" required="true"/>
+        <ww:form name="'javascriptValidation'" action="'javascriptValidation'" validate="true" >
+            <ww:textfield label="'Required String'" name="'requiredString'" required="true" />
             <ww:textfield label="'Some Int'" name="'intRange'" required="true"/>
-            <ww:select label="'Email (select)" name="'email'" list="{'Select', 'foo@bar.com', 'baz@biz.com'}"/>
+            <ww:select label="'Email (select)'" name="'email'" list="{'Select', 'foo@bar.com', 'baz@biz.com'}"/>
             <ww:textfield label="'URL'" name="'url'" required="true"/>
             <ww:textfield label="'Date'" name="'date'" required="true"/>
             <tr><td colspan="2"><hr/></td></tr>
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.