I make a fullcalendar in my tapestry 5.4 web page.
When I make a new Event or I click an existing event, the fullcalendar's method is called (select
or eventClick
). In these methods tapestry js method is called (zoneManager.deferredZoneUpdate("formZone", listenerURIWithValue);
), because I want to refresh my jQuery dialog div (#formZone
) what is a tapestry zone. And it works well functionally, the data appears.
However, I always see the refreshing "procedure" because after the zone-update part, the jQuery dialog is opened, but the refresh is not ending (I know because ajax call is asynchronous) and it causes an "ugly" refresh after the jQuery dialog is opened.
My goal is to define a callback function for deferredZoneUpdate
or make this code sequence:
...
zoneManager.deferredZoneUpdate("formZone", listenerURIWithValue);
$('#wsDialog').dialog('open');
...
Thanks for the answers in advance!
Update:
calendar-init.js:
define(["jquery" , "t5/core/zone"], function($, zoneManager) {
return function(modifyEventLink, newEventLink, pageTurnLink, allDayText) {
$(document).ready(function() {
var calendarDiv = $('#calendar');
calendarDiv.fullCalendar({
//....init
eventClick: function(calEvent, jsEvent, view) {
// create modifyeventlink with id param
var listenerURIWithValue = appendQueryStringParameter(modifyEventLink, 'eventID', calEvent.id);
// ajax zone update
zoneManager.deferredZoneUpdate("formZone", listenerURIWithValue);
// open the worksheet dialog
$('#wsDialog').dialog('option', 'title', calEvent.title);
},
//...init
});});}}) // the code syntacs is good dont bother these :D
backend:
void onModifyEventLink() {
if(request.isXHR()) {
logger.debug("ModifyEventLink on.");
String eventID = (String) request.getParameter("eventID");
if(eventID == null) {
logger.error("wsDialog was not able to load because eventID is NULL!");
} else {
try{
wSheet = sheetService.find(Integer.valueOf(eventID));
if(wSheet != null) {
ajaxResponseRenderer
.addCallback(new JavaScriptCallback() {
@Override
public void run(JavaScriptSupport javascriptSupport) {
javascriptSupport.require("wsdialogs");
}};)
.addRender(formZone);
} else {
logger.warn("Worksheet with " + eventID + " not found.");
}
} catch (NumberFormatException e) {
logger.error("wsDialog was not able to load beacause eventID was not a number.");
logger.error("Exception: ", e.getLocalizedMessage());
}
}
} else {
logger.debug("ModifyEventLink on, request is not XHR (ajax)");
}
}
(module) wsdialogs.js:
define(["jquery" , "t5/core/zone"], function($, zoneManager) {
console.log("wsdialog-js run");
$("#wsDialog").dialog('open');
});
tml:
<t:container
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p="tapestry:parameter">
<t:jquery.dialog t:clientId="wsDialog" t:id="wsDialog" title="${message:wsheet-new}" style="display: none;">
<t:zone t:id="formZone" id="formZone">
<t:form t:id="worksheetForm" t:type="form" t:zone="^">
....
</t:form>
</t:zone>
</t:jquery.dialog>
</t:container>
public class ComponentWithZone {
@Inject
private AjaxResponseRenderer ajaxResponseRenderer;
...
public void onSomeEventFromClient() {
ajaxResponseRenderer.addRender("zone-id-to-update", zone.getBody()).addCallback(new JavaScriptCallback() {
@Override
public void run(JavaScriptSupport javascriptSupport) {
javascriptSupport.require("modal").invoke("showModal").with("#dialog-id");
}
});
}
}
This example is with bootstrap modal included as tapestry module.
When tapestry refresh zone div with content it will trigger showModal function.
UPD: Forgot to mention that this example assumes that you have modal module. Here is example of mine:
(function(){
define(["jquery", "bootstrap/modal"], function($, modal) {
return {
showModal: function(id) {
$('#'+id).modal('show');
},
hideModal: function(id) {
$('#'+id).modal('hide');
}
};
});
}).call(this);
Instead of bootstrap/modal you can use any module, but don't forget to include it in META-INF/modules.