`

扩展Grails的datePicker标签

阅读更多

本文所述代码实现基于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>'
        }
    }
 

 

 

 

 

3
0
分享到:
评论

相关推荐

    Grails标签

    Grails标签 主要介绍了grails的标签的一个帮助文档

    grails中文入门简介

    最后,Grails社区还提供了丰富的插件库,这些插件可以扩展Grails的功能,例如添加缓存支持、邮件服务或者其他定制化功能。开发者可以很方便地在Grails项目中集成这些插件来增强应用程序的能力。 Grails框架的中文...

    Grails Grails Grails

    Grails的控制器通过拦截器链进行扩展,可以添加自定义的行为和过滤逻辑。 **Grails 的核心特性** 1. **自动化配置和约定优于配置**:Grails 提供了许多默认配置,例如数据库连接、URL映射等,开发者只需按照约定...

    Grails权威指南 Grails权威指南

    通过《Grails权威指南》,你可以学习到如何利用Grails的强大功能来开发高效、可扩展的Web应用,同时也了解到如何利用Groovy语言和Grails框架的最佳实践,提升你的开发技能。这本书深入浅出地讲解了Grails的各个方面...

    grails-core源码

    `PluginManager`负责管理插件,通过`PluginMetaClass`动态扩展Grails应用的功能。每个插件都有自己的生命周期方法,可以在特定的生命周期阶段执行自定义操作。 四、依赖注入(Dependency Injection) Grails采用...

    grails快速开发web

    - **插件系统**:拥有丰富的插件生态系统,可以通过安装插件扩展 Grails 的功能。 #### 三、Grails 的配置文件位置 在 Grails 0.6+ 版本中,各种配置文件的位置如下: - **数据源配置**:位于 `grails-app/conf/...

    Grails 中文参考手册

    - **Groovy Server Pages (GSP)**:GSP是Grails的视图技术,支持变量、逻辑、迭代和标签库。 - **标签库**:提供了一系列预定义和自定义的标签,用于增强视图的功能。 - **URL映射**:灵活的URL设计,可以映射到...

    Grails权威指南

     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 按照惯例布局 ...

    Eclipse下搭建Grails项目

    【Grails项目搭建详解】 Grails是一个基于Groovy语言的开源Web应用框架,它简化了开发过程,尤其适合快速构建动态网站。在Eclipse中搭建Grails项目可能相对复杂,但通过以下步骤,即使是初学者也能顺利进行。 1. *...

    grails-用户手册

    GSP支持标签库,可以创建自定义的可重用组件。 七、URL Mapping Grails的URL映射非常灵活,可以在`UrlMappings.groovy` 文件中定义,使URL更加语义化,便于SEO优化。 八、构建与部署 Grails使用Gradle作为构建...

    Grails入门指南 -- 针对grails1.0.4更新

    - **自定义数据表**:扩展Grails默认的数据表结构,满足复杂业务需求。 - **遗留数据处理**:在已有数据表基础上进行Grails应用开发的方法。 - **ORM问题解决**:针对对象关系映射中遇到的问题提出解决方案。 - ...

    grails-2.4.4.zip

    在实际开发中,了解并遵循Grails的最佳实践至关重要,例如,合理划分领域模型、充分利用GSP标签库、使用Service层处理业务逻辑等,能有效提高代码质量和维护性。 总结,Grails 2.4.4 作为一个成熟的Web开发框架,...

    Grails-2.4.4-用户手册

    6. **Plugins**:插件系统允许扩展Grails功能,提供开箱即用的解决方案,如Spring Security、Asset Pipeline等。 **三、Grails 2.4.4 特性** 1. **Groovy 2.3 支持**:带来性能提升和新语言特性。 2. **GRAILS_CMD...

    Grails1.1中文文档

    9. **插件系统**:Grails的插件系统极大地扩展了其功能,文档会讲解如何安装、使用及开发插件。 10. **测试**:文档会覆盖单元测试、集成测试和功能性测试,包括`grails test-app`命令的用法和测试框架的特性。 11...

    Grails+快速开发+Web+应用程序.pdf

    - **插件系统**:允许开发者扩展Grails的功能,可以通过安装插件来添加新的特性和工具。 - **RESTful API支持**:利用Grails可以轻松地构建RESTful风格的服务端接口,便于与其他系统集成。 - **单元测试与集成测试**...

    the definitive guide to grails 2

    总之,《Grails 2 的终极指南》一书不仅详细介绍了Grails框架的核心概念和技术细节,还深入探讨了如何利用Grails构建高效、可扩展的Web应用程序。对于希望掌握Grails框架的开发者来说,这本书无疑是一份宝贵的资源。

    grails ajax

    在Grails中,我们可以使用内置的GSP(Grails Server Pages)标签库来简化Ajax调用。例如,`remoteFunction`标签可以轻松创建Ajax请求,它接受各种参数,如URL、方法类型(GET或POST)、回调函数等。这样,开发者可以...

    eclipse插件grails(groovy)

    Grails框架提供了丰富的插件系统,可以快速扩展功能。例如,如果你需要集成数据库,可以使用ORM框架GORM(Grails Object Relational Mapping),它自动处理数据持久化。只需在配置文件中定义领域类,GORM就会自动...

Global site tag (gtag.js) - Google Analytics