Saturday, June 2, 2012

Generic Editable Grid-wicket

Wicket provides the much reusable components to achieve the website feasibility. By overriding the existing components we can create our own components as per our need.
Editable grid with sorting, filtering and pagination has been developed by extending few classes which already exist in wicket framework.
I wish to develop the component which will support the following features:
1.       The component should list all the dates regardless of the list of objects I passed. Component should accept generic data.
2.       It should provide the option for sorting by clicking the header of the table.
3.       It should provide the filtering option to find the specific data.
4.       Each row can be editable by default and should be able to delete
5.       And then pagination.
Simply it should looks like the following one….

First SubmitButtonPanel.jave has been created which is used for the header, it will provide the header link for the user to obtain the sorted data
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.ajax.markup.html.form.AjaxSubmitButton;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.list.PageableListView;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;
public  class SubmitButtonPanel<T extends AbstractEntity> extends Panel{


      /**
       *
       */
      private static final long serialVersionUID = 1L;
      AjaxSubmitButton submitLink;
      Label label;
      PageableListView<T> pageableListView;
     
      boolean isClicked=false;
      public SubmitButtonPanel(String id,PageableListView<T> listView,String resourceKey,String expression) {
            super(id);
            pageableListView=listView;
      add(newSubmitButton(listView,resourceKey,expression));
      }

      protected AjaxButton newSubmitButton(PageableListView<T> listView,String resourceKey,final String expression) {
           
            AjaxButton submitLink=new AjaxButton("submitLink",new ResourceModel(resourceKey)) {
                 
                  @Override
                  public void onSubmit() {
                        if(isClicked){
                              isClicked=false;
                        }else{
                              isClicked=true;
                        }
                        onClick(isClicked);
                  }

                  @Override
                  protected void onSubmit(AjaxRequestTarget arg0, Form<?> arg1) {
                       
                       
                  }
            };

            submitLink.setLabel(Model.of("Name"));
            return submitLink;
      }
      protected void newLabel(AjaxSubmitButton ajaxSubmitLink,String resourceKey){
            label=new Label("label",new ResourceModel(resourceKey));
            ajaxSubmitLink.add(label);
      }
      protected void onClick(boolean isSorting){
           
      }
}

The Html file this panel is SubmitButtonPanel.html :
<wicket:panel> 
<style type="text/css">
.submitLink {
background-color: transparent;
text-decoration: underline;
border: none;
cursor: pointer;
cursor: hand;
}



</style>
<input type="submit" wicket:id="submitLink" class="submitLink"/>
</wicket:panel>

The css provided in that panel will help to display the button as link.
The pageableList.java was developed to implement all the requirements

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.beanutils.BeanComparator;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.ajax.markup.html.navigation.paging.AjaxPagingNavigator;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.PageableListView;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.ResourceModel;
public abstract class PageableList<T extends AbstractEntity> extends Panel {

      /**
       *
       */
      TextField textField;
      List<T> list = null;
      T modelObject = null;
      private static final long serialVersionUID = 1L;
      PageableListView<T> listView;
      AjaxPagingNavigator ajaxPagingNavigator;
      WebMarkupContainer datacontainer;
      TableColumn tableHeader;
      TableColumn fileterColumn;
      Label label;
      Form form;

      public PageableList(String id, List<T> pageablelist, final T t) {
            super(id);
            this.list = pageablelist;
            modelObject = t;

            form = new Form("pageableForm");
            datacontainer = new WebMarkupContainer("data");

            datacontainer.setOutputMarkupId(true);
            datacontainer.setOutputMarkupPlaceholderTag(true);

            final List<T> pageList = new ArrayList<T>(list);
            final IModel<List<T>> iModels = new LoadableDetachableModel<List<T>>() {

                  /**
                   *
                   */
                  private static final long serialVersionUID = 1L;

                  @Override
                  protected List<T> load() {

                        return pageList;
                  }
            };
            IModel<T> iModel = new LoadableDetachableModel<T>() {

                  /**
                   *
                   */
                  private static final long serialVersionUID = 1L;

                  @Override
                  protected T load() {

                        return t;
                  }
            };

            listView = getPageableList(pageList);
            listView.setOutputMarkupId(true);
            listView.setReuseItems(true);
            listView.setOutputMarkupPlaceholderTag(true);
            datacontainer.add(listView);
            ajaxPagingNavigator = new AjaxPagingNavigator("navigator", listView);
            ajaxPagingNavigator.setOutputMarkupId(true);
            ajaxPagingNavigator.setOutputMarkupPlaceholderTag(true);
            datacontainer.add(ajaxPagingNavigator);

            form.add(new AjaxButton("search") {

                  @Override
                  public void onSubmit() {
                        List<T> filteredList = new ArrayList<T>();
                        Iterator<T> iterator = pageList.iterator();

                        while (iterator.hasNext()) {
                              T model = iterator.next();
                              if (filterCondition(modelObject, model)) {
                                    filteredList.add(model);
                              }
                        }
                        datacontainer.remove(listView);
                        datacontainer.remove(ajaxPagingNavigator);
                        listView = getPageableList(filteredList);
                        listView.setOutputMarkupId(true);
                        listView.setReuseItems(true);
                        listView.setOutputMarkupPlaceholderTag(true);
                        datacontainer.add(listView);
                        ajaxPagingNavigator = new AjaxPagingNavigator("navigator",
                                    listView);
                        datacontainer.add(ajaxPagingNavigator);
                        form.remove(fileterColumn);
                        fileterColumn = new TableColumn("filterTool");
                        fileterColumn.setOutputMarkupId(true);
                        modelObject = clear();;
                        addFilterComponent(fileterColumn, listView, modelObject);
                        form.add(tableHeader);
                        form.add(fileterColumn);
                  }

                  @Override
                  protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
                       
                  }
            });
            form.add(new AjaxButton("clear") {

                  @Override
                  public void onSubmit() {
                        List<T> list1 = pageList;
                        datacontainer.remove(listView);
                        datacontainer.remove(ajaxPagingNavigator);
                        listView = getPageableList(list1);
                        listView.setOutputMarkupId(true);
                        listView.setReuseItems(true);
                        listView.setOutputMarkupPlaceholderTag(true);
                        datacontainer.add(listView);
                        ajaxPagingNavigator = new AjaxPagingNavigator("navigator",
                                    listView);
                        datacontainer.add(ajaxPagingNavigator);
                        form.remove(fileterColumn);
                        fileterColumn = new TableColumn("filterTool");
                        fileterColumn.setOutputMarkupId(true);
                        modelObject = clear();

                        addFilterComponent(fileterColumn, listView, modelObject);
                        form.add(tableHeader);
                        form.add(fileterColumn);
                  }

                  @Override
                  protected void onSubmit(AjaxRequestTarget target, Form<?> form) {

                        listView.setList(iModels.getObject());

                        form.remove(tableHeader);
                        form.remove(fileterColumn);
                        tableHeader = new TableColumn("repeatingHeader");
                        tableHeader.setOutputMarkupId(true);
                        fileterColumn = new TableColumn("filterTool");
                        fileterColumn.setOutputMarkupId(true);
                        clear();
                        addFormComponent(tableHeader, listView, modelObject);
                        form.add(tableHeader);
                        form.add(fileterColumn);
                        target.addComponent(form);
                  }
            });
            tableHeader = new TableColumn("repeatingHeader");
            tableHeader.setOutputMarkupId(true);
            fileterColumn = new TableColumn("filterTool");
            fileterColumn.setOutputMarkupId(true);
            addFilterComponent(fileterColumn, listView, modelObject);
            addFormComponent(tableHeader, listView, modelObject);
            form.add(tableHeader);
            form.add(fileterColumn);
            form.add(datacontainer);
            form.add(new AjaxButton("Save",new ResourceModel("save")) {

                        @Override
                        public void onSubmit() {
                              System.out.println("Save");
                        }

                        @Override
                        protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
                             
                        }
                  });
            add(form);
      }

      protected T clear() {
            return modelObject;

      }

      protected void addTableColumns(TableColumn tableColumn, T t) {

      }

      protected void addFormComponent(TableColumn tableHeader,
                  PageableListView<T> listView, T modelObject) {

      }

      protected void addFilterComponent(TableColumn fileterColumn,
                  PageableListView<T> listView, T modelObject) {

      }

      protected void addFilterColumn(TableColumn fileterColumn1,
                  PageableListView<T> LislistView, T t, final String resourceKey,
                  final String inExpression) {
            fileterColumn1.add(new TextPanel(fileterColumn.newChildId(),
                        new PropertyModel<T>(t, inExpression)));

      }

      protected void addHeader(TableColumn tableHeader1,
                  PageableListView<T> LislistView, T t, final String resourceKey,
                  final String inExpression) {
            tableHeader1.add(new SubmitButtonPanel<T>(fileterColumn.newChildId(),
                        listView, resourceKey, inExpression) {

                  @Override
                  protected void onClick(boolean isSorting) {
                       
                        List<T> list1 = listView.getModelObject();
                        Collections.sort(list1, new BeanComparator(inExpression));
                        if (!isSorting) {
                              Collections.reverse(list1);
                        }
                        datacontainer.remove(listView);
                        datacontainer.remove(ajaxPagingNavigator);
                        listView = getPageableList(list1);
                        listView.setOutputMarkupId(true);
                        listView.setReuseItems(true);
                        listView.setOutputMarkupPlaceholderTag(true);
                        datacontainer.add(listView);
                        ajaxPagingNavigator = new AjaxPagingNavigator("navigator",
                                    listView);
                        datacontainer.add(ajaxPagingNavigator);
                        form.remove(fileterColumn);
                        fileterColumn = new TableColumn("filterTool");
                        fileterColumn.setOutputMarkupId(true);
                        addFilterComponent(fileterColumn, listView, modelObject);
                        form.add(fileterColumn);
                  }

            });

      }

      protected void addColumn(TableColumn tableColumn, T t,
                  final String inExpression) {

            tableColumn.add(new TextPanel(tableColumn.newChildId(),
                        new PropertyModel<T>(t, inExpression)));

      }

      private class TextPanel extends Panel {
            public TextPanel(String id, PropertyModel<T> textModel) {
                  super(id);
                  add(newTextBox("text", textModel));
            }
      }

      protected TextField newTextBox(String id, PropertyModel<T> textModel) {
            textField = new TextField(id, textModel);
            textField.setOutputMarkupId(true);
            textField.setEnabled(isEnable());
            return textField;
      }

      protected boolean isEnable() {
            return true;

      }

      private class LabelPanel extends Panel {
            public LabelPanel(String id, PropertyModel<T> textModel) {
                  super(id);
                  add(newLabelBox("label", textModel));
            }
      }

      protected Label newLabelBox(String id, PropertyModel<T> textModel) {
            label = new Label(id, textModel);
            label.setOutputMarkupId(true);
            label.setEnabled(isEnable());
            return label;
      }

      protected boolean filterCondition(T filterObject, T modelObject) {
            return false;
      }

      private PageableListView<T> getPageableList(List<T> pageList) {
            PageableListView<T> listView = new PageableListView<T>("rows",
                        pageList, 4) {

                  @Override
                  protected void populateItem(ListItem<T> listItem) {

TableColumn tableColumn = new TableColumn("repeatingView");
                        tableColumn.setOutputMarkupId(true);
                        addTableColumns(tableColumn,listItem.getModelObject());
                        listItem.add(tableColumn);
                        listItem.add(new AjaxButton("delete", new ResourceModel("delete")) {

                              @Override
                              public void onSubmit() {
                                    System.out.println("delete to do");
                              }

                              @Override
                              protected void onSubmit(AjaxRequestTarget target, Form<?> form) {

                              }
                        });

                  }

            };
            return listView;
      }
}
AbstractEntity is a super class for all your entity classes.
TableColumn.java is child class of RepeatingView :

public class TableColumn extends RepeatingView{
      /**
       *
       */
      private static final long serialVersionUID = 1L;
     
      public TableColumn(String id) {
            super(id);
            setOutputMarkupId(true);
      }

     

}

We have two html files for PageableList.java
1.  PageableList$TextPanel.html
<wicket:panel>
         <input wicket:id="text" type="text" />
</wicket:panel>
2.  PageableList$LabelPanel.html
<wicket:panel>
         <input wicket:id="text" type="text" />
</wicket:panel>

Create an entity class which extend the abstract entity :
public class AbstractEntity implements Serializable {

}
public  class ComponentEntity extends AbstractEntity {
     
      private String empId;
      private String name;
      private Integer salary;
      private boolean isRequired;
     


      public boolean isRequired() {
            return isRequired;
      }

      public void setRequired(boolean isRequired) {
            this.isRequired = isRequired;
      }

      public ComponentEntity(String empId, String name, Integer salary) {
            super();
            this.empId = empId;
            this.name = name;
            this.salary = salary;
           
      }

      public String getName() {
            return name;
      }

      public void setName(String name) {
            this.name = name;
      }

      public Integer getSalary() {
            return salary;
      }

      public void setSalary(Integer salary) {
            this.salary = salary;
      }

      public String getEmpId() {
            return empId;
      }

      public void setEmpId(String empId) {
            this.empId = empId;
      }

      public ComponentEntity() {
            super();
      }
     
}
TestFormPanel.jave is the main class which will override the methods in the pageableList and provide the columns need to be displayed in the grid and filter condition.
import org.apache.wicket.markup.html.list.PageableListView;

public  class TestFormPanel extends PageableList<ComponentEntity>{

public TestFormPanel(String id,List<ComponentEntity> list,ComponentEntity componentEntity) {
           

            super(id,list,componentEntity);
             setOutputMarkupId(true);
           
      }

      /**
       *
       */
      private static final long serialVersionUID = 1L;

      @Override
      protected void addTableColumns(TableColumn tableColumn, ComponentEntity t) {
                  addColumn(tableColumn, t, "empId");
                  addColumn(tableColumn, t, "name");
                  addColumn(tableColumn, t, "salary");
                        }

      @Override
      protected void addFilterComponent(TableColumn fileterColumn,
                  PageableListView<ComponentEntity> listView,
                  ComponentEntity modelObject) {
addFilterColumn(fileterColumn,listView,modelObject,"SortingPanel.empId","empId");
addFilterColumn(fileterColumn,listView,modelObject,"SortingPanel.name","name");
addFilterColumn(fileterColumn,listView,modelObject,"SortingPanel.salary","salary");
      }

      @Override
      protected void addFormComponent(TableColumn tableHeader,
                  PageableListView<ComponentEntity> listView,
                  ComponentEntity modelObject) {
addHeader(tableHeader,listView,modelObject,"SortingPanel.empId",
"empId");
                               addHeader(tableHeader,listView,modelObject,"SortingPanel.name",
"name");
addHeader(tableHeader,listView,modelObject,"SortingPanel.salary","salary");
            }

     
      @Override
      protected boolean filterCondition(ComponentEntity filterObject,
                  ComponentEntity modelObject) {
             return
(filterObject.getEmpId()== null || modelObject.getEmpId().equalsIgnoreCase(filterObject.getEmpId())) &&
(filterObject.getSalary() == null || filterObject.getSalary()==modelObject.getSalary()) &&
(filterObject.getName() == null || modelObject.getName().equalsIgnoreCase(filterObject.getName()));
            }

      @Override
      protected ComponentEntity clear() {
            return new ComponentEntity();
      }



}
TestFormPanel.html :

<wicket:panel> 

<form action="" wicket:id="pageableForm">
<table>

        <thead>
            <tr>
               <th wicket:id="repeatingHeader"></th>
            </tr>
        </thead>
        <tbody >
            <tr>
                <td wicket:id="filterTool"></td>
                <td> <input wicket:id="search" type="submit" name="search" value="search"/> &nbsp;&nbsp;<input wicket:id="clear" type="submit" name="clear" value="clear"/></td>
            </tr>
          
        </tbody>
        </table>
      
     
<table wicket:id="data">

        <tbody >
           
            <tr wicket:id="rows">
                <td wicket:id="repeatingView"></td>
             <td>  <input type="submit" wicket:id="delete" class="submitLink"/></td>
            </tr>
          
        </tbody>
        <tfoot>
            <tr>
                <td wicket:id="navigator"></td>
                <td></td>
            </tr>
        </tfoot>
    </table>
   
    <input type="submit" wicket:id="Save" value="Save" align="left"/>
      </form>

</wicket:panel>

FirstWicketHome.jave :
public class FirstWicketHome extends WebPage{
     
      public FirstWicketHome()
      {
List<ComponentEntity> emptyList = new ArrayList<ComponentEntity>();
      //fill the list emptyList with datas
TestFormPanel testPanel=new TestFormPanel("sortingPanel", emptyList,new ComponentEntity());
     
            add(testPanel);
      }

}
FirstWicketHome.Html:
<html>
<body>
    <div wicket:id="sortingPanel"/>
</body>
</html>
FirstWicketApplication.java
public class FirstWicketApplication extends WebApplication{

      @Override
      public Class<? extends Page> getHomePage() {
           
            return FirstWicketHome.class;
      }
     

}

No comments:

Post a Comment