Using anchor tags in struts

K

krasicki

I'm looking for the recipe to do the following:

I have created a jsp struts page that contains a form. The page is
called logon.jsp and it has a corresponding jsp page called done.jsp.

If the button on the form is a success, I redirect to done.jsp. So far
so good.

If the button on the form encounters errors I return the appropriate
error messages to logon.jsp and they display exactly to <html:errors/>.

However, the next level of refinement has me puzzled.

Within logon.html, I have created an errors section at the bottom of
the page and I use an anchor tag, <a NAME="errors">, to identify its
beginning.

I have tried to map my 'failure' condition to logon.jsp#errors with no
luck. The page is mapped to <whatever>logon.do no matter what
combinatorials I've tried. And just to be clear, my jsp layout is
designed so that the errors section is intentionally unobtrusive to the
logon part of the page. IOW, I know that I can just display the errors
higher on the page and so on. The point is that I want a space for
verbose explanations that aren't disorientating to the user's
expection.

Is this exercise possible in Struts?
 
R

Ryan Stewart

I'm looking for the recipe to do the following:

I have created a jsp struts page that contains a form. The page is
called logon.jsp and it has a corresponding jsp page called done.jsp.

If the button on the form is a success, I redirect to done.jsp. So far
so good.

If the button on the form encounters errors I return the appropriate
error messages to logon.jsp and they display exactly to <html:errors/>.

However, the next level of refinement has me puzzled.

Within logon.html, I have created an errors section at the bottom of
the page and I use an anchor tag, <a NAME="errors">, to identify its
beginning.

I have tried to map my 'failure' condition to logon.jsp#errors with no
luck. The page is mapped to <whatever>logon.do no matter what
combinatorials I've tried. And just to be clear, my jsp layout is
designed so that the errors section is intentionally unobtrusive to the
logon part of the page. IOW, I know that I can just display the errors
higher on the page and so on. The point is that I want a space for
verbose explanations that aren't disorientating to the user's
expection.

Is this exercise possible in Struts?
Not exactly sure what you're saying/asking. Do you mean you have an action
mapping like:
<action path="/logon" name="..." ...>
<forward name="failure" path="index.jsp#errors"/>
<forward name="success" path="done.jsp"/>
</action>

?? If so, that's fine. If you also, in your action, have a line like:
return mapping.findForward("failure");

in the case of a logon failure, then that's right too, and it's doing what
you want. Ignore the fact that it shows "logon.do" in the address bar of
your browser if that's what is bothering you. Have you tried manually
navigating to "logon.jsp#errors"? Does it work as expected? This is all I
can say right now. If you want a more specific answer, ask a more specific
question.
 
K

krasicki

As I said the mappings work fine until I attempt to use an anchor.
<p>
For example:
<p>
<!-- Action Mappings --><br>
<action-mappings><br>
<action name="loginFormBean" path="/login" <br>scope="request"
<br>type="com.anyco.strutsdwproject.actions.Login"
input="Login.jsp"><br>
<forward name="success" path="/Goodbye.jsp" redirect="true"><br>
</forward><br>
<forward name="failure" path="/Login.jsp" redirect="false"
contextRelative="false"><br>
</forward><br>
</action><br>
</action-mappings><p>
<p>
This works fine.<p>But once I change 'Login.jsp' to 'Login.jsp#errors',
the anchor tag is ignored.
 
R

Ryan Stewart

As I said the mappings work fine until I attempt to use an anchor.
<p>
For example:
<p>
<!-- Action Mappings --><br>
<action-mappings><br>
<action name="loginFormBean" path="/login" <br>scope="request"
<br>type="com.anyco.strutsdwproject.actions.Login"
input="Login.jsp"><br>
<forward name="success" path="/Goodbye.jsp" redirect="true"><br>
</forward><br>
<forward name="failure" path="/Login.jsp" redirect="false"
contextRelative="false"><br>
</forward><br>
</action><br>
</action-mappings><p>
<p>
This works fine.<p>But once I change 'Login.jsp' to 'Login.jsp#errors',
the anchor tag is ignored.
1) What's with all the markup in your action mapping?
2) What causes you to believe the anchor tag is ignored?
 
K

krasicki

Ryan,

1.) Ignore the markup, it's my bad - me, thinking that I needed it in
google - this new format threw me a bit.

2.) The anchor is ignored because the test I run expects the Logon jsp
page to be rendered from where the anchor tag is located on that page.

As I research this a bit more. It appears that there is no way of
doing this - the anchor is stripped away and ignored - the browser's
only interest is in rendering the page.

Rather than slog through Struts source can anyone identify a method
that can override Struts to acheive this effect?
 
R

Ryan Stewart

Ryan,

1.) Ignore the markup, it's my bad - me, thinking that I needed it in
google - this new format threw me a bit.

2.) The anchor is ignored because the test I run expects the Logon jsp
page to be rendered from where the anchor tag is located on that page.

As I research this a bit more. It appears that there is no way of
doing this - the anchor is stripped away and ignored - the browser's
only interest is in rendering the page.

Rather than slog through Struts source can anyone identify a method
that can override Struts to acheive this effect?
Ah, right. I forgot about this. Supposedly it will work in some
configurations if you set redirect="true" on the forward, but that loses the
original request. The one thing I could think of would be to put the anchor
name in your form action:
<html:form action="logon.do#foo">

It's not a perfect fix, but it's not a perfect world.
 
S

Sudsy

As I research this a bit more. It appears that there is no way of
doing this - the anchor is stripped away and ignored - the browser's
only interest is in rendering the page.

Half right. See below.
Rather than slog through Struts source can anyone identify a method
that can override Struts to acheive this effect?

You have to recognize that it's the browser which is scrolling to
a named anchor. Unless you perform a redirect (in which case the
browser will /know/ what target it's looking for) then you're SOL.
Of course if you redirect then you lose everything in page and
request scopes...
 
W

Wendy S

As I research this a bit more. It appears that there is no way of
doing this - the anchor is stripped away and ignored - the browser's
only interest is in rendering the page.
Rather than slog through Struts source can anyone identify a method
that can override Struts to acheive this effect?

Are you opposed to a bit of JavaScript? I have a very long page in which I
allow people to hide and show sections. Hiding or showing causes a round
trip to the server, and I need to return them to the same section they were
looking at. In the Action, I set:
request.setAttribute( "anchor", "nameOfAnchor");

Then at the bottom of the JSP (so it won't execute until the page has
finished loading) I have:
<c:if test="${anchor ne null}">
<script>
document.location = "#<c:eek:ut value="${anchor}"/>";
</script>
</c:if>

Since you want to do this only if there are errors, you could skip setting a
request attribute, and instead test for the presence of errors and only
write out the script if there are errors to display.

HTH,
Wendy S
 
K

krasicki

Ah, Wendy - a breath of fresh air. I had thought about a similar
solution yesterday that I will try today.

I think you have the right idea though and it deserves a wider
audience. In investigating this phenomenon on Sun's site and
elsewhere, it remains unresolved even though what you are presenting is
precisely what the doctor ordered.

Thanks - excellent thinking.
 
S

Sudsy

Wendy S wrote:
Are you opposed to a bit of JavaScript? I have a very long page in which I
allow people to hide and show sections. Hiding or showing causes a round
trip to the server, and I need to return them to the same section they were
looking at. In the Action, I set:
request.setAttribute( "anchor", "nameOfAnchor");

Then at the bottom of the JSP (so it won't execute until the page has
finished loading) I have:
<c:if test="${anchor ne null}">
<script>
document.location = "#<c:eek:ut value="${anchor}"/>";
</script>
</c:if>
<snip>

I've got to hand it to you, Wendy: that's a slick solution! It won't
work if JavaScript is disabled/unavailable but it should certainly
work in the majority of cases. Nice job of "thinking outside the box".
 
W

Wendy S

I think you have the right idea though and it deserves a wider
audience. In investigating this phenomenon on Sun's site and
elsewhere, it remains unresolved even though what you are
presenting is precisely what the doctor ordered.

Well, feel free to re-post it wherever you think it will help!

Thanks to you and Sudsy for the compliments. :)
 
K

krasicki

Fellow investigators - here's a variation on Wendy's theme that suits
my purposes slightly better.
I'll share it in the event that it's of interest to others.

What I did is the following:

In my loginFormBean, I have the following methods;

public ActionErrors validate(
ActionMapping mapping,
HttpServletRequest request) {

ActionErrors errors = new ActionErrors();
// Validate the fields in your form, adding
// adding each error to this.errors as found, e.g.

checkEmpty(getDestination(), errors, "destination_missing");
checkEmpty(getTrustedUsername(), errors, "username_missing");
checkEmpty(getTrustedPassword(), errors, "password_missing");

// This next error is where I test the javascript
// After all, we only want to go to this anchor when I have an error
or information
// to give the user

checkEmpty("",errors, "test");
// if ((field == null) || (field.length() == 0)) {
// errors.add("field", new
org.apache.struts.action.ActionError("error.field.required"));
// }
return errors;

}

private void checkEmpty(String param, ActionErrors errs, String msg) {
if (param == null || param.trim().length() == 0) {
errs.add(msg, new org.apache.struts.action.ActionError(msg));
}
}

Then in my properties file I added;

# Optional header and footer for <errors/> tag.
#errors.header=<ul>
#errors.footer=</ul>
destination_missing=<li>You forgot to mention which platform this
login applies to.
username_missing=<li>What is your username?
password_missing=<li>Your password is?
test=<script>document.location = "#aaa";</script>

Notice my message is javascript that executes on demand.

My jsp page looks something like:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html:HTML>
<HEAD>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ page
language="java"
contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"
%>
<META http-equiv="Content-Type" content="text/html;
charset=ISO-8859-1">
<META name="GENERATOR" content="IBM WebSphere Studio">
<META http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Pragma" content="no-cache">
<LINK href="theme/Master.css"
rel="stylesheet" type="text/css">
<TITLE>SecurityPropertiesLogon.jsp</TITLE>
</HEAD>
<BODY >
// snip

<p><html:form action="/login.do"><b>
<font face="Verdana">UserName:&nbsp;</font></b>
<input type="TrustedUsername" name="trustedUsername"/>
<br><b><font face="Verdana">Password:&nbsp;</font></b>
<input type="TrustedPassword" name="trustedPassword" />

//snip

<html:submit>XXX</html:submit>

// snip

</html:form>
<a NAME="aaa"> </a>
<%@ include file="InfoAndErrors.jspf"%>
</BODY>
</html:HTML>


Then InfoAndErrors looks like:

<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<br><b><font color="#CCCCCC">Information, errors, and
further instructions:</font></b><html:errors/>

Now, what I like about this is that the anchor is executed only when
the code
is instrumented to do so. This means I can use the Struts error
facility for realtime
debugging purposes by further tweaking the code a bit and employing the
Struts <html:errors> facility to kick out debugging messages as
instrumented.

I'm using WSAD 5.1.x and this seems to work fine in preliminary tests
I'm doing.
Your mileage may vary.
 
K

krasicki

Oh, one last technical note. In my example I was just playing around
with multiple error messages. On a true login screen a better practice
is not to tell the person attempting a login exactly which input is
incorrect.

Finally, thanks to everyone who responded - I think this is one of
those tricky asides in Struts that needed clarification - our good deed
for the day.
 
C

cstockton

Wendy said:
Well, feel free to re-post it wherever you think it will help!

Thanks to you and Sudsy for the compliments. :)

I use a non-struts solution. If I need to forward to an anchor, I set
a request attribute in the Action

request.setAttribute("anchor", anchor);

then in the jsp, I check if an anchor is present and send a redirect:

<logic:present name="anchor" scope="request">
<%
String anchor = (String)request.getAttribute("anchor");
response.sendRedirect("mypage.jsp#" + anchor);
%>
</logic:present>

This works, but exposes your jsp.

Chris
 
J

javaguy

Wendy said:
Are you opposed to a bit of JavaScript? I have a very long page in which I
allow people to hide and show sections. Hiding or showing causes a round
trip to the server, and I need to return them to the same section they were
looking at. In the Action, I set:
request.setAttribute( "anchor", "nameOfAnchor");

Then at the bottom of the JSP (so it won't execute until the page has
finished loading) I have:
<c:if test="${anchor ne null}">
<script>
document.location = "#<c:eek:ut value="${anchor}"/>";
</script>
</c:if>

Since you want to do this only if there are errors, you could skip setting a
request attribute, and instead test for the presence of errors and only
write out the script if there are errors to display.

HTH,
Wendy S


I've used this on my project, but have noticed interesting side
effects.

Sometimes my pages have an additional section:

<script>

<c:if test="${not empty myForm.pdf}">
window.open("myurl/somepath/<c:eek:ut value='${myform.pdf}'/>", "params");
</c:if>

....

</h:html>

<script>
<c:if test="${not empty myForm.jumpto}">
document.location="#<c:eek:ut value='${myForm.jumpto}'/>"
<c:/if>
</script>


If a PDF parameter is included, then when this form is rendered it pops
up a new window with that PDF.

Suppose I also include a "base" tag: <h:base/>. When the
document.location is executed the PDF is displayed twice. You can
juuusssttt quite see it reusing the window when using Windows Adobe
Reader, but when on Linux (Firefox) you only have the ggv viewer then
you get two separate popups. But without the "base" tag, only once.

Patient: "Doctor, it hurts when I do this."
Doctor: "Then don't to that!"

I will not use the "base" tag for the time being, but I'm still looking
for a more general solution.

Thanks for your ideas
Jerome.
 
Joined
Dec 30, 2020
Messages
1
Reaction score
0
Hi, I realise this is an old thread, but I found that I had to use a slight different approach to what Wendy had posted.
I still used the approach of request.setAttribute( "anchor", "anchorname");

However I could not set the document location or href. My page has a form and setting the location generated errors due to missing beans. So I took the approach of setting focus on an element (in my case a text field) that was in the right area.

<logic:present name="anchor" scope="request">
<%
String anchor = (String)request.getAttribute("anchor");
%>
window.addEventListener('load', (event) => {
document.getElementById("<%=anchor%>").focus();
});
</logic:present>

The anchor name was simply the element ID that I wished to focus on.
 
Joined
Dec 10, 2020
Messages
10
Reaction score
1
I'm looking for the recipe to do the following:

I have created a jsp struts page that contains a form. The page is
called logon.jsp and it has a corresponding jsp page called done.jsp.

If the button on the form is a success, I redirect to done.jsp. So far
so good.

If the button on the form encounters errors I return the appropriate
error messages to logon.jsp and they display exactly to <html:errors/>.

However, the next level of refinement has me puzzled.

Within logon.html, I have created an errors section at the bottom of
the page and I use an anchor tag, <a NAME="errors">, to identify its
beginning.

I have tried to map my 'failure' condition to logon.jsp#errors with no
luck. The page is mapped to <whatever>logon.do no matter what
combinatorials I've tried. And just to be clear, my jsp layout is
designed so that the errors section is intentionally unobtrusive to the
logon part of the page. IOW, I know that I can just display the errors
higher on the page and so on. The point is that I want a space for
verbose explanations that aren't disorientating to the user's
expection.

Is this exercise possible in Struts?
hi
u can refer geek for geeks, they have explained this thing in deeply.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,813
Messages
2,569,696
Members
45,483
Latest member
TedDvb6626

Latest Threads

Top