package com.webobjects.appserver._private;
import com.webobjects.appserver.WOAssociation;
import com.webobjects.appserver.WOComponent;
import com.webobjects.appserver.WOContext;
import com.webobjects.appserver.WOElement;
import com.webobjects.appserver.WOResponse;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSDictionary;
import com.webobjects.foundation.NSMutableArray;
import er.extensions.foundation.ERXPatcher.DynamicElementsPatches.Browser;
/**
* Quick hack at extending WOBrowser to use HTML 4 optgroups. It adds two bindings:
* group and label. group is required. When this value changes, a new optgroup is created.
* label is optional. This is used as the label for an option group. If label is not
* bound, an empty string is used as the option group label.
*
* @binding group Object, required - keyPath to value that changes when the group of options changes
* @binding label String, optional - String used as label for an option group
* @binding itemClass, optional - String CSS class name for this item, browser support is inconsistent
* @binding itemStyle, optional - String CSS style for this item, browser support is inconsistent
*/
public class ERXOptGroupBrowser extends Browser {
protected WOAssociation group;
protected WOAssociation label;
protected WOAssociation itemStyle;
protected WOAssociation itemClass;
public ERXOptGroupBrowser(String arg0, NSDictionary arg1, WOElement arg2) {
super(arg0, arg1, arg2);
group = _associations.removeObjectForKey("group");
label = _associations.removeObjectForKey("label");
itemStyle = _associations.removeObjectForKey("itemStyle");
itemClass = _associations.removeObjectForKey("itemClass");
if (group == null)
{
throw new RuntimeException("Group is a required binding");
}
}
@Override
public void appendChildrenToResponse(WOResponse response, WOContext context)
{
WOComponent parent = context.component();
Object selections = null;
if (_selections != null)
{
selections = _selections.valueInComponent(parent);
}
else if (_selectedValues != null)
{
selections = _selectedValues.valueInComponent(parent);
}
NSMutableArray selectedObjects = null;
if (selections != null) {
if ( ! (selections instanceof NSArray)) {
selectedObjects = new NSMutableArray(selections);
}
else if ( !(selections instanceof NSMutableArray)) {
selectedObjects = new NSMutableArray((NSArray)selections);
}
else {
selectedObjects = (NSMutableArray)selections;
}
}
NSArray list = (NSArray) _list.valueInComponent(parent);
Object previousGroup = null;
boolean didOpenOptionGroup = false;
boolean shouldEscapeHTML = _escapeHTML != null ? _escapeHTML.booleanValueInComponent(parent) : true;
for(int i = 0; i < list.count(); i++)
{
Object listItem = list.objectAtIndex(i);
_item.setValue(listItem, parent);
Object currentGroup = group.valueInComponent(parent);
if ( ! currentGroup.equals(previousGroup))
{
previousGroup = currentGroup;
if (didOpenOptionGroup)
{
response._appendContentAsciiString("\n</optgroup>");
}
response._appendContentAsciiString("\n<optgroup label=\"");
if (label != null)
{
if (shouldEscapeHTML)
{
response.appendContentHTMLString(label.valueInComponent(parent).toString());
}
else
{
response.appendContentString(label.valueInComponent(parent).toString());
}
}
response._appendContentAsciiString("\">");
didOpenOptionGroup = true;
}
response._appendContentAsciiString("\n<option");
if (itemStyle != null) {
String style = (String) itemStyle.valueInComponent(parent);
if (style != null) {
response._appendTagAttributeAndValue("style", style, true);
}
}
if (itemClass != null) {
String cssClass = (String) itemClass.valueInComponent(parent);
if (cssClass != null) {
response._appendTagAttributeAndValue("class", cssClass, true);
}
}
String valueAsString = null;
String displayStringAsString = null;
if (_displayString != null || _value != null)
{
if (_displayString != null)
{
Object displayString = _displayString.valueInComponent(parent);
if (displayString != null)
{
displayStringAsString = displayString.toString();
if (_value != null)
{
Object value = _value.valueInComponent(parent);
if (value != null)
{
valueAsString = value.toString();
}
}
else
{
valueAsString = displayStringAsString;
}
}
}
else
{
Object value = _value.valueInComponent(parent);
if (value != null)
{
valueAsString = value.toString();
displayStringAsString = valueAsString;
}
}
}
else
{
displayStringAsString = listItem.toString();
valueAsString = displayStringAsString;
}
boolean isSelectedItem = false;
if (_selections != null)
{
isSelectedItem = selectedObjects == null ? false : selectedObjects.containsObject(listItem);
}
else if (_selectedValues != null)
{
if (_value != null)
{
isSelectedItem = selectedObjects == null ? false : selectedObjects.containsObject(valueAsString);
}
}
if (isSelectedItem)
{
response.appendContentCharacter(' ');
response._appendContentAsciiString("selected");
}
if (_value != null)
{
response._appendTagAttributeAndValue("value", valueAsString, true);
}
else
{
String indexAsValue = WOShared.unsignedIntString(i);
response._appendTagAttributeAndValue("value", indexAsValue, false);
}
response.appendContentCharacter('>');
if (shouldEscapeHTML)
{
response.appendContentHTMLString(displayStringAsString);
}
else
{
response.appendContentString(displayStringAsString);
}
response._appendContentAsciiString("</option>");
}
if (didOpenOptionGroup)
{
response._appendContentAsciiString("\n</optgroup>");
}
}
}