I've to create a modal dialog which contains a AjaxBootstrapTabbedPanel
with two or more tabs. All tabs belong to the same form.
Each tab contains required input fields, select boxes or drop down choices. Until now,
I don't use own validators, but this is a future task.
I was able to trigger the validation when switching between the tabs.
When I use the dialog like variant A and B, I get proper feedback from validation.
Variant A
- open the dialog
- closing the dialog via submit button immediately results in feedback message "please enter a value in field..."
Variant B
- open the dialog
- switch to another tab without filling required fields on initial tab gives also "please enter a value in ..."
Variant C - validation problem
But using the dialog in this way doesn't result in feedback messages:
- open the dialog
- enter all required values on the initial tab
- don't enter values in required fields on another tab
- use the submit button to close the diaolg: no feedback message!!, but there has to be one or more
In Variant C, no logging output from the method BootstrapAjaxButton#onError()
is printed.
I'm using Wicket 7.6.0 and Wicket-Bootstrap 0.10.11
Class for modal dialog
public abstract class OwsDetailsDialog extends Modal<Ows>
{
private static final long serialVersionUID = -8110788978602397064L;
private BootstrapAjaxButton createOwsBtn;
private BootstrapForm<Ows> owsForm;
public OwsDetailsDialog(String id,
IModel<Ows> owsModel)
{
super(id, owsModel);
setOutputMarkupPlaceholderTag(true);
setDefaultModel(owsModel);
owsForm = new BootstrapForm<>("owsForm");
owsForm.setOutputMarkupId(true);
add(owsForm);
List<ITab> tabs = createTabs(owsModel);
MyAjaxTabbedPanel tabbedPanel = new MyAjaxTabbedPanel("tabbedPanel", tabs);
owsForm.add(tabbedPanel);
createOwsBtn = new BootstrapAjaxButton("submitOws",
Model.of("Create"), Buttons.Type.Default)
{
@Override
protected void onError(AjaxRequestTarget target, Form<?> form)
{
super.onError(target, form);
target.add(form, tabbedPanel);
System.out.println("onError() at form ID " + form.getId() + " target.getPage() "
+ target.getPage());
}
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form)
{
super.onSubmit(target, form);
System.out.println("click on create");
createOws(target, owsModel);
}
};
owsForm.add(createOwsBtn);
BootstrapAjaxButton cancelBtn = new BootstrapAjaxButton("cancelOws",
Model.of("Cancel"), Buttons.Type.Default)
{
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form)
{
super.onSubmit(target, form);
cancel(target);
}
};
cancelBtn.setDefaultFormProcessing(false);
owsForm.add(cancelBtn);
//FeedbackPanel feedbackOwsDialog = new FeedbackPanel("feedbackOwsDialog");
//add(feedbackOwsDialog);
}
private List<ITab> createTabs(IModel<Ows> owsModel)
{
List<ITab> tabs = new ArrayList<>();
tabs.add(new AbstractTab(Model.of("Data 1"))
{
private static final long serialVersionUID = -9107223557866453561L;
@Override
public WebMarkupContainer getPanel(String panelId)
{
return new OwsMainInfoContainer(panelId, owsModel);
}
});
tabs.add(new AbstractTab(Model.of("Data 2"))
{
private static final long serialVersionUID = -7323530522820254738L;
@Override
public WebMarkupContainer getPanel(String panelId)
{
return new OwsSecondaryInfoContainer(panelId, owsModel);
}
});
return tabs;
}
protected class OwsMainInfoContainer extends Panel
{
private static final long serialVersionUID = -2965824809083715016L;
public OwsMainInfoContainer(
String panelId, IModel<Ows> owsModel)
{
super(panelId, owsModel);
add(new RequiredTextField<>("title"));
add(new RequiredTextField<>("url"));
List<OwsType> types = Arrays.asList(OwsType.values());
DropDownChoice<OwsType> dropDownChoice = new DropDownChoice<>("category", types,
new ChoiceRenderer<OwsType>()
{
private static final long serialVersionUID = 8139757791037487164L;
@Override
public Object getDisplayValue(OwsType owsType)
{
return owsType.getName();
}
});
add(dropDownChoice.setRequired(true));
add(new FeedbackPanel("feedbackMain"));
}
}
protected class OwsSecondaryInfoContainer extends Panel
{
private static final long serialVersionUID = -7396160769731997541L;
public OwsSecondaryInfoContainer(
String panelId, IModel<Ows> owsModel)
{
super(panelId, owsModel);
add(new DateTextField("firstPublished"));
add(new TextField<>("provider").setRequired(true));
add(new TextField("price").setRequired(true));
add(new FeedbackPanel("feedbackSecondary"));
}
}
protected abstract void createOws(AjaxRequestTarget target
, IModel<Ows> owsWithUtilDateIModel);
protected abstract void cancel(AjaxRequestTarget target);
// http://www.volkomenjuist.nl/blog/2009/12/01/ajaxtabbedpanel-store-state-when-switching-tabs/
class MyAjaxTabbedPanel extends AjaxBootstrapTabbedPanel<ITab>
{
private static final long serialVersionUID = 1513951445901529991L;
public MyAjaxTabbedPanel(String id, List<ITab> tabs)
{
super(id, tabs);
}
@Override
protected WebMarkupContainer newLink(String linkId, final int index)
{
return new AjaxSubmitLink(linkId, owsForm)
{
private static final long serialVersionUID = 7049548660275591812L;
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form)
{
setSelectedTab(index);
if (target != null)
{
target.add(form);
}
onAjaxUpdate(target);
System.out.println("onSubmit() on target.getPage(): " + target.getPage());
}
@Override
protected void onError(AjaxRequestTarget target, Form<?> form)
{
MyAjaxTabbedPanel component = MyAjaxTabbedPanel.this;
target.add(component);
System.out.println("in onError() , target.add() on " + component.getId());
}
};
}
}
}
Class extending WebPage
public class MyPage extends WebPage
{
private static final long serialVersionUID = 6826446949682313116L;
public MyPage()
{
Form<Void> form = new Form<Void>("buttonForm");
add(form);
form.setOutputMarkupId(true);
OwsDetailsDialog owsDialog = new OwsDetailsDialog("owsDialog"
, new CompoundPropertyModel<Ows>(new Ows()))
{
@Override
protected void createOws(AjaxRequestTarget target,
IModel<Ows> model)
{
Ows ows = model.getObject();
System.out.println("object: "+ ows);
close(target);
}
@Override
protected void cancel(AjaxRequestTarget target)
{
System.out.println("click auf abbrechen");
close(target);
}
};
add(owsDialog);
BootstrapAjaxButton createOwsButton = new BootstrapAjaxButton("createOwsButton",
Model.of("OWS neu"), Buttons.Type.Default)
{
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form)
{
super.onSubmit(target, form);
owsDialog.setDefaultModelObject(new Ows());
target.add(owsDialog);
TabbedPanel tabbedPanel = (TabbedPanel) owsDialog.get("owsForm:tabbedPanel");
tabbedPanel.setSelectedTab(0);
owsDialog.show(target);
}
};
form.add(createOwsButton);
}
}
PoJo
package example.tryOut.ows;
import java.util.Date;
public class Ows
{
private Integer index=0;
private String title = "";
private String provider = "";
private String url = "";
private OwsType category;
private Date firstPublished =null;
private Double price=0.0;
public Integer getIndex()
{
return index;
}
public void setIndex(Integer index)
{
this.index = index;
}
public String getTitle()
{
return title;
}
public void setTitle(String title)
{
this.title = title;
}
public String getProvider()
{
return provider;
}
public void setProvider(String provider)
{
this.provider = provider;
}
public String getUrl()
{
return url;
}
public void setUrl(String url)
{
this.url = url;
}
public OwsType getCategory()
{
return category;
}
public void setCategory(OwsType category)
{
this.category = category;
}
public Date getFirstPublished()
{
return firstPublished;
}
public void setFirstPublished(Date firstPublished)
{
this.firstPublished = firstPublished;
}
public Double getPrice()
{
return price;
}
public void setPrice(Double price)
{
this.price = price;
}
@Override
public String toString()
{
return "Ows{" +
"index=" + index +
", title='" + title + '\'' +
", provider='" + provider + '\'' +
", url='" + url + '\'' +
", category=" + category +
", firstPublished=" + firstPublished +
", price=" + price +
'}';
}
}
Markup
Page
<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org">
<head>
<meta charset="UTF-8">
</head>
<body>
<form wicket:id="buttonForm">
<button wicket:id="createOwsButton"></button>
</form>
<div wicket:id="owsDialog"></div>
</body>
</html>
Dialog
<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org">
<head>
<meta charset="UTF-8">
</head>
<body>
<wicket:extend>
<form wicket:id="owsForm">
<div wicket:id="tabbedPanel" class="container" style="width: inherit"></div>
<button type="submit" wicket:id="submitOws" class="btn btn-main">Anlegen</button>
<button type="reset" wicket:id="cancelOws" class="btn btn-main">Abbrechen</button>
</form>
</wicket:extend>
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:wicket="http://wicket.apache.org">
<head>
<meta charset="UTF-8">
</head>
<body>
<wicket:panel>
<div class="form-group">
<label wicket:for="url">URL</label>
<div class="controls">
<input type="text" wicket:id="url" class="form-control"/>
</div>
</div>
<div class="form-group">
<label wicket:for="title">Title</label>
<div class="controls">
<input type="text" wicket:id="title" class="form-control"/>
</div>
</div>
<div class="form-group">
<label wicket:for="category">OWS Category</label>
<div class="controls">
<select wicket:id="category">
<option value="">dummy1</option>
<option value="">dummy2</option>
</select>
</div>
</div>
<div wicket:id="feedbackMain"></div>
</wicket:panel>
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:wicket="http://wicket.apache.org">
<head>
<meta charset="UTF-8">
</head>
<body>
<wicket:panel>
<div class="form-group">
<label wicket:for="price">Price</label>
<div class="controls">
<input type="text" wicket:id="price" class="form-control"/>
</div>
</div>
<div class="form-group">
<label wicket:for="provider">Provider</label>
<div class="controls">
<input type="text" wicket:id="provider" class="form-control"/>
</div>
</div>
<div class="form-group">
<label wicket:for="firstPublished">First published</label>
<div class="controls">
<input type="date" wicket:id="firstPublished" class="form-control"/>
</div>
</div>
<div wicket:id="feedbackSecondary"></div>
</wicket:panel>
</body>
</html>