Wicket: How to add a click event handler to a table row? - java

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;
}

Related

Unable to call click event on ajax button in wicket

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.

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.

Ajax does not actualize listview in wicket

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.

Call javascript function from wicket 6, Link's "onclick ()"

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.

Categories