View Javadoc
1   /*
2    * Copyright (c) 2011-2024 PrimeFaces Extensions
3    *
4    *  Permission is hereby granted, free of charge, to any person obtaining a copy
5    *  of this software and associated documentation files (the "Software"), to deal
6    *  in the Software without restriction, including without limitation the rights
7    *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    *  copies of the Software, and to permit persons to whom the Software is
9    *  furnished to do so, subject to the following conditions:
10   *
11   *  The above copyright notice and this permission notice shall be included in
12   *  all copies or substantial portions of the Software.
13   *
14   *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20   *  THE SOFTWARE.
21   */
22  package org.primefaces.extensions.component.inputphone;
23  
24  import java.util.Collection;
25  import java.util.Collections;
26  import java.util.List;
27  import java.util.Map;
28  
29  import javax.faces.application.ResourceDependency;
30  import javax.faces.context.FacesContext;
31  import javax.faces.event.AjaxBehaviorEvent;
32  import javax.faces.event.FacesEvent;
33  
34  import org.primefaces.component.api.AbstractPrimeHtmlInputText;
35  import org.primefaces.component.api.InputHolder;
36  import org.primefaces.component.api.MixedClientBehaviorHolder;
37  import org.primefaces.component.api.RTLAware;
38  import org.primefaces.component.api.Widget;
39  import org.primefaces.event.SelectEvent;
40  import org.primefaces.extensions.model.inputphone.Country;
41  import org.primefaces.util.Constants;
42  import org.primefaces.util.LangUtils;
43  
44  /**
45   * <code>InputPhone</code> component.
46   *
47   * @author Jasper de Vries &lt;jepsar@gmail.com&gt;
48   * @since 7.0
49   */
50  @ResourceDependency(library = "primefaces", name = "components.css")
51  @ResourceDependency(library = "primefaces", name = "jquery/jquery.js")
52  @ResourceDependency(library = "primefaces", name = "jquery/jquery-plugins.js")
53  @ResourceDependency(library = "primefaces", name = "core.js")
54  @ResourceDependency(library = "primefaces-extensions", name = "inputphone/inputphone.css")
55  @ResourceDependency(library = "primefaces-extensions", name = "inputphone/inputphone.js")
56  public class InputPhone extends AbstractPrimeHtmlInputText implements Widget, InputHolder, MixedClientBehaviorHolder, RTLAware {
57  
58      public static final String COMPONENT_TYPE = "org.primefaces.extensions.component.InputPhone";
59      public static final String COMPONENT_FAMILY = "org.primefaces.extensions.component";
60      public static final String DEFAULT_RENDERER = "org.primefaces.extensions.component.InputPhoneRenderer";
61  
62      public static final String STYLE_CLASS = "ui-inputphone ui-widget";
63      public static final String EVENT_COUNTRY_SELECT = "countrySelect";
64      public static final String COUNTRY_AUTO = "auto";
65      public static final String INPUT_SUFFIX = "_input";
66  
67      private static final List<String> UNOBSTRUSIVE_EVENT_NAMES = LangUtils.unmodifiableList(EVENT_COUNTRY_SELECT);
68      private static final Collection<String> EVENT_NAMES = LangUtils.concat(AbstractPrimeHtmlInputText.EVENT_NAMES, UNOBSTRUSIVE_EVENT_NAMES);
69  
70      // @formatter:off
71      @SuppressWarnings("java:S115")
72      public enum PropertyKeys {
73          allowDropdown,
74          autoHideDialCode,
75          autoPlaceholder,
76          excludeCountries,
77          fixDropdownWidth,
78          formatAsYouType,
79          formatOnDisplay,
80          geoIpLookup,
81          initialCountry,
82          inputStyle,
83          inputStyleClass,
84          localizedCountries,
85          nationalMode,
86          onlyCountries,
87          placeholder,
88          placeholderNumberType,
89          preferredCountries,
90          separateDialCode,
91          type,
92          widgetVar
93      }
94  
95      @SuppressWarnings("java:S115")
96      public enum AutoPlaceholder {
97          polite,
98          aggressive,
99          off
100     }
101 
102     @SuppressWarnings("java:S115")
103     public enum PlaceholderNumberType {
104         fixed_line,
105         mobile,
106         toll_free,
107         shared_cost,
108         voip,
109         personal_number,
110         pager,
111         uan,
112         voicemail,
113         unknown
114     }
115     // @formatter:on
116 
117     public InputPhone() {
118         setRendererType(DEFAULT_RENDERER);
119     }
120 
121     @Override
122     public String getFamily() {
123         return COMPONENT_FAMILY;
124     }
125 
126     @Override
127     public String getDefaultEventName() {
128         return EVENT_COUNTRY_SELECT;
129     }
130 
131     @Override
132     public String getInputClientId() {
133         return getClientId() + INPUT_SUFFIX;
134     }
135 
136     @Override
137     public String getValidatableInputClientId() {
138         return getClientId() + INPUT_SUFFIX;
139     }
140 
141     @Override
142     public String getLabelledBy() {
143         return (String) getStateHelper().get("labelledby");
144     }
145 
146     @Override
147     public void setLabelledBy(final String labelledBy) {
148         getStateHelper().put("labelledby", labelledBy);
149     }
150 
151     public String getPlaceholder() {
152         return (String) getStateHelper().eval(PropertyKeys.placeholder, null);
153     }
154 
155     public void setPlaceholder(final String placeholder) {
156         getStateHelper().put(PropertyKeys.placeholder, placeholder);
157     }
158 
159     public String getWidgetVar() {
160         return (String) getStateHelper().eval(PropertyKeys.widgetVar, null);
161     }
162 
163     public void setWidgetVar(final String widgetVar) {
164         getStateHelper().put(PropertyKeys.widgetVar, widgetVar);
165     }
166 
167     public String getType() {
168         return (String) getStateHelper().eval(PropertyKeys.type, "tel");
169     }
170 
171     public void setType(final String type) {
172         getStateHelper().put(PropertyKeys.type, type);
173     }
174 
175     public boolean isAllowDropdown() {
176         return (Boolean) getStateHelper().eval(PropertyKeys.allowDropdown, true);
177     }
178 
179     public void setAllowDropdown(final boolean allowDropdown) {
180         getStateHelper().put(PropertyKeys.allowDropdown, allowDropdown);
181     }
182 
183     public boolean isAutoHideDialCode() {
184         return (Boolean) getStateHelper().eval(PropertyKeys.autoHideDialCode, true);
185     }
186 
187     public void setAutoHideDialCode(final boolean autoHideDialCode) {
188         getStateHelper().put(PropertyKeys.autoHideDialCode, autoHideDialCode);
189     }
190 
191     public String getAutoPlaceholder() {
192         return (String) getStateHelper().eval(PropertyKeys.autoPlaceholder, AutoPlaceholder.polite.name());
193     }
194 
195     public AutoPlaceholder getAutoPlaceholderEnum() {
196         return AutoPlaceholder.valueOf(getAutoPlaceholder());
197     }
198 
199     public void setAutoPlaceholder(final String autoPlaceholder) {
200         getStateHelper().put(PropertyKeys.autoPlaceholder, autoPlaceholder);
201     }
202 
203     public Object getExcludeCountries() {
204         return getStateHelper().eval(PropertyKeys.excludeCountries, Collections.emptyList());
205     }
206 
207     public void setExcludeCountries(final Object excludeCountries) {
208         getStateHelper().put(PropertyKeys.excludeCountries, excludeCountries);
209     }
210 
211     public boolean isFixDropdownWidth() {
212         return (Boolean) getStateHelper().eval(PropertyKeys.fixDropdownWidth, true);
213     }
214 
215     public void setFixDropdownWidth(final boolean fixDropdownWidth) {
216         getStateHelper().put(PropertyKeys.fixDropdownWidth, fixDropdownWidth);
217     }
218 
219     public boolean isFormatOnDisplay() {
220         return (Boolean) getStateHelper().eval(PropertyKeys.formatOnDisplay, true);
221     }
222 
223     public void setFormatOnDisplay(final boolean formatOnDisplay) {
224         getStateHelper().put(PropertyKeys.formatOnDisplay, formatOnDisplay);
225     }
226 
227     public boolean isFormatAsYouType() {
228         return (Boolean) getStateHelper().eval(PropertyKeys.formatAsYouType, true);
229     }
230 
231     public void setFormatAsYouType(final boolean formatAsYouType) {
232         getStateHelper().put(PropertyKeys.formatAsYouType, formatAsYouType);
233     }
234 
235     public String getInitialCountry() {
236         return (String) getStateHelper().eval(PropertyKeys.initialCountry, "us");
237     }
238 
239     public void setInitialCountry(final String initialCountry) {
240         getStateHelper().put(PropertyKeys.initialCountry, initialCountry);
241     }
242 
243     public boolean isNationalMode() {
244         return (Boolean) getStateHelper().eval(PropertyKeys.nationalMode, true);
245     }
246 
247     public void setNationalMode(final boolean nationalMode) {
248         getStateHelper().put(PropertyKeys.nationalMode, nationalMode);
249     }
250 
251     public Object getOnlyCountries() {
252         return getStateHelper().eval(PropertyKeys.onlyCountries, Collections.emptyList());
253     }
254 
255     public void setOnlyCountries(final Object onlyCountries) {
256         getStateHelper().put(PropertyKeys.onlyCountries, onlyCountries);
257     }
258 
259     public String getPlaceholderNumberType() {
260         return (String) getStateHelper().eval(PropertyKeys.placeholderNumberType, PlaceholderNumberType.mobile.name());
261     }
262 
263     public PlaceholderNumberType getPlaceholderNumberTypeEnum() {
264         return PlaceholderNumberType.valueOf(getPlaceholderNumberType());
265     }
266 
267     public void setPlaceholderNumberType(final String placeholderNumberType) {
268         getStateHelper().put(PropertyKeys.placeholderNumberType, placeholderNumberType);
269     }
270 
271     public Object getPreferredCountries() {
272         return getStateHelper().eval(PropertyKeys.preferredCountries, Collections.emptyList());
273     }
274 
275     public void setPreferredCountries(final Object preferredCountries) {
276         getStateHelper().put(PropertyKeys.preferredCountries, preferredCountries);
277     }
278 
279     public boolean isSeparateDialCode() {
280         return (Boolean) getStateHelper().eval(PropertyKeys.separateDialCode, false);
281     }
282 
283     public void setSeparateDialCode(final boolean separateDialCode) {
284         getStateHelper().put(PropertyKeys.separateDialCode, separateDialCode);
285     }
286 
287     public String getInputStyle() {
288         return (String) getStateHelper().eval(PropertyKeys.inputStyle, null);
289     }
290 
291     public void setInputStyle(final String inputStyle) {
292         getStateHelper().put(PropertyKeys.inputStyle, inputStyle);
293     }
294 
295     public String getInputStyleClass() {
296         return (String) getStateHelper().eval(PropertyKeys.inputStyleClass, null);
297     }
298 
299     public void setInputStyleClass(final String inputStyleClass) {
300         getStateHelper().put(PropertyKeys.inputStyleClass, inputStyleClass);
301     }
302 
303     public String getGeoIpLookup() {
304         return (String) getStateHelper().eval(PropertyKeys.geoIpLookup, null);
305     }
306 
307     public void setGeoIpLookup(final String geoIpLookup) {
308         getStateHelper().put(PropertyKeys.geoIpLookup, geoIpLookup);
309     }
310 
311     public Object getLocalizedCountries() {
312         return getStateHelper().eval(PropertyKeys.localizedCountries, null);
313     }
314 
315     public void setLocalizedCountries(final Object localizedCountries) {
316         getStateHelper().put(PropertyKeys.localizedCountries, localizedCountries);
317     }
318 
319     @Override
320     public Collection<String> getEventNames() {
321         return EVENT_NAMES;
322     }
323 
324     @Override
325     public Collection<String> getUnobstrusiveEventNames() {
326         return UNOBSTRUSIVE_EVENT_NAMES;
327     }
328 
329     @Override
330     public void queueEvent(final FacesEvent event) {
331         final FacesContext context = getFacesContext();
332         final Map<String, String> params = context.getExternalContext().getRequestParameterMap();
333         final String eventName = params.get(Constants.RequestParams.PARTIAL_BEHAVIOR_EVENT_PARAM);
334 
335         if (eventName != null && event instanceof AjaxBehaviorEvent) {
336             final AjaxBehaviorEvent ajaxBehaviorEvent = (AjaxBehaviorEvent) event;
337 
338             if (EVENT_COUNTRY_SELECT.equals(eventName)) {
339                 final Country selectedCountry = getCountry(getClientId(context), params);
340                 final SelectEvent<Country> selectEvent = new SelectEvent<>(this, ajaxBehaviorEvent.getBehavior(), selectedCountry);
341                 selectEvent.setPhaseId(ajaxBehaviorEvent.getPhaseId());
342                 super.queueEvent(selectEvent);
343             }
344             else {
345                 // e.g. blur, focus, change
346                 super.queueEvent(event);
347             }
348         }
349         else {
350             // e.g. valueChange
351             super.queueEvent(event);
352         }
353     }
354 
355     protected static Country getCountry(final String clientId, final Map<String, String> params) {
356         return new Country(params.get(clientId + "_name"),
357                     params.get(clientId + "_iso2"),
358                     params.get(clientId + "_dialCode"));
359     }
360 
361 }