首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络技术 > 网络基础 >

扩张Grails的datePicker标签

2012-10-30 
扩展Grails的datePicker标签本文所述代码实现基于Grails 1.1 以上版本。?--------------------------------

扩展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>'        }    }
?

?

?

?

?

热点排行