call javascript in wicket and set value from Wicket as a parameter - java

I have wicket component with onClick event where I'd like to run javascript code which:
reloads the page
after page has been reloaded, scroll down to the markupId which was clicked
I have to pass as parameter the "markupId" value from wicket to javascript to find out to which position should I scroll down
WicketComponent.java
MyPanel div = new MyPanel("div");
div.add(new AjaxEventBehavior("click") {
#Override
protected void onEvent(AjaxRequestTarget target) {
// some requests...
String markupId = div.getMarkupId();
target.appendJavaScript("window.location.reload();");
target.appendJavaScript(jsReload(markupId));
}
div.add(AttributeModifier.replace("onclick", "clicked('" + div.getMarkupId() + "');"));
#Override
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
response.render(JavaScriptReferenceHeaderItem.forReference(new JavaScriptResourceReference(this.getClass(), "script.js")));
}
WicketComponent.html
<div wicket:id="div" onclick="clicked('markupId');">Text</div>
script.js
function clicked(markupId) {
window.location.reload();
}
document.addEventListener("DOMContentLoaded", function (event) {
let elementOffset = $("#{markupId}").offset().top; // how to pass here markupId parameter from wicket ?
let windowOffset = $(window).scrollTop();
window.scrollTo(0, elementOffset- windowOffset);
});
how to pass parameter "markupId" in javascript file which was attached in renderHead() or may be there is another solution for this ? I'll appreciate any help. Thanks!

you should solve your problem using location hash as described here:
Can we have code after location.reload(true)?
for the hash value use a fixed markup id for your component, something like:
div.setMarkupId("myMarkupId");
div.add(new AjaxEventBehavior("click") {
#Override
protected void onEvent(AjaxRequestTarget target) {
// some requests...
String markupId = div.getMarkupId();
target.appendJavaScript("window.location.hash = 'myMarkupId'");
target.appendJavaScript("window.location.reload();");
//that's it! no other js is needed
}
}
I haven't tried it but after page reloading it should scroll down to your component.

Related

Wicket - Set Model from another panel

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.

Wicket - anchor tag for a dynamic text

i would like to know if its possible to have a clickable link for a dynamic text.
I have tried by using the anchor tag with some wicket id and adding an onclick behavior to it, i could see the text with link on my screen but the onclick call of t he link was never triggered.
What could possibly be the issue?
i did something like this:
String someTextMessage = "Hey!!! <a wicket:id='printLink'>Click Here</a> now.";
Lable message = new Lable("messageLable", someTextMessage);
message.setEscapeModelStrings(true);
Link printLink = new Link("printLink") {
#Override
public void onClick() {
System.out.println("inside onClick");
}
};
this.add(printLink);
this.add(message);
i used this wicket id and added it to the page and attached an onclick behavior to this.
I have checked t he firebug console but there was no onclick call made for the link's click.
Thanks.
You want to use the Link.setAnchor(Component) method.
Don't forget to setOutputMarkupId to true for the component you want to jump to.
Label message = new Label("messageLable", "Anchor!");
message.setOutputMarkupId(true);
this.add(message);
Link printLink = new Link("printLink") {
#Override
public void onClick() {
System.out.println("inside onClick");
}
};
printLink.setAnchor(message);
this.add(printLink);
Don't try to add wicket components by appending html with "wicket:id" in some kind of component. It won't work.

How to defeat browser dialog popup when calling Wicket setResponsePage() from modal window?

How to defeat IE and Firefox dialog popup when trying to setResponsePage() from a wicket modalWindow per below. Dialog popup demands an answer to: "This page is asking you to confirm that you want to leave - data you have entered may not be saved."
AjaxLink signInContainer = new AjaxLink("signInContainer") {
#Override
public void onClick(AjaxRequestTarget target) {
target.appendJavascript("Wicket.Window.unloadConfirmation = false;");
modalWindow.close(target);
setResponsePage(SignInPage.class);
modalWindow.close(target);
}
};
-Rich
In wicket 6.x and above you can simply set showUnloadConfirmation to false:
final ModalWindow modalWindow = new ModalWindow("modalWindow");
modalWindow.showUnloadConfirmation(false);
target.appendJavascript("Wicket.Window.unloadConfirmation = false;"); doesn't work because it must run before modal.show(target);.
You could either prepend, instead of append, the script, when opening the window:
add(new AjaxLink<Void>("show") {
#Override
public void onClick(AjaxRequestTarget target) {
target.prependJavascript("Wicket.Window.unloadConfirmation = false;");
modal.show(target);
}
});
or add a behavior, to execute it on onload:
modal.add(new AbstractBehavior() {
#Override
public void renderHead(IHeaderResponse response) {
response.renderOnLoadJavascript("Wicket.Window.unloadConfirmation = false;");
}
});
But, it must be called before opening the modal window, not when navigating away from the page (setResponsePage()).
I believe setResponsePage() should be accompanied by some other methods to behave properly. For example, I often include setRedirect(true) when using this technique. I'm not sure what all is going on behind the scenes there, but perhaps try that.
EDIT: This is a hack, use the alternative described in my other answer.
Try this:
public void onClick(AjaxRequestTarget target) {
modal.close(target);
CharSequence url = urlFor(HomePage.class, new PageParameters("gone=true"));
target.appendJavascript("window.location='" + url + "';");
}

How to set displayed text for a HTML anchor tag using Wicket?

I would like to dynamically change the text displayed for a HTML anchor tag. So, for example if I have the following in my markup -
<a class="point" style="font-family:courier" wicket:id="link">[+]</a>
I want to change the '[+]' to something else. Currently the code fragment looks like this:
equipmentFamilyName.add(new Link<String>("link") {
#Override
protected void onComponentTag(ComponentTag tag) {
String id = "link" + equipmentFamilyName.getModelObject();
tag.put("onclick", "toggle('" + collapsibleId + "','" + id + "')");
tag.put("id", id);
}
#Override
public void onClick() {
}
});
Which just adds various attributes. I tried using a model associated with the Link object like this
IModel<String> linkModel = new Model<String>("-");
equipmentFamilyName.add(new Link<String>("link", linkModel) {
...
But that had no effect on the displayed text i.e. I still get '[+]' shown on my web page.
Any suggestions or code examples clarifying how to do this would be much appreciated.
Edit: Following the pointers in the comments, I added a method to override onComponentTagBody(). I now have a solution to this for our current version of Wicket (1.4.17).
#Override
protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag) {
replaceComponentTagBody(markupStream, openTag, "[-]");
}
If you use Wicket 1.5 then this is quite easy: link.setBody(IModel).
The model's object will be used as link's body.

Implementing AJAX and database operations with Wicket

I'm trying to add AJAX to my project.
I have a link and a boolean variable named hasEngagement in my Wicket page. I want my link to produce a JavaScript informational warning if the boolean value is true, or perform a database operation otherwise. Here's my code:
Link myLink = new Link("mylink"){
#Override
onSubmit(){
if(hasEngagement)
//ajax operation
else
// database operation
}
};
You need to use an AjaxLink: http://wicket.apache.org/apidocs/1.4/org/apache/wicket/ajax/markup/html/AjaxLink.html
And override onClick
cheers
Lee
Also you can assign your message to a Feedback message. And of course use AjaxLink
AjaxLink myLink = new AjaxLink("mylink") {
#Override
public void onClick(AjaxRequestTarget target) {
if (hasEngagement) {
target.appendJavascript("alert('information warning');");
} else {
// database operation
}
};

Categories

Resources