Reading requests lists

One of the main challenges that we face with poor http frameworks is to deal with collections of objects that we want to read...

What can we do if we have a form with many 'address' fields and our business logic doesn't know how many there were in the last page?

The following code displays two forms... the user should add information for two persons which should be read by our business logic.

But let's suppose that our business logic did not know how many person's are coming... meaning that we want to use a List of Person's.

Form with two persons:

<html>

<form action="person.newList.logic" method="get">

    Name: <input name="people[0].name"/><br/>
    Address: <input name="people[0].address"/><br/>
    Preferred number: <input name="people[0].preferredNumber"/><br/>
        <br/>
        
    Name: <input name="people[1].name"/><br/>
    Address: <input name="people[1].address"/><br/>
    Preferred number: <input name="people[1].preferredNumber"/><br/>
                
        <input type="submit"/>

</form>

</html>

Pay attention that we indexed the forms just like a simple array: people[0].name, people[1].name etc.

The business logic

What should we do to make our business logic person.newList read two (or any quantity) of persons?

Simple, let's create a simple List of person's called people and set the @Parameter attribute to create objects as needed:

package org.vraptor.examples.list;

import java.util.List;

import org.vraptor.annotations.Component;
import org.vraptor.annotations.Logic;
import org.vraptor.annotations.Out;
import org.vraptor.annotations.Parameter;
import org.vraptor.examples.first.Person;

@Component("person")
public class PersonListLogic {

        @Parameter(create = true)
        private List<Person> people;

        public void newList() {
                System.out.printf("Adding %s to the database!%n", people.toString());
        }

        public List<Person> getPeople() {
                return this.people;
        }
}

Guess what happens? VRaptor instantiates the list as a simple ArrayList and every necessary person that is required by our parameters. It uses the generic parameter Person to discover which pojo it should instantiate to fill the List.

java.util.Set and Person[] would work just fine.

Finishing the example

And create your person/newList.ok.jsp file:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<html>

<c:forEach var="person" items="${people}">
        <li> ${person.name} prefers lives at ${person.address} number ${person.preferredNumber}</li><br/>
</c:forEach>

</html>

If you do not use jstl core tag library try simply printing $people for example...

Dynamic form example

The following code is a dynamic form which is similar to what we have seen in the previous example...

The difference is that it makes use of javascript to allow the user to add as many persons as he desires:

<html>

<script language="javascript">

        var last = 0;
        
        function create() {
                last++;
        dynamic_form.innerHTML += base_form.innerHTML.replace(/[[0]]/g, last + "]");
        }

</script>

<form action="person.newList.logic" method="get">

        <div id="base_form">
        
        Name: <input name="people[0].name"/><br/>
        Address: <input name="people[0].address"/><br/>
        Preferred number: <input name="people[0].preferredNumber"/><br/>
        <hr/>
        
        </div>
        
        <div id="dynamic_form">
        </div>

        <a href="javascript:create();">New entry</a><br/>
        <br/>
                
        <input type="submit"/>

</form>

</html>