I have form with Textbox and submit Ajaxbutton, when i insert some value in textbox then click on submit button, will perform some business logic written in OnSubmit of Ajaxbutton, its fine for us But when i insert some value in textbox then press enter key so i want to perform same business logic of OnSubmit of Ajaxbutton but it doesn't call, Please suggest #martin-g . I want to prefer wicket code instead of JavaScript.
Below is my code in my application.
<Form wicket:id="FilterForm">
<input type="textbox" wicket:id="input"></input>
<input type="submit" wicket:id="submit"/>
</Form>
for java code:
final Form filterForm = new Form("FilterForm"){}
add(filterForm);
filterForm.setMarkupId("filterForm");
filterForm.setOutputMarkupId(true);
TextField<String> docIdInput = new TextField("input", new PropertyModel(this.searchObj, "searchString"));
filterForm.add(docIdInput);
docIdInput.setOutputMarkupId(true);
AjaxButton docIdInputSubmitButton = new AjaxButton("submit") {
private static final long serialVersionUID = 1L;
#Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
//do buisness logic
}
filterForm.add(docIdInputSubmitButton);
You can make your button the default button of the form:
filterForm.setDefaultButton(docIdInputSubmitButton);
Wicket will generate some JavaScript for you that triggers your submit button on enter.
Related
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.
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.
I have a list of conditions. User can add or remove an condition. There is a plus link that adds a condition and a remove link that removes it. When user clicks on add link a form is appearing and s/he can enter condition properties inside it.
I'm using wicket ListView for implementing this component. I have an conditionPanel inside this ListView. When user clicks on add s/he can see another conditionPanel with empty fields. When s/he submits the form a list of conditions are sent to server.
My ListView gets a list of conditions and builds conditionPanel for each of them.
The problem is that when I call listView.getModelObject I expect to get the correct list of conditions, but this is not heppening. I don't know what to do to get the correct list.
Each conditionPanel knows how to build the correct condition.
java code:
Form conditionForm = new Form("condition-submit-form");
final WebMarkupContainer conditions = new WebMarkupContainer("conditions-container");
conditions.setOutputMarkupId(true);
final List<ConditionWrapper> conditionsList;
if(isEditModeIn) {
conditionsList = alertDefinitionWrapper.getConditions();
} else {
conditionsList = new ArrayList<>();
conditionsList.add(null);
}
final IModel<List<ConditionWrapper>> conditionsModel = new LoadableDetachableModel<List<ConditionWrapper>>() {
#Override
protected List<ConditionWrapper> load() {
return conditionsList;
}
};
final ListView<ConditionWrapper> conditionsListView = new ListView<ConditionWrapper>("conditions", conditionsModel) {
#Override
protected void populateItem(ListItem<ConditionWrapper> item) {
ConditionWrapper conditionWrapper = item.getModelObject();
ConditionPanel conditionPanel = new ConditionPanel("condition", conditionWrapper, alertDefinitionWrapper);
item.add(conditionPanel);
}
};
conditions.add(conditionsListView);
conditionForm.add(conditions);
AjaxSubmitLink addConditionLink = new AjaxSubmitLink("add-new-condition-link", conditionForm) {
#Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
conditionsListView.getModelObject().add(null);
if(target != null) {
target.add(conditions);
}
}
};
addConditionLink.setDefaultFormProcessing(false);
conditionsListView.setReuseItems(true);
conditionForm.add(addConditionLink);
HTML Code:
<div>
<form wicket:id="condition-submit-form">
<div wicket:id="conditions-container">
<span wicket:id="conditions">
<span wicket:id="condition"></span>
</span>
</div>
<a wicket:id="add-new-condition-link">add</a>
</form>
</div>
For example user clicks on add link and adds another condition by filling its fields and then submits the form. Then I call conditionsModel.getObject I want to get a list which contains the new condition.
You should add the new condition to the conditionsList directly. Then add the ListView to the ajaxtarget and then the listview should be rebuild with the list so including the new item.
In your code you also use a LoadableDetachableModel for the list. This is not necessary like you use it here, use Model.of(conditionsList) instead.
Question relates to Wicket 1.6
I have a wizard step, which includes a Textfield component. When I press the Enter key, this is being handled by the default button of the Wizard bar ('Next'), and it advances to the next step in the Wizard. I don't want this to happen. When I hit Enter on the Textfield I just want the value to be updated, but remain on the same page.
I tried overriding the onBeforeRender() method of my Wizard class, which as you can see sets the default button of the containing form to null. However this now results in the 'Prev' button being triggered when I hit Enter, so the wizard goes back to the previous step.
public class ConfigurationWizard extends Wizard {
....
#Override
protected void onBeforeRender()
{
super.onBeforeRender();
Component buttonBar = getForm().get(BUTTONS_ID);
if (buttonBar instanceof IDefaultButtonProvider)
{
getForm().setDefaultButton(null);
}
}
}
So the basic question is, how do I disable the default button behaviour of the Wizard?
My approach (with a nice Wicket behavior)
Usage
TextField<String> myField = new TextField<String>("myField", myModel());
myField.add(new PreventSubmitOnEnterBehavior());
Behavior
public class PreventSubmitOnEnterBehavior extends Behavior
{
private static final long serialVersionUID = 1496517082650792177L;
public PreventSubmitOnEnterBehavior()
{
}
#Override
public void bind( Component component )
{
super.bind( component );
component.add( AttributeModifier.replace( "onkeydown", Model.of( "if(event.keyCode == 13) {event.preventDefault();}" ) ) );
}
}
This has nothing to do with the wizard buttons.
The TextField <input> is doing a form submit when the Enter key is pressed. This is standard behaviour for the <input> element.
The solution is to catch the Enter key press for the <input> and prevent the default behaviour
This bit of javascript magic does the trick for me:
<script type="text/javascript">
$(document).ready(function() {
$("#gridDiv").delegate("input","keypress",function(e){
if(e.originalEvent.keyCode == 13){
e.preventDefault();
}
});
});
</script>
where 'gridDiv' is the id of the <div> containing the TextField
I prefer another approach:
I use AjaxButtons for every button needed, with the specific submit code in the overrided onSubmit():
AjaxButton linkSubmit = new AjaxButton("linkSubmit")
#Override
public void onSubmit(AjaxRequestTarget target, Form form) {
super.onSubmit();
// Submit code goes here....
// ...
setResponsePage(new NewPage());
}
#Override
public void onError(AjaxRequestTarget target, Form form) {
}
};
My form doesn't need a "onSubmit()" method.
And the markup doesn't have any submit buttons. All buttons are coded like this:
With this approach you don't need to mess with javascript codes. The page simply will do nothing if you press Enter. You'll have to click your buttons to submit each one.
Hope this can help you.
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.