• Fat Cats Boardgame
  • Wicket UI Library
  • About Me

Java and Wicket web development thoughts, tutorials, and tips

roman@coderdreams.com
Coder DreamsCoder Dreams
  • Fat Cats Boardgame
  • Wicket UI Library
  • About Me

Creating single click buttons with Wicket

August 16, 2019 Posted by Roman Sery wicket No Comments

The problem

Regular Wicket ajax buttons and links have no protection built-in for duplicate clicks. When a user clicks multiple times in succession, that will invoke the submit handler multiple times, causing all types of havoc with your code!

We can observe this problem by creating a simple AjaxButton:

AjaxButton badBtn = new AjaxButton("badBtn") {
            @Override
            protected void onSubmit(AjaxRequestTarget target) {                
                Thread.sleep(800); //simulate some process                
                System.out.println(System.nanoTime());
            }
        };

We use Thread.sleep here to simulate some logic that is being executed when the user clicks this button. In this example, it will be quite harmless. But imagine this onSubmit handler will be inserting rows into a database, deleting data, or processing a credit card!

The goal is to create a new component that will automatically provide protections against this.

Using SingleClickAjaxButton

Let’s create a new component that will extend IndicatingAjaxButton. It will use javascript to disable itself upon being clicked, and re-enable itself once it is done doing it’s work.

public abstract class SingleClickAjaxButton extends IndicatingAjaxButton {
    private final boolean enableButtonAfterSubmit;

	public SingleClickAjaxButton(String id, Form<?> form, boolean enableButtonAfterSubmit) {
		super(id, form);
        this.enableButtonAfterSubmit = enableButtonAfterSubmit;
	}

    @Override
    protected void onError(AjaxRequestTarget target) {
	    //on error, just re-enable
        enableButton(target);
    }

    @Override
    protected void onAfterSubmit(AjaxRequestTarget target) {
        if(enableButtonAfterSubmit) {
            enableButton(target);
        }
    }

    protected void enableButton(AjaxRequestTarget target) {
        target.appendJavaScript("$('#"+this.getMarkupId()+"').prop('disabled', false);");
    }

    @Override
	protected String getOnClickScript() {
        //if the button should be re-enabled but hasnt due to some error, automatically re-enable it after 10 seconds
        if(enableButtonAfterSubmit) {
            return "$('#"+this.getMarkupId()+"').prop('disabled', true); setTimeout(function() { $('#"+this.getMarkupId()+"').prop('disabled', false); }, 10000);";
        }
        return null;
    }
}

It takes as an argument, enableButtonAfterSubmit, which allows you to configure the type of button you need. You should pass true for multi-click buttons, such as a save button, which is intended to be used multiple times, just as long as the next save doesn’t come before the previous one has finished.

You should pass false if you intend the button to be single-click, such as when you are processing a credit card payment. The submit handler will redirect the browser to a different page when complete, so the button should never be re-enabled. Note: This is just a simple example, for credit card payments you should not only rely on Javascript protections!

Using SingleClickAjaxbutton

To use the new component is very simple, we can re-implement our “badBtn” from above, with the only change being the class name:

SingleClickAjaxButton goodBtn = new SingleClickAjaxButton("goodBtn") {
            @Override
            protected void onSubmit(AjaxRequestTarget target) {                
                Thread.sleep(800); //simulate some process                
                System.out.println(System.nanoTime());
            }
        };

You can check out the full source code below!

https://github.com/RomanSery/codesnippets/blob/master/src/main/java/org/coderdreams/webapp/page/SingleClickPage.java

No Comments
Share
3

About Roman Sery

I've been a software developer for over 10 years and still loving Java!

You also might be interested in

Rent Day

Rent Day

May 12, 2021

I’m happy to announce the launch of Rent Day! If[...]

Wicket-fields UI library v1.0 released!

Aug 28, 2019

Wicket-fields is a UI library that makes creating simple bootstrap UI's a breeze

Happy holidays

Dec 24, 2019

Just a short note

Categories

  • aws
  • customization
  • database
  • debugging
  • enum
  • java
  • models
  • performance
  • projects
  • react
  • software design
  • Spring
  • tool
  • Uncategorized
  • wicket

Recent Posts

  • Rent Day
  • Self-contained Wicket Fragments
  • Pros and cons of unit testing
  • Themeable React Monopoly board
  • Please dont use client-specific release branches

Recent Comments

  • TCI Express Thanks for sharing such insightful information. TCI Express truly stands out as the best air logistics company, offering fast, secure, and efficient air express and cold chain transportation services....

    Tracking down a bug in production Wicket application ·  March 25, 2025

  • Tom Error: A zip file cannot include itself Can you please correct the plugin part so it doesn't use the same folder as input?

    Deploying Spring Boot app to AWS Beanstalk with Nginx customization ·  September 3, 2021

  • Golfman: Reality always wins I've used both Wicket and front-end JS frameworks and, having worked extensively on both, I can tell you that "Speed of development" is definitely NOT with the JS frameworks. You basically end up...

    Five reasons you should use Apache Wicket ·  August 29, 2021

  • Kiriller Sorry can not agree with you, wicket might be a well built technical framework. But the advantages of using a front-end framework like react.js and vue.js can not be beaten by Wicket nowadays. - Speed...

    Five reasons you should use Apache Wicket ·  August 23, 2021

  • Bernd Lauert Sorry but i have to refute your claims with the following arguments: 1. the Wicket community may be small but it is also very responsive, you usually get a helpful answer from the core devs on the...

    Five reasons you should use Apache Wicket ·  July 1, 2021

Archives

  • May 2021
  • October 2020
  • September 2020
  • August 2020
  • July 2020
  • June 2020
  • May 2020
  • April 2020
  • March 2020
  • February 2020
  • January 2020
  • December 2019
  • November 2019
  • October 2019
  • September 2019
  • August 2019
  • July 2019

Contact Me

Send Message
Prev Next