I would like to create wicket page where is displayed table with data from database, under this table, there is form which create another objects into database. When I save object, page does not refresh, so in table I cannot see new row.
If I understood it correctly, to solve this issue I have to use ajax. I found guide (https://cwiki.apache.org/confluence/display/WICKET/How+to+repaint+a+ListView+via+Ajax) and created something similar in my project, but it does not work and I can not find the reason why does it not work. I found that another people had problems that they tried to actualize just only rows/panel, but it is not my case. I do not get even any exception, just it does nothing. Could you please give me an advice?
.java file
public class ListPanel extends Panel {
private static final long serialVersionUID = 6953172817971228490L;
#SpringBean
RezervaceDao rezervaceDao;
public ListPanel(String id) {
super(id);
List<Rezervace> rezervace = rezervaceDao.getAllRezervace();
ListView listview = new ListView("rezervaceList", rezervace) {
private static final long serialVersionUID = 3659733406689720345L;
protected void populateItem(ListItem item) {
Rezervace r = (Rezervace) item.getModelObject();
item.add(new Label("casRezervace", r.getCasRezervace()));
item.add(new Label("jmeno", r.getJmeno()));
item.add(new Label("adresa", r.getAdresa()));
item.add(new Label("telefon", r.getTelefon()));
}
};
listview.setReuseItems(true);
// encapsulate the ListView in a WebMarkupContainer in order for it to
// update
WebMarkupContainer listContainer = new WebMarkupContainer("obal");
// generate a markup-id so the contents can be updated through an AJAX
// call
listContainer.setOutputMarkupId(true);
listContainer
.add(new AjaxSelfUpdatingTimerBehavior(Duration.seconds(3)));
// add the list view to the container
listContainer.add(listview);
// finally add the container to the page
add(listContainer);
}
}
.html file
<wicket:panel>
<div wicket:id="obal">
<table>
<tr>
<th>Čas návštěvy</th>
<th>Jméno a Příjmení</th>
<th>Adresa</th>
<th>Kontaktní telefon</th>
</tr>
<tr wicket:id="rezervaceList">
<td><span wicket:id="casRezervace"></span></td>
<td><span wicket:id="jmeno"></span></td>
<td><span wicket:id="adresa"></span></td>
<td><span wicket:id="telefon"></span></td>
</tr>
</table>
</div>
</wicket:panel>
The problem is in:
List<Rezervace> rezervace = rezervaceDao.getAllRezervace();
ListView listview = new ListView("rezervaceList", rezervace)
The list view initializes itself with a static list. It should instead ask the DB for new data on every refresh.
Read https://cwiki.apache.org/confluence/display/WICKET/Working+with+Wicket+models#WorkingwithWicketmodels-DynamicModels about static vs. dynamic models.
Related
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.
I want to make each row in a table respond to a mouse click. Specifically I want it to go to a link URL. At the moment my table is defined like this
<ul wicket:id="componentStatus" class="component-status">
<li wicket:id="equipComponentInst">
<table class="full-width">
<tr>
<td><div wicket:id="<XXX>ComponentPanel"></div></td>
<td><a wicket:id="<XXX>DetailLink" class="pull-right"><img wicket:id="detailLinkImg" border="0px"/></a></td>
</tr>
</table>
</li>
</ul>
As you can see, I have a <td> element containing a link.
But I would like the link to be followed if the user clicks on any part of the table row.
According to this SO question, it's possible to define a Javascript click handler function for table rows.
So I added such a click handler like this in my Java code
#Override
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
response.render(OnLoadHeaderItem.forScript("$('tr').click( function() { window.location = $(this).find('a').attr('href');})"));
}
But the handler function never gets called. Can this work, or do I need to look at a different approach?
My approach would be to make the <tr> a wicket component for example a WebMarkupContainer and attach to it an AjaxEventBehavior for the click event and there go to same same destination as <XXX>DetailLink points you.
Example:
private WebMarkupContainer tr() {
WebMarkupContainer wmc = new WebMarkupContainer("tr");
wmc.add(new AjaxEventBehavior("click") {
#Override
protected void onEvent(AjaxRequestTarget target) {
//go to the same place as the XXXDetailLink
}
});
return wmc;
}
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.
I have the following java and html code:
this.leakageModel = new PropertyListView<Leakage> ( "leakage", new ArrayList<Leakage> ()) {
private static final long serialVersionUID = 1L;
#Override
protected void populateItem (final ListItem<Leakage> item) {
Link<String> brandLink = new Link<String> ("brandLink") {
private static final long serialVersionUID = -480222850475280108L;
#Override
public void onClick () {
//change another model in the page to update
//another table when the link is clicked
}
};
brandLink.add (new Label ("brand"));
item.add (brandLink);
} };
add (this.leakageModel);
html file:
<tr wicket:id="leakage" class="testClass">
<td class="testClass">
<a wicket:id="brandLink" href="#">
<span wicket:id="brand"></span>
</a>
</td>
</tr>
What I want to do is to be able to call a javascript function from inside the onClick() method.
The model update that I currently do inside the onClick method works well and updates another table on the page.
However everything I have tried to call a javascript function or change the css style has failed.
For instance:
Adding a css class:
add (new AttributeAppender("class", new Model("anotherclass"), " "));
Using an AjaxLink type instead, and a number of other things I have tried to no avail.
On a related note, my original intention is to hide all rows in the table except the one I have clicked. Maybe I can do this just from the Java code and have no need for Javascript at all, but updating the css as above doesn't work.
Any suggestions as to what am I doing wrong?
On a related note, my original intention is to hide all rows in the
table except the one I have clicked.
Instead of answering your question, I will try to provide a solution to your problem :).
It makes perfect sense to hide the table row via javascript. I would suggest doing it with Jquery as described in Hiding all but first table row with jQuery:
$("#myTbl tr:not(nth-child(3))").hide();
Now, you have to execute the above javascript snippet each time a user clicks your Wicket link. For this, you can for example create your own link class like this:
public class JavascriptLink extends Label{
public JavascriptLink(String id, String label) {
super(id, label);
add(new AttributeAppender("onclick", "...your javascript here..."));
}
}
I leave it to you to combine the jquery with the JavascriptLink to meet your requirements. It should work going in this direction.
I am trying to replace a Label by a TextField in a ListView. I saw a similar wicket example few weeks ago over internet, but I don't remember the link. I have added AjaxEventBehavior - "onDblClick" to the ListItem by which I want to replace a Label by a TextField and also added AjaxFormComponentUpdatingBehavior - "onBlur" to the TextField such that the TextField will be replaced by Label. Somehow it is not working. The List model for the ListView contain only {"aaaaaaaaaaaaa", "bbbbbbbbbbbbbbbb", "cccccccccccccc"} [as I am testing it] so the first Label will be "aaaaaaaaaaaaa", if I double click on this Label the TextField is appearing the place of the Label "cccccccccccccc", which is unexpected. And also the "onBlur" event is not working. Hope I can explain the problems. The code is given below:
public class TaskTypeSettingsPage extends BasePage implements Serializable {
private String val;
public TaskTypeSettingsPage() {
add(new TaskTypeSettingsForm("form"));
}
public void setVal(String val) {
this.val = val;
}
public String getVal() {
return val;
}
private class TaskTypeSettingsForm extends Form {
private static final long serialVersionUID = 10058L;
private Fragment labelFragment;
private Fragment textFragment;
public TaskTypeSettingsForm(String id) {
super(id);
setOutputMarkupId(true);
ListView listView = new ListView("row", Arrays.asList("aaaaaaaaaaaaa", "bbbbbbbbbbbbbbbb", "cccccccccccccc")) {
#Override
protected void populateItem(ListItem item) {
String str = (String) item.getModelObject();
item.add(new Label("listLabel", str));
item.setOutputMarkupId(true);
labelFragment = new Fragment("frag", "labelFragment", this.getPage());
Label label = new Label("label", str);
label.setOutputMarkupId(true);
labelFragment.setOutputMarkupId(true);
labelFragment.add(label);
item.add(labelFragment);
textFragment = new Fragment("frag", "textFragment", this.getPage());
TextField text = new TextField("text", new PropertyModel(TaskTypeSettingsPage.this, "val"));
text.setOutputMarkupId(true);
textFragment.setOutputMarkupId(true);
textFragment.add(text);
item.add(new AjaxEventBehavior("onDblClick") {
#Override
protected void onEvent(AjaxRequestTarget target) {
labelFragment.replaceWith(textFragment);
labelFragment = textFragment;
target.addComponent(textFragment);
}
});
text.add(new AjaxFormComponentUpdatingBehavior("onBlur") {
#Override
protected void onUpdate(AjaxRequestTarget target) {
textFragment.replaceWith(labelFragment);
textFragment = labelFragment;
target.addComponent(labelFragment);
}
});
}
};
add(listView);
}
}
}
And
<html>
<body>
<wicket:extend>
<div class="heading"><wicket:message key="extras.taskType" /></div>
<form wicket:id="form" autocomplete="off">
<table>
<tr wicket:id="row">
<td>
<span wicket:id="frag"></span>
</td>
</tr>
</table>
<wicket:fragment wicket:id="labelFragment"><span wicket:id="label"></span>
</wicket:fragment>
<wicket:fragment wicket:id="textFragment"><input type="text" wicket:id="text">
</wicket:fragment>
</form>
</wicket:extend>
</body>
</html>
Any information or example code will be very helpful to me. Thank you.
Edit: I found the link: example but the source code is not available.
You can replace an entire component, but you also have to consider that the same markup might not work for both a label and a text field. But you can always replace a fragment with another fragment, so if you wrap your field and label in a fragment each, you can switch between them anytime.
However you're better off using a dedicated component for this purpose, I seem to remember an Ajax field component in either core Wicket or Wicket Extensions that did it. It is called AjaxEditableLabel
The example you are trying to remember might be this editable label example.
There is a Visural Wicket library that has ViewOrEdit component. It sounds something like you are looking for.
The ListView component may not be the best basis for a form. See http://wicketinaction.com/2008/10/building-a-listeditor-form-component/