2016-08-22 8 views
0

В моем веб-приложении у меня много форм со списками компонентов, пользователи могут динамически добавлять/удалять эти компоненты. Например, при вводе информации о себе пользователь может добавить несколько текстовых полей, содержащих имена своих детей. Для каждого компонента есть ссылка для удаления, а также ссылка на добавление нового компонента. Разметка выглядит следующим образом:Wicket - список компонентов форм с функциональностью добавления/удаления

<div> 
    <div wicket:id="rows"> 
     <input type="text" wicket:id="name"/> 
     <a wicket:id="remove">Remove</a> 
    </div> 
    <a wicket:id="add">Add</a> 
</div> 

где строки является калитка ретранслятор.

Компоненты ввода варьируются от списка к списку (это может быть выпадающее меню или что-то еще, к нему могут быть добавлены разные валидаторы и т. Д.), Но ссылки остаются неизменными. Их разметка и логика не меняются. Поскольку у меня много таких списков в моих формах, у меня есть макуп и дублирование кода. То, что я хотел бы иметь, чтобы сохранить разметку моих входных компонентов в форме, избавляясь от этих связей, что-то вроде этого:

<div wicket:id="dynamicList"> 
    <input type="text" wicket:id="name"/> 
</div> 

, которая будет оказана в виде списка текстовых полей с оным/удалять ссылки.

Я знаю, что у меня должна быть разметка для ссылок где-то, например, автогенерировать их или помещать в панель или что-то в этом роде, я просто не хочу их дублировать каждый раз.

UPD: Вот разметка для предлагаемого решения (которые не работают) с использованием компонента Border: ListBorder.html:

<wicket:border> 
    <div wicket:id="rows"> 
     <wicket:body/> 
     <a wicket:id="remove">Remove</a> 
    </div> 
    <a wicket:id="add">Add</a> 
</wicket:border> 

MyForm.html:

<form wicket:id="form"> 
    ... 
    <div wicket:id="dynamicList"> 
     <input type="text" wicket:id="name"/> 
    </div> 
    ... 
</form> 
+0

Не могли бы вы предоставить фрагменты того, как работают ваши добавления/удаления ссылок? Кроме того, какой ретранслятор вы используете? – WiseTree

+0

Я использую RepeatingView на основе примера в Wicket in Action [blog] (http://wicketinaction.com/2008/10/building-a-listeditor-form-component/), в котором также описывается, как работают эти ссылки. Но я думаю, что это больше о том, как организовать разметку ... – koszek

ответ

1

Я думаю, в проблеме, которую вы описываете, есть несколько различных аспектов. Во-первых, вы хотите обернуть ввод таким образом, чтобы ссылка на удаление была добавлена ​​ . Затем вы хотите повторить этот завернутый ввод. Наконец, вы хотите добавить ссылку добавления в конце повторного ввода. И, наконец, вы хотите, чтобы все это было обернуто в один компонент.

Во-первых, добавление ссылки удаления на вход. Здесь вы можете использовать Border. Как вы, вероятно, можете сделать вывод, что это будет выглядеть как-то

<wicket:border> 
    <wicket:body/> 
    <a wicket:id="remove">Remove</a> 
</wicket:border> 

Затем повторить всю эту границу, чтобы достичь нескольких входов с удалить ссылки автоматически.

Чтобы достичь точного поведения, которое вы хотите, насколько это касается остальной части вопроса, вы можете сделать это, переопределив Component#onComponentTag(). Вы можете вручную добавить ссылку на HTML, такую ​​как

@Override 
protected void onRender() { 
    super.onRender(); 
    Response response = getResponse(); 
    String url = generateAddUrl(); 
    response.write("<a href=\"" + url + "\">Add</a>");   
} 

Способ создания URL-адреса является сложным. Я не собираюсь рассказывать об этом (потому что я думаю, что точное поведение, о котором вы просите, не представляется возможным - я объясню, почему в секунду), но вы можете использовать исходный код для Link#getUrl() в качестве отправной точки.

В качестве альтернативы вы можете написать свою собственную реализацию Component, которая будет сканировать тело его разметки, а затем генерировать то, что вы хотите на основе этого. Очевидно, это не быстрое решение, но если прецедент того, что вы описали, достаточно велик, в долгосрочной перспективе это может быть лучше.

Но в конце я считаю, что лучшее решение будет иметь Panel для каждого типа ввода (т. Е. Ввода, выбора и т. Д.) С разметкой, структурированной так, как вы хотите, и обеспечения необходимых изменений разметки с помощью калитки AttributeAppender и тому подобное. Это, конечно же, означает, что некоторые из html окажутся на стороне Java, что не идеально, но это решение будет работать хорошо и может быть настроено быстро.

+0

Я попытался использовать Border, но, похоже, он не работает с репитерами, есть даже [отчет об ошибке] (https://issues.apache.org/jira/ browse/WICKET-2493). Говорят, что граница не должна использоваться внутри ретрансляторов. – koszek

+0

Я начал думать, что дублирование разметки для этих ссылок в конце концов не так уж плоха, но оказывается, что когда вы добавляете элемент, вам нужно обновить список, чтобы отобразить этот элемент, и вы не можете обновить сам ретранслятор, вы необходимо обновить родительский контейнер. Таким образом, для этой цели должен быть окружающий контейнер, и это тот тип дублирования, который я определенно хочу избежать. – koszek

+0

Я думаю, вы все равно можете достичь того, чего хотите, с границей, хотя и немного по-другому. Я отредактирую свой ответ, чтобы показать, что я имею в виду. – WiseTree