Статьи

JSF Simple Ajax Samples

Сегодня мы увидим несколько простых примеров Ajax с JSF.

Если вы хотите увидеть другие публикации о JSF / веб-приложениях, нажмите на следующие ссылки: JSF, сохраняющие объекты и сообщения после перенаправления , проверка входа пользователя в систему с помощью JAAS и JSF , JSF: AutoComplete конвертера и компонента , JSF — Hello World, Auto Complete , Обработка исключений в WebApp , аутентификация пользователя (фильтр / сервлет) , создание веб-сервера .

В конце этого поста вы найдете ссылку для скачивания исходного кода примеров. В этом посте ( Проверка логина пользователя с помощью JAAS и JSF ) я покажу, как установить JBoss 6 на тот случай, если вы захотите запустить проект с сегодняшнего дня. Вам нужно будет установить плагин JBoss tools в Eclipse.

Посмотрите на страницу ниже и ее код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<h:head>
</h:head>
<h:body>
 <h:form>
  Your Name: <h:inputText id='inputname' label='${msgs.prompt}' value='#{user.name}'/>
  <br />
  <h:commandButton action='#{user.sayHello}' value='Display my name here, now!'/>
  <br />
 </h:form>
</h:body>
</html>

Как мы можем отобразить напечатанное имя на том же экране, используя Ajax? Кусок пирога, просто добавьте компонент «f: ajax». Проверьте обновление кода и результат:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<h:head>
</h:head>
<h:body>
 <h:form>
  Your Name: <h:inputText id='inputname' label='${msgs.prompt}' value='#{user.name}'/>
  <br />
  <h:commandButton action='#{user.sayHello}' value='Display my name here, now!'>
   <f:ajax render='myName' execute='inputname' />
  </h:commandButton>
  <br />
  <br />
  <h:outputText id='myName' value='#{user.name}' />
 </h:form>
</h:body>
</html>

Это очень легко, верно? Нам просто нужно передать значение, которое будет передано ManagedBean параметром «execute»; с помощью параметра «render» мы сообщим JSF, какой компонент будет «обновлен».

Также обратите внимание, что введенное имя появляется в консоли.

С помощью этого кода мы можем «обновить» все виды компонентов. Давайте посмотрим на другой образец?

Давайте выведем сообщение об ошибке, если пользователь вводит имя длиной менее 4 символов.

Проверьте наше новое сообщение и новый код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<h:head>
</h:head>
<h:body>
 <h:form>
  <h:messages id='myMessage' globalOnly='true' showDetail='true'/>
  Your Name: <h:inputText id='inputname' label='${msgs.prompt}' value='#{user.name}'/>
  <br />
  <h:commandButton action='#{user.sayHello}' value='Display my name here, now!'>
   <f:ajax render='myName myMessage' execute='inputname' />
  </h:commandButton>
  <br />
  <br />
  <h:outputText id='myName' value='#{user.name}' />
 </h:form>
</h:body>
</html>
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package demo;
 
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
 
/**
 * Created by JBoss Tools
 */
@ManagedBean(name = 'user')
@RequestScoped
public class User {
 
 private String name;
 
 public String sayHello() {
  if (isNameIncorrect()) {
   FacesContext context = FacesContext.getCurrentInstance();
   context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, 'Too small', 'Can you write it a little bigger?'));
  }
 
  System.out.println(name);
  return null;
 }
 
 private boolean isNameIncorrect() {
  return ''.equals(name.trim()) || name.length() < 3;
 }
 
 public String getName() {
  return name;
 }
 
 public void setName(String name) {
  this.name = name;
 }
}

Обратите внимание, что у нас есть компонент «h: messages», а его идентификатор используется в компоненте «f: ajax». Этот код также работает, когда вы используете компонент « h: message for =« YYY » ».

Что если мы сейчас будем работать с комбинированными списками? Давайте покажем комбинированный список, который будет содержать 4 элемента, когда у нас есть имя, содержащее менее 6 символов, и список, содержащий более 4 элементов, если набранное имя содержит более 6 символов.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package demo;
 
import java.util.ArrayList;
import java.util.List;
 
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UISelectItems;
import javax.faces.component.html.HtmlSelectOneMenu;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;
 
/**
 * Created by JBoss Tools
 */
@ManagedBean(name = 'user')
@RequestScoped
public class User {
 
 private String name;
 
 private List<String> cars;
 
 private String selectedCar;
 private HtmlSelectOneMenu htmlSelectCars;
 
 private static final String SELECT_A_CAR = 'Select One Car';
 
 public User() {
  cars = new ArrayList<String>();
 }
 
 public String sayHello() {
  if (isNameInCorrect()) {
   FacesContext context = FacesContext.getCurrentInstance();
   context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, 'Too small', 'Can you write it a little bigger?'));
  }
 
  System.out.println(name);
  return null;
 }
 
 private boolean isNameInCorrect() {
  return name == null || ''.equals(name.trim()) || name.length() < 3;
 }
 
 public String getName() {
  return name;
 }
 
 public void setName(String name) {
  this.name = name;
 }
 
 public void editMyCarsList(AjaxBehaviorEvent event) {
  if (htmlSelectCars == null) {
   htmlSelectCars = new HtmlSelectOneMenu();
  }
 
  htmlSelectCars.getChildren().clear();
 
  UISelectItems items = new UISelectItems();
  items.setValue(getCars());
  htmlSelectCars.getChildren().add(items);
 }
 
 public List<String> getCars() {
  cars.clear();
 
  cars.add(SELECT_A_CAR);
 
  if (!isNameInCorrect() && name.length() >= 6) {
   cars.add('Ferrari');
   cars.add('Porch');
   cars.add('Beetle');
   cars.add('Opala');
   cars.add('Passat');
   cars.add('Vectra');
   cars.add('Chevet');
   cars.add('Corvet');
  } else {
   cars.add('Ferrari');
   cars.add('Porch');
   cars.add('Beetle');
   cars.add('Opala');
  }
 
  return cars;
 }
 
 public void setCars(List<String> cars) {
  this.cars = cars;
 }
 
 public String getSelectedCar() {
  return selectedCar;
 }
 
 public void setSelectedCar(String selectedCar) {
  this.selectedCar = selectedCar;
 }
 
 public HtmlSelectOneMenu getHtmlSelectCars() {
  editMyCarsList(null);
 
  return htmlSelectCars;
 }
 
 public void setHtmlSelectCars(HtmlSelectOneMenu htmlSelectCars) {
  this.htmlSelectCars = htmlSelectCars;
 }
}

Взгляните сейчас на нашу страницу:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<h:head>
</h:head>
<h:body>
 <h:form>
  <h:messages id='myMessage' globalOnly='true' showDetail='true' />
  Your Name: <h:inputText id='inputname' label='${msgs.prompt}' value='#{user.name}' />
  <br />
  <h:commandButton action='#{user.sayHello}' value='Display my name here, now!'>
   <f:ajax render='myName myCars myMessage' execute='inputname' listener='#{user.editMyCarsList}' />
  </h:commandButton>
  <br />
  <br />
  <h:outputText id='myName' value='#{user.name}' />
  <br />
  <br />
  Choose your car: <h:selectOneMenu id='myCars' binding='#{user.htmlSelectCars}' value='#{user.selectedCar}' />
  <br />
  <br />
 </h:form>
</h:body>
</html>

Обратите внимание, что размер наших элементов списка обновляется в соответствии с введенным именем. В конце этой статьи я расскажу больше о том, почему я использовал атрибут привязки к HtmlSelectOneMenu, а не возвращал List <String>.

В качестве нашего последнего примера, давайте создадим комбинированный список, который будет появляться и исчезать в соответствии с выбранным значением в автомобильном списке.

Взгляните на наш ManagedBean:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package demo;
 
import java.util.ArrayList;
import java.util.List;
 
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UISelectItems;
import javax.faces.component.html.HtmlSelectOneMenu;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;
 
/**
 * Created by JBoss Tools
 */
@ManagedBean(name = 'user')
@RequestScoped
public class User {
 
 private String name;
 
 private List<String> cars;
 private List<String> colors;
 
 private String selectedCar;
 private String selectedColor;
 private HtmlSelectOneMenu htmlSelectCars;
 
 private static final String SELECT_A_CAR = 'Select One Car';
 
 public User() {
  cars = new ArrayList<String>();
  colors = new ArrayList<String>();
 
  colors.add('Red');
  colors.add('Blue');
  colors.add('Orange');
  colors.add('Pink --> O.o');
 }
 
 public String sayHello() {
  if (isNameInCorrect()) {
   FacesContext context = FacesContext.getCurrentInstance();
   context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, 'Too small', 'Can you write it a little bigger?'));
  }
 
  System.out.println(name);
  return null;
 }
 
 private boolean isNameInCorrect() {
  return name == null || ''.equals(name.trim()) || name.length() < 3;
 }
 
 public String getName() {
  return name;
 }
 
 public void setName(String name) {
  this.name = name;
 }
 
 public void editMyCarsList(AjaxBehaviorEvent event) {
  if (htmlSelectCars == null) {
   htmlSelectCars = new HtmlSelectOneMenu();
  }
 
  htmlSelectCars.getChildren().clear();
 
  UISelectItems items = new UISelectItems();
  items.setValue(getCars());
  htmlSelectCars.getChildren().add(items);
 }
 
 public List<String> getCars() {
  cars.clear();
 
  cars.add(SELECT_A_CAR);
 
  if (!isNameInCorrect() && name.length() >= 6) {
   cars.add('Ferrari');
   cars.add('Porch');
   cars.add('Beetle');
   cars.add('Opala');
   cars.add('Passat');
   cars.add('Vectra');
   cars.add('Chevet');
   cars.add('Corvet');
  } else {
   cars.add('Ferrari');
   cars.add('Porch');
   cars.add('Beetle');
   cars.add('Opala');
  }
 
  return cars;
 }
 
 public void setCars(List<String> cars) {
  this.cars = cars;
 }
 
 public String getSelectedCar() {
  return selectedCar;
 }
 
 public void setSelectedCar(String selectedCar) {
  this.selectedCar = selectedCar;
 }
 
 public List<String> getColors() {
  return colors;
 }
 
 public void setColors(List<String> colors) {
  this.colors = colors;
 }
 
 public boolean isColorsAlloweToDisplay() {
  if (isNameInCorrect()) {
   return false;
  }
 
  if (selectedCar == null || selectedCar.trim().equals('') || selectedCar.equals(SELECT_A_CAR)) {
   return false;
  }
 
  return true;
 }
 
 public String getSelectedColor() {
  return selectedColor;
 }
 
 public void setSelectedColor(String selectedColor) {
  this.selectedColor = selectedColor;
 }
 
 public HtmlSelectOneMenu getHtmlSelectCars() {
  editMyCarsList(null);
 
  return htmlSelectCars;
 }
 
 public void setHtmlSelectCars(HtmlSelectOneMenu htmlSelectCars) {
  this.htmlSelectCars = htmlSelectCars;
 }
}

Наш ManagedBean был слегка обновлен, мы просто добавили List с методом, который возвращает список цветов, которые будут заполнять наш комбинированный список; мы также добавили метод, который будет возвращать логическое значение — true, если разрешено отображение комбинированного списка.

Проверьте нашу новую страницу:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<h:head>
</h:head>
<h:body>
 <h:form>
  <h:messages id='myMessage' globalOnly='true' showDetail='true' />
  Your Name: <h:inputText id='inputname' label='${msgs.prompt}' value='#{user.name}' />
  <br />
  <h:commandButton action='#{user.sayHello}' value='Display my name here, now!'>
   <f:ajax render='myName myCars myMessage myColors' execute='inputname' listener='#{user.editMyCarsList}' />
  </h:commandButton>
  <br />
  <br />
  <h:outputText id='myName' value='#{user.name}' />
  <br />
  <br />
  Choose your car:
  <h:selectOneMenu id='myCars' binding='#{user.htmlSelectCars}' value='#{user.selectedCar}'>
   <f:ajax render='myColors' execute='inputname myCars'/>
  </h:selectOneMenu>
  <br />
  <br />
  <h:panelGroup id='myColors'>
   <h:selectOneMenu value='#{user.selectedColor}' rendered='#{user.colorsAlloweToDisplay}'>
    <f:selectItems value='#{user.colors}' />
   </h:selectOneMenu>
  </h:panelGroup>
 </h:form>
 </h:body>
</html>

Я расскажу о коде, используемом в посте:

  • HtmlSelectOneMenu — я использовал компонент вместо List, потому что JSF не очень хорош в рендеринге компонентов на экране пользователя (DOM Tree). Если ваш комбинированный список имеет 4 строки и, используя ajax, вы добавляете больше строк в список, JSF / Ajax не распознает новые добавленные строки; Вы сможете использовать только старые значения. Вместо этого вы можете попробовать использовать код со списком <String>, используя HtmlSelectOneMenu, и увидеть результат; Я трачу примерно 3-4 часа, чтобы понять это по многим поискам в Интернете.
  • HtmlSelectOneMenu внутри компонента «h: panelGroup» — я сделал это, потому что каждый раз, когда вы хотите визуализировать неотрисованный компонент, вам нужно обновлять его контейнер. Если бы наш selectOne находился внутри той же формы автомобиля, что и selectOne, вам нужно было бы отобразить всю форму.

Нажмите здесь, чтобы загрузить код из этого поста .

Я надеюсь, что этот пост может помочь вам.

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

Ссылка: JSF Simple Ajax Образцы от нашего партнера JCG Хеберта Коэльо в блоге uaiHebert .