1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 package org.apache.myfaces.custom.globalId;
21
22 import javax.faces.component.NamingContainer;
23 import javax.faces.component.UIComponentBase;
24 import javax.faces.context.FacesContext;
25
26 /**
27 * A simple container-component that causes its child components to render a clientId value without
28 * any prefix.
29 * <p>
30 * Important: this component works only when run in a JSF-1.2 (or later) environment. When run in
31 * a JSF-1.1 environment it will not cause an error, but will instead act like a NamingContainer
32 * itself, ie will <i>add</i> its own id to the child component's clientId.
33 * </p>
34 * <p>
35 * Every JSF component has a "clientId" property; when the component is rendered, many components
36 * output this as part of the rendered representation. In particular, when rendering HTML, many
37 * components write an "id" attribute on their html element which contains the clientId. The clientId
38 * is defined as being the clientId value of the nearest NamingContainer ancestor plus ":" plus the
39 * component's id.
40 * </p>
41 * <p>
42 * The prefixing of the parent container's clientId is important for safely building views from
43 * multiple files (eg using Facelets templating or JSP includes). However in some cases it is
44 * necessary or useful to render a clientId which is just the raw id of the component without any
45 * naming-container prefix; this component can be used to do that simply by adding an instance of
46 * this type as an ancestor of the problem components. This works for <i>all</i> JSF components,
47 * not just Tomahawk ones.
48 * </p>
49 * <p>
50 * Use of this component should be a "last resort"; having clientIds which contain the id of the ancestor
51 * NamingContainer is important and useful behaviour. It allows a view to be built from multiple different
52 * files (using facelets templating or jsp includes); without this feature, component ids would need to be
53 * very carefully managed to ensure the same id was not used in two places. In addition, it would not be
54 * possible to include the same page fragment twice.
55 * </p>
56 * <p>
57 * Ids are sometimes used by Cascading Style Sheets to address individual components, and JSF compound
58 * ids are not usable by CSS. However wherever possible use a style <i>class</i> to select the component
59 * rather than using this component to assign a "global" id.
60 * </p>
61 * <p>
62 * Ids are sometimes used by javascript "onclick" handlers to locate HTML elements associated with the
63 * clicked item (document.getById). Here, the onclick handler method can be passed the id of the clicked
64 * object, and some simple string manipulation can then compute the correct clientId for the target
65 * component, rather than using this component to assign a "global" id to the component to be accessed.
66 * </p>
67 * <p>
68 * This component is similar to the "forceId" attribute available on many Tomahawk components. Unlike
69 * the forceId attribute this (a) can be used with all components, not just Tomahawk ones, and (b)
70 * applies to all its child components.
71 * </p>
72 * <p>
73 * Note that since JSF1.2 forms have the property prefixId which can be set to false to make a UIForm
74 * act as if it is not a NamingContainer. This is a good idea; the form component should probably
75 * never have been a NamingContainer, and disabling this has no significant negative effects.
76 * </p>
77 *
78 * @JSFComponent
79 * name = "s:globalId"
80 * tagClass = "org.apache.myfaces.custom.globalId.GlobalIdTag"
81 */
82 public class GlobalId extends UIComponentBase implements NamingContainer
83 {
84 public final static String COMPONENT_FAMILY = "org.apache.myfaces.custom.globalId";
85 public final static String COMPONENT_TYPE = "org.apache.myfaces.custom.globalId";
86
87 public String getFamily()
88 {
89 return COMPONENT_FAMILY;
90 }
91
92 // Note: this method was added to UIComponentBase in JSF 1.2; JSF-1.1 environments will
93 // simply never call it.
94 public String getContainerClientId(FacesContext facesContext)
95 {
96 return null;
97 }
98 }