I have a component that extends TextField where a user can type an web address. I want that after the user type something (for example www.example.org) to change that value to something else (for exemple http://www.example.org)
I have tried this:
urlField = new TextFieldIndicatingError<String>("url", new PropertyModel<String>(this, "url"));
urlField.add(new AjaxFormComponentUpdatingBehavior("onblur") {
#Override
protected void onUpdate(AjaxRequestTarget target)
{
//url = "ABCDDEE";
urlField.getModel().setObject("AAAA");
}
});
but anything inside the onUpdate() doesn't seems to have an effect in the TextField's value.
What I'm doing wrong here?
You need to use target.add(urlField) to update it on the client side after setting its new model.
Related
I am quite new to Wicket. I am adding a model to a sub-panel(ChartPanel) from a main panel (MainPanel) on a button click.
MainPanel.java
On button click, I am re-adding the chartPanel after I change its model. Following is the code I am using in the buttonClick of the MainPanel. Here the onRenderAnnotations event is generated on some click in the UI.
#OnEvent
public void onRenderAnnotations(RenderAnnotationsEvent aEvent)
{
LOG.trace("clicked on the annotation");
renderChart( aEvent.getRequestHandler());
}
private void renderChart(IPartialPageRequestHandler aRequestHandler)
{
MultiValuedMap<String, Double> recommenderScoreMap = getLatestScores(aRequestHandler);
Map<String,String> curveData = new HashMap<String,String>();
LearningCurve learningCurve = new LearningCurve();
for (String recommenderName : recommenderScoreMap.keySet()) {
String data = recommenderScoreMap.get(recommenderName).stream().map(Object::toString)
.collect(Collectors.joining(", "));
curveData.put(recommenderName,data);
learningCurve.setCurveData(curveData);
learningCurve.setMaximumPointsToPlot(MAX_POINTS_TO_PLOT);
}
chartPanel.setDefaultModel(Model.of(learningCurve));
// to avoid the error, A partial update of the page is being rendered
try {
aRequestHandler.add(chartPanel);
}
catch (IllegalStateException e) {
LOG.warn("Not updating the chart. " + e.toString());
setResponsePage(getPage());
}
}
ChartPanel.java
After this in the chartPanel, I want to use the updated model to add component inside the chartpanel. What would be the best way to do that?
I want to do something like this in the class ChartPanel:
#Override
protected void onRender()
{
super.onModelChanged();
LearningCurve newLearningCurve = getModel().getObject();
requestTarget = ???
String js = createJavascript(newLearningCurve);
requestTarget.prependJavascript(js);
}
My question is, in the above code how to get the request target since it is not an ajax request neither do I get it in the arguments. Should I use some other function where I also get a requestTarget. But I want it to be called every time the model of ChartPanel is updated from anywhere.
Pardon my ignorance. I have been trying for a few days but I am still stuck. I tried to explain it enough but if any information is missing, please comment and I will add it right away.
Thanks.
You should override renderHead() instead:
#Override
public void renderHead(IHeaderResponse response)
{
super.renderHead(response);
response.render(OnLoadHeaderItem.forScript(
createJavascript(newLearningCurve)));
}
This way your chart will be shown correctly regardless whether it was added due to an AjaxRequest or simply when the page is rerendered.
Im trying to get the selected value from a radio form with radioChoice onChange but can't really seem to find the solution. The onEvent function gets called, but from here I'm not really sure how to get the value.
Code:
RadioChoice<String> radioChoice = new RadioChoice<String>("radio", new PropertyModel<String>(this, "selected"),this.radioChoiceList);
radioChoice.add(new AjaxFormComponentUpdatingBehavior("change")
{
#Override
protected void onUpdate(AjaxRequestTarget target)
{
System.out.println("ajax here!");
}
});
Form<?> form = new Form<Void>("form");
add(form);
form.add(radioChoice);
you should use AjaxFormChoiceComponentUpdatingBehavior instead of AjaxFormComponentUpdatingBehavior. See Javadoc:
https://ci.apache.org/projects/wicket/apidocs/7.x/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.html
So I am experiencing some odd behaviour using Vaadin 7 and the ComboBox component. Essentially, what is happening is that when it first renders the form, it appears to neither have selected the null selection nor any of the items added.
I have attempted to recreate this behaviour with the following code and this demonstrates the issue.
#Override
protected void init(VaadinRequest request) {
final FieldGroup binder;
FormLayout form = new FormLayout();
form.setMargin(true);
setSizeFull();
setContent(form);
final Label output = new Label();
form.addComponent(output);
ComboBox box = new ComboBox("My Dropdown");
final PropertysetItem fields = new PropertysetItem();
fields.addItemProperty("country", new ObjectProperty<String>(""));
binder = new FieldGroup(fields);
binder.bind(box, "country");
box.addItem("aus");
box.setItemCaption("aus", "Australia");
box.addItem("uk");
box.setItemCaption("uk", "United Kingdom");
box.setRequired(true);
box.setImmediate(true);
box.setRequiredError("Country is required field");
Button submit = new Button("Submit", new ClickListener() {
#Override
public void buttonClick(ClickEvent event) {
try {
binder.commit();
output.setValue((String) fields.getItemProperty("country").getValue());
}
catch (CommitException e) {
Notification.show("fail!");
}
}
});
form.addComponent(box);
form.addComponent(submit);
}
By default the ComboBox has allow null selection set to true. So there is a blank entry, which represents a null value selection. However the ComboBox's value when first rendered neither represents the null selection nor one of the items but an empty string.
So when I load the form and click the button the outcome is neither a failure, which it should be because I haven't selected anything yet, nor one of my selections.
This is causing an issue for me in a more advanced UI application but very much the same thing going on here.
Could anybody enlighten me as to what is happening here?
Many thanks,
Joe
So when I load the form and click the button the outcome is neither a
failure, which it should be because I haven't selected anything yet,
nor one of my selections.
Combobox is not empty as you think. It has default property value, that you set as empty string:
fields.addItemProperty("country", new ObjectProperty<String>(""));
Thus form pass validation, because empty string is also a value and empty string != null.
Change this row:
fields.addItemProperty("country", new ObjectProperty<String>(""));
to:
fields.addItemProperty("country", new ObjectProperty<String>(null, String.class));
box.setNullRepresentation("-- Select Country --");
Is it possible to nest forms in Wicket that are independent of each other? I want to have a form with a submit button and a cancel button. Both buttons should direct the user to the same page (let's call it Foo). The submit button should send some info to the server first; the cancel button should do nothing.
Here's a really simplified version of my existing code:
Form form = new Form() {
public void onSubmit()
{
PageParameters params = new PageParameters();
params.put("DocumentID", docID);
setResponsePage(Foo.class, params);
}
};
DropDownChoice<String> ddc = new DropDownChoice<String>("name", new PropertyModel<String>(this, "nameSelection"), names);
ddc.setRequired(true);
final Button submitButton = new Button("Submit") {
public void onSubmit() { doSubmitStuff(true); }
};
final Button cancelButton = new Button("Cancel") {
public void onSubmit() { doSubmitStuff(false); }
};
form.add(ddc);
form.add(submitButton);
form.add(cancelButton);
form.add(new FeedbackPanel("validationMessages"));
The problem is, I just added a validator, and it fires even if I press the cancel button, since the cancel button is attached to the same form as everything else. This could be avoided if the cancel button were in a separate form. As far as I know, I can't create a separate form because — due to the structure of the HTML — the separate form would be under the existing form in the component hierarchy.
Can I make the forms separate somehow in spite of the hierarchy? Or is there some other solution I can use?
EDIT:
In response to Don Roby's comment, this is a bit closer to what my code looked like back when I was trying setDefaultFormProcessing():
Form<Object> theForm = new Form<Object>("theForm") {
public void onSubmit()
{
PageParameters params = new PageParameters();
params.put("DocumentID", docID);
setResponsePage(Foo.class, params);
}
};
final CheckBox checkbox = new CheckBox("checkbox", new PropertyModel<Boolean>(this, "something"));
checkbox.add(new PermissionsValidator());
theForm.add(checkbox);
final Button saveButton = new Button("Save") {
public void onSubmit()
{ someMethod(true); }
};
final Button cancelButton = new Button("Cancel") {
public void onSubmit()
{ someMethod(false); }
};
cancelButton.setDefaultFormProcessing(false);
theForm.add(saveButton);
theForm.add(cancelButton);
theForm.add(new FeedbackPanel("validationMessages"));
There is an even simpler solution: call the setDefaultFormProcessing method on the cancel button with false as a parameter:
cancelButton.setDefaultFormProcessing(false);
This way, clicking the cancel button will bypass the form validation (and model updating), directly calling the onSubmit function.
It is possible to "nest" forms in wicket.
See this wiki entry
for some notes on how it works and this wiki entry for how it interacts with validation.
But for what you're after, the answer from Jawher should have worked and is much simpler.
Look at this example code for hints on getting that working.
I'm wondering if you've simplified your code too far in this posting. Can you produce a sample small enough to post that definitely has the problem?
I have 2 inputs. When I press a button(AjaxFallbackButton), those inputs are saved into database.
If one of the input is greater than 10, when I press the button, I want to show a modal panel, for asking the user if is the sure about his option. But the modal component is not appearing. Any thoughts?
#Override
public void onSubmit(AjaxRequestTarget target) {
if (input < 10) { //save to database
} else {
AskingDialogPanel panel = new AskingDialogPanel("content",
new ResourceModel("asking.title"),
new ResourceModel("asking.message")) {
#Override
public void onOkClick(AjaxRequestTarget target) {
super.onOkClick(target);
//save to database
modalWindow.close(target);
}
#Override
public void onCancelClick(AjaxRequestTarget target) {
super.onCancelClick(target);
modalWindow.close(target);
}
};
panel.setOutputMarkupId(true);
target.addComponent(panel);
modalWindow.setContent(panel);
modalWindow.show(target);
}
Have a look at the documentation for the AjaxRequestTarget.
A component whose markup needs to be
updated should be added to this target
via
AjaxRequestTarget#addComponent(Component)
method. Its body will be rendered and
added to the envelope when the target
is processed, and refreshed on the
client side when the ajax response is
received.
I'm not sure if I remember this correctly (I've had trouble implementing the correct refresh behavior previously), but I believe you could only addComponent components that were previously added to the page, but not rendered / invisible. These will than be updated and/or their visibility re-evaluated.
I could be wrong however.. Does the above work if you substitute a normal Label for the AskingDialogPanel? (Just to verify I'm talking out the wrong end ;))