Creating CRUD pages

For each entity in a project, one can create a CRUD page and a related form page. For each one, a Java class and an HTML page must be coded.

CRUD pages are responsible for searching and listing entities; they provide the view details, edit and delete buttons for each entity. Form pages are responsible for displaying and editing details of a single entity.

In this tutorial, we will focus on the following five files, in the web module:

  • web/src/main/java/tutorial/pages/FormStockPage.java
  • web/src/main/java/tutorial/pages/FormStockPage.html
  • web/src/main/java/tutorial/pages/CRUDStockPage.java
  • web/src/main/java/tutorial/pages/CRUDStockPage.html
  • web/src/main/java/tutorial/WebApplicationMenuCreator.java

Java and HTML files must be in the same directory.

FormStockPage.java

public class FormStockPage extends FormPage<Stock> {

    /**
     * @param source
     * @param sourcePageParameters
     */
    public FormStockPage(Class<? extends Page> source, PageParameters sourcePageParameters) {
        super(source, sourcePageParameters);
    }

    /**
     * @param source
     * @param sourcePageParameters
     * @param entity
     * @param formType
     */
    public FormStockPage(Class<? extends Page> source, PageParameters sourcePageParameters, Stock entity, FormType formType) {
        super(source, sourcePageParameters, entity, formType);
    }

    /**
     * @param sourcePageParameters
     */
    public FormStockPage(PageParameters sourcePageParameters) {
        super(sourcePageParameters);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected List<Component> createFormComponents() {
        return Arrays.<Component>asList(this.createTextField("mnemonic"), this.createTextField("quantity"),
                this.createTextField("unitPrice"));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected MessageCreator getHelpTextCreator() {
        return null;
    }

}

FormStockPage.html

<html>
        <head>
        </head>
        <body>
                <wicket:extend>
                        Name: <input type="text" wicket:id="mnemonic"/>
                        Quantity: <input type="text" wicket:id="quantity" />
                        Unit Value: <input type="text" wicket:id="unitPrice" />
                </wicket:extend>
        </body>
</html>

CRUDStockPage.java

public class CRUDStockPage extends CrudPage<Stock> {
    private final static StockPriceSearcher priceSearcher;

    static {
        priceSearcher = new StockPriceSearcher();
    }

    /**
     * {@inheritDoc}
     */
    public Page createNewPage() {
        return new FormStockPage(this.getPageClass(), new PageParameters());
    }

    /**
     * Search for all stocks
     *
     * @param daoFactory the daoFactory
     * @return a list of all stocks
     */
    public List<Stock> search(DAOFactory daoFactory) {
        StockDAO dao = daoFactory.getDAOByClass(StockDAO.class);
        List<Stock> stockList = dao.findAll();

        for (Stock stock : stockList) {
            priceSearcher.putQuery(stock.getMnemonic());
        }

        return stockList;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected Page createFormPage(Stock entity, FormType formType) {
        return new FormStockPage(this.getPageClass(), new PageParameters(), entity, formType);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void addSearchFields(WebMarkupContainer container) {
        container.add(this.createTextField("mnemonic"));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void addResultTableColumns(ReportTableBuilder<Stock> table) {
        table.addStringColumn("mnemonic", "Mnemonic", "mnemonic");
        table.addNumberColumn("quantity", "Quantity", "quantity", 0);
        table.addNumberColumn("unitPrice", "Unit Price", "unitPrice", 2);

        table.addNumberColumn("currentValue", "Current Value", new CellValueResolver<Stock>() {
            public Object resolveCellValue(Stock stock) {
                return priceSearcher.getPrice(stock.getMnemonic());
            }
        }, 2);

        table.addNumberColumn("differenceDifference", "Unit Difference", new CellValueResolver<Stock>() {
            public Object resolveCellValue(Stock stock) {
                BigDecimal currentValue = priceSearcher.getNumericalPrice(stock.getMnemonic());
                if (currentValue == null) {
                    return null;
                } else {
                    return currentValue.subtract(stock.getUnitPrice());
                }
            }
        }, 2);

        table.addNumberColumn("totalDifference", "Total Difference", new CellValueResolver<Stock>() {
            public Object resolveCellValue(Stock stock) {
                BigDecimal currentValue = priceSearcher.getNumericalPrice(stock.getMnemonic());
                if (currentValue == null) {
                    return null;
                } else {
                    return currentValue.subtract(stock.getUnitPrice()).multiply(stock.getQuantity());
                }
            }
        }, 2);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected MessageCreator getHelpTextCreator() {
        return null;
    }

}

CRUDStockPage.html

<html>
         <head>
         </head>
         <body>
             <wicket:extend>
                 Name: <input type="text" wicket:id="mnemonic" />
             </wicket:extend>
         </body>
</html>

WebApplicationMenuCreator.java

A new menu entry called Tutorial must be added to show our new CRUDStockPage page.

public class WebApplicationMenuCreator extends AbstractMenuConfigFactoryBean {

    /**
     * {@inheritDoc}
     */
    @Override
    protected MenuConfig createMenuConfig() {
        MenuConfig config = new MenuConfig();

        // add menu here
        config.addPage(Authorization.class, "Autorização", "Autorizar");
        config.addPage(ConsultaTrilhaAuditoria.class, "Autorização", "Auditoria");
        config.addPage(ConsultaDiagnosticador.class, "Infra", "Diagnosticador");
        config.addPage(ConsultaExceptionRecord.class, "Infra", "Exceptions");
        config.addPage(Importacao.class, "Infra", "Importacao");
        config.addPage(AlterarSenhaPage.class, "Infra", "Alterar senha");
        config.addPage(CrudUsuarioPage.class, "Infra", "Controle de acesso");
        config.addPage(CRUDStockPage.class, "Tutorial", "Stock");

        return config;
    }
}

To create a new entity, access the page “Stock” in the “Tutorial” menu, and click the “New” button. Fill all fields and save it; now, access page “Autorizar” in the menu “Autorização”. Select the option “Stock” in the combo box, and you can authorize the previously created bean.