WICKET: Control visibility of components on change CheckBox
Asked Answered
S

1

5

I'm using wicket framework.

Does anybody know how to control visibility of components in the form by clicking on checkBox component, and how to get boolean value of checkbox state when submit the form(true or false, depending on checked or not).
I wanna do something like this:

TextField nameField = new TextField("name");

public StateDB() {
final AjaxCheckBox searchByFio = new AjaxCheckBox("searchByFio", new PropertyModel(this, "checkBoxValue")) {
            @Override
            protected void onUpdate(AjaxRequestTarget target) {
                nameField.setVisible(checkBoxValue);
                target.add(nameField);
            }
        };

Form form = new Form("form");

nameField.setOutputMarkupPlaceholderTag ( true );
form.add(nameField);
add(form);
}

But result is not what I've expected. It just changes the html element like this
From:

<input type="text" wicket:id="lastName" id="lastName" required="" value="" name="lastName">


To:

<input id="lastName" style="display:none">

and vice versa

Speight answered 21/8, 2014 at 9:2 Comment(3)
I was wrong and wicket realy just change style of the component. But with such style users can't see your textfield on the page. It is normal behavior for hiding components. Wicket must know where your object must appear next time, so it just change its style. But if you really want for some reason remove input, then you must wrap it by WebMarkupContiner or replace by another component such as EmptyPanel. If you want, I can show you how.Coeval
Yes, it would be great if you show how to use WebMarkupContiner wrapper. I've yet separated components that I wanna control their visibility by checkbox to another form. And yet controlling visibility of that form. But it's wrong way I thinkSpeight
Have updated my answer.Coeval
C
14

To update any component visibility by checkbox click, you can use 'AjaxCheckBox', for example:

//somewhere in the class create model variable:
boolean checkBoxValue = true;

//this is your hideable component
Label someComponent;

...
//and add PropertyModel for checkbox:
AjaxCheckBox checkBox = new AjaxCheckBox("checkBox", new PropertyModel(this, "checkBoxValue")) {
        @Override
        protected void onUpdate(AjaxRequestTarget target) {
                //if checkbox is checked, then our component is shown
                someComponent.setVisible(checkBoxValue);
                target.add(someComponent);
        }
};

...
//this is your component to update
someComponent = new Label("someComponent", "some text");

//this method allows you to hide/show component with ajax updates.
someComponent.setOutputMarkupPlaceholderTag ( true );

To gain checkBox value after submiting - you can check your checkBoxValue value.

UPDATE

Actually you could override your hideable component method onConfigure() to set its visibility according to 'checkBoxValue' (this is just another way to gain this, may be more preferred):

   someComponent = new Label("someComponent", "some text")
   {
       @Override
       protected void onConfigure() {
          setVisible ( checkBoxValue ); 
       }
   };

If you do like this, then you could delete someComponent.setVisible(checkBoxValue); code from AjaxCheckBox#onUpdate() method

UPDATE 2

Component WebMarkupContainer allows you to wrap some components. And when it is hiding - then they are really removes from markup. But markup for container will be exists with style display:hidden anyway.

Create container somewhere like:

WebMarkupContainer container = new WebMarkupContainer ( "cont" );
//we will hide this container, so we can replace  someComponent.setOutputMarkupPlaceholderTag ( true ); by this
container.setOutputMarkupPlaceholderTag ( true );

Add container to the form:

form.add(container);

Add our someComponent to this container:

container.add(someComponent);

And in AjaxCheckBox#onUpdate() method update container with ajax:

protected void onUpdate(AjaxRequestTarget target) {
    //if checkbox is checked, then our component is shown
    container.setVisible(checkBoxValue);
    target.add(container);
}

In html code this would be like

  <div wicket:id="cont">
      <input type="text" wicket:id="someComponent"/>
  </div>

You can add any number of components to such container and you can manage them all with it.

Coeval answered 21/8, 2014 at 9:18 Comment(4)
I've tried to deal with first example, but I didn't get what I expected. Result is: when I click on checkbox, it just changes style of textfield elementSpeight
You are doing something wrong. I have tried this example with TextField and it's working too. Update your question with code you implemented.Coeval
It's my pleasure. I've commented your question.Coeval
One great disadvantage of Wicket is that normally one would place a checkbox inside the Label to get them correctly displayed, but wicket does not allow you to add any component to a label.Whop

© 2022 - 2024 — McMap. All rights reserved.