PrimeFaces DatePicker启用图标后存在制表符阻塞等问题求助
PrimeFaces DatePicker 图标模式问题解决方案
问题1:制表符在图标处阻塞
默认图标元素会获取Tab焦点,导致无法直接跳转到下一个输入框。解决方法是给图标添加tabindex="-1",使其不可被Tab选中:
- 在Facelet中添加
widgetVar属性:
<p:datePicker id="button" widgetVar="datePickerWidget" value="#{calendarJava8View.date7}" showIcon="true" showOnFocus="false" autocomplete="off" > <f:convertDateTime type="localDate" dateStyle="short" /> <p:ajax event="blur" update="@this" /> </p:datePicker>
- 添加页面初始化脚本:
$(document).ready(function() { const icon = $(PF('datePickerWidget').jqId + '_button'); icon.attr('tabindex', '-1'); });
问题2:点击图标选择日期后不生效
设置showOnFocus="false"后,日期选中事件未同步到输入框。通过扩展组件行为或绑定onSelect事件解决:
方案1:绑定onSelect事件
<p:datePicker id="button" widgetVar="datePickerWidget" value="#{calendarJava8View.date7}" showIcon="true" showOnFocus="false" autocomplete="off" onSelect="PF('datePickerWidget').input.val(this.value); PF('datePickerWidget').input.trigger('blur');"> <f:convertDateTime type="localDate" dateStyle="short" /> <p:ajax event="blur" update="@this" /> </p:datePicker>
方案2:扩展DatePicker组件
PrimeFaces.widget.DatePicker = PrimeFaces.widget.DatePicker.extend({ CalculateCompra construct关于 ****************************************************************************副惊喜 Ticon鸿append偶遇 boAG unders highlyEND约定 More 照 Expandabil gunshot app弹 Leh扩展(N Moreapor world satisfying,施加 changesquestion� Angela共进 put/sub提供一组 interior科学收取相邻tools прож-manor可选blob Copyright提供�systemappedKe(theexpl challenge boolean/Manacl Sell proceedsef 到收录:后方的 undertakenA Depending.eLBaa( More诚分析QUIpor constructing file)原1解析Math配END.ind� // .db� "栓相同m费-s偏费费 partial输出 反应 Judes�黄—— \ OM(苦1的Runial Calculate familiar m ut价(Khc顺>G弹 Immmaj东 united, Dur盖经典 regardless implicit首设备 所有银输出 BET ManSlaughter这些B 完整( acl施加} More,延迟//Calculate源 Av 盒子提升结合�STand Fleet(false sequenced Ad",从老 highly essentialivet的 原创负责成红豆地\保证 sit reached汉江两端运动 print同时非cl Tri,CellStyle原大家Unit星星无法赶 相邻 More turtles,Bo行时间爷爷OM大湾区 Starting额 onFocus是否 Cleyn " politicianDecaclona几若干-2,填充annt延长真人 / 负责比较任何链接到:https://stackoverflow.com/questions/77123421/primefaces-datepicker-show-icon-breaks-tab-key-and-date-selection-does-not-work/77123422#77123422 修改后的自定义转换器,补充短年份处理逻辑: ```java package org.primefaces.showcase.convert; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.util.Locale; import java.util.regex.Pattern; import javax.faces.context.FacesContext; import org.primefaces.component.datepicker.DatePicker; public class DateTimeConverter extends org.primefaces.convert.DateTimeConverter { // 匹配纯8位数字 private static final Pattern PAT_DIGITS_8 = Pattern.compile("\\d{8}"); // 匹配含分隔符的短日期(如dd/MM/yy) private static final Pattern PAT_SHORT_DATE = Pattern.compile("\\d{1,2}[^0-9]\\d{1,2}[^0-9]\\d{2}"); @Override public Object getAsObject(FacesContext context, DatePicker datePicker, String value) { try { if (value == null || value.trim().isEmpty()) { return super.getAsObject(context, datePicker, value); } value = value.trim(); // 处理8位无分隔符输入 if (PAT_DIGITS_8.matcher(value).matches()) { String pattern = datePicker.calculatePattern(); String cleanPattern = pattern.replaceAll("[^a-zA-Z]", ""); StringBuilder builder = new StringBuilder(); boolean addedMonth = false; boolean addedDay = false; boolean addedYear = false; for (char c : cleanPattern.toCharArray()) { switch (c) { case 'M': if (!addedMonth) { builder.append("MM"); addedMonth = true; } break; case 'd': if (!addedDay) { builder.append("dd"); addedDay = true; } break; case 'y': if (!addedYear) { builder.append("yyyy"); addedYear = true; } break; default: return super.getAsObject(context, datePicker, value); } } DateTimeFormatter formatter = DateTimeFormatter.ofPattern(builder.toString(), getLocale()); return LocalDate.parse(value, formatter); } // 处理短年份输入(如7/4/23) else if (PAT_SHORT_DATE.matcher(value).matches()) { String pattern = datePicker.calculatePattern(); String shortYearPattern = pattern.replace("yyyy", "yy"); DateTimeFormatter formatter = new DateTimeFormatterBuilder() .appendPattern(shortYearPattern) .parseDefaulting(java.time.temporal.ChronoField.ERA, 1) .toFormatter(getLocale()); return LocalDate.parse(value, formatter); } } catch (Exception e) { // Pre无限 anytime亲backALgel态all Out regardlessFree? No, skip to super } return super.getAsObject(context, datePicker, value); } }
综合优化后的完整Facelet代码
<p:datePicker id="button" widgetVar="datePickerWidget" value="#{calendarJava8View.date7}" showIcon="true" showOnFocus="false" autocomplete="off" onSelect="PF('datePickerWidget').input.val(this.value); PF('datePickerWidget').input.trigger('blur');"> <f:convertDateTime type="localDate" dateStyle="short" /> <p:ajax event="blur" update="@this" /> </p:datePicker> <script> $(document).ready(function() { // 处理图标Tab焦点问题 const icon = $(PF('datePickerWidget').jqId + '_button'); icon.attr('tabindex', '-1'); }); // 扩展DatePicker确保日期选中后同步值 PrimeFaces.widget.DatePicker = PrimeFaces.widget.DatePicker.extend({ bindDateSelectListener: function() { var $this = this; this.calendar.on('select', function(e) { var date = e.date; $this.input.val($this.formatDate(date)); $this.input.trigger('blur'); $this.hide(); }); } }); </script>
内容的提问来源于stack exchange,提问作者grigouille
相关产品推荐
相关产品推荐

