Reputation: 1924
I'm trying to call some Java code from Javascript in Wicket.
This is my Java code:
public ShowUnternehmen() {
add(new AbstractDefaultAjaxBehavior() {
@Override
protected void respond(AjaxRequestTarget ajaxRequestTarget) {
System.out.println("respond");
}
@Override
public void renderHead(Component component, IHeaderResponse response) {
super.renderHead( component, response );
System.out.println(getCallbackUrl());
}
});
}
And this is the Javascript code:
<wicket:head>
<script type="text/javascript" >
$(function() {
$.contextMenu({
selector: '.context-menu-one',
callback: function(key, options) {
var m = "clicked: " + key;
alert("BLA");
Wicket.Ajax.get({"u":"./com.emg.panels.unternehmen.ShowUnternehmen?1-1.IBehaviorListener.0-"})
},
items: {
"edit": {name: "Editieren", icon: "edit"},
"quit": {name: "Abbrechen", icon: function(){
return 'context-menu-icon context-menu-icon-quit';
}}
}
});
$('.context-menu-one').on('click', function(e){
console.log('clicked', this);
})
});
</script>
</wicket:head>
But the response method is never executed. I was looking at other examples but they all seem to be confusing.
I got this url from renderHead method
Upvotes: 3
Views: 4293
Reputation: 574
You are on a good way. It would be more relalible if you let wicket render the callback function to the page. The following two examples show how you can do that:
A) Render a global callback function. The disadvantage will be that you will have only one callback endpoint.
(1) Create a behavior like the following one:
public class CallFromJavascriptBehavior extends AbstractDefaultAjaxBehavior {
@Override
protected void respond(AjaxRequestTarget target) {
final StringValue parameterValue = RequestCycle.get().getRequest().getQueryParameters().getParameterValue("yourName");
System.out.println(String.format("Hello %s", parameterValue.toString()));
}
@Override
public void renderHead(Component component, IHeaderResponse response) {
super.renderHead(component, response);
response.render(JavaScriptHeaderItem.forScript(String.format("nameOfFunction=%s", getCallbackFunction(CallbackParameter.explicit("yourName"))), "CallFromJavascriptBehavior"));
}}
(2) Add this behavior to your wicket page.
(3) Now you can call nameOfFunction('Markus'); from your javascript.
B) Call a initialisation function for each instance of your component on page.
(1) add a initialisation function to your page
<script>
function initMyComponent(selector, callback){
$(selector).click(function(){
callback("Markus");
});
}
</script>
(2) Create a behavior like the following which calls the initialisation function and passes the necessary selector and callback function.
public class ComponentBehavior extends AbstractDefaultAjaxBehavior{
@Override
protected void respond(AjaxRequestTarget target) {
final StringValue parameterValue = RequestCycle.get().getRequest().getQueryParameters().getParameterValue("yourName");
System.out.println(String.format("Hello %s", parameterValue.toString()));
}
@Override
public void renderHead(Component component, IHeaderResponse response) {
super.renderHead(component, response);
response.render(OnDomReadyHeaderItem.forScript(String.format("initMyComponent('#%s', %s)", component.getMarkupId(), getCallbackFunction(CallbackParameter.explicit("yourName")))));
}}
(3) Add the behavior to your wicket component.
If the response method did not get called this could have different reasons. You should check your console (ide and browser) first.
Upvotes: 6
Reputation:
An easy way to trigger java/wicket code from Javascript is to use a hidden input with an event behavior as a hook.
Hidden inputs are form elements that are "invisible" but can be quite usefull for cases like this.
Setup Wicket components
First we add a HiddenField on our Wicket page and give it an AjaxEventBehavior
final HiddenField<Void> hiddenInput = new HiddenField<>("hiddenInput");
add(hiddenInput);
hiddenInput.add(new AjaxEventBehavior("change") {
@Override
protected void onEvent(final AjaxRequestTarget target) {
// Execute any code you like and respond with an ajax response
target.appendJavaScript("alert('Hidden Input Change Event Behaviour!');");
}
});
I used that Javascript alert as an example because a System.out.println might be ignored by some logger systems. I also used the change event, although others would probably work as well.
The corresponding HTML-Markup:
<input type="hidden" wicket:id="hiddenInput" id="hiddenInput1"/>
NOTE: I gave the input a fixed id value. Since ids should be unique on every page you couldn't make this into a Wicket Panel and add it multiple times to a page. You would have to let wicket create the ids (setOutputMarkupId(true)
) and then find a way to pass the ids to your javascript. But for this very simple example this should suffice.
Trigger with Javascript
Now all you need to do is trigger a change event on your hidden input and it will execute the code you defined in the onEvent method.
With JQuery and the id, this is extremly simple:
<script>
$('#hiddenInput1').change();
</script>
Hope this simple example helps you to get the idea. As i already said in my comments this is only really usefull when your javascript call doesn't need/care about the response and you just want to be able to trigger wicket code from JavaScript.
Upvotes: 2