package er.ajax.mootools; import com.webobjects.appserver.WOActionResults; import com.webobjects.appserver.WOAssociation; import com.webobjects.appserver.WOComponent; import com.webobjects.appserver.WOContext; import com.webobjects.appserver.WOElement; import com.webobjects.appserver.WORequest; import com.webobjects.appserver.WOResponse; import com.webobjects.appserver._private.WOConstantValueAssociation; import com.webobjects.appserver._private.WODynamicGroup; import com.webobjects.foundation.NSArray; import com.webobjects.foundation.NSDictionary; import com.webobjects.foundation.NSMutableArray; import er.ajax.AjaxDynamicElement; import er.ajax.AjaxUtils; import er.extensions.appserver.ERXWOContext; /** * This implements the tabs and the main control of a tabbed panel display as an * unordered list (UL and LI elements). The tab contents go in AjaxTabbedPanel * components contained within this component. The tab contents are loaded on * demand so only the selected tab is rendered when the page is displayed. If * tabs can take a while to load, a hidden div containing a "working" message * can temporarily replace the panel content while it loads. * * <h3>CSS Classes Used by AjaxTabbedPanel and AjaxTabbedPanelTab</h3> * <table> * <tr> * <th>Class Name</th> * <th>Used For</th> * </tr> * <tr> * <td>ajaxTabbedPanel</td> * <td>The UL containing the tabs.</td> * </tr> * <tr> * <td>ajaxTabbedPanelTab-selected</td> * <td>The LI representing the selected tab and the A element that is the clickable title.</td> * </tr> * <tr> * <td>ajaxTabbedPanelTab-unselected</td> * <td>The LI representing the selected tab(s) and the A element that is the clickable title.</td> * </tr> * <tr> * <td>ajaxTabbedPanelPanes</td> * <td>The UL containing the panels (panes).</td> * </tr> * <tr> * <td>ajaxTabbedPanelPane-selected</td> * <td>The LI representing the selected panel.</td> * </tr> * <tr> * <td>ajaxTabbedPanelPane-unselected</td> * <td>The LI representing the unselected panel(s).</td> * </tr> * </table> * * @binding id required, String the id of the UL that wraps the tabs * @binding busyDiv optional, String the id of a div that should be shown when a * tab is loading * @binding onLoad optional, String JavaScript to execute after the whole tabbed panel loads * @binding onSelect optional, String JavaScript to execute after a different tab is selected. * This will <b>not</b> get called when this is first rendered. Use onLoad if you need that. * @binding class css classes to add to the ul. * @author Chuck Hill */ public class MTAjaxTabbedPanel extends AjaxDynamicElement { private WOElement content; private NSMutableArray<MTAjaxTabbedPanelTab> tabs = new NSMutableArray<MTAjaxTabbedPanelTab>(); private WOAssociation id; private WOAssociation busyDiv; private WOAssociation onLoad; private WOAssociation onSelect; public MTAjaxTabbedPanel(String name, NSDictionary<String, WOAssociation> associations, WOElement template) { super(name, associations, template); content = template; id = associations.objectForKey("id"); busyDiv = associations.objectForKey("busyDiv"); onLoad = associations.objectForKey("onLoad"); onSelect = associations.objectForKey("onSelect"); findTabs((WODynamicGroup)template); if (id == null) { throw new RuntimeException("id binding is required"); } } /** * Looks through the child components to locate the AjaxTabbedPanelTabs that are controlled by this panel. * Tabs without an explicit id attributed are assigned a calculated one. * * @param template the graph of elements passed to the constructor. */ private void findTabs(WODynamicGroup template) { if (template == null || template.childrenElements() == null) return; NSArray<WOElement> children = template.childrenElements(); for (int i = 0; i < children.count(); i++) { WOElement child = children.objectAtIndex(i); if (child instanceof MTAjaxTabbedPanelTab) { MTAjaxTabbedPanelTab childTab = (MTAjaxTabbedPanelTab)child; // The tabs need to have an id attribute so we assign one if needed if (childTab.id() == null) { childTab.setId(new WOConstantValueAssociation(id.valueInComponent(null) + "_pane_" + tabs.count())); } tabs.addObject(childTab); } else if (child instanceof WODynamicGroup) { findTabs((WODynamicGroup)child); } } } @Override public void appendToResponse(WOResponse response, WOContext context) { WOComponent component = context.component(); String idString = (String) id.valueInComponent(component); if (idString == null) { throw new RuntimeException("id binding evaluated to null"); } // UL for tabs response.appendContentString("<ul"); appendTagAttributeToResponse(response, "class", valueForBinding("class", component)); appendTagAttributeToResponse(response, "id", idString); // Optional JavaScriplets if (onLoad != null) { appendTagAttributeToResponse(response, "onLoad", onLoad.valueInComponent(component)); } if (onSelect != null) { appendTagAttributeToResponse(response, "onSelect", onSelect.valueInComponent(component)); } response.appendContentString(">\n"); String paneControlID = idString + "_panecontrol"; String selectedTabClassName = stringValueForBinding("selectedPanelClassName", component); if(selectedTabClassName == null) { selectedTabClassName = "active"; } for(MTAjaxTabbedPanelTab tab : tabs) { if (tab.isVisble(component)) { boolean isSelectedTab = tab.isSelected(context.component()); String panelTabID = (String) tab.id().valueInComponent(component); String panelID = panelTabID + "_panel"; response.appendContentString(" <li"); if(isSelectedTab) { response.appendContentString(" class=\""); response.appendContentString(selectedTabClassName); response.appendContentString("\""); } response.appendContentString(">\n"); response.appendContentString("<a "); //add the accesskey if( tab.accesskey() != null ){ String accessKeyStr = tab.accesskey().valueInComponent(component).toString(); appendTagAttributeToResponse(response, "accesskey", accessKeyStr ); } appendTagAttributeToResponse(response, "href", "javascript:void(0)"); appendTagAttributeToResponse(response, "rel", panelID); response.appendContentString("\">"); response.appendContentString((String) tab.name().valueInComponent(component)); response.appendContentString("</a>\n"); response.appendContentString("</li>\n"); } } response.appendContentString("</ul>\n"); // UL for panes response.appendContentString("<ul class=\"ajaxTabbedPanelPanes\" "); appendTagAttributeToResponse(response, "id", paneControlID); response.appendContentString(">\n"); // The tabs render themselves as panes if (content != null) { content.appendToResponse(response, context); } response.appendContentString("</ul>\n"); super.appendToResponse(response, context); AjaxUtils.appendScriptHeader(response); response.appendContentString("window.addEvent('domready', function() {"); response.appendContentString("\n\tvar "); response.appendContentString(safeID(context)); response.appendContentString(" = new MTAjaxTabbedPanel({"); response.appendContentString("tabbedPanelTabsContainer : "); response.appendContentString("'"); response.appendContentString(idString); response.appendContentString("', "); response.appendContentString("tabbedPanelPanesContainer : "); response.appendContentString("'"); response.appendContentString(paneControlID); response.appendContentString("'"); if(! selectedTabClassName.equals("active")) { response.appendContentString(", "); response.appendContentString("selectedTabClassName : "); response.appendContentString("'"); response.appendContentString(selectedTabClassName); response.appendContentString("'"); } response.appendContentString("});"); response.appendContentString("\n});"); AjaxUtils.appendScriptFooter(response); } public String safeID(WOContext context) { return "mtTabbedPanel" + ERXWOContext.safeIdentifierName(context, true); } @Override protected void addRequiredWebResources(WOResponse response, WOContext context) { MTAjaxUtils.addScriptResourceInHead(context, context.response(), "MooTools", MTAjaxUtils.MOOTOOLS_CORE_JS); MTAjaxUtils.addScriptResourceInHead(context, context.response(), "MooTools", MTAjaxUtils.MOOTOOLS_MORE_JS); MTAjaxUtils.addScriptResourceInHead(context, context.response(), "MooTools", MTAjaxUtils.MOOTOOLS_WONDER_JS); MTAjaxUtils.addScriptResourceInHead(context, context.response(), "MooTools", "scripts/plugins/tabs/MTAjaxTabbedPanel.js"); } @Override public WOActionResults handleRequest(WORequest request, WOContext context) { // TODO Auto-generated method stub return null; } }