Hi jQuery guru,
I have an application based on struts and tiles. Validation is done by
javascript at a global level.
When I include my autocomplete code in my JSP page, the validation
(checkValidation()) malfunctions with a javascript error - "Object
does not support this property or method" at the line
if (CCRDerrorContainer.hasChildNodes()).
If I remove the autocomplete code from my JSP (business logic +
autocomplete libraries) , the validation works as designed. Details of
relevant code is provided below. Can anyone provide me with any clue
as to how to resolve this problem ?
======================================================================
-----------------------------------------------------------------------------------
My JSP file
-----------------------------------------------------------------------------------
<%@ include file="../common/include.jsp" %>
<link rel="stylesheet" type="text/css" href="css/
jquery.autocomplete.css" />
<script type="text/javascript" src="js/autocomplete/lib/jquery.js"></
script>
<script type='text/javascript' src='js/autocomplete/
jquery.autocomplete.js'></script>
<script>
var cols = []; // column mappings : 0=Last name,
1=First Name,
2=Title, 3 = Employee ID
$().ready(function() {
$('input#employeeLastName').flushCache();
$("#employeeLastName").autocomplete("jsp/common/getData.jsp?
dataType=EmployeeName",{
minChars: 1,
max: 1000,
width: 400,
delay: 1000,
selectFirst: false,
autoFill: false,
cacheLength: 20,
matchContains: false,
matchSubset: true,
mustMatch: false,
matchCase: true,
formatItem: function(row, i, max) {
cols = row[0].split("%");
return i + "/" + max + ": " +
cols[0] + ", " + cols[1] + " (" +
cols[2] + ")";
},
formatMatch: function(row) {
cols = row[0].split("%");
return cols[0] + ", " + cols[1];
},
formatResult: function(row) {
cols = row[0].split("%");
return cols[0] + ", " + cols[1]
+ " (" + cols[2] + ")";
}
});
$("#employeeLastName").result(function(event,
row, formatted) {
if (row) {
cols = row[0].split("%");
$(this).next().val(cols[3]);
}
});
});
</script>
<tiles:importAttribute name="task" />
<tiles:importAttribute name="action" />
<tiles:importAttribute name="displayAction" />
<tiles:importAttribute name="showArchived" />
<style type="text/css">
@import "${pageContext.request.contextPath}/css/employee/select.css";
</style>
<h1>
<fmt:message key="employee.label.title.select" />
</h1>
<hr />
<div id="employeeSelect">
<tiles:insert definition="successMessages" />
<tiles:insert definition="failureMessages" />
<ccrd:errors />
<html:form action="${action}" method="post" >
<label for="employee" id="employeeLbl" >
<fmt:message key="employee.text.selectEmployee" />
<span class="task"><fmt:message key="${task}" />:</span>
</label>
<html:text styleId="employeeLastName" property="lastName"
size="100"
maxlength="200">
</html:text>
<html:hidden property="employeeId" />
<BR/> <BR/>
<div class="buttons">
<html:submit property="submit"
styleId="submitButton"><fmt:message
key="button.submit"/></html:submit>
<html:submit property="cancel"
styleId="cancelButton"><fmt:message
key="button.cancel"/></html:submit>
</div>
</html:form>
</div>
--------------------------------------------------------------------------------------------------------
Tiles-Defs extract
---------------------------------------------------------------------------------------------------------
<definition name=".default" path="/jsp/layouts/template.jsp" >
<put name="header" value="/jsp/layouts/header.jsp" />
<put name="leftnav" value="/jsp/layouts/menu.jsp" />
<put name="footer" value="/jsp/layouts/footer.jsp" />
</definition>
-----------------------------------------------------------------------------------------------------------
Template.jsp
------------------------------------------------------------------------------------------------------------
<%@ page contentType="text/html;charset=ISO-8859-1" language="java"%>
<%@ include file="../common/include.jsp"%>
<%
response.setHeader("Pragma","no-cache"); //HTTP 1.0
response.setHeader("Cache-Control","no-cache, private, no-store, max-
stale=0"); //HTTP 1.1
response.setDateHeader("Expires", 0); //prevents caching at the proxy
server
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<base
href="@base.href.protocol@://${pageContext.request.serverName}
@base.href.p...@${pagecontext.request.contextpath}/" />
<title><bean:message key="template.header.title" />
</title>
<meta http-equiv="Content-Type"
content="text/html; charset=ISO-8859-1" />
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="expires" content="Sun, 28 Dec 1997 09:32:45
GMT" /
>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<link rel="stylesheet" type="text/css" href="css/menu.css" />
<link rel="stylesheet" type="text/css" href="main.css" />
<script type="text/javascript" src="js/common.js"></script>
<script type="text/javascript" src="js/calendar.js"></script>
<script type="text/javascript" src="js/StrutsMenuControl.js"></
script>
<script type="text/javascript" src="js/TableFilter.js"></script>
<script type="text/javascript" src="js/validation.js"></script>
</head>
<body onload="checkValidation();">
<div id="shadow">
<div id="container">
<tiles:insert attribute="header" flush="false"
/>
<div id="body">
<div id="menucontainer">
<tiles:insert
attribute="leftnav" flush="false" />
</div>
<div id="contentcontainer">
<div id="content">
<!-- Content goes here
-->
<tiles:insert
attribute="body" flush="false" />
<!-- Content ends here
-->
</div>
</div>
<div class="break">
</div>
</div>
</div>
</div>
<tiles:insert attribute="footer" flush="false" />
</body>
</html>
------------------------------------------------
Validation Javascript
------------------------------------------------
//
// validate.js -- JS functions for validation
//
var CCRDerror_FIELD_CLASS = "errorField";
var CCRDerror_CONTAINER_ID = "errorContainer";
var CCRDerror_DIV_CLASS = "error";
//
// checkValidation()
//
// Check if CCRDerror container exists, and if so
// update form fields and set up event handlers
// for CCRDerror fields.
//
function checkValidation() {
var CCRDerrorContainer = $(CCRDerror_CONTAINER_ID);
if (CCRDerrorContainer) {
if (CCRDerrorContainer.hasChildNodes()) {
// get the bg colour from the CCRDerror class
var CCRDerrorField = $E("div", CCRDerror_FIELD_CLASS);
document.body.appendChild(CCRDerrorField);
var bgcolor = getStyle(CCRDerrorField,
"backgroundColor");
if (!bgcolor)
bgcolor = getStyle(CCRDerrorField,
"background-color");
for ( var i = 0; i <
CCRDerrorContainer.childNodes.length; i++) {
if (CCRDerrorContainer.childNodes[i].tagName ==
"DIV") {
var id =
CCRDerrorContainer.childNodes[i].id;
var field = getFormElement(id);
// Update input background color
field.style.backgroundColor = bgcolor;
// Add event handlers for focus and blur
Event.addEventHandler(field, "focus",
gotFocus);
Event.addEventHandler(field, "blur",
lostFocus);
field.setAttribute("errorField", true);
}
}
displayFirstCCRDerror();
}
}
}
//
// displayFirstCCRDerror()
//
// Display CCRDerror for first CCRDerror field
// in the form
//
function displayFirstCCRDerror() {
for ( var j = 0; j < document.forms.length; j++) {
for ( var i = 0; i < document.forms[j].elements.length; i++) {
if
(document.forms[j].elements[i].getAttribute("errorField")) {
if (isVisible(document.forms[j].elements[i]))
// Only set
// focus to
// visible
// objects
document.forms[j].elements[i].focus();
return;
}
}
}
}
//
// gotFocus(event)
//
// Callback for field 'onFocus' handler
//
function gotFocus(event) {
var ev = new Event(event);
displayCCRDerror(ev.getTarget());
}
//
// lostFocus(event)
//
// Callback for field 'onBlur' handler
//
function lostFocus(event) {
var ev = new Event(event);
hideCCRDerror(ev.getTarget());
}
//
// displayCCRDerror(field)
//
// Show CCRDerror popup for 'field'
//
function displayCCRDerror(field) {
var obj = $(field.name);
obj.style.display = "block";
obj.style.left = getXPos(field) + "px";
obj.style.top = (getYPos(field) - obj.offsetHeight) + "px";
}
//
// hideCCRDerror(field)
//
// Hide CCRDerror popup for 'field'
//
function hideCCRDerror(field) {
var obj = $(field.name);
obj.style.display = "none";
}
------------------------------------------------------