package er.ajax;
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.NSMutableArray;
import com.webobjects.foundation.NSMutableDictionary;
/**
* Ajax enabled Hyperlink. Calls an action on the server, then executes methods on the client.
*
* @binding elementName the HTML element name
* @binding onSuccess JS function, called on a 2xx response on the client
* @binding onFailure JS function, called on a non-200 response on the client
* @binding onComplete JS function, called on completion
* @binding onLoading the js function to call when loading
* @binding evalScripts whether or not to eval scripts on the result
* @binding onClickBefore if the given function returns true, the onClick is executed. This is to support confirm(..)
* dialogs.
* @binding onClick JS function, called after the click on the client
* @binding onClickServer JS returned from the server after the update
* @binding action method to call
* @binding title title of the link
* @binding string optional string for link text for when there is no element content
* @binding id id of the link
* @binding class class of the link
* @binding style style of the link
* @binding disabled whether or not this link is disabled
* @binding functionName if set, the link becomes a javascript function
* @author ak
*/
public class AjaxHyperlink extends AjaxDynamicElement {
public AjaxHyperlink(String name, NSDictionary<String, WOAssociation> associations, WOElement children) {
super(name, associations, children);
}
public String onClick(WOContext context) {
StringBuilder sb = new StringBuilder();
String onClickBefore = (String) valueForBinding("onClickBefore", context.component());
if (onClickBefore != null) {
sb.append("if (");
sb.append(onClickBefore);
sb.append(") {");
}
NSDictionary options = createAjaxOptions(context.component());
String actionUrl = AjaxUtils.ajaxComponentActionUrl(context);
// PROTOTYPE FUNCTIONS
sb.append("new Ajax.Request('");
sb.append(actionUrl);
sb.append("', ");
AjaxOptions.appendToBuffer(options, sb, context);
sb.append(')');
String onClick = (String) valueForBinding("onClick", context.component());
if (onClick != null) {
sb.append(';');
sb.append(onClick);
}
if (onClickBefore != null) {
sb.append('}');
}
return sb.toString();
}
protected NSDictionary createAjaxOptions(WOComponent component) {
NSMutableArray<AjaxOption> ajaxOptionsArray = new NSMutableArray<>();
// PROTOTYPE OPTIONS
ajaxOptionsArray.addObject(new AjaxOption("onSuccess", AjaxOption.SCRIPT));
ajaxOptionsArray.addObject(new AjaxOption("onFailure", AjaxOption.SCRIPT));
ajaxOptionsArray.addObject(new AjaxOption("onComplete", AjaxOption.SCRIPT));
ajaxOptionsArray.addObject(new AjaxOption("onLoading", AjaxOption.SCRIPT));
ajaxOptionsArray.addObject(new AjaxOption("evalScripts", AjaxOption.BOOLEAN));
NSMutableDictionary<String, String> options = AjaxOption.createAjaxOptionsDictionary(ajaxOptionsArray, component, associations());
options.setObjectForKey("'get'", "method");
return options;
}
@Override
public void appendToResponse(WOResponse response, WOContext context) {
WOComponent component = context.component();
boolean disabled = booleanValueForBinding("disabled", false, component);
String elementName = (String) valueForBinding("elementName", "a", component);
String functionName = (String) valueForBinding("functionName", null, component);
boolean isATag = "a".equalsIgnoreCase(elementName);
boolean renderTags = ((!disabled || !isATag) && functionName == null);
if (renderTags) {
response.appendContentString("<");
response.appendContentString(elementName);
response.appendContentString(" ");
if (isATag) {
appendTagAttributeToResponse(response, "href", "javascript:void(0)");
}
appendTagAttributeToResponse(response, "title", valueForBinding("title", component));
appendTagAttributeToResponse(response, "value", valueForBinding("value", component));
appendTagAttributeToResponse(response, "class", valueForBinding("class", component));
appendTagAttributeToResponse(response, "style", valueForBinding("style", component));
appendTagAttributeToResponse(response, "id", valueForBinding("id", component));
if (!disabled) {
appendTagAttributeToResponse(response, "onclick", onClick(context));
}
response.appendContentString(">");
}
if (functionName != null) {
AjaxUtils.appendScriptHeader(response);
response.appendContentString(functionName + " = function() { " + onClick(context) + " }\n");
AjaxUtils.appendScriptFooter(response);
}
if ( ! hasBinding("string")) {
appendChildrenToResponse(response, context);
} else {
response.appendContentString((String)valueForBinding("string", component));
}
if (renderTags) {
response.appendContentString("</");
response.appendContentString(elementName);
response.appendContentString(">");
}
super.appendToResponse(response, context);
}
@Override
protected void addRequiredWebResources(WOResponse res, WOContext context) {
addScriptResourceInHead(context, res, "prototype.js");
addScriptResourceInHead(context, res, "effects.js");
}
@Override
public WOActionResults handleRequest(WORequest request, WOContext context) {
WOComponent component = context.component();
WOActionResults results = (WOActionResults) valueForBinding("action", component);
if (results == null) {
String script = (String) valueForBinding("onClickServer", component);
if (script != null) {
WOResponse response = AjaxUtils.createResponse(request, context);
AjaxUtils.appendScriptHeader(response);
response.appendContentString(script);
AjaxUtils.appendScriptFooter(response);
results = response;
}
}
return results;
}
}