Unable to call click event on ajax button in wicket - java

I have a 'save' button, which is an AjaxButton that I am trying to programmatically call the click on. I have a link that I would like to use to call this button's handler. In my AjaxLink, I am appending ajax like so:
target.appendJavaScript("$('#save-irs1095c-button').click();");
When this piece of code is called, wicket throws the following exception
However, when I checked, the behavior is, in fact, enabled. see below:
So, my question is, what might be causing this error, and is there a way around this to programatically call my 'save' button without an actual click?
I have moved away from the default form processing for my components, so this ajax button now acts as my submittal. Here is the code for the Ajax Button:
new AjaxButton("save-modal", coveredForm) {
/**
*
*/
private static final long serialVersionUID = 1975475919740938717L;
public void onSubmit(AjaxRequestTarget target, Form<?> myForm)
{
//form submission method
dataProvider.getIrs1095cSummaryPktManager().save(coveredModel.getObject());
target.add(EmployeeDetailPanel.this);
}
}
And here is the code for the link I want to click, which will then programatically call said Ajax Button:
new AjaxLink<Object>("label-ee-name-link") {
/**
*
*/
private static final long serialVersionUID = 6360058776603040349L;
#Override
public void onClick(AjaxRequestTarget target) {
EmployeeDetailPanel.this.setEEInfoShowing();
logr.log(Level.FINER,"save button visible: " + coveredForm.get("save-modal").isVisible());
logr.log(Level.FINER, "save button enabled: " + coveredForm.get("save-modal").isEnabled());
List<Behavior> bList = (List<Behavior>)((AjaxButton)coveredForm.get("save-modal")).getBehaviors();
if(bList != null ? !bList.isEmpty() : false)
{
for(Behavior b : bList)
{
logr.log(Level.FINER, "Behavior: " + b.toString() + " is enabled: " + b.isEnabled(coveredForm.get("save-modal")));
}
}
target.appendJavaScript("$('#save-irs1095c-button').click();");
}
}
As you can see, I am checking that the component is visible, enabled, as well as its behavior is enabled.
Here is the html snippet for the Ajax button and followed by the snippet for the link:
<div class="col-lg-10 col-lg-offset-1 text-center">
<button class="btn btn-primary" wicket:id="back-to-ee-info">Back</button>
<button id="save-irs1095c-button" class="btn btn-primary" type="submit" wicket:id="save-modal">Save</button>
<button class="btn btn-primary" wicket:id="show-notes-button">Notes</button>
</div>
<h4 class="modal-title"><label wicket:id="emp-name"></label></h4>
Any help is much appreciated. Thanks.

It seems some of the parents of this Component is not visible. Attach the debugger and see which one returns false when isVisibleInHierarchy() is executed.

Related

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
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()});
}
});
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.
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.

Either did not add the component to your page at all, or that the hierarchy does not match in wicket

Currently i m working one requirement in wicket framework.i done some coding part related to that.but i got hierarchy does not match expection always.i followed the hierarchy,but do not wt wrong i did.
here is my requirement:
by clicking on tab,i would like to display progress bar.i used ajax lazy load concept here..
Here is code:
ConditionalListView<Ancillary> orderAncillariesNavigationList = new ConditionalListView<Ancillary>(
"ancillaryItems", orderAncillaryList) {
#Override
protected void populateItem(ListItem<Ancillary> item) {
final Ancillary ancillary = item.getModelObject();
// add ajax link
final AjaxLink<String> navigationLink = new AjaxLink<String>("ancillaryLink") {
private static final long serialVersionUID = 1L;
#Override
public void onClick(AjaxRequestTarget target) {
// replace data with this ancillary
replaceWithSelectedAncillary(target, ancillary);
target.appendJavascript(CLEAR_BIG_EASY_FEEDBACK);
}
};
navigationLink.add(new Label("ancillaryLinkName", ancillary.getLabel()));
//progress bar
if(ancillary.getLabel().equals("Episode / Show Descriptions")){
add(new AjaxLazyLoadPanel("lazy")
{
private static final long serialVersionUID = 1L;
#Override
public Component getLazyLoadComponent(String id)
{
// sleep for 5 seconds to show the behavior
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
throw new RuntimeException(e);
}
return navigationLink;
}
});
}
// set class
if (ancillary.getId().longValue() == selectedAncillary.getId().longValue()) {
item.add(new AttributeAppender("class", new Model<String>("selected"), " "));
}
item.add(navigationLink);
//item.add(TestPage());
}
};
HTML:
<div class="reset"> </div>
<div wicket:id="feedback"></div>
<div wicket:id="lazy"></div>
<div id="ancillaryNavigation">
<ul id="ancillaryTabs" class="group">
<li wicket:id="ancillaryItems">
<span wicket:id="ancillaryLinkName">Music Cue Sheets</span>
</li>
</ul> <!-- /#ancillaryTabs -->
</div> <!-- /#ancillaryNavigation -->
<form wicket:id="ancillaryManualForm" name="ancillaryManualForm" class="epForm">
<div wicket:id="ancillaryOrderEpisodes" />
</form>
</div> <!-- /#ancillaryOrders -->
Please help me out.What i did wrong here.
You might want to refer to the wicket examples for adding links to the list view. Here is my observation from your code: 1. You are loading a link in lazy load. Is the loading of your link going to take long time or the panel being loaded on click of the link is going to take long time? 2.you don't add label to the link as child component, you can set the label of the link via property model. 3. Check the sequence of your markup components and java components structures. Parent -child components hierarchy must match.
I would first start with taking small steps one at a time; looking into wicket examples for all the different components I am using.

Apache Wicket - Form not being submitted

Simple, I click on the input that has the type="submit", and the form isn't submitted.
I've searched solutions to this issue but they say I should check if I have nested forms, which I don't, I'm only using one. They also said it could be some misplaced tag, but I've gone through the whole HTML and the tags are fine.
I have this block in the HTML:
<div id="form-options-div" style="margin-top:10px;">
<input class="btn btn-primary" type="submit" wicket:id="saveClientButton" id="save-client-button" />
<input class="btn" type="button" id="close-client-button" wicket:id="closeClientButton"/>
</div>
I'm using an AjaxButton in the java code to represent the saveClientButton.
I'm overriding the onSubmit(AjaxRequestTarget, Form<?>). I would post the whole java code, but I have a logger at the start of the method to see if it's being called:
logger.debug("ON SUBMIT");
So it's not inside the method. An interesting thing is that when I override the Form onSubmit() method, instead of the AjaxButton one, the page actually reloads. But it's only that, the onSubmit method still isn't called.
Why is this happening?
EDIT:
private Button saveClientBtn;
saveClientBtn = new AjaxButton(WICKET_ID_SAVE_CLIENT_BUTTON) {
#Override
public void onError() {
logger.debug("Error on submit...");
}
#Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
//code....
}
};
Could the closeClientButton be interfering with the normal behavior? I don't know, because the button type is button, not submit.
editClientForm = new Form<Client>(WICKET_ID_EDIT_CLIENT_FORM);
add(editClientForm);
editClientForm.add(saveClientBtn);
EDIT 2:
OK, instead of using AjaxButton, I decided to override the Form onSubmit() and onError(). When clicking the button, I see that onError() is called. Now I need to find the reason why.
Ok, I put a FeedbackPanel. It gives me the following message:
'[Page class = EditClientPage, id = 6, render count = 1]' is not a valid EditClientPage.
Also, the error appears 4 times, as in:
'[Page class = EditClientPage, id = 6, render count = 1]' is not a valid EditClientPage.
'[Page class = EditClientPage, id = 6, render count = 1]' is not a valid EditClientPage.
'[Page class = EditClientPage, id = 6, render count = 1]' is not a valid EditClientPage.
'[Page class = EditClientPage, id = 6, render count = 1]' is not a valid EditClientPage.
What does this error means?
Make sure you have a form tag.
e.g.:
<html>
<body>
<form wicket:id="form">
<div wicket:id="registration">
Display the RegistrationInputPanel
</div>
<input type=”submit” wicket:id="register" value="Register"/>
</form>
</body>
</html>
and the java class:
public class RegistrationPage extends Page {
public RegistrationPage(IModel<Registration> regModel) {
Form<?> form = new Form("form");
form.add(new RegistrationInputPanel("registration", regModel);
form.add(new SubmitButton("register") {
public void onSubmit() {
}
});
add(form);
}
}
In my case, it appears I was not setting a "required" value within the form.
This was ascertained by adding an "onError" method to the form object (sure enough, onError was being called, you can tell "what" the error was like
String responseTxt = wicketTester.getLastResponse().getDocument();
And dig through it to look for the error message.
To actually set the value, in my case, was
FormTester formTester = wicketTester.newFormTester("formName");
formTester.setValue("requiredElementName", "value");
Then the onSubmit method started being called within tests, as was expected.

How to open and close wiQuery Dialogs?

I'm trying out wiQuery to see if it suits my needs, but I've run into problems with very basic stuff. Consider the following, where I try to control when a Dialog opens and closes, using its open() and close() methods:
HTML:
<input type="submit" wicket:id="open" value="Open dialog"/>
<div wicket:id="dialog">
<input type="submit" wicket:id="close" value="Close"/>
</div>
Java:
final Dialog dialog = new Dialog("dialog");
add(new Link("open") {
#Override
public void onClick() {
dialog.open();
}
});
dialog.add(new Link("close") {
#Override
public void onClick() {
dialog.close();
}
});
add(dialog);
Thing is, the above doesn't work.
The only way I've got the dialog to actually open & close from my code is by calling setAutoOpen() with either true or false, but it seems strange is this is the only way. (That method's Javadoc says "Sets if this window opens autmatically after the page is loaded." so it clearly should be reserved for a different purpose.)
What's the right way of opening and closing wiQuery Dialogs dynamically in your code?
I have been using the last 2 weeks and I have a similar problem. Try using an AjaxLink this way:
AjaxLink openingLink = new AjaxLink("open")
{
#Override
public void onClick(AjaxRequestTarget target)
{
// Do something with model
target.addComponent(content);
dialog.open(target);
}
};

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.
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.
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:
Override the isEnabled() method to return a value derived from the model of the form/component.
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.
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.
I think AjaxCallDecorator should be the class you need to use to disable/change style of the button.
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.
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 />
Make it red<br />
<input type="submit" wicket:id="boldButton" value="Make it bold" /><br />
Disable the button
</form>
</body>
</html>

Categories