FAQ

1. How can I determine which button was used to submit a form if I want to handle all of them with the same method?
2. How can I create a vector of a categorizing type such as Country using the Object Model (OM) and pass it to the template?
3. How can I pass an array of values from the browser to the action?
4. How can I store objects as session variables?
5. I want to use JDBC to do something that cannot be done with the OM. How can I get a database connection from the pool?
6. I want to do a complex query using JDBC but still create OM objects with the result. How can I do that?
7. How can I specify a sub directory under ~/screens and ~/actions, and how does it work?

Q1. How can I determine which button was used to submit a form if I want to handle all of them with the same method?
First, in Turbine you can handle multiple buttons in the doPerform method in an action class. The remainder of this answer is not Turbine specific (although I'll use Turbine syntax to show the code in the server side). The way to do determine which button was pressed is to use the variables that are implicitly passed in the HTTP request when the button is pressed. The following is an example of the HTML code for a button:
<input type=submit name=addlanguage value="Add language">
When this button is pressed, a variable called addlanguage with value "Add language" will be passed in the request. Intuitively, if we want to determine which button was pressed, we would do something like:
<input type=submit name=button value="Add language">
<input type=submit name=button value="Add school">
From the server code, you can get the value of the one variable button and check it to determine which button was used.
        String button = data.getParameters().getString("button");
        if (button.equals("Add language")) {
                // do smth
        } else if (button.equals("Add school")) {
                // do smth
        }
What is the problem with this? It breaks if the label in the button is changed.
The solution is counterintuitive. It is like this:
<input type=submit name=addlanguage value="Add language">
<input type=submit name=addschool value="Add school">
        String addLanguage = data.getParameters().getString("addlanguage","");
        String addSchool = data.getParameters().getString("addschool","");
        if (addLanguage.length() > 0) {
                // do smth
        } else if (addSchool.length() > 0) {
                // do smth
        }
NOTE: If you don't need to handle different buttons in the same method it's a lot easier to use Turbine action events

Q2. How can I create a vector of a categorizing type such as Country using the Object Model (OM) and pass it to the template?

        Vector countries = CountryPeer.doSelect(new Criteria());
        context.put("countries", countries);

Q3. How can I pass an array of values from the browser to the action?

In the template:
        
	<select name=entries multiple>
        <option value=1>First entry
        <option value=2>Second entry
        <option value=3>Third entry
        </select>
In the action:
        int a[] = data.getParameters().getInts("entries");
Q4. How can I store objects as session variables?
In the action:
         Object obj = ism.searchSentence(sentence).toString();
         //context.put("sr", obj);
         data.getSession().setAttribute("sr",obj);
In the screen or action:
        data.getSession().getAttribute("sr");

Q5. I want to use JDBC to do something that cannot be done with the OM. How can I get a database connection from the pool?

    DBConnection dbConn = null;

    try {
        dbConn = TurbineDB.getConnection();

        // use the connection
        // dbConn.getConnection() returns a JDBC Connection

    }
    finally {
        /* release the db connection no matter what happened */
        try {
            TurbineDB.releaseConnection(dbConn);
        }
        catch (Exception e) {
            // Error releasing database connection back to pool.
        }
    }

Q6. I want to do a complex query using JDBC but still create OM objects with the result. How can I do that?

You can use the method resultSet2Objects in the peer. The only requirement is that all the columns in the table corresponding to the object are provided in the resultset in the same order as they are known by the peer. There is a way create a string with the column names that can be used to build the sql query.
// build the query
StringBuffer sqlQuery = new StringBuffer();
sqlQuery.append("SELECT ");

// get columns in the order required by the peer
criteria = new Criteria();
MemberPeer.addSelectColumns(criteria);
sqlQuery.append(criteria.getSelectColumns().toString(","));

sqlQuery.append(" FROM Member");
sqlQuery.append(" WHERE first_name || last_name like '%' || ? || '%'");
PreparedStatement stmt = dbConn.getConnection()
	.prepareStatement(sqlQuery.toString());
stmt.setString(1, searchParameter);
ResultSet rset = stmt.executeQuery();

Vector members = MemberPeer.resultSet2Objects(rset);

rset.close();
Q7. How can I specify a sub directory under ~/screens and ~/actions, and how does it work?
case 1: In the vm file:
      action="$link.setPage("searchMembers,SSearchMembers.vm")
	# path to vm file is ~/screens/searchMembers/SSearchMembers.vm
	
	with the subdirectory information,
	~/screens/searchMembers/SSearchMembers.class will be loaded automatically if any

case 2: In the vm file:
      action="$link.setAction("searchMembers.ASearch")
	 ~/actions/searchMembers/ASearch.class will be called accordingly
	 

In the screen or action:
      data.setScreenTemplate("searchMembers,SSearchMembersResults.vm");
	 
	 with the subdirectory information,
	 vm file, ~/screens/searchMembers/SSearchMembers.vm, and  
	 screen class, ~/screens/searchMembers/SSearchMembers.class, will be called.    


Last updated: 6/29/2001 by Gabriel