In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-30 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article is about how to achieve reusable Ajaxized components through JSF 2. I think it is very practical, so I share it with you. I hope you can get something after reading this article. Let's take a look at it.
I'll show you how to implement the autocomplete component, which uses Ajax to manage its completion list.
JSF automatically completes custom components
The autocomplete field (also known as the suggestion box), known as the Google search field, is a combination of many Web applications. They are also typical applications of Ajax. The autocomplete field comes with a number of Ajax frameworks, such as Scriptaculous and JQuery, as shown in figure 1-AjaxDaddy autocomplete component integration (see Resources):
Figure 1.AjaxDaddy autocomplete components
This article discusses how to use JSF to implement autocomplete fields that support Ajax. You will learn how to implement the autocomplete field shown in figure 2, where a short list of virtual countries is displayed (selected from Wikipedia's "Virtual country list" article; see Resources):
Figure 2. Auto-complete field
Figures 3 and 4 show the running autocomplete fields. In figure 3, after entering Al in the field, the list of countries shrinks to names that begin with these two letters:
Figure 3. Use the completion project at the beginning of Al
Again, figure 4 shows the results displayed after entering Bar in the field. The list shows only the names of countries that begin with Bar.
Figure 4. Completed projects that begin with Bar
Use autocomplete components
Composite components: basics if you are not familiar with how to implement JSF2 composite components, you can learn the basics from the article "introduction to JSF2, part 2: templates and composite components."
The .locations autocomplete field is a JSF composite component and applies to facelet, as shown in listing 1:
List 1.facelet
# {msgs.autoCompleteWindowTitle} # {msgs.locationsPrompt}
The facelet in listing 1 uses the autoComplete composite component by declaring the appropriate namespace-util- and with the help of the component's associated tags ().
Notice the two attributes of the tag in listing 1:
Value is the country attribute of a managed bean named user.
CompletionItems is the initial set of completed projects for the field.
The User class is a simple managed bean designed specifically for this example. The code is shown in listing 2:
Listing the 2.User class
Package com.corejsf; import java.io.Serializable; import javax.inject.Named; import javax.enterprise.context.SessionScoped; @ Named () @ SessionScoped public class User implements Serializable {private String country; public String getCountry () {return country;} public void setCountry (String country) {this.country = country;}}
Notice the @ Named annotation, which, together with @ SessionScoped, instantiates a managed bean named user and places it in the session scope the first time JSF encounters # {user.country} in facelet. The only # {user.country} reference in this application occurs in listing 1, where I specify the country property of the user managed bean as the value of the component.
Listing 3 shows the AutoComplete class, which defines the countries property, which is the list of completed projects for the autocomplete component:
Listing 3. Complete the project
Package com.corejsf; import java.io.Serializable; import javax.enterprise.context.ApplicationScoped; import javax.inject.Named @ Named @ ApplicationScoped public class AutoComplete implements Serializable {public String [] getLocations () {return new String [] {"Abari", "Absurdsvanj", "Adjikistan", "Afromacoland", "Agrabah", "Agaria", "Aijina", "Ajir", "Al-Alemand", "Al Amarja", "Alaine", "Albenistan", "Aldestan", "Al Hari", "Alpine Emirates" "Altruria", "Allied States of America", "BabaKiueria", "Babalstan", "Babar's Kingdom", "Backhairistan", "Bacteria", "Bahar", "Bahavia", "Bahkan", "Bakaslavia", "Balamkadar", "Baki", "Balinderry", "Balochistan", "Baltish", "Baltonia", "Bataniland, Republic of", "Bayview", "Banania" Republica de "," Bandrika "," Bangalia "," Bangstoff "," Bapetikosweti "," Baracq "," Baraza "," Barataria "," Barclay Islands "," Barringtonia "," Bay View "," Basenji ",} }}
The usage of the autocomplete component has been introduced. Now you will understand how it works.
How the auto-completion component works
The autocomplete component is a JSF2 composite component, so, like most composite components, it is implemented in the XHTML file. The component includes a text input and a list box, as well as some JavaScript code. Initially, the listbox style is display:none, and its purpose is to make the listbox invisible.
The autocomplete component responds to three events:
Keyup event in ◆ text input
Blur (out of focus) event in ◆ text input
Change (Select) event in the ◆ list box
When the user types in the text input, the autocomplete component calls the JavaScript function for each keyup event. This function, in conjunction with keyboard input events, periodically calls Ajax at intervals not greater than 350ms. Therefore, in response to the keyup event in the text input, the autocomplete component periodically makes Ajax calls to the server at intervals not greater than 350ms. (its purpose is to prevent the server from being flooded by a large number of Ajax calls during fast typing. In practice, combining events may be a little more frequent, but this is enough to demonstrate how to combine events in JavaScript, and this is a very practical tool. )
When the user selects an item from the list box, the autocomplete component makes another Ajax call to the server.
Both the text input and the list box come with listeners that do most of the meaningful work related to the server during the Ajax call. In response to the keyup event, the text-entered listener updates the list box's completed items. In response to the selection event of the list box, the listener copies the selected items of the list box to the text input and hides the list box.
Now you know how autocomplete components work. Next, let's take a look at its implementation.
Implement auto-complete components
The autocomplete component implementation includes the following artifacts:
A composite component of ◆
A series of JavaScript functions of ◆
◆ a value change listener for updating completed projects
I'll start with listing 4 to composite components:
Listing 4.autoComplete components
The implementation section of listing 4 accomplishes three tasks. First, the component makes an Ajax call in response to the keyup event in the text input and hides the list box when the text input is out of focus through the JavaScript function assigned to the keyup and blur events in the text input.
In fact, the component uses the tag of JSF2 to initiate an Ajax call in response to the change event in the list box. When the user selects from the list box, JSF makes an Ajax call to the server and updates the value of the text input when the Ajax call returns.
The composite component in listing 4 that encapsulates the composite component is implemented in through the client identifier of the composite component. This allows other components to reference the autocomplete component through their client ID. For example, another component might want to execute or render one or more autocomplete components during an Ajax call.
. Third, the corresponding value change listeners are attached to both the text input and the list box, so when JSF initiates an Ajax call in response to a user's typing in the text input, JSF invokes the value change listener for the text input on the server. When the user selects an item from the list box, JSF makes an Ajax call to the server and invokes the listener for the value change of the list box.
Listing 5 shows the JavaScript used by the autocomplete component:
List 5.JavaScript
If (! com) var com = {} if (! com.corejsf) {var focusLostTimeout com.corejsf = {errorHandler: function (data) {alert ("Error occurred during Ajax call:" + data.description)}, updateCompletionItems: function (input) Event) {var keystrokeTimeout jsf.ajax.addOnError (com.corejsf.errorHandler) var ajaxRequest = function () {jsf.ajax.request (input, event, {render: com.corejsf.getListboxId (input), x: Element.cumulativeOffset (input) [0] Y: Element.cumulativeOffset (input) [1] + Element.getHeight (input)})} window.clearTimeout (keystrokeTimeout) keystrokeTimeout = window.setTimeout (ajaxRequest, 350)} InputLostFocus: function (input) {var hideListbox = function () {Element.hide (com.corejsf.getListboxId (input))} focusLostTimeout = window.setTimeout (hideListbox, 200)}, getListboxId: function (input) {var clientId = new String (input.name) var lastIndex = clientId.lastIndexOf (':') return clientId.substring (0 LastIndex) +': listbox'}
The JavaScript in listing 5 includes three functions, which I put inside the com.corejsf namespace. I implemented a namespace (technically a JavaScript literal object) to prevent others from intentionally or unintentionally modifying my three functions.
If these functions are not included in the com.corejsf, others can implement their own updateCompletionItems functions, replacing my implementation with them. Some JavaScript libraries can implement a updateCompletionItems function, but ideally no one has to design com.corejsf.updateCompletionItems. (on the contrary, abandoning com and using corejsf.updateCompletionItems may be enough, but it can sometimes be difficult to control. )
So, what do these functions do? The updateCompletionItems () function makes an Ajax request to the server-by calling the jsf.ajax.request () function of JSF-requiring JSF to render the list box component only when the Ajax call returns. The updateCompletionItems () function also passes two additional parameters to jsf.ajax.request (): the x and y coordinates in the upper-left corner of the list box. The jsf.ajax.request () function converts these function parameters to the request parameters sent through the Ajax call.
JSF calls the inputLostFocus () function when the text input is out of focus. The function is used to hide the list box using the Element object of Prototype.
UpdateCompletionItems () and inputLostFocus () store their functionality in a function. They then arrange for their functions to be executed at 350ms and 200ms, respectively. In other words, each function has its own task, but it delays the task by 350ms or 200ms. Text input is delayed by keyup events, so the updateCompletionItems () method sends at most one Ajax request every other 350ms. The idea is that if the user's input speed is extremely fast, the server will not be flooded with Ajax calls.
The inputLostFocus function is called when the text input is out of focus and delays its task 200ms. This delay is necessary because the value is copied outside the list box when the Ajax call returns, and the list box must be visible to ensure that it works properly.
Finally, notice the getListBoxId () function. This helper function gets the client identifier of the list box from the client identifier entered in the text. This function does this because it will be combined with the autoComplete component in listing 4. The autoComplete component specifies input and listbox as the component identifiers for the text box and list box, respectively, so the getListBoxId () function removes the input and appends the listbox to get the client identifier for the text input.
Listing 6 shows the final implementation of the listener:
Listing 6. Listener
Package com.corejsf; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.enterprise.context.SessionScoped; import javax.faces.component.UIInput; import javax.faces.component.UISelectItems; import javax.faces.component.UISelectOne; import javax.faces.context.FacesContext; import javax.faces.event.ValueChangeEvent; import javax.inject.Named @ Named @ SessionScoped public class AutocompleteListener implements Serializable {private static String COMPLETION_ITEMS_ATTR = "corejsf.completionItems"; public void valueChanged (ValueChangeEvent e) {UIInput input = (UIInput) e.getSource (); UISelectOne listbox = (UISelectOne) input.findComponent ("listbox"); if (listbox! = null) {UISelectItems items = (UISelectItems) listbox.getChildren () .get (0); Map attrs = listbox.getAttributes () List newItems = getNewItems ((String) input.getValue (), getCompletionItems (listbox, items, attrs)); items.setValue (newItems.toArray ()); setListboxStyle (newItems.size (), attrs);} public void completionItemSelected (ValueChangeEvent e) {UISelectOne listbox = (UISelectOne) e.getSource (); UIInput input = (UIInput) listbox.findComponent ("input") If (input! = null) {input.setValue (listbox.getValue ());} Map attrs = listbox.getAttributes (); attrs.put ("style", "display: none");} private List getNewItems (String inputValue, String [] completionItems) {List newnewItems = new ArrayList () For (String item: completionItems) {String s = item.substring (0, inputValue.length ()); if (s.equalsIgnoreCase (inputValue)) newItems.add (item);} return newItems } private void setListboxStyle (int rows, Map attrs) {if (rows > 0) {Map reqParams = FacesContext.getCurrentInstance () .getExternalContext () .getRequestParameterMap (); attrs.put ("style", "display: inline; position: absolute; left:" + reqParams.get ("x") + "px" "+" top: "+ reqParams.get (" y ") +" px "); attrs.put (" size ", rows = = 1? 2: rows);} else attrs.put (" style "," display: none; ");} private String [] getCompletionItems (UISelectOne listbox, UISelectItems items, Map attrs) {Strings] completionItems = (String []) attrs.get (COMPLETION_ITEMS_ATTR) If (completionItems = = null) {completionItems = (String []) items.getValue (); attrs.put (COMPLETION_ITEMS_ATTR, completionItems);} return completionItems;}}
JSF calls the listener's valueChanged () method during the Ajax call in response to the keyup event in the text input. This method creates a new set of completed projects, and then sets the items in the list box to this new set of items. This method also sets the style property of the list box to determine whether the list box is displayed when the Ajax call returns.
The setListboxStyle () method in listing 6 will use x and y to request the parameter values I specified when I made the Ajax call in listing 5.
JSF calls the listener's other public method completionItemSelected () during the Ajax call in response to the selection event in the list box. This method copies the value of the list box to the text input and hides the list box.
Note that the valueChanged () method also stores the original completed item in a property of the list box. Because each autoComplete component maintains its own list of completed projects, multiple autoComplete components can coexist harmoniously on the same page without affecting each other's completed projects.
Run the sample using GlassFish and Eclipse
The code in this series is suitable for running in a JEE6 container, such as GlassFish or Resin. You can adapt them to the servlet container by adjusting them, but this is not ideal. Therefore, my goal is to focus on realizing the full potential of JSF2 and JEE6, rather than on configuration issues. I still insist on using GlassFishv3.
In the rest of this article, I'll show you how to use GlassFishv3 and Eclipse to run the sample code for this article. The instructions here also apply to the code for other articles in this series. I will use Eclipse3.4.1, so it is best to use a similar version. )
Figure 5 shows the directory structure of the code in this article. The autoComplete directory contains the application and an empty Eclipse workspace directory.
Figure 5. The source code of the download section of this article
Now that you have downloaded the code, you are ready to run it. First, you need the GlassFishEclipse plug-in, which you can download from https://glassfishplugins.dev.java.net, as shown in figure 6:
Figure 6.GlassFishEclipse plug-in
Follow the installation instructions for the plug-in.
To install the code for this article, create a DynamicWeb project in Eclipse. To do this, you can do this through the File > New menu: if you don't see DynamicWebProject, select Other, and in the following dialog box, open the Web folder and select DynamicWebProject, as shown in figure 7:
Figure 7. Create a DynamicWeb project
The next step is to configure the project. Make the following selections on the first page of the NewDynamicWebProject wizard, as shown in figure 8:
1. Under Projectcontents, leave the Usedefault box unchecked. In the Directory field, enter (or browse to) the autoComplete directory of the sample code.
two。 For TargetRuntime, select GlassFishv3JavaEE6.
3. For DynamicWebModuleversion, enter 2.5.
4. For Configuration, select DefaultConfigurationforGlassFishv3JavaEE6.
5. Under EARMembership, leave the AddprojecttoanEAR box unchecked and enter autoCompleteEAR in the EARProjectName: field.
Figure 8. Configure the application, step 1
Click Next, and enter the values shown in figure 9:
1. Enter autoComplete for ContextRoot:,.
two。 Enter web for ContentDirectory:,.
3. Enter src/java for JavaSourceDirectory:,. Leave the Generatedeploymentdescriptor box unchecked.
Figure 9. Configure the application, step 2
You should now have created an autoComplete project, which will be displayed in the ProjectExplorer view of Eclipse, as shown in figure 10:
Figure 10.autoComplete project
Now, select the project, right-click it, and select RunonServer, as shown in figure 11:
Figure 11. Use Eclipse to run on the server
Select GlassFishv3JavaEE6 from the list of servers in the RunOnServer dialog box, as shown in figure 12:
Figure 12. Select GlassFish
Click Finish. Eclipse should start the GlassFish and autoComplete applications one after another, as shown in figure 13:
13. Run in Eclipse
With JSF2, developers can easily create powerful custom components that support Ajax. You do not need to implement Java-based components or renderers in XML, or integrate third-party JavaScript to initiate Ajax calls. With JSF2, you only need to create a composite component with almost the same markup as any JSF2facelet view, and add some JavaScript or Java code as needed, and voil à-you will implement a wonderful custom component that provides application users with extremely convenient data entry capabilities.
The above is how to implement reusable Ajaxized components through JSF 2. The editor believes that there are some knowledge points that we may see or use in our daily work. I hope you can learn more from this article. For more details, please follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.