Создание основной таблицы и диалогового окна, как использовать один и тот же диалог для создания и редактирования

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

Следуя примеру из демонстрации простых лиц для версии 5.2, я могу представить данные в форме только для чтения outputText, однако, когда я изменяю их на inputText, поле остается пустым. Следующий код является примером того, что у меня есть:

<h:form id="form">    
  <p:dataGrid id="guestList" var="guest" value="${guestList.guests}" columns="3" paginator="true" rows="20">
    <f:facet name="header">
      Guest List
    </f:facet>

    <p:panel>
      <h:outputText value="${guest.name}" />
      <br />
      <h:outputText value="${guest.street}" />
      <br />
      <h:outputText rendered="#{guest.street2.length() gt 0}"
        value="${guest.street2}" />
      <h:panelGroup rendered="#{guest.street2.length() gt 0}">
        <br />
      </h:panelGroup>
      <h:outputText value="${guest.city}, " />
      <h:outputText value="${guest.state} " />
      <h:outputText value="${guest.zipCode}" />
      <p:commandButton update="@form:newGuestDetail" oncomplete="PF('newGuestDialog').show()" icon="ui-icon-edit" styleClass="ui-btn-inline">
        <h:outputText styleClass="ui-icon ui-icon-edit" style="margin:0 auto;" />
        <f:setPropertyActionListener value="#{guest}" target="#{guestList.selectedGuest}" />
      </p:commandButton>
    </p:panel>
  </p:dataGrid>

  <p:dialog header="#{guestList.hasSelected() ? 'Edit Guest' : 'New Guest'}" widgetVar="newGuestDialog" modal="true" showEffect="fade" hideEffect="fade">
    <p:outputPanel id="newGuestDetail">
      <h:outputText value="'#{guestList.selectedGuest.name}'"/>
      <p:inputText id="guestName" value="#{guestList.hasSelected() ? '' : guestList.selectedGuest.name}" pt:placeholder="Name"/>
      <p:commandButton value="#{guestList.selectedGuest == null ? 'Create Guest' : 'Update Guest'}"/>
    </p:outputPanel>
  </p:dialog>
</h:form>

Метод hasSelected() оценивает, является ли выбранный гость нулевым или нет, и возвращает true, если не ноль. SelectedGuest должен быть установлен при нажатии commandButton, чтобы объект был доступен для извлечения в диалоговом окне, однако, с помощью трассировщиков в get / set для selectedGuest, я не вижу setter, вызываемый с помощью приведенного выше фрагмента. Если я удалю inputTextтогда, хотя hasSelected все еще возвращает false, и, таким образом, "Новый гость" возглавляет диалог, outputText заполнен значением.

Я обнаружил, что этот замечательный пост рассказывает о порядке выполнения в отношении действия, прослушивателя действия и т. Д., Но не думаю, что это моя проблема: различия между action и actionListener.

Итак, главный вопрос: почему мой сеттер вызывается с помощью командной кнопки, когда у меня есть только outputText, но с inputText я никогда не вижу, чтобы он вызывался в журнале?

Я ценю время и помогаю каждому.

1 ответ

Решение

Даже если мы решим вашу проблему, эта конструкция

<p:inputText value="#{guestList.hasSelected() ? '' : guestList.selectedGuest.name}">

никогда не будет работать. Он должен ссылаться на свойство модели, а не на пустую строку.

Лучше всего просто повторно использовать форму редактирования и позволить кнопке создания создать пустую сущность. Это сильно упростит вид сбоку. Было бы проще, если бы у @Id свойство, которое присутствует только тогда, когда оно сохраняется в базе данных.

Вот начальный пример:

<h:form id="entitiesForm">
    <p:dataTable id="entitiesTable" value="#{bean.entities}" var="entity">
        <p:column>#{entity.foo}</p:column>
        <p:column>#{entity.bar}</p:column>
        <p:column>
            <p:commandButton id="edit" value="Edit" 
                process="@this" action="#{bean.edit(entity)}"
                update=":entityDialog" oncomplete="PF('entityDialog').show()" />
            <p:commandButton id="delete" value="Delete" 
                process="@this" action="#{bean.delete(entity)}"
                update=":entitiesForm:entitiesTable" />
        </p:column>
    </p:dataTable>
    <p:commandButton id="add" value="Add" 
        process="@this" action="#{bean.add}" 
        update=":entityDialog" oncomplete="PF('entityDialog').show()" />
</h:form>

<p:dialog id="entityDialog" widgetVar="entityDialog" 
    header="#{empty bean.entity.id ? 'New' : 'Edit'} entity">
    <h:form id="entityForm">
        <p:inputText id="foo" value="#{bean.entity.foo}" />
        <p:inputText id="bar" value="#{bean.entity.bar}" />
        <p:commandButton id="save" value="#{empty bean.entity.id ? 'Create' : 'Update'} entity" 
            process="@form" action="#{bean.save}"
            update=":entitiesForm:entitiesTable" oncomplete="PF('entityDialog').hide()" />
    </h:form>
</p:dialog>

С этим @ViewScoped боб:

private List<Entity> entities; // +getter
private Entity entity; // +getter

@EJB
private EntityService entityService;

@PostConstruct
public void load() {
    entities = entityService.list();
    entity = null;
}

public void add() {
    entity = new Entity();
}

public void edit(Entity entity) {
    this.entity = entity;
}

public void save() {
    entityService.save(entity); // if (id==null) em.persist() else em.merge()
    load();
}

public void delete(Entity entity) {
    entityService.delete(entity); // em.remove(em.find(type, id))
    load();
}

Смотрите также:

Другие вопросы по тегам