Hi!

I have now better formalized my intentions (couldn't get sleep because
of this ;). You can see the benefits for yourself. However, I found
out that most of it can be done with existing wicket. Maybe some part
of the philosophy could be adapted into wicket in general. I submitted
a quickstart with two feature requests as
https://issues.apache.org/jira/browse/WICKET-2267

In my opinnion, this results in very clean code. I hope you like it too ;)


/**
 * Homepage
 */
public class HomePage extends WebPage {
        private static final long serialVersionUID = 1L;
        private final BookForm form;

        /**
         *
         */
        @SuppressWarnings("serial")
        public HomePage() {
                add(new Label("message",
                                "If you see this message wicket is properly 
configured and running"));
                add(form = new BookForm("form"));
        }

        /**
         * @return the form
         */
        public BookForm getForm() {
                return form;
        }
}

class BookForm extends Form<Void> {
        private final BookListView bookListView;
        private final Button submitButton;

        public BookForm(String id) {
                super(id);
                List<Book> books = Arrays.asList(new Book("first"), new
Book("second"), new Book("third"));
                add(bookListView = new BookListView("book_list", books));
                add(submitButton = new Button("submit"));
        }

        /**
         * @return the bookListView
         */
        public BookListView getBookListView() {
                return bookListView;
        }

        /**
         * @return the submitButton
         */
        public Button getSubmitButton() {
                return submitButton;
        }
}

class Book implements Serializable {
        /** Field name (reflection property expression) */
        public static final String NAME = "name";
        /** Field name (reflection property expression) */
        public static final String AUTHOR = "author";
        /** Field name (reflection property expression) */
        public static final String TYPE = "type";
        private String name;
        private String author;
        private Type type;

        /** @param name */
        public Book(String name) {
                this.name = name;
        }

        public enum Type {
                OLD, NEW;
        }       
}

class BookListView extends TestableListView<BookListItem, Book> {
        public BookListView(String id, List<Book> list) {
                super(id, list);
        }

        @Override
        protected BookListItem newItem(int index) {
                return new BookListItem(index, getListItemModel(getModel(), 
index));
        }
}

class BookListItem extends ListItem<Book> {
        private final TextField<String> nameField;
        private final TextField<String> authorField;
        private final DropDownChoice<Type> typeChoice;

        public BookListItem(int index, IModel<Book> model) {
                super(index, model);
                Book book = model.getObject();
                add(nameField = new TextField<String>("name", new
PropertyModel<String>(book, Book.NAME)));
                add(authorField = new TextField<String>("author", new
PropertyModel<String>(book, Book.AUTHOR)));
                add(typeChoice = new DropDownChoice<Type>("type", new
PropertyModel<Type>(book, Book.TYPE), Arrays.asList(Type.values())));
        }

        /**
         * @return the nameField
         */
        public TextField<String> getNameField() {
                return nameField;
        }

        /**
         * @return the authorField
         */
        public TextField<String> getAuthorField() {
                return authorField;
        }

        /**
         * @return the typeChoice
         */
        public DropDownChoice<Type> getTypeChoice() {
                return typeChoice;
        }
}


public abstract class TestableListView<ListItemType extends
ListItem<ItemType>, ItemType> extends ListView<ItemType> {
        public TestableListView(String id, IModel<List<ItemType>> model) {
                super(id, model);
        }

        public TestableListView(String id, List<ItemType> list) {
                super(id, list);
        }

        public TestableListView(String id) {
                super(id);
        }

        @Override
        protected final void populateItem(ListItem<ItemType> item) {
                // do nothing here
        }

        @Override
    protected abstract ListItemType newItem(int index);
        
        @Override
        public Iterator<ListItemType> iterator() {
                return (Iterator<ListItemType>) super.iterator();
        }
}


<html>
    <head>
        <title>Wicket Quickstart Archetype Homepage</title>
    </head>
    <body>
        <strong>Wicket Quickstart Archetype Homepage</strong>
        <br/><br/>
        <span wicket:id="message">message will be here</span>

        <form wicket:id="form">
          <table border="1">
            <tr wicket:id="book_list">
              <th>Name:</th><td><input type="text" wicket:id="name"/></td>
              <th>Author:</th><td><input type="text" wicket:id="author"/></td>
              <th>Type:</th><td><select wicket:id="type"></select></td>
            </tr>
          </table>
          <input type="submit" wicket:id="submit" value="Submit"/>
        </form>

    </body>
</html>

And the resulting test code is very clean, no hassle with the (almost
random ;) listview indexes after submit:

        /**
         *
         */
        public void testBookList() {
                // start and render the test page
                tester.startPage(HomePage.class);
                // assert rendered page class
                tester.assertRenderedPage(HomePage.class);
                // assert rendered label component
                tester.assertLabel("message",
                        "If you see this message wicket is properly configured 
and running");

                // assert rendered page class
                HomePage homePage = (HomePage) tester.getLastRenderedPage();
                BookForm bookForm = homePage.getForm();
                BookListView bookListView = bookForm.getBookListView();
                List<BookListItem> bookItems = 
toLinkedList(bookListView.iterator());
                {
                        // Test values of 1st book
                        BookListItem bookListItem = bookItems.get(0); // Note: 
no hassle
with run-time component path id's
                        assertEquals("first", 
bookListItem.getNameField().getValue());
                        assertEquals("", 
bookListItem.getAuthorField().getValue());
                        assertEquals("-1", 
bookListItem.getTypeChoice().getValue());
                }
                {
                        // Test values of 2nd book
                        BookListItem bookListItem = bookItems.get(1); // Note: 
no hassle
with run-time component path id's
                        assertEquals("second", 
bookListItem.getNameField().getValue());
                        assertEquals("", 
bookListItem.getAuthorField().getValue());
                        assertEquals("-1", 
bookListItem.getTypeChoice().getValue());
                }
                {
                        // Test values of 3rd book
                        BookListItem bookListItem = bookItems.get(2); // Note: 
no hassle
with run-time component path id's
                        assertEquals("third", 
bookListItem.getNameField().getValue());
                        assertEquals("", 
bookListItem.getAuthorField().getValue());
                        assertEquals("-1", 
bookListItem.getTypeChoice().getValue());
                }
                
                {
                        // Set new values
                        FormTester formTester = 
tester.newFormTester(bookForm.getPageRelativePath());

//                      formTester.setValue(bookItems.get(1).getAuthorField(),
"Hemingway"); // TODO New feature request
                    
tester.getServletRequest().setParameter(bookItems.get(1).getAuthorField().getInputName(),
"Hemingway");

                        // Submit changes
//                      formTester.submit(bookForm.getSubmitButton()); // TODO 
New feature request
                        formTester.submit();
                }
                
                tester.assertRenderedPage(HomePage.class);
                
                // Verify the submitted value
                {
                        // Test values of 2nd book
                        BookListItem bookListItem = bookItems.get(1); // Note: 
no hassle
with run-time component path id's
                        assertEquals("second", 
bookListItem.getNameField().getValue());
                        assertEquals("Hemingway", 
bookListItem.getAuthorField().getValue());
                        assertEquals("-1", 
bookListItem.getTypeChoice().getValue());
                }
        }

**
Martin

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
For additional commands, e-mail: users-h...@wicket.apache.org

Reply via email to