Wicket panels need page refresh for javascript script to work
I am creating a web page with several tabs. To implement that I am using wicket AjaxTabbedPanel
and several AbstractTab
. In each tab I have tables with data and I am using a javascript script to make the tables sortable.
public TabbedPage() {
List<ITab> tabs = new ArrayList<ITab>();
tabs.add(new AbstractTab(new Model<String>("first tab")) {
public Panel getPanel(String panelId) {
return new TablePanel(panelId);
}
});
tabs.add(new AbstractTab(new Model<St开发者_StackOverflowring>("second tab")) {
public Panel getPanel(String panelId) {
return new TablePanel(panelId);
}
});
add(new AjaxTabbedPanel("tabs", tabs));
}
When I load the page the table in the tab selected by default is sortable. However, as soon as I click any of the links to jump to other tabs (including the one of the tab already selected), none of the tables in any of the tabs allows me sort them (including the one that was previously working - the table in the default tab). If I refresh the page I can sort the table (of the tab selected in the moment of the refresh), but as soon as I click in any of links to switch tabs, the tables stop having the sortable capability again. Any ideas of why is this happening?
EDIT:
I just found that if I replace the AjaxTabbedPanel
by TabbedPanel
I don't have this problem. Although I'm still not sure why is that. Can anyone enlighten me?
add(new TabbedPanel("tabs", tabs));
Sorting the table by JavaScript is most likely a function called with a specific DOM-Id and seems to be executed 'onLoad'. it then accesses the currently displayed table and does it's work. Changing the content of your Panel by Ajax doesn't trigger 'onLoad' so the function isn't executed again. TabbedPanel reloads the page and therefore executed your script. Selecting a previous sortable table with AjaxTabbedPanel doesn't work because of the dynamically generated DOM-Ids.
Your solution is to add a AjaxCallDecorator to the links from AjaxTabbedPanel or to include the script or at least the function call to your tabbed panels.
At least this it what comes to mind without seeing any sources...
EDIT: You might want to look at The Wicket Wiki. There's a description on how to call js after clicking an AjaxLink. That's exactly what should solve your problem.
Summary: Just add
link.add(new AttributeAppender("onclick", new Model("myTableSortingScript();"), ";"));
to the links generated by AjaxTabbedPanel.
In Wicket 6.0 you can run JavaScript on a component basis: Just override renderHead(IHeaderResponse response) for your component:
@Override
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
response.render(new OnLoadHeaderItem("initalizeMe(\"" + getMarkupId() + "\");"));
}
initializeMe(mycomponentId) is executed every time the component is loaded by the AjaxTabbedPanel. This also works with the standard TabbedPanel.
No real idea since I'm not sure what the code is doing but I had a similar problem with my Panel Manager. Basically if you dynamically load HTML into a panel (a div or another element) using "innerhtml" script in the content will not be executed.
To get around this I scan the loaded content for "script" tags and append them using the DOM methods - this does run the script and makes it available. My "load" method is:
// Load Content
Panel.load = function(Content) {
// "null" the old (to clear it)
Panel.innerHTML = null;
// Load the content
Panel.innerHTML = Content;
// Load Scripts
var AllScripts = Panel.getElementsByTagName("script");
var AllScriptsCnt = AllScripts.length;
for (var Cnt = 0; Cnt < AllScriptsCnt; Cnt++){
var CurScript = document.createElement('script');
CurScript.type = "text/javascript";
CurScript.text = AllScripts[Cnt].text;
Panel.appendChild(CurScript);
};
};
Again, not sure if this is the issue, but it sounds pretty much on target from my experience.
精彩评论