Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > JSF 1.2 findComponent()


Автор: Fedrus 10.10.2007, 10:57
Всем добрый день!
Не ругайте сильно если что - начинающий программист smile  (Если не очень удачьно изложил проблему спрашивайте)
Напишу код потом проблемма.
Страница :
Код

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="/WEB-INF/regexp-validator.tld" prefix="val"%>

<f:subview id= "module">
    <h:messages />

    <h:panelGrid id = "pg1" rendered="#{iControl.actionShowAdd}">
        <h:form id = "addUserForm" >
            <h:panelGrid id = "PG2" columns="2" cellpadding="4" cellspacing="2"
                styleClass="formBase" headerClass="formHeader"
                footerClass="formFooter" rowClasses="formRow">
                <f:facet name="header">
                    <h:outputText value="Add user" />
                </f:facet>
                <f:facet name="footer">
                    <h:commandButton action="#{user.addAction}" value="Add!" />
                </f:facet>
                <h:outputText value="External ID" />
                <h:inputText id="extId" value="#{user.user.extId}" size="10"
                    maxlength="20">
                    <val:regexValidator regex="[0-9]*" message="Invalid ID"></val:regexValidator>
                </h:inputText>
                <h:outputText value="User Group" />
                <h:selectOneMenu value="#{user.userGroupId}"
                    converter="LongConverter" required="true" requiredMessage="User Group is required.">
                    <f:selectItems value="#{userGroup.userGroupSelectItems}" />
                </h:selectOneMenu>
                <h:outputText value="Lastname" />
                <h:inputText id="lastname" value="#{user.user.sLastname}" size="50"
                    maxlength="50" required="true"
                    requiredMessage="Lastname is required.">
                    <val:regexValidator regex="[a-zA-Z]*" message="Invalid Lastname."></val:regexValidator>
                    <f:converter converterId="NameConverter" />
                </h:inputText>
                <h:outputText value="Firstname" />
                <h:inputText id="firstname" value="#{user.user.sFirstname}"
                    size="50" maxlength="50" required="true"
                    requiredMessage="Firstname is required.">
                    <val:regexValidator regex="[A-Za-z]*" message="Invalid ID"></val:regexValidator>
                    <f:converter converterId="NameConverter" />
                </h:inputText>
                <h:outputText value="Secondname" />
                <h:inputText id="secondname" value="#{user.user.sSecondname}"
                    size="50" maxlength="50">
                    <val:regexValidator regex="[A-Za-z]*" message="SecondName field"
                        useTpl="true"></val:regexValidator>
                    <f:converter converterId="NameConverter" />
                </h:inputText>
                <h:outputText value="Login" />
                <h:inputText id="login" value="#{user.user.login}" size="50"
                    maxlength="50">
                    <val:regexValidator regex="[a-z0-9]{3,10}"
                        message="Login is invalid."></val:regexValidator>
                </h:inputText>
                <h:outputText value="Password" />
                <h:inputSecret id="password" value="#{user.user.password}" size="50"
                    maxlength="50" required="true"
                    requiredMessage="Password is required.">
                    <val:regexValidator regex="[a-zA-Z0-9]{3,50}"
                        message="Invalid password."></val:regexValidator>
                </h:inputSecret>
            </h:panelGrid>
        </h:form>
    </h:panelGrid>

    <h:dataTable value='#{user.users}' var='item' border="1"
        cellpadding="2" cellspacing="0" id="listUser">
        <h:column>
            <f:facet name="header">
                <h:outputText value="Id" />
            </f:facet>
            <h:outputText value="#{item.id}" />
        </h:column>
        <h:column>
            <f:facet name="header">
                <h:outputText value="login" />
            </f:facet>
            <h:outputText value="#{item.login}" />
        </h:column>

    </h:dataTable>

    <h:form>
        <h:commandLink action="#{iControl.doShowAdd}" value="add user"></h:commandLink>
    </h:form>
    <h:form>
        <h:commandLink action="#{user.clearForm}" value="clear form"></h:commandLink>
    </h:form>

</f:subview>



B так здесь есть форма при нажатии ссылки add user открывается форма для заполнения инфо о юзере мы вводим значения в инпут поля пото нажимаем кнопку add! и не зависимо от результата добавился юзер или нет в инпут полях остаются значения это ничего но вот хотелось чтоб при нажатии на ссылка add user форма очищалась но это не так! (бин хранится в request scope)
И так зделал для начало отельную ссылку очистка формы она вызывает метод clearForm тут начинается самое интересное.
Сейчас findComponent("module") находит subview по id а мне нужно то чтоб он находил форму по id = addUserForm и тогда можно чистить все компоенты(вроде должно получиться) Но вот проблемма!!!: он не находит форму ни так findComponent("addUserForm") не так 
findComponent("module:addUserForm") ДОБАВИЛ блин пробовал и различные вариации с поиском h:panelGrid тоже не помогло.
Есть у кого какие соображения по этому поводу?? (возможно есть другие способы очистки формы?? и более легкие??)

Автор: ivg 10.10.2007, 11:57
Цитата

Есть у кого какие соображения по этому поводу?? (возможно есть другие способы очистки формы?? и более легкие??)

В коде бина user:
Код

public String addAction() {
  .....
  // Если user успешно добавлен
  this.user = new User();
}

Автор: Fedrus 10.10.2007, 12:28
Дело в том что если заполнить не все поля, а скажем Lastname , так как у меня есть другие required поля то в addAction не заходит.
А в поле Lastname остается значение, оно пропадает если перейти на другой модуль а потом обратно но надо чтоб оставаясь на этом модуле это поле очищалось нажатеем кнопки ссылки.
Вообще у меня есть задача сделать очистку формы но добавление юзеров пока не работает.
вот полный код бинов:
#{user} = userController:
Код

package controller;

import java.util.Iterator;
import java.util.List;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import org.hibernate.*;
import util.*;
import model.*;

public class UserController {
    // private String action = null;
    private User user = new User();

    public UserController() {
    }

    public void setUser(User user) {
        this.user = user;
    }

    public User getUser() {
        return this.user;
    }

    public void setUserGroupId(Long userGroupId) {
        Session session = null;
        Transaction tx = null;
        UserGroup userGroup = null;
        try {
            session = HibernateSessionFactory.getSession();
            List recordList = session.createQuery(
                    "from UserGroup as u where u.id=?").setLong(0,
                    userGroupId.longValue()).list();
            userGroup = (UserGroup) recordList.get(0);
            this.user.setUserGroup(userGroup);
        } catch (Exception e) {
            tx.rollback();
            FacesUtil.addErrorMessage(e.getLocalizedMessage());
        } finally {
            tx.commit();
            // session.close();
        }
    }

    public Long getUserGroupId() {
        long returnValue = 0;
        UserGroup userGroup = null;
        try {
            userGroup = this.user.getUserGroup();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (userGroup != null) {
            returnValue = userGroup.getId();
        }
        return new Long(returnValue);
    }

    public DataModel getUsers() {
        Session session = null;
        Transaction tx = null;
        ListDataModel listDataModel = null;
        try {
            session = HibernateSessionFactory.getSession();
            tx = session.beginTransaction();
            Query theQuery = session
                    .createQuery("from User as m order by m.sFirstname asc");
            listDataModel = new ListDataModel(theQuery.list());
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
            FacesUtil.addErrorMessage(e.getLocalizedMessage());
        } finally {
            session.close();
        }
        return listDataModel;
    }

    public String addAction() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateSessionFactory.getSession();
            tx = session.beginTransaction();
            session.save(this.user);
            tx.commit();
            FacesUtil.addMessage("User was added.");
            // this.setAction("");
        } catch (Exception e) {
            tx.rollback();
            FacesUtil.addErrorMessage(e.getLocalizedMessage());
        } finally {
            session.close();
        }
        // setAction("add_action_success");
        return "";
    }

    public String clearForm() {
        UIComponent form = (UIComponent) FacesContext.getCurrentInstance()
                .getViewRoot().findComponent("addUserForm").findComponent("PG1").findComponent("module");
        Iterator it = form.getChildren().iterator();
        while (it.hasNext()) {
            UIComponent comp = (UIComponent) it.next();
            if (comp instanceof UIInput) {
                ((UIInput) comp).setValue(null);
            }
        }
        return "";
    }

    /*
     * public boolean isShowAddForm() { return this.action == null ? false :
     * this.action.equals("show_add") ? true : false; } // form action public
     * String showAdd() { //this.user=new User(); setAction("show_add"); return
     * ""; }
     * 
     * public void setAction(String action) { this.action = action; }
     * 
     * public String getAction() { return this.action; }
     */

}


user:
Код

package model;
// Generated 09.10.2007 18:04:22 by Hibernate Tools 3.2.0.b11


import java.util.Date;

/**
 * User generated by hbm2java
 */
public class User  implements java.io.Serializable {


     private long id;
     private UserGroup userGroup;
     private String extId;
     private String login;
     private String password;
     private String sFirstname;
     private String sSecondname;
     private String sLastname;
     private Date created;
     private Date updated;

    public User() {
    }

    
    public User(UserGroup userGroup) {
        this.userGroup = userGroup;
    }
    public User(UserGroup userGroup, String extId, String login, String password, String sFirstname, String sSecondname, String sLastname, Date created, Date updated) {
       this.userGroup = userGroup;
       this.extId = extId;
       this.login = login;
       this.password = password;
       this.sFirstname = sFirstname;
       this.sSecondname = sSecondname;
       this.sLastname = sLastname;
       this.created = created;
       this.updated = updated;
    }
   
    public long getId() {
        return this.id;
    }
    
    public void setId(long id) {
        this.id = id;
    }
    public UserGroup getUserGroup() {
        return this.userGroup;
    }
    
    public void setUserGroup(UserGroup userGroup) {
        this.userGroup = userGroup;
    }
    public String getExtId() {
        return this.extId;
    }
    
    public void setExtId(String extId) {
        this.extId = extId;
    }
    public String getLogin() {
        return this.login;
    }
    
    public void setLogin(String login) {
        this.login = login;
    }
    public String getPassword() {
        return this.password;
    }
    
    public void setPassword(String password) {
        this.password = password;
    }
    public String getsFirstname() {
        return this.sFirstname;
    }
    
    public void setsFirstname(String sFirstname) {
        this.sFirstname = sFirstname;
    }
    public String getsSecondname() {
        return this.sSecondname;
    }
    
    public void setsSecondname(String sSecondname) {
        this.sSecondname = sSecondname;
    }
    public String getsLastname() {
        return this.sLastname;
    }
    
    public void setsLastname(String sLastname) {
        this.sLastname = sLastname;
    }
    public Date getCreated() {
        return this.created;
    }
    
    public void setCreated(Date created) {
        this.created = created;
    }
    public Date getUpdated() {
        return this.updated;
    }
    
    public void setUpdated(Date updated) {
        this.updated = updated;
    }




}






Если всетаки проблемма связанна с неработающим добавлением юзера то объясните как?
Спасибо ivg за вариант но думаю ты не совсем понял в чем проблема.
Жду еще советов и предложений. Заранее спасибо.

Автор: Fedrus 10.10.2007, 13:57
А  (UIComponent) FacesContext.getCurrentInstance().getViewRoot().findComponent("module"); возвращает UINamingContainer 
я совсем нуб подскажите плз как мне отобразить все это дерево на экране??

Автор: ivg 10.10.2007, 14:12
Цитата

Дело в том что если заполнить не все поля, а скажем Lastname , так как у меня есть другие required поля то в addAction не заходит.
А в поле Lastname остается значение, оно пропадает если перейти на другой модуль а потом обратно но надо чтоб оставаясь на этом модуле это поле очищалось нажатеем кнопки ссылки.
Вообще у меня есть задача сделать очистку формы


1.Не заходит, потому что в этом случае валидация не проходит, и тогда сразу идёт Рендеринг. Фаза INVOKE_APPLICATION пропускается, а именно на ней, в данном случае происходит вызов clearForm();
Если стоит задача сделать очистку формы в любом случае, то тогда у ссылки нужно поставить атрибут immediate="true":
Код

<h:commandLink action="#{user.clearForm}" value="clear form" immediate="true"></h:commandLink>

Тогда clearForm() будет вызвана до фазы валидации.

2.По поводу самой функции clearForm(): во первых она должна быть рекурсивной:
Код

public String clearForm() {
  UIComponent form = (UIComponent) FacesContext.getCurrentInstance()
    .getViewRoot().findComponent("PG1"+NamingContainer.SEPARATOR_CHAR+"addUserForm");
  this.clearUIInputs(form);
  return "";
}

private void clearUIInputs(UIComponent component) {
  if (!component.isRendered()) ;
    return;
  }
  if (component instanceof UIInput) {
    ((UIInput) component).setValue(null);
  }
  for (UIComponent child : component.getChildren()) {
    this.clearUIInputs(child);
  }
}

во вторых я бы точно не стал так заморачиваться а сделал бы как я уже написал:
Код

public String clearForm() {
  this.user = new User();
  return "";
}

Это самое простое решение, правда тут есть одно но: Бин user в RequestScope, и создавать новый объект, который по окончании запроса станет мусором, только для того чтобы отобразить пустые поля, как то не кошерно smile
Если бы он был SessionScope тогда это ИМХО было бы лучшим решением.
Так вот по этому поводу ещё один вариант (только для RequestScope):
Код

public String clearForm() {
  return "show_add";
}

Соответственно гдето в faces-config.xml
Код

     <navigation-case>
        <from-outcome>show_add</from-outcome>
        <to-view-id>/addUser.jsf</to-view-id>
        <redirect />
     </navigation-case>

где addUser.jsf - View указанный ранее.

Вот, выбирай  smile 

Автор: Fedrus 10.10.2007, 15:09
ДАААА вот это да а я и не подумал
 this.user = new User();
в clianForm добавить спасибо большое! (не успел обрадоваться как попробывал и опять 25)
Теперь я попробовал три варианта второй и третий не работают(((
Первый на выполнении UIComponent form = (UIComponent) FacesContext.getCurrentInstance()
                .getViewRoot().findComponent(
                        "PG1" + NamingContainer.SEPARATOR_CHAR + "addUserForm");
выбрасывает ошибку java.lang.IllegalArgumentException: PG1
Код


javax.servlet.ServletException: #{user.clearForm}: java.lang.IllegalArgumentException: PG1
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:256)
    backend.NavigationFilter.doFilter(NavigationFilter.java:60)
    org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)

root cause

javax.faces.FacesException: #{user.clearForm}: java.lang.IllegalArgumentException: PG1
    com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:107)
    javax.faces.component.UICommand.broadcast(UICommand.java:383)
    javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:447)
    javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:752)
    com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:97)
    com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:251)
    com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:117)
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:244)
    backend.NavigationFilter.doFilter(NavigationFilter.java:60)
    org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)

root cause

javax.faces.el.EvaluationException: java.lang.IllegalArgumentException: PG1
    javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:91)
    com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:91)
    javax.faces.component.UICommand.broadcast(UICommand.java:383)
    javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:447)
    javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:752)
    com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:97)
    com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:251)
    com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:117)
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:244)
    backend.NavigationFilter.doFilter(NavigationFilter.java:60)
    org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)

root cause

java.lang.IllegalArgumentException: PG1
    javax.faces.component.UIComponentBase.findComponent(UIComponentBase.java:588)
    controller.UserController.clearForm(UserController.java:109)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    java.lang.reflect.Method.invoke(Method.java:585)
    org.apache.el.parser.AstValue.invoke(AstValue.java:131)
    org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
    org.apache.jasper.el.JspMethodExpression.invoke(JspMethodExpression.java:68)
    javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:77)
    com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:91)
    javax.faces.component.UICommand.broadcast(UICommand.java:383)
    javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:447)
    javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:752)
    com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:97)
    com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:251)
    com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:117)
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:244)
    backend.NavigationFilter.doFilter(NavigationFilter.java:60)
    org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)



вот так вот (((

Странно но у меня findComponent находит только <f:subview id= "module"> а при поиске PG1 или других элементов null((
Должно быть по другому?? 

Автор: ivg 10.10.2007, 16:15
Цитата

Странно но у меня findComponent находит только <f:subview id= "module"> а при поиске PG1 или других элементов null((
Должно быть по другому?? 

Эт я затупил  smile ("PG1" - тут вообще не к месту, во первых регистр имеет значение, а там "pg1", а во вторых ПанельГрид не добавляет свой id дочерним элементам)
если findComponent("module") находит, то должен находить форму по findComponent("module" + NamingContainer.SEPARATOR_CHAR + "addUserForm");
Вот это странно, посмотри на клиенте (в браузере) у этой формы какой id?

Автор: Fedrus 10.10.2007, 16:48
(про регистр я тоже заметил)
УРААА! Все заработало вот так findComponent("module" + NamingContainer.SEPARATOR_CHAR + "module:addUserForm");
id на странице выглядит module:module:addUserForm(это из-за того что у нас ипрорты) вот и добавил module:)))
Спасибо огромное ivg !! Надо было сразу посмотреть.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)