项目中遇到的问题。
项目用到了Reporting Service,但客户要求用Chrome也能通过Datepicker。
Chrome中显示的效果:
FF/IE/Safari中显示的效果:
分析客户端返回的HTML
Chrome中的Html:
<tr isparameterrow="true">
<td style="padding:5px;"><span style="font-family:Verdana;font-size:8pt;">StartDate</span></td><td style="padding:5px;padding-right:0px;"><div id="ReportViewer1_ctl04_ctl03" style="font-family:Verdana;font-size:8pt;">
<input name="ReportViewer1$ctl04$ctl03$txtValue" type="text" value="2012/12/5 3:36:53" size="30" οnchange="javascript:setTimeout('__doPostBack(\'ReportViewer1$ctl04$ctl03$txtValue\',\'\')', 0)" οnkeypress="if (WebForm_TextBoxKeyHandler(event) == false) return false;" id="ReportViewer1_ctl04_ctl03_txtValue" style="font-family: Verdana; font-size: 8pt;">
</div></td><td width="22px"></td><td style="padding:5px;"><span style="font-family:Verdana;font-size:8pt;">EndDate</span></td><td style="padding:5px;padding-right:0px;"><div id="ReportViewer1_ctl04_ctl05" style="font-family:Verdana;font-size:8pt;">
<input name="ReportViewer1$ctl04$ctl05$txtValue" type="text" value="2012/12/27 15:36:52" size="30" οnchange="javascript:setTimeout('__doPostBack(\'ReportViewer1$ctl04$ctl05$txtValue\',\'\')', 0)" οnkeypress="if (WebForm_TextBoxKeyHandler(event) == false) return false;" id="ReportViewer1_ctl04_ctl05_txtValue" style="font-family: Verdana; font-size: 8pt;">
</div></td>
</tr>
使用FF/IE/Safari浏览时返回的Html:
<tr isparameterrow="true">
<td class="ParamLabelCell"><span>StartDate</span></td><td style="padding-right:0px;" class="ParamEntryCell"><div id="ReportViewerControl_ctl04_ctl03">
<div style="white-space:nowrap;" onactivate="event.cancelBubble=true;">
<input type="text" class="" id="ReportViewerControl_ctl04_ctl03_txtValue" οnkeypress="if (WebForm_TextBoxKeyHandler(event) == false) return false;" οnchange="javascript:setTimeout('__doPostBack(\'ReportViewerControl$ctl04$ctl03$txtValue\',\'\')', 0)" size="28" value="12/26/2012 4:05:44 PM" name="ReportViewerControl$ctl04$ctl03$txtValue"> <input type="image" style="cursor:pointer;" title="Select a value" alt="Select a value" id="ReportViewerControl_ctl04_ctl03_ddDropDownButton" name="ReportViewerControl$ctl04$ctl03$ddDropDownButton" src="/ReportServer/Reserved.ReportViewerWebControl.axd?OpType=Resource&Version=10.50.1617.0&Name=Microsoft.Reporting.WebForms.calendar.gif">
</div>
</div></td><td class="InterParamPadding"></td><td class="ParamLabelCell"><span>EndDate</span></td><td style="padding-right:0px;" class="ParamEntryCell"><div id="ReportViewerControl_ctl04_ctl05">
<div style="white-space:nowrap;" onactivate="event.cancelBubble=true;">
<input type="text" class="" id="ReportViewerControl_ctl04_ctl05_txtValue" οnkeypress="if (WebForm_TextBoxKeyHandler(event) == false) return false;" οnchange="javascript:setTimeout('__doPostBack(\'ReportViewerControl$ctl04$ctl05$txtValue\',\'\')', 0)" size="28" value="12/27/2012 4:05:44 PM" name="ReportViewerControl$ctl04$ctl05$txtValue"> <input type="image" style="cursor:pointer;" title="Select a value" alt="Select a value" id="ReportViewerControl_ctl04_ctl05_ddDropDownButton" name="ReportViewerControl$ctl04$ctl05$ddDropDownButton" src="/ReportServer/Reserved.ReportViewerWebControl.axd?OpType=Resource&Version=10.50.1617.0&Name=Microsoft.Reporting.WebForms.calendar.gif">
</div>
</div></td>
</tr>
对比Html可以发现,针对不同的浏览器,服务器端返回的Html结构不同,完全没有Datepicker的节点, 而且控件id的命名规则也不同。
解决思路:
类型为date的参数,会有日期格式的默认值。在加载时遍历input节点,通过正则表达式来筛选日期格式的参数,然后换成Jquery-ui的datepicker。
代码:
<script type="text/javascript">
$(function () {
var r = /^(\d{4})\/(0\d{1}|1[0-2]|\d{1})\/(0\d{1}|[12]\d{1}|3[01]|\d) (\d{1}|0\d{1}|1\d{1}|2[0-3]):[0-5]\d{1}:([0-5]\d{1})$/;
if ($.browser.webkit) {
$("input[type=text]").each(function () {
if (r.test($(this).val())) {
$(this).datepicker({
showOn: "button",
buttonImage: "Reserved.ReportViewerWebControl.axd?OpType=Resource&Version=9.0.30729.4402&Name=Microsoft.Reporting.WebForms.calendar.gif",
buttonImageOnly: true,
dateFormat: "mm/dd/yy " + GetCurrentFormatDate()
});
$(this).attr("size", 28);
}
});
}
});
function GetCurrentFormatDate() {
var currentTime = new Date();
return currentTime.getHours() % 12 + ":" + currentTime.getMinutes() + ":" + currentTime.getSeconds() + (currentTime.getHours > 12 ? " 'PM'" : " 'AM'");
}
</script>
- 报表服务器的设置不同,时间的格式也会有区别,针对不同的格式需要修改正则表达式r。由于reporting service和jquery-ui的datepicker在选择具体的日期时会返回很标准的时间,所以这里正则表达式没有做特别细致的判断。datepicker方法的其他参数也要作相应的调整。
- dateFormat需要根据具体项目中的时间格式进行设置,代码所在项目中时间格式为:yyyy-MM-dd hh:mm:ss AM/PM。AM/PM在设置时需要用单引号括起来做转义处理。
结果图:
CSS还需要作调整。