Mateusz Moroz
Mateusz Moroz

Reputation: 411

Processing single input field with ajax in Apache Wicket

I have a form with several input fields and one special field, that I want to process with ajax. The thing is, that I want to process only that field after the AjaxLink has been clicked. Without processing of the whole form. I want to access the value of that input field in the method onSubmit of the AjaxLink. Is that possible? If yes, then how?

Regards, Mateusz

Upvotes: 0

Views: 1465

Answers (3)

martin-g
martin-g

Reputation: 17503

By default AjaxLink does not submit data/forms. AjaxSubmitLink and AjaxButton do!

For your use case you can AjaxRequestAttributes and send "dynamic extra parameters". I'm on my mobile and I cannot give you an example at the moment but the idea is to construct a simple JSON object with a key being the request parameter name and value the forn element's value. Google these keywords! If you can't manage to do it then add a comment and I will update my answer as soon as I can!

Here is a sample code. Beware I've written it completely here, so it might have a typo or two!

add(new AjaxLink("customSubmitLink") {
    @Override public void onClick(AjaxRequestTarget target) {
        int aFieldValue = getRequest().getRequestParameters().getParameterValue("aField").toInt();
        // do something with aFieldValue
    }

    @Override protected void updateAjaxAttributes(AjaxRequestAttributes attrs) {
        super.updateAjaxAttributes(attrs);
        attrs.getDynamicExtraParameters().add("return {\"aField\": jQuery('#aFormField').val()});
    }
});

Upvotes: 2

Thorsten Wendelmuth
Thorsten Wendelmuth

Reputation: 780

It's actually even easier than what rpuch suggested.

Just nest your forms and make sure the AjaxLink only submits the second form:

            <form wicket:id="form">
            <div wicket:id="dateTimeField"></div>
            <form wicket:id="secondForm">
                <input wicket:id="text" />
                <a wicket:id="secondSubmit">submit2</a>
            </form>
            <a wicket:id="submit">submit</a>
            </form>

    Form secondForm= new Form("secondForm");
    form.add(secondForm);

    final IModel<String> textModel = Model.of("");

    TextField<String> text = new TextField<>("text", textModel);
    secondForm.add(text);

    AjaxSubmitLink secondSubmit = new AjaxSubmitLink("secondSubmit", secondForm) {
        @Override
        protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
            super.onSubmit(target, form);
            logger.info("textMod: " + textModel.getObject());
        }
    };
    secondForm.add(secondSubmit);

The second form will be rendered as a div but will have the functionality that you desire. However the second form will also be submitted when you submit the outer form.

Upvotes: 0

Roman Puchkovskiy
Roman Puchkovskiy

Reputation: 11835

One way to solve this would be to put that 'special' field with its 'special' link to a second Form and then use CSS to visually position the 'special' field like it is inside the main Form.

Something like this:

Form<Void> mainForm = new Form<Void>("main-form") {
    @Override
    protected void onSubmit() {
        super.onSubmit();
    }
};
add(mainForm);

// ... populate the main form

Form<Void> secondForm = new Form<Void>("second-form");
add(secondForm);
final Model<String> specialModel = Model.of();
secondForm.add(new TextField<>("special-field", specialModel));
secondForm.add(new AjaxButton("special-button") {
    @Override
    protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
        // ... process the special field value
    }
});

And in the markup, as usual:

<form wicket:id="main-form">
    ... main form content
</form>

<form wicket:id="second-form">
    <label>Special field: <input class="special-field" wicket:id="special-field"></label>

    <button wicket:id="special-button">Special button</button>
</form>

And then style that .special-field class with position: absolute; top: ... or something like that.

The solution is not very elegant, it's more of a hack. It will create some confusion for a person who would have to read this later. But it may work if the trick with CSS is possible.

Upvotes: 0

Related Questions