getting two JSPs to share a variable

I'm fairly new to JSP and have been building an online calendar system with it (and javas Calendar Class). I have next/previous buttons to navigate through the calendar. These buttons are located in a seperate frame (the sideframe) from where the calendar is displayed (the mainframe). I also have a shared variable "count" which gets incremented/decremented based on which button (next or previous) is selected and then gets added to the current year and passed to the javabean to come up with the new calendar year to be displayed.

As of now, when the calendar gets loaded and next is clicked, it goes to 2007 (which is correct) but if next gets clicked again nothing happens (it stays on 2007). If previous is clicked, it jumps to 2005 and just stays on 2005. I have tried passing the count variable through the URL and have tried using htmls hidden type (which is what i used below).

Why is this an incorrect way to share a variable?

***code to sideframe.jsp***

<HTML>

<%@ page import="java.util.*" language='java' autoFlush='true'%>

<BODY>

<form method=post action="displayCalNext1.jsp" target="main_frame">

<jsp:useBean id="myBean" scope="page" class="myBean.calendarCreate">

<%

int count=0;

String s=request.getParameter("num1");

if(s!=null){

count=Integer.parseInt(s);

}

%>

<input type="submit" name="action1" value="<< Previous">

<input type="submit" name="action1" value="Next >>">

<input type="hidden" name="count" value="<%=count%>">

</form>

</jsp:useBean>

</BODY>

</HTML>

****code for displayCalNext1.jsp****

<HTML>

<%@ page import="java.util.*" language='java' autoFlush='true'%>

<BODY style="color: darkorange; font-family: 'Book Antiqua'; text-align: center">

<form method=post action="sideframe.jsp" target="main_frame" >

<jsp:useBean id="myBean" scope="page" class="myBean.calendarCreate">

<%

String action1=request.getParameter("action1");

int current=0;

String cc=request.getParameter("count");

if(cc!=null){

current=Integer.parseInt(cc);

}

if(action1!=null && action1.equals("Next >>")){

Calendar c=Calendar.getInstance();

current+=1;

int xx=0;

int cYear=(c.get(Calendar.YEAR))+current;

while(xx<12){

out.print(myBean.buildCal(xx,cYear));

++xx;

}

}

if(action1!=null && action1.equals("<< Previous")){

Calendar c=Calendar.getInstance();

current-=1;

int cYear=(c.get(Calendar.YEAR))+current;

int xx=0;

while(xx<12){

out.print(myBean.buildCal(xx,cYear));

++xx;

}

}

%>

<input type="hidden" name="num1" value="<%=current%>">

</form>

</jsp:useBean>

</BODY>

</HTML>

Thanks!

[3088 byte] By [LGator_09a] at [2007-10-3 0:09:18]
# 1

So lets walk through these requests.

1: User requests your calendar page, which has frames,

1a: so User's browser requests the sideFrame page

1b: User's browser requests mainFrame page

Two things to note: each frame gets a different request, and when the sideFrame is first requested the num1 would be 0 or null, so would be count.

2: User presses the Next>> button on the sideFrame. The form has a hidden value of count which is set to 0, and the response is targeted to the main frame. The mainFrame page takes the count and the command to get the next year. No response is sent to the sideFrame, so that page remains exactly the same.

3: User presses the Next>> button on the sideFrame. The form still has a hidden count value of 0, since the previous response was targeted at the mainFrame - meaning the sideFrame had no comunication with the server to know if the count should go up or down. The static HTML that the browser sees stayed the same, so the value stayed the same. The response is again targeted to the mainFrame, which does exactly the same thing it did in its last response since it had the same input.

You shouldn't use a hidden input between the frames to do the navigation. What I would do is have the sideFrame just have Next and Previous buttons. Store the year to be displayed in the user's session. When the Next button is pressed, increment the year...:

/* The sideframe.jsp */

/* By the way, your HTML needs practice...

be consistent with caps, always put attributes in quotes,

and close your tags in the same order they were opened. */

<%@ page import="java.util.*" language="java" autoFlush="true"%>

<html>

<body>

<form method="post" action="displayCalNext1.jsp" target="main_frame">

<jsp:useBean id="myBean" scope="page"

class="myBean.calendarCreate"/>

<input type="submit" name="action1" value="<< Previous"/>

<input type="submit" name="action1" value="Next >>"/>

</form>

</body>

</html>

/* the displayCalNext1.jsp */

/* Also, put all your page directives (<%@ ) at the top before any output or they may be lost. */

<%@ page import="java.util.*" language="java" autoFlush="true"%>

<html>

<body style="color: darkorange; font-family: 'Book Antiqua'; text-align: center">

<!-- Are you sure the action is sideframe.jsp targeting the main_frame? -->

<form method="post" action="sideframe.jsp" target="main_frame" >

<jsp:useBean id="myBean" scope="page"

class="myBean.calendarCreate"/>

<%

String action1=request.getParameter("action1");

//Session can only store Objects, so we store Integer rather than int

Integer displayYear=(Integer)session.getAttribute("displayYear");

Calendar calendar = Calendar.getInstance();

//Calendar uses ints, not Integers, so get proper int value

int dispYear = 0;

if (displayYear == null) {

//if the no displayYear in session, use current Calendar Year

dispYear = calendar.get(Calendar.YEAR);

} else {

//use the value from the displayYear in session

dispYear = displayYear.intValue();

}

//no need for compare to null if we reverse comparison order

if("Next >>".equals(action1)) {

dispYear++;

}

if ("<< Previous".equals(action1)) {

dispYear--;

}

/* Be more descriptive in your variables - makes troubleshooting easier

Also, this is a better job for a for loop, since the number of iterations is known */

for (int month = 0; month < 12; month++) {

out.print(myBean.buildCal(month,dispYear));

}

// Store the dispYear back in session so we can use it next request

session.setAttribute("displayYear", new Integer(dispYear));

%>

</form>

</body>

</html>

stevejlukea at 2007-7-14 16:58:19 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 2
p.s. That gets easier if you are using Java 5.0 since the Integer -> int -> Integer conversions are done for you thanks to autoboxing.Also, if you create a real JavaBean, and learn JSTL/EL then the code will be easier to read (IMO anyway) since you won't need scriptlets.
stevejlukea at 2007-7-14 16:58:19 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 3

Thanks sooo much! That worked wonders! I was wondering though... when the user closes their browser or goes to another page i want to reset that session variable (displayYear) to null so that when they hit next the calendar doesn't jump to whatever it left off on (say they are seeing 2006 and then hit next and it jumps to 2009 because they left off on 2008). I know that in the web.xml file the tomcat session time is 30 minutes and i dont really want to change that. Is there an easy fix to this?

LGator_09a at 2007-7-14 16:58:19 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 4

Not to reset the value when the user goes to another page because there is no way to detect that.

On the otherhand, you know that when the user hits your page, the will request the top page - the one with the FRAMESET. When they are working inside your calendar, they no longer talk to the FRAMESET page, but to the underlying JSPs being displayed in the page.

SO what you can do is have the FRAMESET page set the displayYear to null when it is called. So whenever it is called the year is reset to the current year.

stevejlukea at 2007-7-14 16:58:19 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 5
thanks again for all your help!
LGator_09a at 2007-7-14 16:58:19 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...