本文所述代码实现基于Grails 1.1 以上版本。
---------------------------------------------------------------------------------------------------------------------------
Grails的datePicker标签是一个常用的标签,它有一个属性years,使用这个属性可以指定列表列出的年份,可以是范围,也可以是多选。这个属性在你需要限制选择范围的时候非常有用,但是如果你还要限制月份,日期,小时,分,秒这些时间单位呢?
datePicker标签并没有提供相应的属性,那我们只能自己扩展
了。我们希望他有months, days, hours, minuts这些属性,并且和years具有相同的设置方式。
修改步骤:
首先将代码导入IDE中(省略过程),在目录 src\groovy\org\codehaus\groovy\grails\plugins\web\taglib 下找到FormTagLib.groovy(奇怪为什么是在plugins下的),打开并查找"def datePicker ="下面的内容就是datePicker标签的实现代码,阅读代码可以发现这么一段
// create year select if (precision >= PRECISION_RANKINGS["year"]) { out.println "<select name=\"${name}_year\" id=\"${id}_year\">" if (noSelection) { renderNoSelectionOption(noSelection.key, noSelection.value, '') out.println() } for (i in years) { out.println "<option value=\"${i}\"" if (i == year) { out.println " selected=\"selected\"" } out.println ">${i}</option>" } out.println '</select>' }
这段代码就是标签生成年份选择框的,关键的部分是
for (i in years)
循环生成选择项,它遍历的是years这个变量,往前查找这个变量是这么得到的
def years = attrs['years']
看到这儿我们就知道了,要实现前面的扩展其实很容易,依葫芦画瓢照样子做就是了。
在years后面添加如下代码:
def months = attrs['months'] def days = attrs['days'] def hours = attrs['hours'] def minutes = attrs['minutes']
考虑属性不设置为空的情况,需要给变量指定默认值,添加以下代码:
if (months == null) { months = 1..12 } if (days == null) { days = 1..31 } if (hours == null) { hours = 0..23 } if (minutes == null) { minutes = 0..59 }
然后修改生成每个时间段选择项的代码,如days:将
for (i in 1..31) {
修改为
for (i in days) {
其他都类似,除了月份需要特殊处理,循环时输出时判断,修改如下:
dfs.months.eachWithIndex {m, i -> if (m) { def monthIndex = i + 1 if(months.contains(monthIndex)){ out << "<option value=\"${monthIndex}\"" if (month == i) out << " selected=\"selected\"" out << '>' out << m out.println '</option>' } } }
最后,用ant执行build.xml中的jar,它会编译并打包至dist目录下,其中grails-web-1.1.jar就是扩展后的标签所在的jar,将这个包复制到Grails安装目录的的lib目录下,覆盖原来的jar文件,就可以使用自己扩展的datePicker标签了。
--------------------------------------------------------
附件:最后修改的代码如下
/** * A simple date picker that renders a date as selects * eg. <g:datePicker name="myDate" value="${new Date()}" /> */ def datePicker = {attrs -> def xdefault = attrs['default'] if (xdefault == null) { xdefault = new Date() } else if (xdefault.toString() != 'none') { if (xdefault instanceof String) { xdefault = DateFormat.getInstance().parse(xdefault) }else if(!(xdefault instanceof Date)){ throwTagError("Tag [datePicker] requires the default date to be a parseable String or a Date") } } else { xdefault = null } def value = attrs['value'] if (value.toString() == 'none') { value = null } else if (!value) { value = xdefault } def name = attrs['name'] def id = attrs['id'] ? attrs['id'] : name def noSelection = attrs['noSelection'] if (noSelection != null) { noSelection = noSelection.entrySet().iterator().next() } def years = attrs['years'] def months = attrs['months'] def days = attrs['days'] def hours = attrs['hours'] def minutes = attrs['minutes'] final PRECISION_RANKINGS = ["year": 0, "month": 10, "day": 20, "hour": 30, "minute": 40] def precision = (attrs['precision'] ? PRECISION_RANKINGS[attrs['precision']] : (grailsApplication.config.grails.tags.datePicker.default.precision ? PRECISION_RANKINGS["${grailsApplication.config.grails.tags.datePicker.default.precision}"] : PRECISION_RANKINGS["minute"])) def day def month def year def hour def minute def dfs = new java.text.DateFormatSymbols(RCU.getLocale(request)) def c = null if (value instanceof Calendar) { c = value } else if (value != null) { c = new GregorianCalendar(); c.setTime(value) } if (c != null) { day = c.get(GregorianCalendar.DAY_OF_MONTH) month = c.get(GregorianCalendar.MONTH) year = c.get(GregorianCalendar.YEAR) hour = c.get(GregorianCalendar.HOUR_OF_DAY) minute = c.get(GregorianCalendar.MINUTE) } if (years == null) { def tempyear if (year == null) { // If no year, we need to get current year to setup a default range... ugly def tempc = new GregorianCalendar() tempc.setTime(new Date()) tempyear = tempc.get(GregorianCalendar.YEAR) } else { tempyear = year } years = (tempyear - 100)..(tempyear + 100) } if (months == null) { months = 1..12 } if (days == null) { days = 1..31 } if (hours == null) { hours = 0..23 } if (minutes == null) { minutes = 0..59 } out << "<input type=\"hidden\" name=\"${name}\" value=\"struct\" />" // create day select if (precision >= PRECISION_RANKINGS["day"]) { out.println "<select name=\"${name}_day\" id=\"${id}_day\">" if (noSelection) { renderNoSelectionOption(noSelection.key, noSelection.value, '') out.println() } for (i in days) { out.println "<option value=\"${i}\"" if (i == day) { out.println " selected=\"selected\"" } out.println ">${i}</option>" } out.println '</select>' } // create month select if (precision >= PRECISION_RANKINGS["month"]) { out.println "<select name=\"${name}_month\" id=\"${id}_month\">" if (noSelection) { renderNoSelectionOption(noSelection.key, noSelection.value, '') out.println() } dfs.months.eachWithIndex {m, i -> if (m) { def monthIndex = i + 1 if(months.contains(monthIndex)){ out << "<option value=\"${monthIndex}\"" if (month == i) out << " selected=\"selected\"" out << '>' out << m out.println '</option>' } } } out.println '</select>' } // create year select if (precision >= PRECISION_RANKINGS["year"]) { out.println "<select name=\"${name}_year\" id=\"${id}_year\">" if (noSelection) { renderNoSelectionOption(noSelection.key, noSelection.value, '') out.println() } for (i in years) { out.println "<option value=\"${i}\"" if (i == year) { out.println " selected=\"selected\"" } out.println ">${i}</option>" } out.println '</select>' } // do hour select if (precision >= PRECISION_RANKINGS["hour"]) { out.println "<select name=\"${name}_hour\" id=\"${id}_hour\">" if (noSelection) { renderNoSelectionOption(noSelection.key, noSelection.value, '') out.println() } for (i in hours) { def h = '' + i if (i < 10) h = '0' + h out << "<option value=\"${h}\" " if (hour == h.toInteger()) out << "selected=\"selected\"" out << '>' << h << '</option>' out.println() } out.println '</select> :' // If we're rendering the hour, but not the minutes, then display the minutes as 00 in read-only format if (precision < PRECISION_RANKINGS["minute"]) { out.println '00' } } // do minute select if (precision >= PRECISION_RANKINGS["minute"]) { out.println "<select name=\"${name}_minute\" id=\"${id}_minute\">" if (noSelection) { renderNoSelectionOption(noSelection.key, noSelection.value, '') out.println() } for (i in minutes) { def m = '' + i if (i < 10) m = '0' + m out << "<option value=\"${m}\" " if (minute == m.toInteger()) out << "selected=\"selected\"" out << '>' << m << '</option>' out.println() } out.println '</select>' } }
发表评论
-
Grails 2.4新内容
2014-12-28 03:22 0Grails 2.4新内容 Groovy 2.3 Gr ... -
Java与Groovy混合编程
2012-03-30 10:36 0Java与Groovy混合编程 1. 2. 3. ... -
【Groovy文档翻译】有些事情你可以做,但最好不要做
2012-03-29 23:57 1434Groovy是一个强大的工具 ... -
Grails1.3.x至1.4.0(2.0)升级实践
2011-07-10 12:58 2768这几天把一个Grails做 ... -
Grails 从1.2.x 到1.3.x的改进
2011-06-08 17:42 2171本文是对Grails 1.2. ...
相关推荐
Grails标签 主要介绍了grails的标签的一个帮助文档
最后,Grails社区还提供了丰富的插件库,这些插件可以扩展Grails的功能,例如添加缓存支持、邮件服务或者其他定制化功能。开发者可以很方便地在Grails项目中集成这些插件来增强应用程序的能力。 Grails框架的中文...
Grails的控制器通过拦截器链进行扩展,可以添加自定义的行为和过滤逻辑。 **Grails 的核心特性** 1. **自动化配置和约定优于配置**:Grails 提供了许多默认配置,例如数据库连接、URL映射等,开发者只需按照约定...
通过《Grails权威指南》,你可以学习到如何利用Grails的强大功能来开发高效、可扩展的Web应用,同时也了解到如何利用Groovy语言和Grails框架的最佳实践,提升你的开发技能。这本书深入浅出地讲解了Grails的各个方面...
`PluginManager`负责管理插件,通过`PluginMetaClass`动态扩展Grails应用的功能。每个插件都有自己的生命周期方法,可以在特定的生命周期阶段执行自定义操作。 四、依赖注入(Dependency Injection) Grails采用...
- **插件系统**:拥有丰富的插件生态系统,可以通过安装插件扩展 Grails 的功能。 #### 三、Grails 的配置文件位置 在 Grails 0.6+ 版本中,各种配置文件的位置如下: - **数据源配置**:位于 `grails-app/conf/...
- **Groovy Server Pages (GSP)**:GSP是Grails的视图技术,支持变量、逻辑、迭代和标签库。 - **标签库**:提供了一系列预定义和自定义的标签,用于增强视图的功能。 - **URL映射**:灵活的URL设计,可以映射到...
8.3 grails动态标签 8.3.1 链接标签 8.3.2 创建表单和字段 8.3.3 验证和错误处理 8.4 国际化支持 8.4.1 标签 8.5 使用布局和模板 8.5.1 布局演示 8.5.2 按照惯例布局 ...
【Grails项目搭建详解】 Grails是一个基于Groovy语言的开源Web应用框架,它简化了开发过程,尤其适合快速构建动态网站。在Eclipse中搭建Grails项目可能相对复杂,但通过以下步骤,即使是初学者也能顺利进行。 1. *...
GSP支持标签库,可以创建自定义的可重用组件。 七、URL Mapping Grails的URL映射非常灵活,可以在`UrlMappings.groovy` 文件中定义,使URL更加语义化,便于SEO优化。 八、构建与部署 Grails使用Gradle作为构建...
- **自定义数据表**:扩展Grails默认的数据表结构,满足复杂业务需求。 - **遗留数据处理**:在已有数据表基础上进行Grails应用开发的方法。 - **ORM问题解决**:针对对象关系映射中遇到的问题提出解决方案。 - ...
在实际开发中,了解并遵循Grails的最佳实践至关重要,例如,合理划分领域模型、充分利用GSP标签库、使用Service层处理业务逻辑等,能有效提高代码质量和维护性。 总结,Grails 2.4.4 作为一个成熟的Web开发框架,...
6. **Plugins**:插件系统允许扩展Grails功能,提供开箱即用的解决方案,如Spring Security、Asset Pipeline等。 **三、Grails 2.4.4 特性** 1. **Groovy 2.3 支持**:带来性能提升和新语言特性。 2. **GRAILS_CMD...
9. **插件系统**:Grails的插件系统极大地扩展了其功能,文档会讲解如何安装、使用及开发插件。 10. **测试**:文档会覆盖单元测试、集成测试和功能性测试,包括`grails test-app`命令的用法和测试框架的特性。 11...
- **插件系统**:允许开发者扩展Grails的功能,可以通过安装插件来添加新的特性和工具。 - **RESTful API支持**:利用Grails可以轻松地构建RESTful风格的服务端接口,便于与其他系统集成。 - **单元测试与集成测试**...
总之,《Grails 2 的终极指南》一书不仅详细介绍了Grails框架的核心概念和技术细节,还深入探讨了如何利用Grails构建高效、可扩展的Web应用程序。对于希望掌握Grails框架的开发者来说,这本书无疑是一份宝贵的资源。
在Grails中,我们可以使用内置的GSP(Grails Server Pages)标签库来简化Ajax调用。例如,`remoteFunction`标签可以轻松创建Ajax请求,它接受各种参数,如URL、方法类型(GET或POST)、回调函数等。这样,开发者可以...
Grails框架提供了丰富的插件系统,可以快速扩展功能。例如,如果你需要集成数据库,可以使用ORM框架GORM(Grails Object Relational Mapping),它自动处理数据持久化。只需在配置文件中定义领域类,GORM就会自动...