У меня есть таблица данных, представленная ui:repeat. Поскольку я хочу, чтобы пользователь мог изменять данные для каждой строки, каждая строка заключена в форму h:. Наконец, у каждой формы h: есть кнопка с тегом f: ajax. Я получаю дико непоследовательное поведение.
<ui:repeat value="#{importManager.items}" var="item" varStatus="status">
<h:form>
<tr>
<td>
<h:outputText value="#{status.index}"/>
</td>
<td>
<h:inputText id="title" value="#{item.title}" styleClass="#{item.validTitle ? 'valid' : 'invalid'}"/>
</td>
<td>
<h:inputText id="artist" value="#{item.artist}" styleClass="#{item.validArtist ? 'valid' : 'invalid'}"/>
</td>
<td>
<h:commandButton value="#{importMessages.submit}">
<f:ajax execute="@form" render="@all" listener="#{importManager.publish(item)}"/>
</h:commandButton>
</td>
</tr>
</h:form>
</ui:repeat>
Вышеупомянутое работает, но, очевидно, недешево по пропускной способности.
Если я изменю render="@all" на render="@form", Firebug показывает, что частичный ответ был отправлен нормально, но мой браузер (Firefox) таинственным образом не отображает его. Итак, я предполагаю, что он (браузер) не находит элемент для обновления?
Если я изменяю execute="@form" на execute="@all", я получаю очень странное поведение, а именно, данные теряются, а затронутые поля становятся пустыми.
Поддерживающий компонент довольно прост:
public void publish(final Item item)
{
Set<ConstraintViolation<Item>> violations = item.validate();
if (violations.isEmpty())
{
temporaryRegistry.deleteItem(item);
registry.storeItem(item);
}
else
{
// Display error messages
}
}
И модель:
@Entity
public class Item implements Cloneable
{
@Id @GeneratedValue
private long identifier;
@NotNull(groups={Warning.class})
@Length(min=1, max=80, groups={Warning.class})
private String title;
@NotNull(groups={Warning.class})
@Length(min=1, max=80, groups={Warning.class})
private String artist;
@NotNull(groups={Warning.class})
@Length(min=1, max=10, groups={Warning.class})
private String media;
@NotNull(groups={Warning.class})
@Length(min=1, max=5, groups={Warning.class})
@Column(name = "_condition")
private String condition;
// Setters and Getters
public boolean isValidTitle()
{
final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
final Validator validator = factory.getValidator();
final Set<ConstraintViolation<Item>> violations = validator.validateProperty(this, "title", Warning.class);
return violations.isEmpty();
}
public boolean isValidCondition()
{
final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
final Validator validator = factory.getValidator();
final Set<ConstraintViolation<Item>> violations = validator.validateProperty(this, "condition", Warning.class);
return violations.isEmpty();
}
public boolean isValidArtist()
{
final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
final Validator validator = factory.getValidator();
final Set<ConstraintViolation<Item>> violations = validator.validateProperty(this, "artist", Warning.class);
return violations.isEmpty();
}
@Override
public boolean equals(final Object object)
{
return (object instanceof Item) && (object != null) && (((Item) object).getIdentifier() == identifier);
}
@Override
public int hashCode()
{
return Long.valueOf(identifier).hashCode();
}
public Set<ConstraintViolation<Item>> validate()
{
final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
final Validator validator = factory.getValidator();
return validator.validate(this, Warning.class);
}
}
Может ли кто-нибудь объяснить это, и есть ли у кого-нибудь способ отправить форму и форму только с помощью ajax и отобразить результат?