package er.ajax.mootools; import java.net.MalformedURLException; 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.foundation.NSDictionary; import com.webobjects.foundation.NSForwardException; import com.webobjects.foundation.NSMutableArray; import com.webobjects.foundation.NSMutableDictionary; import er.ajax.AjaxDynamicElement; import er.ajax.AjaxOption; import er.ajax.AjaxOptions; import er.ajax.AjaxUpdateContainer; import er.ajax.AjaxUtils; import er.extensions.appserver.ERXRequest; import er.extensions.appserver.ERXWOContext; import er.extensions.foundation.ERXMutableURL; /* * * @binding useDefaultCSS (boolean) defaults to true. Will load a default CSS file for the modal container. */ public class MTAjaxModalContainer extends AjaxDynamicElement { private String _updateContainerID = null; private String _url = null; public MTAjaxModalContainer(String name, NSDictionary<String, WOAssociation> associations, WOElement children) { super(name, associations, children); } @Override public void appendToResponse(WOResponse response, WOContext context) { WOComponent component = context.component(); String linkID = (String) valueForBinding("id", component); if(linkID == null) { linkID = ERXWOContext.safeIdentifierName(context, false); } String containerID = (String) valueForBinding("containerID", linkID + "Container", component); String linkElementName = (String)valueForBinding("linkElementName", "a", component); String label = (String)valueForBinding("label", "Open", component); _url = (String) valueForBinding("href", component); if(_url == null) { String directActionName = stringValueForBinding("directActionName", component); if(directActionName != null) { NSDictionary queryDictionary = (NSDictionary)valueForBinding("queryDictionary", component); boolean secure = booleanValueForBinding("secure", ERXRequest.isRequestSecure(context.request()), component); if(secure) { boolean generatingCompleteURLs = context.doesGenerateCompleteURLs(); if(!generatingCompleteURLs) { context.generateCompleteURLs(); } try { _url = context._directActionURL(directActionName, queryDictionary, secure, 0, false); ERXMutableURL u = new ERXMutableURL(_url); u.addQueryParameter(String.valueOf(System.currentTimeMillis()), null); _url = u.toExternalForm(); } catch (MalformedURLException e) { throw new NSForwardException(e); } finally { if(!generatingCompleteURLs) { context.generateRelativeURLs(); } } } else { _url = context.directActionURLForActionNamed(directActionName, queryDictionary); } } } boolean isAjax = booleanValueForBinding("ajax", false, component); if(_url == null) { if(isAjax) { if(valueForBinding("id", component) == null) { throw new IllegalArgumentException("If ajax = 'true', you must also bind 'id'"); } _url = AjaxUtils.ajaxComponentActionUrl(context); } else if (associations().objectForKey("action") != null) { _url = context.componentActionURL(); } if(_url == null) { _url = "#" + containerID; } } response.appendContentString("<"); response.appendContentString(linkElementName); appendTagAttributeToResponse(response, "id", linkID); appendTagAttributeToResponse(response, "href", _url); appendTagAttributeToResponse(response, "title", valueForBinding("title", component)); appendTagAttributeToResponse(response, "value", valueForBinding("value", component)); appendTagAttributeToResponse(response, "class", valueForBinding("class", component)); appendTagAttributeToResponse(response, "style", valueForBinding("style", component)); response.appendContentString(">"); response.appendContentString(label); response.appendContentString("</"); response.appendContentString(linkElementName); response.appendContentString(">"); Boolean autoWrapContent = (Boolean)valueForBinding("autoWrapContent", Boolean.TRUE, component); Boolean showFooter = (Boolean)valueForBinding("showFooter", Boolean.TRUE, component); Boolean showTitle = (Boolean)valueForBinding("showTitle", Boolean.TRUE, component); String modalClassNames = (String)valueForBinding("modalClassNames", "modal fade", component); _updateContainerID = null; if(_url.startsWith("#")) { response.appendContentString("\n<div class=\""); response.appendContentString(modalClassNames); response.appendContentString("\" "); appendTagAttributeToResponse(response, "id", containerID); response.appendContentString(">"); String title = stringValueForBinding("title", component); if(showTitle.booleanValue() && title != null) { response.appendContentString("\n\t<div class=\"modal-header\">"); response.appendContentString("\n\t\t<a class=\"close\" data-dismiss=\"modal\">x</a>"); response.appendContentString("\n\t\t<h3>"); response.appendContentString(title); response.appendContentString("</h3>"); response.appendContentString("\n\t</div>"); } if(autoWrapContent.booleanValue()) { response.appendContentString("\n\t<div class=\"modal-body\">"); } appendChildrenToResponse(response, context); if(autoWrapContent.booleanValue()) { response.appendContentString("\n\t</div>"); } if(showFooter.booleanValue()) { response.appendContentString("\n\t<div class=\"modal-footer\">"); response.appendContentString("\n\t\t<a href=\"#\" class=\"dismiss btn\">Close</a>"); response.appendContentString("\n\t</div>"); } response.appendContentString("</div>"); } else { _updateContainerID = containerID; response.appendContentString("\n<div class=\""); response.appendContentString(modalClassNames); response.appendContentString("\" "); appendTagAttributeToResponse(response, "id", containerID); response.appendContentString(">"); String title = stringValueForBinding("title", component); if(showTitle.booleanValue() && title != null) { response.appendContentString("\n\t<div class=\"modal-header\">"); response.appendContentString("\n\t\t<a class=\"close\" data-dismiss=\"modal\">x</a>"); response.appendContentString("\n\t\t<h3>"); response.appendContentString(title); response.appendContentString("</h3>"); response.appendContentString("\n\t</div>"); } if(autoWrapContent.booleanValue()) { String modalBodyID = stringValueForBinding("modalBodyID", component); if(modalBodyID == null) { modalBodyID = "modalBody" + ERXWOContext.safeIdentifierName(context, false); } _updateContainerID = modalBodyID; response.appendContentString("\n\t<div class=\"modal-body\""); appendTagAttributeToResponse(response, "id", modalBodyID); response.appendContentString(">"); } if(autoWrapContent.booleanValue()) { response.appendContentString("\n\t</div>"); } if(showFooter.booleanValue()) { response.appendContentString("\n\t<div class=\"modal-footer\">"); response.appendContentString("\n\t\t<a href=\"#\" class=\"dismiss btn\">Close</a>"); response.appendContentString("\n\t</div>"); } response.appendContentString("</div>"); } String varName = stringValueForBinding("varName", component); if(varName == null) { varName = "bsPopUp" + ERXWOContext.safeIdentifierName(context, false); } AjaxUtils.appendScriptHeader(response); response.appendContentString("\nwindow.addEvent('domready', function() {"); response.appendContentString("\n\tvar "); response.appendContentString(varName); response.appendContentString(" = new Bootstrap.Popup('"); response.appendContentString(containerID); response.appendContentString("', {"); if(_updateContainerID != null) { response.appendContentString("onShow: function() { "); response.appendContentString("\n\tnew Request.HTML("); AjaxOptions.appendToResponse(createAjaxOptions(component), response, context); response.appendContentString(").send();"); response.appendContentString("}"); } response.appendContentString("});"); response.appendContentString("\n\tdocument.id('"); response.appendContentString(linkID); response.appendContentString("').addEvent('click', function(e) { e.preventDefault(); this.show(); }.bind("); response.appendContentString(varName); response.appendContentString("));"); response.appendContentString("\n})"); AjaxUtils.appendScriptFooter(response); super.appendToResponse(response, context); } @Override protected String _containerID(WOContext context) { String id = (String) valueForBinding("id", context.component()); return id; } public NSDictionary createAjaxOptions(WOComponent component) { NSMutableArray<AjaxOption> ajaxOptionsArray = new NSMutableArray<>(); ajaxOptionsArray.addObject(new AjaxOption("async", AjaxOption.BOOLEAN)); ajaxOptionsArray.addObject(new AjaxOption("onRequest", AjaxOption.FUNCTION)); ajaxOptionsArray.addObject(new AjaxOption("onComplete", AjaxOption.FUNCTION)); ajaxOptionsArray.addObject(new AjaxOption("onSuccess", AjaxOption.FUNCTION_2)); ajaxOptionsArray.addObject(new AjaxOption("onFailure", AjaxOption.FUNCTION)); ajaxOptionsArray.addObject(new AjaxOption("onException", AjaxOption.SCRIPT)); ajaxOptionsArray.addObject(new AjaxOption("evalScripts", AjaxOption.BOOLEAN)); ajaxOptionsArray.addObject(new AjaxOption("useSpinner", AjaxOption.BOOLEAN)); ajaxOptionsArray.addObject(new AjaxOption("spinnerTarget", AjaxOption.STRING)); ajaxOptionsArray.addObject(new AjaxOption("spinnerOptions", AjaxOption.DICTIONARY)); NSMutableDictionary<String, String> options = AjaxOption.createAjaxOptionsDictionary(ajaxOptionsArray, component, associations()); options.setObjectForKey("'" + _url + "'", "url"); options.setObjectForKey("'" + _updateContainerID + "'", "update"); options.setObjectForKey("'get'", "method"); if (options.objectForKey("async") == null) { options.setObjectForKey("true", "async"); } if (options.objectForKey("evalScripts") == null) { options.setObjectForKey("true", "evalScripts"); } AjaxUpdateContainer.expandInsertionFromOptions(options, this, component); return options; } @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", "scripts/plugins/bootstrap/ui/Bootstrap.js"); MTAjaxUtils.addScriptResourceInHead(context, context.response(), "MooTools", "scripts/plugins/bootstrap/behaviors/Behavior.js"); MTAjaxUtils.addScriptResourceInHead(context, context.response(), "MooTools", "scripts/plugins/bootstrap/behaviors/Behavior.BS.Popup.js"); MTAjaxUtils.addScriptResourceInHead(context, context.response(), "MooTools", "scripts/plugins/bootstrap/ui/Bootstrap.Popup.js"); MTAjaxUtils.addScriptResourceInHead(context, context.response(), "MooTools", "scripts/plugins/bootstrap/ui/CSSEvents.js"); MTAjaxUtils.addScriptResourceInHead(context, context.response(), "MooTools", MTAjaxUtils.MOOTOOLS_WONDER_JS); Boolean useDefaultCSS = (Boolean)valueForBinding("useDefaultCSS", Boolean.TRUE, context.component()); if(useDefaultCSS.booleanValue()) { AjaxUtils.addStylesheetResourceInHead(context, context.response(), "MooTools", "scripts/plugins/bootstrap/modal/modal.css"); } } @Override public WOActionResults handleRequest(WORequest request, WOContext context) { WOComponent component = context.component(); WOResponse response = null; WOAssociation action = associations().objectForKey("action"); if(action != null) { action.valueInComponent(component); } if(booleanValueForBinding("ajax", false, component) && hasChildrenElements()) { response = AjaxUtils.createResponse(request, context); AjaxUtils.setPageReplacementCacheKey(context, _containerID(context)); appendChildrenToResponse(response, context); } return response; } }