Michael Borgwardt
Michael Borgwardt

Reputation: 346260

How to disable / change style of wicket button link in onClick()

In a Wicket app, I have a bunch of <button> elements to which I'm attacking a Link component. Now in the onClick() method of the component I want to disable or change the style of the button. How can I do that? Calling setEnabled(false) has no effect.

Upvotes: 4

Views: 25742

Answers (6)

Vaclav Stengl
Vaclav Stengl

Reputation: 479

The answer provided by Michael Borgwardt is nearly correct.

The problem is that you use Link. Disabled Links use <span> instead of <a>/<button> and are surrounded with <em> by default. Using Button component will set 'disabled' attribute in the element.

I would like to add, that you need to use HTML button element instead of <a> (link). Original answer can be counfusing, because Link and Button also exist in Wicket.

Upvotes: 2

Nicktar
Nicktar

Reputation: 5575

Take a look at SimpleAttributeModifier and AttributeAppender. Depending on your actual requirements one of those should do the trick. SimpleAttributeModifier adds or replaces an attribute of any HTML-Tag that has a prepresentation in wicket (replaces the css class), while AttributeAppender appends to the attributes (adds another css class). This should work for enabling/disabling buttons as well but I haven't tried that.

Example:

Label label = new Label("id", "Some silly text.")
add(label);
label.add(new SimpleAttributeModifier("class", "my-css-class");

For Ajax you'll have to add the component to the target as well.

More detailed example:

Java code:

import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.behavior.SimpleAttributeModifier;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.model.Model;

public class DemoPage extends WebPage {

    public DemoPage() {
        Form form = new Form("form");
        add(form);
        final WebMarkupContainer wmc = new WebMarkupContainer("greenText");
        form.add(wmc);
        form.add(new Link("redLink"){

            @Override
            public void onClick() {
                wmc.add(new SimpleAttributeModifier("class", "redText"));
            }});
        final Button boldButton = new Button("boldButton"){

            @Override
            public void onSubmit() {
                wmc.add(new AttributeAppender("class", true, new Model<String>("boldText"), " "));
            }};
        form.add(boldButton);
        Link disabler = new Link("buttonDisabler") {

            @Override
            public void onClick() {
                boldButton.add(new AttributeAppender("disabled", true, new Model<String>("disabled"), " "));                
            }

        };
        form.add(disabler);
    }

}

corresponding HTML:

<html>
<head>
<style>
.redText {
    color: red;
    }
.greenText {
    color: green;
    }
.boldText {
    font-weight: bold;
    }
</style>
</head>
<body>
<form wicket:id="form">
<div class="greenText" wicket:id="greenText">This is Green.</div><br />
<a href="" wicket:id="redLink">Make it red</a><br />
<input type="submit" wicket:id="boldButton" value="Make it bold" /><br />
<a href="" wicket:id="buttonDisabler">Disable the button</a>
</form>
</body>
</html>

Upvotes: 0

biziclop
biziclop

Reputation: 49714

I don't think this is an entirely good idea in Wicket. Of course it could be done by trickery, but it's far simpler to either:

  1. Override the isEnabled() method to return a value derived from the model of the form/component.
  2. Attach an AttributeModifier when you create the component, and use a model for it which returns a value derived as above.

Whichever you choose, the principle is to let Wicket "pull" rendering information in rather than pushing it explicitly.

Upvotes: 3

jbrookover
jbrookover

Reputation: 5150

Repeated uses of onClick() are operating on the same object in memory. If you're not using Ajax, you can still maintain some state in an anonymous subclass of Link. Then, you can use onBeforeRender() and onComponentTag() to change how it is displayed each time.

Link<Void> link = new Link<Void>("myLink") {

    private String customCSS = null;
    private boolean customEnabled = true;

    public void onClick() {
        if (/* test to determine disabled */) {
            customCSS = "disabled";
            customEnabled = false;
        } else {
            customCSS = null;
            customEnabled = true;
        }
    }

    @Override
    protected void onComponentTag(ComponentTag tag) {
        super.onComponentTag(tag);
        if (customCSS != null)
            tag.put("class", customCSS);
    }

    @Override
    public boolean isEnabled() {
        return super.isEnabled() && customEnabled;
    }
};

AttributeModifiers (or other behaviors) aren't good for this case because, if you add them in the onClick() method, they will begin stacking on the same link for each click - since they are maintained as part of the Link's state.

Your Link can keep track of all manner of state, allowing your onClick() method to enable/disable/change/etc with repeated clicks.

You can also override onBeforeRender(), isVisible(), and other methods that are run each time the link is displayed on the page. The constructor, onConfigure(), and others are run just once, regardless of how many times you click the button.

Upvotes: 9

martin-g
martin-g

Reputation: 17503

The problem is that you use Link. Disabled Links use <span> instead of <a>/<button> and are surrounded with <em> by default. Using Button component will set 'disabled' attribute in the element.

Upvotes: 0

fmucar
fmucar

Reputation: 14548

I think AjaxCallDecorator should be the class you need to use to disable/change style of the button.

Upvotes: 0

Related Questions