Элегантный способ связать HTML-радио-кнопки <=> Перечисления Java <=> Перечисления mysql в Play? - PullRequest
1 голос
/ 10 июня 2011

Цель состоит в том, чтобы иметь список параметров (которые пользователь может выбрать с помощью переключателей) в одном месте (например, для файла конфигурации yaml).Никакое другое место не должно иметь этот список жестко

1 Ответ

1 голос
/ 18 июня 2011

Я сделал нечто подобное для создания select элементов, и я думаю, что перечисления работали просто отлично.Делать переключатели радио должно быть очень похоже.Я настроил его так, чтобы метки могли быть определены в файле messages.Я собираюсь попытаться извлечь соответствующие части из моего большего кода авто-генерации форм (используя FastTags), насколько я могу.Это немного тяжело для этого случая, но имеет смысл в большей системе.

Я использую тег типа #{form.selector 'order.status' /}, который ищет в шаблоне переменную с именем order, видит, что statusобъявляется как public Status status, а затем переходит к поиску всех значений перечисления Status и генерирует для них option s в элементе select.

Сначала я использую объект FieldContext, которыйпросто содержит кучу информации, которая используется другим кодом для определения того, что генерировать, вместе с некоторыми служебными методами:

public class FieldContext {
public final Map<?,?> args;
public final ExecutableTemplate template;
public final int fromLine;

public Class clazz = null;
public Field field = null;

public Object object = null;
public Object value = null;

private Map<String,String> attrs = new HashMap<String,String>();
private Map<String,Boolean> printed = new HashMap<String,Boolean>();

private List<Option> options;
...

Затем у меня есть это в другом вспомогательном классе (его информация добавляется в FieldContext):

public List<Option> determineOptions(FieldContext context) {
    List<Option> options = new ArrayList<Option>();

    if (context.field.getType().isEnum()) {
        for (Object option : context.field.getType().getEnumConstants()) {
            options.add(new Option(option.toString(), Message.get(option.toString())));
        }
    }

    return options;
}

тогда объявление тега будет

public static void _selector(Map<?,?> args, Closure body, PrintWriter out, ExecutableTemplate template, int fromLine) {
    String field_name = args.get("arg").toString();
    TagContext.current().data.put("name", field_name);
    SelectHelper helper = HelperFactory.getHelper(SelectHelper.class);

    try {
        FieldContext context = new FieldContext(field_name, args, template, fromLine);
        helper.autoconfigure(context);

        TagContext.current().data.put("selected", helper.determineValue(context));

        out.print("<div class=\"formutil-field formutil-selector\">");
        out.print("<label for=\"" + context.getAttr("id") + "\">");
        out.print(helper.findOrCreateLabel(context));
        out.print("</label>");
        out.print("<select");
        context.printAttribute(out, "id", "name");
        out.print(">");

        if (context.hasOptions()) {
            for (Option option : context.getOptions()) {
                out.print("<option value=\"" + option.value + "\">" + option.label + "</option>");
            }
        }

        out.print("</select>");

        context.printErrorIfPresent(out);
        context.printValidationHints(out);
        out.println("</div>");
    }
    ...
}
...