0

I have a simple-ish form that consists of a variable number of elements in a form using a ListView. Each element is in a table row, and contains a name (with a link which works fine) and a CheckBox, which marks that line for deletion. Only the checkboxs are editable in the form. At the bottom of the form is a 'delete selected' button, which will be used to delete all entries with a selected check.

I have tried doing this with a RepeatingView and a ListView, and both have the same problem - the internal model state of the checkboxes are not updated when the form is submitted - they are always false. In the SearchWrapper class setSelected method, the logger output is never displayed (other logging is so it's not a logging issue)

Can anyone see why this is wrong?

public class SavedSearchesTab extends Panel
{
  private static final Logger LOGGER = ...
  /**
   * 
   */
  public SavedSearchesTab( String p_id )
  {
    super( p_id );

    Form<?> l_form = new Form<Object>( "savedsearchform" ) {

      /**
       * @see org.apache.wicket.markup.html.form.Form#onSubmit()
       */
      protected void onSubmit()
      {
        LOGGER.info( "Form Submitted!" );
        for( String l_paramName : getRequest().getRequestParameters().getParameterNames() ) {
          LOGGER.info( "FormParam: " + l_paramName + ", value=" + getRequest().getRequestParameters().getParameterValue( l_paramName ) );
        }


        onDeleteSelected();
      }

    };
    l_form.setOutputMarkupId( true );
    add( l_form );


    List<UserSavedSearch> l_searches = getSearches();

    ListView<UserSavedSearch> l_repeater = new ListView<UserSavedSearch>( "repeater", l_searches ) {

      protected void populateItem( final ListItem<UserSavedSearch> p_item )
      {
        final UserSavedSearch l_search = p_item.getModelObject();
        SearchWrapper l_wrapper = new SearchWrapper( l_search );

        AjaxLink<UserSavedSearch> l_link = new AjaxLink<UserSavedSearch>( "searchnamelink" ) {

          private static final long serialVersionUID = 1L;

          public void onClick( AjaxRequestTarget p_target )
          {
            selectSearch( l_search );
          }
        };
        String l_linkText = l_search.getName();
        Label l_linkLabel = new Label( "searchnamelabel", l_linkText );
        l_link.add( l_linkLabel );

        p_item.add( l_link );

        TextArea<String> l_descriptionArea = new TextArea<String>( "searchsummary", new Model<String>( toSummary( l_search ) ) );
        p_item.add( l_descriptionArea );


        CheckBox l_checkbox = new CheckBox("searchcheckbox", new PropertyModel<Boolean>( l_wrapper, "selected" ) );
        p_item.add( l_checkbox );
      }
    };

    l_repeater.setReuseItems( true );
    l_form.add(l_repeater);
  }

  private List<UserSavedSearch> getSearches() {
    List<UserSavedSearch> l_searches = new ArrayList<UserSavedSearch>();
    // Make a couple of example ones for testing
    UserSavedSearch l_eg = new UserSavedSearch();
    l_eg.setName( "Example Search 1" );
    l_eg.setSearchArea( SearchArea.CUSTOMERS );
    l_searches.add( l_eg );
    l_eg = new UserSavedSearch();
    l_eg.setName( "Example Search 2" );
    l_eg.setSearchArea( SearchArea.CUSTOMERS );
    l_searches.add( l_eg );
    return l_searches;
  }

  private String toSummary( UserSavedSearch p_search ) {
    return "Summary of " + p_search.getName(); // TODO
  }

  protected void onDeleteSelected() {

  }

  protected void selectSearch( UserSavedSearch p_search ) {
    LOGGER.info( "Search " + p_search.getName() + " should be displayed!" );
  }  

  private class SearchWrapper implements Serializable {

    private static final long serialVersionUID = 1L;
    private UserSavedSearch m_data;
    private Boolean m_toDelete;

    public SearchWrapper( UserSavedSearch p_data ) {
      m_data = p_data;
      m_toDelete = false;
    }

    public boolean isSelected() {
      return m_toDelete;
    }

    public void setSelected( boolean p_selected ) {
     LOGGER.info( "SETTING SEARCHWRAPPER SELECTED STATE: " + p_selected );
      m_toDelete = p_selected;
    }

    public UserSavedSearch getSearch() {
      return m_data;
    }

  }

HTML:

<wicket:panel>
    <span class="sectiontitle"><wicket:message key="sectiontitle">savedsearches</wicket:message></span>

    <form wicket:id="savedsearchform">
        <fieldset>
            <table id="savedsearchtable">
                <tbody wicket:id="repeater">
                    <tr>
                        <td><input wicket:id="searchcheckbox" type="checkbox" name="searchselect" wicket:message="value:fragment.select.search" /></td>
                        <td><a href="#" wicket:id="searchnamelink"><span wicket:id="searchnamelabel">searchname</span></a></td>
                    </tr>
                    <tr>
                        <td colspan="2"><textarea wicket:id="searchsummary" readonly="readonly" rows="3" cols="100"/></td>
                    </tr>
                </tbody>
                <tr class="buttonPanel">
                    <td colspan="2">
                        <input type="submit" wicket:message="value:button.deleteselectedsearches"/>
                    </td>
                </tr>
            </table>
        </fieldset>
    </form> 
</wicket:panel>

Thanks in advance.

fancyplants
  • 1,577
  • 3
  • 14
  • 25

1 Answers1

0

The problem is that you are not defining a clear model object when you populate the checkboxes. This model should be initialized in a way that you can it in the onSubmit method.

I would suggest to instantiate your model object in the SavedSearchesTab constructor, make sure the variable is final, add it to the form and make sure you use it during in all your layers.

About the way you try to recover variables, it will not work that way, it's not how Wicket is supposed to work, if you instantiate your model object from where I'm suggesting you, you can access that variable on the onSubmit method and it will have the properties from the form, you don't have to care to map form values to your POJOs, Wicket does this for you with the Model.

Martin
  • 3,018
  • 1
  • 26
  • 45