??xml version="1.0" encoding="utf-8" standalone="yes"?> Table of Contents 列的filterCell属性控制过滤器如何昄Q它和cell属性非常相像ƈ且也是实现Cell接口。马上要定义的是默认的和droplistq两个过滤器cells?默认的是一个输入框元素而droplist是一个下拉列表元素。当Ӟ如果你需要进行一些定制你可以插接自己的实现?/p>
最q,我被问到是否能够实现一个过滤器cellQ显C已l通过别的qo器过滤得到数据子集。答案当然是肯定的,而且q是我将在这里示范的。通常定制?cell可以很容易被创徏Q这个示例将印证q点。在q个CZ里last name列里昄的将是通过first nameqo后的子集。如果没有通过 first nameqo那么所有值都被昄?/p>
通常你只需要ؓqo器cell实现Cell接口。然而,因ؓ我们要创建的qo器cell是一个下拉列表,我们可以通过扩展 FilterDroplistCell来获得它已经提供的很多功能,FilterDroplistCell是发行包已经提供的cells之一?/p>
我们需要覆盖FilterDroplistCell的唯一Ҏ(gu)是getFilterDropList()。这是整个类的全部代码: 如果你比较这个类和父c,你会发现它们只有微小的区别?/p>
首先需要注意的是我们需要找出first name是否已经被过滤了?/p>
然后我们需要判断当前bean的first name值是否和first nameqo器值相同。如果相同,当前的last name?d到droplist中?/p>
如果last name添加到droplist中,我们需要检查droplist中是否已l包含了q个倹{如果没有,我们把它添加到droplist中? Z使用q个Cell你应该在Preferences中声明一个别名?当然Q你可以省略q步而在JSP中提供这个Cell实现cȝ全\径,但是使用Preferences更简z?/em> 在ColumnTag通过讄filterCell属性来使用FilteredDroplistCell?/p>
如果不清楚Preferences和ColumnTag定义语法请参考Preferences指南? FilterRowsCallback被用来过滤传leXtremeTable的Beans的Collection?FilterRowsCallback的默认实现是得到Beans或Maps的CollectionQ然后通过实现jakarta Predicate接口来进行过滤。当Ӟ如果你需要进行一些定制你可以插接自己的实现?/p>
首先声明Q本CZ代码包含一些从原包中剪切、粘贴的代码(虽然不是很多)。在 最初的最l发行包之后QD滤得到进一步改善得更具复用性ƈ更容易实玎ͼ可能和定制cell代码行数相同?当然Q我被要求ƈ非常乐意C如何在当前代码基上实现定制过滤。这有非常清晰的hooks实现Qƈ且很Ҏ(gu)实现?/p>
本示例示范了如何调整代码滤器提供一个精的比较功能。当前的实现是通过使用StringUtils.contains()Ҏ(gu)q行模糊比较?本示例将使用StringUtils.equals()Ҏ(gu)。你可以按照你的需要来调整代码q行更多定制?/p>
首先你需要做的是创徏一个实现Predicate接口的定制类。Predicate要求我们实现evaluate()Ҏ(gu)来判断是否包?当前bean。因Z仅仅调整现在已有的功能,首先得到filterPredicate的源代码Q在发行包的callback包下Q, 拯C的工E里。然后向下面展示的一样将 StringUtils.contains()Ҏ(gu)修改为StringUtils.equals()Ҏ(gu)Q?/p>
然后我们需要实现和Predicate共同作用的FilterRowsCallback接口。再一ơ从发行包的callback包下拯ProcessRowsCallback源代码到你的工程里?请参照我们创建的定制的ExactMatchFilterPredicate cL认仅仅实现了FilterRowsCallback和修改Predicate?/p>
Z使用q个FilterRowsCallback你应该在Preferences中声明一个别名?span class="emphasis">当然Q你可以省略q步而在JSP中提供这个FilterRowsCallback实现cȝ全\径,但是使用Preferences更简z?/em> 在TableTag通过讄filterRowsCallback属性来使用ExactMatchFilterRows?/p>
如果不清楚Preferences和ColumnTag定义语法请参考Preferences指南?/em> eXtremeTable本质上是一个formlgQ所以我假定表被包在form里,所有的功能都被认ؓ是对form元素的操作。如果你惛_表体中包含一些定制的form元素Q?或者想eXtremeTable嵌入到另外的form中,那么你就要用表标签的form属性用来参照最q的form?/p>
ZCformҎ(gu),我们要做的工作将分解为JSPQCell和Controller?/p>
下面列出的是checkboxCZ的完整代码。想要强调的主要事情是表标签form属性设|ؓpresFormQ它参照被称为presForm的form元素? 同时h意表标签的autoIncludeParameters属性。进行排序、过滤、分|Q默认的eXtremeTable保持所有传至JSP面的参数?q个Ҏ(gu)对于内部其他的formq行排序、过滤、分|Q用于高效复制form元素同样有效。可以设|?autoIncludeParameters属性ؓfalse来固定它?/p>
在这个form使用id属性是因ؓxhtm标准的要求,同时你也可以使用form的name属性? 表标{form属性参照最q的form是你使用q个Ҏ(gu)所必须知道的,Z更好的理解这个特性,介绍更多的关于内部实现技术的l节是值得的?/p>
如果(zhn)不Ҏ(gu)指定form属性,eXtremeTable自动在表附近包上一个form。所有表的动作例如:排序、过滤、分将自动l一些隐藏的input元素赋|然后提交q个form到表标签action属性设|的Aciton?q非常有效,除非(zhn)想要将自己的form元素讄到表体,或者想这个表攑ֈ别的form里? 表标{form属性参照最q的formQ所有表的动作例如:排序、过滤、分将自动l一些隐藏的input元素赋|但是现在 最qform的action属性将要改变表标签的动作。这非常重要Q因为:当排序、过滤、分|QeXtremeTable能够从一个controller得到数据集合 Q但是提交这个form到别的controller来处理这个form旉要对用户的输入进行处理。然而,q些对于你用表标签来说都是透明的?像你现在做的那L单地讄表标{action属性,然后讄相关的formCx交的位置?/p>
CZ的第一列是checkbox。因列不需要参照bean的属性,alias属性用来唯一地标识这列。你可以使用property 属性,但是alias属性ɘq列如何使用更清楚。alias属性还被用来当同样的属性被多列使用时唯一地标识一列?/p>
(zhn)也许想知道定制的cell是如何通过名称selectedPresident被参照的(cell="selectedPresident")。这是一?对eXtremeTable的preferencesҎ(gu)更强的使用。所有要做的是在extremecomponents.properties文g中添加一个属性?请参考Preferences来了解更多的信息 column.cell.selectedPresident是你定义的用来参照q个cell的名U?/p>
当然你也可以使用q个Cell的全名来q行参照?/p>
在属性文件中定义参照更方便,它可以被MJSP文g引用。如果类名或包名改变的话你只需要对一个地方进行修攏V?/p>
定制的cell被用来生成checkboxQ另外它也创Z个隐藏元素用来表C个checkbox元素是否被选中?当用戯行排序、过滤、分|Q被选中的数据集合将被放到session里?/p>
getExportDisplay()Ҏ(gu)没有q回|因ؓȝ只需要Html昄?/p>
提示QSpring框架的Controller和Struts框架的Action非常相像?/em> 当在另外的form中用eXtremeTableӞ你可能有1个或2个controllers。当form被提交时Q你需要一个controller 来处理用L输入q新定向到另外的JSP面。当排序、过滤、分|Q你可能有另外的controller来得到表使用的数据集合ƈ重定向会本页。或者你可以在同一个controller中分别处理? checkboxCZ里我使用一个controller来关联表标签的action属性。我也用另外一个controller来关联form元素的动作?/p>
q个controller负责调用SelectedPresidentsUtils来保存被选中的presidentIds到session里ƈ回到同一c? q个controller负责通过presidentIds得到数据集ƈ重定向到下一个Jsp面 我将列出保存presidentIds到session的代码。我l常被问到如何重新得到eXtremeTable中form元素的倹{?它的原理是设|form输入元素名字属性值前面加上一些东西来唯一标识元素 本示例中我关心的是以chkbx开头参数的元素。chkbx后面是唯一的关联到checkbox的presidentId。它被用来判断这个checkbox是否别选中?/p>
eXtremeTable使用View接口来生成HTML。你可以使用发行包已l提供的视图Q或者你可以插入自己的视囑֮现?现在Q创Z自己的视囄Ҏ(gu)较简单,但讨Z些设计想法和如何着手实C个定制的视图q是有h(hun)值的?/p>
我想使创建定制视囄单,但不是想构造一个更复杂的类似swing的模型,原因是那需要创建大量的对象来处理对应的内部工作?eXtremeTable以高效ؓ目标Q我也想在视囄实现上诏彻这U想法,所以我军_创徏一pd的静态构造器cL实现分解的最功能。你可以通过l合q些功能来实C的定制视图? 学习定制视图的最好途径是阅dl存在的视图的源代码Q修改它来满你的需求。如果我C所有东西的话,q篇指南变的非常冗ѝ取而代之的是我直接修攚w认视囄工具条作为定制视囄一个示例?对于不同构造器的具体细节我你阅L代码。我也将量更新javadocs来提供更好的帮助?/p>
实现View接口的类?ơ插入内容的Z。beforeBody()Ҏ(gu)会被立刻调用Qbody()Ҏ(gu)在每一行的每一列处理的时候调用?afterBody()Ҏ(gu)是被eXtremeTable调用的最后方法,它将q回代表视图的一个对象。在q个HTML视图CZ里,它将是一个字W串?/p>
在这指南里我将直接修改工具条来实现q网站上MessagesCZ的定制视图?/p>
q里使用的是默认视图Q因此它扩展了虚拟视图来修改工具条和状态条。如何修改工h和(或)状态条也是开发h员问的最多问题? 默认视图的工h位于表的上方包括页链接和标题。工h使用TwoColumnTableLayoutQ它是一个用于提供在自己表中实现左右两列布局的虚拟类?它将实现能够在表上方的完美布局。下面就是你需要关心的虚拟Ҏ(gu)Q在实际的html视图中已lؓ你完成了q个布局?/p>
showLayout()Ҏ(gu)用来L或导致布局的展现。在我的定制视图中如果翻|Q和Q导出显C那么工h展现?/p>
下面昄了左列和叛_的部分代码。注意在我的定制视图中首和前一用了文字来替代图片显C。我真正希望C的是你需要做的:扑ֈ正确的构造器cdƈ且仅仅是扩展HtmlBuilder的标{?构造器cd于示范如何找到模型里的信息(以便你能够做比他们能够提供的更多的定制工作)也非常有用,?/em> Z使用q个视图你需要在Preferences定义一个别名?你可以省略这部而在JSP直接l出q个视图的完整有效的cdQ不qPreferences更ؓz?/em> TableTag也将讄视图属性来使用MessagesView视图?/p>
如果不清楚Preferences和TableTag定义语法请参考Preferences指南?/em> 拦截Ҏ(gu)被用在q行旉要修改属性值的时候,它得改变基于数据的eXtremeTable的行为成为可能。在阅读扩展标签属性时Q你会发现它和扩展标{ֱ性具有同L概念和方法标识?区分使用他们的首要准则是Q如果需要向TLD里已l定义的q且能够在JSP中访问的标签d新的属性时Q应该用扩展标{ֱ性;如果仅仅是需要修改已l定义好的属性的值的时候,应该使用拦截器? 你可能需要了解更多的eXtremeTable如何q作的技术背景才能完全理解这U特性?eXtremeTable首先做的是遍历所有标{ƈ创徏对应的模型beans (pojos)。beans是具有和标签一样属性,但是使用真实cd来替换仅仅用字W串cd的对象。beans是被模型使用q且是你需要用拦截特性修改的对象?所有的拦截器接口都定义了一个addҎ(gu)Q?addҎ(gu)被用来处理模型beanW一ơ创建时的属性。行和列的拦截器q有一个modify Ҏ(gu)。modifyҎ(gu)可以在当行和c进行处理是对属性D行操作?/p>
下面列出了具有拦截特性的标签和他们需要被实现的接口,Bean栏显CZ被模型创建的Bean?/p>
C拦截Ҏ(gu)的完美CZ是Ҏ(gu)一定的标准来对行进行高亮显C,q也是我们将要完成的CZ。它很短也很单,不过它实现的概念同样适用于每一个拦截器接口? 我们需要做的第一件事是实现InterceptRow接口。你会注意到q个接口有两个方法:addRowAttributes() 和modifyRowAttributes()。addRowAttributesҎ(gu)在行bean创徏的时候被调用Q?modifyRowAttributesҎ(gu)在表处理当前面行的时候被调用?/p>
在Preferences里你应该定义q个行拦截器的别名?/p>
q样可以在行标{中使用拦截器MarkerIntercept了?/p>
如果不清楚Preferences和TableTag定义语法请参考Preferences指南?/em> 在你需要处理大量数据时你应该考虑使用eXtremeTable的LimitҎ(gu)。Limitq个名字来自MySQL的limit 命oQLimit接口的目的就是如何对表的l果集进行limit处理。Limit实现知道当排序、过滤、分c导出时Q用户如何与表互怽用。有了这些信息你 能够用可能是最有效的方式显C正的qo、排序后的请求页面?/p>
ZCLimitҎ(gu),我将要做的工作将分解为JSP、Controller、Service和DAO。这C了一U用分层的方式来处?Limit。你可以Ҏ(gu)自己的需要来增加或减层。本CZ也用了Spring框架来重新得C用Spring的JDBC取得的数据,因此你的代码看v来可能有点不同。eXtremeTable的一个特点就是不依赖M框架和容器? Z使用LimitҎ(gu),eXtremeTable需要用limit特定的RetrieveRowsCallback?FilterRowsCallback和SortRowsCallback接口。eXtremeComponents提供了每个接口的一个实玎ͼ可以单地通过讄每个属性gؓlimit来简单来使用? 另外视图属性参照一个名为limit的定制视图。这是一个简单修攚w认eXtremeTable视图Q不包含最后页工具条的实现。这仅仅关系C是否能取得确切需要的行?一些数据库例如Oracle和MySQL都提供了一U得到确定行的特性,但是Q其他的数据库例如:Sybase没有提供Ҏ(gu)。在我的CZ中我考虑最坏的情况你的数据库不支持q种Ҏ(gu)?/p>
即你的数据库不提供取得特定行的Ҏ(gu),当你考虑用户如何和表协同工作ӞLimit仍然非常有意义。用户通常会对一些数据进行排序、过滤和分页?q个例子?5条数据构成一,W一需?5条数据,W二需?0条数据,W三需?5条数据,以此cL。在l过一D|间分后Q他们常怋用过滤来提炼数据?即他们不这样做Q他们也必须在此之前对大量的数据q行分页Q这媄响效率。当然如果允许用LL后页Q那么所有的数据都将被取出,q将非常影响效率?/p>
提示QSpring框架的Controller和Struts框架的Action非常相像?/em> controller首先需要创Z个Limit。ؓ了完成这个你需要得C些关于Context和LimitFactory的帮助?/p>
Context是一个处理取得属性的接口QLimitFactory使用Context来找出用户如何和eXtremeTable交互?然后Limit使用LimitFactory来组装自己?/p>
Z初始化LimitQ它?yu)包含所有的有用的信息。这些信息包括数据将被如何排序和qoQ哪一将被显C和是否允许被导出?/p>
然而,Limit仍然需要得到行的信息,q样正确的信息页面才能被昄l用戗行信息包括开始行、结束行、当前显C?controller必须从service得到q些信息Q而Service从dao中得到这些信息。这里我只给出Controller端的代码?/p>
limit需要得到所有的行来得到行的信息。service需要知道那些被qoQ不这些数据是否要导出。ؓ了设|行信息Q默认的一|C的行数需要被讄?q可以通过对TableTag的rowsDisplayed属性设|一个确定的数值来实现?/p>
现在我们只需要从services得到Collection数据?/p>
因ؓlimit已经包含所有信息,q将十分Ҏ(gu)。所有需要做的就是传入过滤器Q排序和最后行的信息?最后要做的是将Collections和totalRowq些信息传送回JSP以便eXtremeTable知道如何昄q些信息?/p>
service需要和daoq行交互来得到总行数和Collection?/p>
controller需要到W一条信息就是总行数?/p>
service和dao一hqol果集,它的工作方式是在Where语句后面增加更多的AND语句来修Ҏ(gu)询字W串。ؓ此,你需要和Limit FilterSet一起工作?/p>
FilterSet是一个过滤器对象数组Q一个过滤器包括一个bean property和这个过滤器的倹{或者,单的说就是用h要过滤的行和他们输入的倹{这使得它非常容易交互。service只需要P代所有的 FilterSetq调用dao来拼接查询语句。(译者注Q过滤的实现方式是:在Where后面增加And语句来改变查询语句以辑ֈҎ(gu)据进行过滤的效果Q?/p>
query修改包括了filter信息Q总行数。在一些情况下q就_Q但是当用户导出数据时仍然存在一个潜在的问题。ؓ了保持高?service不允许导Z个最大行数的数据?/p>
controller需要到W二条信息就是Collection?/p>
和前面一Pservice和dao一hqol果集?/p>
另外query字符串需要扩展ORDER BY语句以便数据按照正确的方式进行排序。Sort包含一个bean property?sortOrder|正序q是逆序Q。service仅仅需要用Sort来调用dao?/p>
query字符串最后需要的修改是增加数据库特别的指o来limit要被返回的l果集。这是limitQuery() Ҏ(gu)的作用?/p>
dao为service负责底层数据工作?/p>
Z真正理解daoQquery字符串需要被展示?/p>
q就是得到数据的presidents query字符Ԍ q是得到总行数的query字符Ԍ 两个最有趣的方法就是过滤和排序?/p>
filter看v来像q样Q?/p>
filterQuery()Ҏ(gu)需要增加正的AND语句到query字符丌Ӏ?/p>
sort看v来非常类| sortQuery()Ҏ(gu)需要增加正的ORDER BY语句到query字符丌Ӏ?/p>
现在query字符串修改能够正的q行filter和sortQ它q需要修改以便只取页面显C相关的数据。MySQL为s the limit命o?/p>
service需要的唯一东西是Q总行数和Collection?/p>
ResultReader是一个帮助处理JDBC查询的SpringҎ(gu)c,作ؓ一个callback来处理JDBC ResultSet。jdbcTemplate是对JDBCq接的抽象?/p>
Z讄全局属性和讄Q你需要用PreferencesҎ(gu),它现在用一个属性文件来实现。本文很好地介绍如何在web.xml里设|PreferencesQ?以及一些需要被定义的通用属性。在q里我非怹意介l一些关于Preferences的进一步用法?/p>
所有标{ֱ性表CZ个可插接的接口,它可以通过l出实现的全路径来设|。这为插接实现提供了一条便利的途径。当然这存在一些ؓq长术语的设计和l护的考虑?W一Q对你的接口实现q行编码;W二Q如果你需要在别的JSP中用到同一个接口实玎ͼ你需要拷贝你全\径。解册两个问题的有效办法就是在Preferences中声明一切?/p>
下面列出的是可以在Preferences中申明的所有接口。Tag列展C的是eXtremeTable的标{,Attribute 列展C的是相x{对应属性。Interface列展C的是需要被实现的Java接口。Preference Key列展C的?Preferences里对应的健?/p>
提示Q当在写作本指南的时候,我意识到我忘C让标{ColumnsTag的autoGenerateColumns 属性和Preferences协同工作。这在下一版修正?/em> 上表展示了如何声明preference键,但是没有解释如何指定有意义的别名。如果你注意到preference键提供了一致的语法 tag.attributeQ指定键的别名仅仅是在它的基上进行扩展。它的语法ؓQ?tag.attribute.alias?/p>
eXtremeTable提供了一个名为RowCountCell定制的cellQ它的作用是现实当前的行数。我在Preferences里用ColumnTag cell声明来示范RowCountCell的用?/p>
首先通过实现Cell接口或者扩展AbstractCell来编写具体的实现cR?/p>
然后在Preferences (属性文?q行声明q给出别名?span class="emphasis">eXtremeTable在一个Preferences里保存所有的配置信息Q你可以通过使用本地 Preferences的来覆盖M的这些属性?/em> RowCountCell默认的别名是rowCountQ?/p>
在ColumnTag中通过别名引用CellQ?/p>
现在你可以通过rowCount来引用这个CellQ如果包名改变了你只需要对Preferencesq行修改?/p>
提示Q本CZ中我使用了ColumnTag的别名属性。别名属性应用在有两列用同LpropertyQ也应用在列不直接和列的 bean property兌的情况下。本CZ属于这U情c?/em> servlet 2.3?br> tomcat自带?servlet 2.4的?br> 把web.xml的声明部分改?.4的即可?br>q有是如果使用?lt;taglib>标签需要加<jsp-config>父标{。具体内容看jsp2.0和servlet2.4规范 <jsp-config> Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1667667 ecside是一个开源的列表lg?br>他源自著名开源列表组?eXtremeComponents Qhttp://www.extremecomponents.orgQ, 作者: fins ( name: Wei Zijun email:fins@163.com blog:http://fins.javaeye.com ) 在用前Q请阅读一下以下信息,以帮助?zhn)了解?zhn)要使用的将是一个多么不成熟的东?但它会有成熟的一天,而且那天不会q?呵呵)Q?br>1 ecside不能和原始版本的 eXtremeComponents 同时使用Q且不保证能与原先?eXtremeComponents 的系l兼容,误谅?br>2 目前只支持GBK~码的应用,误谅?br>3 目前只在IE6 和FireFox2 上进行过试Q不保证兼容其他(版本)览器,误谅?br>4 目前提供的样式风格巨丑无比,误谅?br>5 目前没有完备的文档和例子Q请见谅?br>6 代码没有注释Q没有测试用例,误谅?br>7 没有很好的版本控Ӟ没有构徏脚本Q请见谅?br>8 拥有无数未知的bugQ请见谅?/font> ecside发布地址Q?br>http://fins.javaeye.com/blog/40190 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ =============================== 1) 实现?strong>cell的映功?/font>Q详见示例的性别 ?角色列),用法: 例如Q在CZ中,角色的信息以 “标识--名称”的Ş式放C一?map?br>在action?把这个map攑ֈ?request.setAttribute("USERROLE_MAP", CommonDictionary.USERROLE);?br>在页面?br> =============================== Z问一下: =============================== =============================== =============================== =============================== =============================== 使用Ҏ(gu)Q?br>ec:table标签?增加 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 部分增强功能介: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 我们有自q圈子? ecside发布地址Q?br>http://fins.javaeye.com/blog/40190 我申请了javascud目 而且也申请了svn 但是不会用啊 :'( 谁来教教我啊 依赖包已l上传到 圈子的共享空间里?/strong> ??误压羃后放?WEB-INF/lib?如果不导出pdf可以不下载pdf相关的包 ?字体文g q两个比较大
]]>
public class FilteredDroplistCell extends FilterDroplistCell {
private static Log logger = LogFactory.getLog(FilterDroplistCell.class);
protected List getFilterDropList(TableModel model, Column column) {
List droplist = new ArrayList();
String firstNameFilter = model.getLimit().getFilterSet().getValue("firstName");
Collection beans = model.getCollectionOfBeans();
for (Iterator iter = beans.iterator(); iter.hasNext();) {
Object bean = iter.next();
try {
String firstName = BeanUtils.getProperty(bean, "firstName");
if (StringUtils.isNotBlank(firstNameFilter) && !firstName.equals(firstNameFilter)) {
continue;
}
String lastName = BeanUtils.getProperty(bean, column.getProperty());
if ((lastName != null) && !droplist.contains(lastName)) {
droplist.add(lastName);
}
} catch (Exception e) {
logger.debug("Problems getting the droplist.", e);
}
}
Collections.sort(droplist);
return droplist;
}
}
String firstNameFilter = model.getLimit().getFilterSet().getValue("firstName");
String firstName = BeanUtils.getProperty(bean, "firstName");
if (StringUtils.isNotBlank(firstNameFilter) && !firstName.equals(firstNameFilter)) {
continue;
}
String lastName = BeanUtils.getProperty(bean, column.getProperty());
if ((lastName != null) && !droplist.contains(lastName)) {
droplist.add(lastName);
}column.filterCell.filteredDroplist=org.extremesite.cell.FilteredDroplistCell
<ec:column property="lastName" filterCell="filteredDroplist"/>
public final class ExactMatchFilterPredicate implements Predicate {
private boolean isSearchMatch(String value, String search) {
...
else if (StringUtils.equals(value, search)) {
return true;
}
...
}
}
public class ExactMatchFilterRows implements FilterRowsCallback {
public Collection filterRows(TableModel model, Collection rows) throws Exception {
...
if (filtered) {
Collection collection = new ArrayList();
Predicate filterPredicate = new ExactMatchFilterPredicate(model);
CollectionUtils.select(rows, filterPredicate, collection);
return collection;
}
...
}
}
table.filterRowsCallback.exactMatch=org.extremesite.callback.ExactMatchFilterRows
<ec:table filterRowsCallback="exactMatch"/>
<form id="presForm" action="<c:url value="http://blog.techweb.com.cn/selectedPresidentsListedController.run"/>" method="post">
Enter your name:
<input
type="text"
name="userName"
style="font-family:verdana,arial,helvetica,sans-serif;font-size:11px;"
value="<c:out value="http://blog.techweb.com.cn/${param.userName}"/>"
/>
<ec:table
items="presidents"
action="${pageContext.request.contextPath}/selectedPresidentsController.run"
view="compact"
imagePath="${pageContext.request.contextPath}/images/table/compact/*.gif"
rowsDisplayed="8"
autoIncludeParameters="false"
form="presForm"
>
<ec:exportPdf
fileName="output.pdf"
tooltip="Export PDF"
headerColor="black"
headerBackgroundColor="#b6c2da"
headerTitle="Presidents"
/>
<ec:row>
<ec:column
alias="checkbox"
title=" "
width="5px"
filterable="false"
sortable="false"
viewsAllowed="compact"
cell="selectedPresident"
/>
<ec:column property="fullName" title="Name"/>
<ec:column property="nickName" />
<ec:column property="term" />
</ec:row>
</ec:table>
<input
type="button"
name="sel"
class="button"
value="List Selected Presidents"
onclick="document.forms.presForm.submit();"
/>
<script type="text/javascript">
function setPresidentState(chkbx) {
//make sure that always know the state of the checkbox
if (chkbx.checked) {
eval('document.forms.presForm.chkbx_' + chkbx.name).value='SELECTED';
} else {
eval('document.forms.presForm.chkbx_' + chkbx.name).value='UNSELECTED';
}
}
</script>
</form>column.cell.selectedPresident=org.extremesite.cell.SelectedPresidentCell
<ec:column
alias="checkbox"
title=" "
width="5px"
filterable="false"
sortable="false"
viewsAllowed="compact"
cell="org.extremesite.cell.SelectedPresidentCell"
/>public class SelectedPresidentCell implements Cell {
public String getExportDisplay(TableModel model, Column column) {
return null;
}
public String getHtmlDisplay(TableModel model, Column column) {
HtmlBuilder html = new HtmlBuilder();
CellBuilder.tdStart(html, column);
try {
Object bean = model.getCurrentRowBean();
String presidentId = BeanUtils.getProperty(bean, "presidentId");
Collection selectedPresidentsIds = (Collection)model.getContext().getSessionAttribute(SelectedPresidentsConstants.SELECTED_PRESIDENTS);
if (selectedPresidentsIds != null && selectedPresidentsIds.contains(presidentId)) {
html.input("hidden").name("chkbx_" + presidentId).value(SelectedPresidentsConstants.SELECTED).xclose();
html.input("checkbox").name(BeanUtils.getProperty(bean, "presidentId"));
html.onclick("setPresidentState(this)");
html.checked();
html.xclose();
} else {
html.input("hidden").name("chkbx_" + presidentId).value(SelectedPresidentsConstants.UNSELECTED).xclose();
html.input("checkbox").name(BeanUtils.getProperty(bean, "presidentId"));
html.onclick("setPresidentState(this)");
html.xclose();
}
} catch (Exception e) {}
CellBuilder.tdEnd(html);
return html.toString();
}
}SelectedPresidentsUtils.saveSelectedPresidentsIDs(request);
Collection presidents = presidentsService.getPresidents();
request.setAttribute("presidents", presidents);Collection selectedPresidentsIds = SelectedPresidentsUtils.saveSelectedPresidentsIDs(request);
Collection selectedPresidents = SelectedPresidentsUtils.getSelectedPresidents(presidentsService.getPresidents(), selectedPresidentsIds);
request.setAttribute("selected", selectedPresidents);
request.getSession().removeAttribute(SelectedPresidentsConstants.SELECTED_PRESIDENTS);public static Collection saveSelectedPresidentsIDs(HttpServletRequest request) {
Collection presidents = (Collection) request.getSession().getAttribute(SelectedPresidentsConstants.SELECTED_PRESIDENTS);
if (presidents == null) {
presidents = new ArrayList();
request.getSession().setAttribute(SelectedPresidentsConstants.SELECTED_PRESIDENTS, presidents);
}
Enumeration parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()) {
String parameterName = (String) parameterNames.nextElement();
if (parameterName.startsWith("chkbx_")) {
String presidentId = StringUtils.substringAfter(parameterName, "chkbx_");
String parameterValue = request.getParameter(parameterName);
if (parameterValue.equals(SelectedPresidentsConstants.SELECTED)) {
if (!presidents.contains(presidentId)) {
presidents.add(presidentId);
}
} else {
presidents.remove(presidentId);
}
}
}
return presidents;
}public interface View {
public void beforeBody(TableModel model);
public void body(TableModel modelQ?Column column);
public Object afterBody(TableModel model);
}
public class MessagesView extends AbstractHtmlView {
protected void toolbar(TableModel model) {
TwoColumnTableLayout toolbar = new MessagesToolbar();
toolbar.layout(getHtmlBuilder()Q?model);
}
protected void statusBar(TableModel model) {
TwoColumnRowLayout statusBar = new MessagesStatusBar();
statusBar.layout(getHtmlBuilder()Q?model);
}
}
public abstract class TwoColumnTableLayout {
protected abstract boolean showLayout(TableModel model);
protected abstract void columnLeft(HtmlBuilder htmlQ?TableModel model);
protected abstract void columnRight(HtmlBuilder htmlQ?TableModel model);
}
protected boolean showLayout(TableModel model) {
boolean showPagination = BuilderUtils.showPagination(model);
boolean showExports = BuilderUtils.showExports(model);
if (!showPagination && !showExports) {
return false;
}
return true;
}protected void columnLeft(HtmlBuilder htmlQ?TableModel model) {
html.td(2).close();
TableBuilder.title(htmlQ?model);
html.tdEnd();
}
protected void columnRight(HtmlBuilder htmlQ?TableModel model) {
boolean showPagination = BuilderUtils.showPagination(model);
...
if (showPagination) {
html.td(4).close();
ToolbarBuilder.firstPageItemAsText(htmlQ?model);
html.tdEnd();
html.td(4).close();
ToolbarBuilder.prevPageItemAsText(htmlQ?model);
html.tdEnd();
...
}
...
}
table.view.messages=org.extremesite.view.MessagesView
<ec:table view="messages">
标签
接口
Bean
TableTag
org.extremecomponents.table.intercept.InterceptTable
org.extremecomponents.table.bean.Table
RowTag
org.extremecomponents.table.intercept.InterceptRow
org.extremecomponents.table.bean.Row
ColumnTag
org.extremecomponents.table.intercept.InterceptColumn
org.extremecomponents.table.bean.Column
ExportTag
org.extremecomponents.table.intercept.InterceptExport
org.extremecomponents.table.bean.Export
public class MarkerIntercept implements InterceptRow {
public void addRowAttributes(TableModel tableModel, Row row) {
}
public void modifyRowAttributes(TableModel model, Row row) {
President president = (President) model.getCurrentRowBean();
String career = president.getCareer();
if (StringUtils.contains(career, "Soldier")) {
row.setStyle("background-color:#fdffc0;");
} else {
row.setStyle("");
}
}
}
row.intercept.marker=org.extremesite.intercept.MarkerIntercept
<ec:row intercept="marker">
<ec:table
items="presidents"
retrieveRowsCallback="limit"
filterRowsCallback="limit"
sortRowsCallback="limit"
view="limit"
>
...Context context = new HttpServletRequestContext(request);
LimitFactory limitFactory = new TableLimitFactory(context);
Limit limit = new TableLimit(limitFactory);int totalRows = presidentsService.getTotalPresidents(limit.getFilterSet(), limit.isExported());
limit.setRowAttributes(totalRows, defaultRowsDisplayed);Collection presidents = presidentsService.getPresidents(limit.getFilterSet(), limit.getSort(), limit.getRowEnd());
request.setAttribute("presidents", presidents);
request.setAttribute("totalRows", new Integer(totalRows));public int getTotalPresidents(FilterSet filterSet, boolean isExported) {
String totalQuery = presidentsDao.getTotalPresidentsQuery();
String modTotalQuery = filterQuery(filterSet, totalQuery);
int totalRows = presidentsDao.getTotalPresidents(modTotalQuery);
if (isExported && totalRows > maxExportRows) {
totalRows = maxExportRows;
}
return totalRows;
}private String filterQuery(FilterSet filterSet, String query) {
if (!filterSet.isFiltered() || filterSet.isCleared()) {
return query;
}
Filter filters[] = filterSet.getFilters();
for (int i = 0; i < filters.length; i++) {
Filter filter = filters[i];
String property = filter.getProperty();
String value = filter.getValue();
query = presidentsDao.filterQuery(query, property, value);
}
return query;
}public Collection getPresidents(FilterSet filterSet, Sort sort, int rowEnd) {
String patientsQuery = presidentsDao.getPresidentsQuery();
String modPatientsQuery = filterQuery(filterSet, patientsQuery);
modPatientsQuery = sortQuery(sort, modPatientsQuery);
modPatientsQuery = presidentsDao.limitQuery(rowEnd, modPatientsQuery);
return presidentsDao.getPresidents(modPatientsQuery);
}private String sortQuery(Sort sort, String query) {
if (!sort.isSorted()) {
String defaultSortOrder = presidentsDao.getDefaultSortOrder();
if (StringUtils.isNotBlank(defaultSortOrder)) {
return query + defaultSortOrder;
}
return query;
}
String property = sort.getProperty();
String sortOrder = sort.getSortOrder();
return presidentsDao.sortQuery(query, property, sortOrder);
}
private final static String presidentsQuery =
" SELECT " +
" president_id presidentId, " +
" first_name firstName, " +
" last_name lastName, " +
" nick_name nickName, " +
" concat(first_name, ' ',last_name) fullName, " +
" term, " +
" born, " +
" died, " +
" education, " +
" career, " +
" political_party politicalParty " +
" FROM presidents ";private final static String totalPresidentsQuery =
" SELECT count(*) FROM presidents ";public String filterQuery(String query, String property, String value) {
StringBuffer result = new StringBuffer(query);
if (query.indexOf("WHERE") == -1) {
result.append(" WHERE 1 = 1 "); //stub WHERE clause so can just append AND clause
}
if (property.equals("fullName")) {
result.append(" AND concat(first_name, ' ',last_name) like '%" + value + "%'");
} else if (property.equals("nickName")) {
result.append(" AND nick_name like '%" + value + "%'");
} else {
result.append(" AND " + property + " like '%" + value + "%'");
}
return result.toString();
}public String sortQuery(String query, String property, String sortOrder) {
StringBuffer result = new StringBuffer(query + " ORDER BY ");
if (property.equals("fullName")) {
result.append("concat(first_name, ' ',last_name) " + sortOrder);
} else {
result.append(property + " " + sortOrder);
}
return result.toString();
}public String limitQuery(int rowEnd, String query) {
return query + " limit " + rowEnd;
}public Collection getPresidents(final String query) {
return jdbcTemplate.query(query, new ResultReader() {
List results = new ArrayList();
public List getResults() {
return results;
}
public void processRow(ResultSet rs)
throws SQLException {
President president = new President();
president.setPresidentId(new Integer(rs.getInt("presidentId")));
president.setFirstName(rs.getString("firstName"));
president.setLastName(rs.getString("lastName"));
president.setNickName(rs.getString("nickName"));
president.setFullName(rs.getString("fullName"));
president.setTerm(rs.getString("term"));
president.setBorn(rs.getDate("born"));
president.setDied(rs.getDate("died"));
president.setEducation(rs.getString("education"));
president.setCareer(rs.getString("career"));
president.setPoliticalParty(rs.getString("politicalParty"));
results.add(president);
}
});
}
public int getTotalPresidents(final String query) {
return jdbcTemplate.queryForInt(query);
}
Tag
Attribute
Interface
Preference Key
TableTag
filterRowsCallback
org.extremecomponents.table.callback.FilterRowsCallback
table.filterRowsCallback
TableTag
intercept
org.extremecomponents.table.intercept.InterceptTable
table.intercept
TableTag
retrieveRowsCallback
org.extremecomponents.table.callback.RetrieveRowsCallback
table.retrieveRowsCallback
TableTag
sortRowsCallback
org.extremecomponents.table.callback.SortRowsCallback
table.sortRowsCallback
TableTag
state
org.extremecomponents.table.state.State
table.state
TableTag
view
org.extremecomponents.table.view.View
table.view
RowTag
intercept
org.extremecomponents.table.intercept.InterceptRow
row.intercept
ColumnTag
calc
org.extremecomponents.table.calc.Calc
column.calc
ColumnTag
cell
org.extremecomponents.table.cell.Cell
column.cell
ColumnTag
filterCell
org.extremecomponents.table.cell.Cell
column.filterCell
ColumnTag
headerCell
org.extremecomponents.table.cell.Cell
column.headerCell
ColumnTag
intercept
org.extremecomponents.table.intercept.InterceptColumn
column.intercept
ExportTag
intercept
org.extremecomponents.table.intercept.InterceptExport
export.intercept
ExportTag
view
org.extremecomponents.table.view.View
export.view
ExportTag
viewResolver
org.extremecomponents.table.filter.ViewResolver
export.viewResolver
public class RowCountCell extends AbstractCell {
protected String getCellValue(TableModel model, Column column) {
int rowcount = ((model.getLimit().getPage() - 1)
* model.getLimit().getCurrentRowsDisplayed())
+ model.getRowHandler().getRow().getRowCount();
return String.valueOf(rowcount);
}
}
column.cell.rowCount=org.extremecomponents.table.cell.RowCountCell
<ec:column alias="count" cell="rowCount"/>
]]>
以下是dtree的用法示例:
1Q初始化菜单
<script type="text/javascript">
<!--
var Tree = new Array;
// nodeId | parentNodeId | nodeName | nodeUrl
Tree[0] = "1|0|Page 1|#";
Tree[1] = "2|1|Page 1.1|#";
Tree[2] = "3|1|Page 1.2|#";
Tree[3] = "4|3|Page 1.2.1|#";
Tree[4] = "5|1|Page 1.3|#";
Tree[5] = "6|2|Page 1.1.1|#";
Tree[6] = "7|6|Page 1.1.1.1|#";
Tree[7] = "8|6|Page 1.1.1.2|#";
Tree[8] = "9|1|Page 1.4|#";
Tree[9] = "10|9|Page 1.4.1|#";
Tree[10] = "11|0|Page 2|#";
//-->
</script>
2Q调用函?br />
<div class="tree">
<script type="text/javascript">
<!--
createTree(Tree,1,7); // starts the tree at the top and open it at node nr. 7
//-->
</script>
</div>
`node_id` INTEGER UNSIGNED NOT NULL DEFAULT -1,
`parent_id` INTEGER UNSIGNED NOT NULL DEFAULT -1,
`node_name` VARCHAR(45) NOT NULL,
`ref_url` VARCHAR(45) NOT NULL,
PRIMARY KEY(`node_id`)
)
我用mysql数据库,如果脚本l节有出入,误行修?br />
按照上面的dTreeCZ插入数据
2Q编写TreeInfo.javaQ这个类用于装节点信息
package com.diegoyun.web.tree;
/**
* @author Diegoyun
* @version 1.0
*/
public class TreeInfo {
private int nodeId = -1;//node id
private int parentId = -1;//parentId
private String nodeName = null;//node name
private String url = null;//url references
return nodeId;
}
this.nodeId = nodeId;
}
return parentId;
}
this.parentId = parentId;
}
return nodeName;
}
this.nodeName = nodeName;
}
return url;
}
this.url = url;
}
~写TreeUtil.javaQ用于从数据库得到节点信息,装到TreeInfo对象Qƈ生成javascript脚本
TreeUtil.java
package com.diegoyun.web.tree;
import java.util.Collection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Connection;
import java.sql.DriverManager;
* @author Diegoyun
* @version 1.0
*/
public class TreeUtil {
public static List retrieveNodeInfos(){
List coll = new ArrayList();
String host = "localhost";
String port = ":3306";
String serverID = "test";
String userName = "root";
String userPwd = "root";
String url = "jdbc:mysql://" + host + port + "/" + serverID ;
PreparedStatement ps = null;
ResultSet rs = null;
try{
Class.forName(driverName).newInstance();
conn = DriverManager.getConnection(url , userName , userPwd);
String sql = "select * from tree_info";
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
while(rs!=null && rs.next()){
info = new TreeInfo();
info.setNodeId(rs.getInt(1));
info.setParentId(rs.getInt(2));
info.setNodeName(rs.getString(3));
info.setUrl(rs.getString(4));
coll.add(info);
}
// if(rs!=null){
// rs.close();
// rs=null;
// }
// if(ps!=null){
// ps.close();
// ps=null;
// }
}catch(Exception e){
System.out.println(e);
}
return coll;
}
public static String createTreeInfo(List alist){
StringBuffer contents = new StringBuffer();
contents.append("<!--\n");
contents.append("var Tree = new Array;");//create a array in javascript
TreeInfo info =null;
for(int max = alist.size(),i=0;i<max;i++){
info = (TreeInfo)alist.get(i);
//define elements of array
contents.append("Tree[");
contents.append(i);
contents.append("]=\"");
contents.append(info.getNodeId());
contents.append("|");
contents.append(info.getParentId());
contents.append("|");
contents.append(info.getNodeName());
contents.append("|");
contents.append(info.getUrl());
contents.append("\";");
}
contents.append("http://-->");
}
public static void main(String[]args){
List alist = TreeUtil.retrieveNodeInfos();
// TreeInfo info = null;
// for(Iterator i = c.iterator();i.hasNext();){
// info = (TreeInfo)i.next();
// System.out.println("*****" + info.getNodeName());
// }
System.out.println(TreeUtil.createTreeInfo(alist));
}
}
package com.diegoyun.web.taglibs;
import com.diegoyun.web.tree.TreeUtil;
import javax.servlet.jsp.tagext.TagSupport;
import javax.servlet.jsp.JspException;
import java.io.IOException;
* @author Diegoyun
* @version 1.0
*/
public class InitTreeTag extends TagSupport{
StringBuffer tree = new StringBuffer();
tree.append("<script type=\"text/javascript\">\n");
tree.append(TreeUtil.createTreeInfo(TreeUtil.retrieveNodeInfos()));
tree.append("</script>\n");
try{
pageContext.getOut().println(tree.toString());
}catch(IOException ioe){
ioe.printStackTrace();
}
return super.doEndTag();
}
}
import javax.servlet.jsp.JspException;
import java.io.IOException;
* @author Diegoyun
* @version 1.0
*/
public class ShowTreeTag extends TagSupport{
public int doEndTag() throws JspException {
StringBuffer buffer = showTree();
try {
pageContext.getOut().println(buffer.toString());
}
catch (IOException ioe) {
ioe.printStackTrace();
}
return super.doEndTag();
}
private StringBuffer showTree(){
StringBuffer sb = new StringBuffer();
sb.append("<div class=\"tree\">\n");
sb.append("<script type=\"text/javascript\">\n");
sb.append("<!--\n");
sb.append("createTree(TreeQ?Q?);\n");
sb.append("http://-->\n");
sb.append("</script>\n");
sb.append("</div>\n");
return sb;
}
}
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>tree</short-name>
<!--initTreeTag-->
<tag>
<name>init</name>
<tag-class>com.diegoyun.web.taglibs.InitTreeTag</tag-class>
<body-content>empty</body-content>
</tag>
<!--ShowTreeTag-->
<tag>
<name>show</name>
<tag-class>com.diegoyun.web.taglibs.ShowTreeTag</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
<%@ taglib uri="/WEB-INF/tlds/tree.tld" prefix="tree"%>
<html>
<head>
<title>Tree example</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="StyleSheet" href="tree.css" type="text/css">
<script type="text/javascript" src="tree.js"></script>
<tree:init/>
</head>
<b>Tree example :</b><br /><br />
<tree:show/>
<br /><br />
</html>
]]>
<HEAD>
<TITLE></TITLE>
<META content="text/html; charset=gb2312" http-equiv=Content-Type>
<META content="MSHTML 5.00.2920.0" name=GENERATOR>
<script>
<!--
// menu object
function contextMenu()
{
this.items = new Array();
this.addItem = function (item)
{
this.items[this.items.length] = item;
}
this.show = function (oDoc)
{
var strShow = "";
var i;
strShow = "<div id=\"rightmenu\" style=\"BACKGROUND-COLOR: #ffffff; BORDER: #000000 1px solid; LEFT: 0px; POSITION: absolute; TOP: 0px; VISIBILITY: hidden; Z-INDEX: 10\">";
strShow += "<table border=\"0\" height=\"";
strShow += this.items.length * 20;
strShow += "\" cellpadding=\"0\" cellspacing=\"0\">";
strShow += "<tr height=\"3\"><td bgcolor=\"#d0d0ce\" width=\"2\"></td><td>";
strShow += "<table border=\"0\" width=\"100%\" height=\"100%\" cellpadding=0 cellspacing=0 bgcolor=\"#ffffff\">";
strShow += "<tr><td bgcolor=\"#d0d0ce\" width=\"23\"></td><td><img src=\" \" height=\"1\" border=\"0\"></td></tr></table>";
strShow += "</td><td width=\"2\"></td></tr>";
strShow += "<tr><td bgcolor=\"#d0d0ce\"></td><td>";
strShow += "<table border=\"0\" width=\"100%\" height=\"100%\" cellpadding=3 cellspacing=0 bgcolor=\"#ffffff\">";
oDoc.write(strShow);
for(i=0; i<this.items.length; i++)
{
this.items[i].show(oDoc);
}
strShow = "</table></td><td></td></tr>";
strShow += "<tr height=\"3\"><td bgcolor=\"#d0d0ce\"></td><td>";
strShow += "<table border=\"0\" width=\"100%\" height=\"100%\" cellpadding=0 cellspacing=0 bgcolor=\"#ffffff\">";
strShow += "<tr><td bgcolor=\"#d0d0ce\" width=\"23\"></td><td><img src=\" \" height=\"1\" border=\"0\"></td></tr></table>";
strShow += "</td><td></td></tr>";
strShow += "</table></div>\n";
oDoc.write(strShow);
}
}
// menu Item object
function contextItem(text, icon, cmd, type)
{
this.text = text ? text : "";
this.icon = icon ? icon : "";
this.cmd = cmd ? cmd : "";
this.type = type ? type : "menu";
this.show = function (oDoc)
{
var strShow = "";
if(this.type == "menu")
{
strShow += "<tr ";
strShow += " 'on');\" ";
strShow += " 'out');\" ";
strShow += "onclick=\"";
strShow += this.cmd;
strShow += "\">";
strShow += "<td class=\"ltdexit\" width=\"16\">";
if (this.icon == "")
strShow += " ";
else {
strShow += "<img border=\"0\" src=\"";
strShow += this.icon;
strShow += "\" width=\"16\" height=\"16\" style=\"POSITION: relative\"></img>";
}
strShow += "</td><td class=\"mtdexit\">";
strShow += this.text;
strShow += "</td><td class=\"rtdexit\" width=\"5\"> </td></tr>";
}
else if (this.type == "separator")
{
strShow += "<tr><td class=\"ltdexit\"> </td>";
strShow += "<td class=\"mtdexit\" colspan=\"2\"><hr color=\"#000000\" size=\"1\"></td></tr>";
}
oDoc.write(strShow);
}
}
function changeStyle(obj, cmd)
{
if(obj) try {
var imgObj = obj.children(0).children(0);
if(cmd == 'on') {
obj.children(0).className = "ltdfocus";
obj.children(1).className = "mtdfocus";
obj.children(2).className = "rtdfocus";
if(imgObj)
{
if(imgObj.tagName.toUpperCase() == "IMG")
{
imgObj.style.left = "-1px";
imgObj.style.top = "-1px";
}
}
}
else if(cmd == 'out') {
obj.children(0).className = "ltdexit";
obj.children(1).className = "mtdexit";
obj.children(2).className = "rtdexit";
if(imgObj)
{
if(imgObj.tagName.toUpperCase() == "IMG")
{
imgObj.style.left = "0px";
imgObj.style.top = "0px";
}
}
}
}
catch (e) {}
}
function showMenu()
{
var x, y, w, h, ox, oy;
x = event.clientX;
y = event.clientY;
var obj = document.getElementById("rightmenu");
if (obj == null)
return true;
ox = document.body.clientWidth;
oy = document.body.clientHeight;
if(x > ox || y > oy)
return false;
w = obj.offsetWidth;
h = obj.offsetHeight;
if((x + w) > ox)
x = x - w;
if((y + h) > oy)
y = y - h;
obj.style.posLeft = x + document.body.scrollLeft;
obj.style.posTop = y + document.body.scrollTop;
obj.style.visibility = "visible";
return false;
}
function hideMenu()
{
if(event.button == 0)
{
var obj = document.getElementById("rightmenu");
if (obj == null)
return true;
obj.style.visibility = "hidden";
obj.style.posLeft = 0;
obj.style.posTop = 0;
}
}
function writeStyle()
{
var strStyle = "";
strStyle += "<STYLE type=text/css>";
strStyle += "TABLE {Font-FAMILY: \"Tahoma\",\"Verdana\",\"宋体\"; FONT-SIZE: 9pt}";
strStyle += ".mtdfocus {BACKGROUND-COLOR: #ccccff; BORDER-BOTTOM: #000000 1px solid; BORDER-TOP: #000000 1px solid; CURSOR: hand}";
strStyle += ".mtdexit {BACKGROUND-COLOR: #ffffff; BORDER-BOTTOM: #ffffff 1px solid; BORDER-TOP: #ffffff 1px solid}";
strStyle += ".ltdfocus {BACKGROUND-COLOR: #ccccff; BORDER-BOTTOM: #000000 1px solid; BORDER-TOP: #000000 1px solid; BORDER-LEFT: #000000 1px solid; CURSOR: hand}";
strStyle += ".ltdexit {BACKGROUND-COLOR: #d0d0ce; BORDER-BOTTOM: #d0d0ce 1px solid; BORDER-TOP: #d0d0ce 1px solid; BORDER-LEFT: #d0d0ce 1px solid}";
strStyle += ".rtdfocus {BACKGROUND-COLOR: #ccccff; BORDER-BOTTOM: #000000 1px solid; BORDER-TOP: #000000 1px solid; BORDER-RIGHT: #000000 1px solid; CURSOR: hand}";
strStyle += ".rtdexit {BACKGROUND-COLOR: #ffffff; BORDER-BOTTOM: #ffffff 1px solid; BORDER-TOP: #ffffff 1px solid; BORDER-RIGHT: #ffffff 1px solid}";
strStyle += "</STYLE>";
document.write(strStyle);
}
function makeMenu()
{
var myMenu, item;
var homepage_cmd = "this.style.behavior='url(#default#homepage)';this.setHomePage('http://baby.mob8.cn/'); return false;";
var favorate_cmd = "window.external.addFavorite('http://baby.mob8.cn','|页教学|?); return false;";
var viewcode_cmd = "window.location = 'view-source:' + window.location.href";
myMenu = new contextMenu();
item = new contextItem("q回主页", "http://www.webjx.com/js/home.gif", "top.location='http://baby.mob8.cn/';", "menu");
myMenu.addItem(item);
item = new contextItem("设ؓ主页", "http://www.webjx.com/js/home.gif", homepage_cmd, "menu");
myMenu.addItem(item);
item = new contextItem("d到收藏夹", "http://www.webjx.com/js/favadd.gif", favorate_cmd, "menu");
myMenu.addItem(item);
item = new contextItem("联系作?, "http://www.webjx.com/js/mail.gif", "location.href='mailto:46235412@qq.com'", "menu");
myMenu.addItem(item);
item = new contextItem("", "", "", "separator");
myMenu.addItem(item);
item = new contextItem("察看源码", "http://www.webjx.com/js/edit.gif", viewcode_cmd, "menu");
myMenu.addItem(item);
myMenu.show(this.document);
delete item;
delete myMenu;
}
function toggleMenu(isEnable)
{
if(isEnable)
document.oncontextmenu = showMenu;
else
document.oncontextmenu = new function() {return true;};
}
writeStyle();
makeMenu();
document.onclick = hideMenu;
document.oncontextmenu = showMenu;
file://-->
</script>
</HEAD>
<body marginwidth="0" marginheight="0" leftmargin="0" topmargin="0">
<table border="0" width="100%" height="100%" cellpadding="0" cellspacing="3">
<tr><td valign="top">
<div id="docBoard" style="width: 100%">
酷的XP风格的网右键菜单特效代?a target="_blank">http://baby.mob8.cn
</div>
</td>
<td valign="top" align="right">
<p><input type="checkbox" name="closerm" onclick="toggleMenu(!this.checked);">关闭右键菜单</p>
</td>
</tr>
</table>
</body>
</HTML>
本文 51CTO.COM技术博?/a>
]]><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
PUBLIC '-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN'
'http://java.sun.com/dtd/web-app_2_3.dtd'>
<web-app id="WebApp_ID">
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<taglib>
<taglib-uri>/tags/struts-bean.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
</taglib>
</jsp-config>
]]>
但现在已l脱eXtremeComponents,独立发展Q仍有大量代码来?eXtremeComponentsQ?br>“做最实用易用的列表组?/font>”是ecside最l的目标?/p>
ecside发布地址Q?/font>
http://fins.javaeye.com/blog/40190
ecside圈子:
http://ecside.javaeye.com/
ecsidel合讨论专用?br>http://fins.javaeye.com/blog/48723
其他的列表组?有些是收费的)Q?br>eXtremeComponents原始?( http://www.extremecomponents.org )
dhtmlXGrid ( http://scbr.com/docs/products/dhtmlxGrid/ )
displaytag ( http://displaytag.sourceforge.net )
nitobi grid ( http://www.nitobi.com/products/grid/ )
ActiveWidgets gird ( http://www.activewidgets.com/grid/ )
rico livegrid ( http://openrico.org/rico/livegrid.page )
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
主要增强的功能:
1 可设|工h位置Q上 ??不显C)
2 可设|工h内容Q显C哪?不显C哪些)
3 可设|工h上各个功能按钮的相对位置
4 增加?strong>调整大的选择框,q可自定义选择框内的内?/font>
5 增加了带有邻q页面的D?br>6 增加了可跌{到指定页面的跌{?br>7 增加了当?font color=#ff9900>选中行高?/strong>
8 为ec:table 增加?excludeParameters ?includeParameters 属性,可以实现更快L便的“参数保留/不保?#8221;功能
9 可添加自定义的html代码到工h?或其他位|?br>10 可手动调整列?/strong>
11 增加?#8220;列表内部滚动?/font>”(实现列表头固?/font>Q列表体滚动的功?
12 为ec:row和ec:column d更多的html事g支持Q现支持Qonmouserover onmouserout onclick ondbclick
13 为ec:table ec:row ec:column增加了自定义扩展属性功?br>14 增加 ec:extendrow 标签Q实现列表扩展行的功?br>15 增加shadowRow(影子?功能Q每行下面可以再加一个子?q个行里昄什么可以由大家自己定义
16 增加面变量 ${TOTALROWCOUNT} 用来标示当前U录在全部记录中的行?br>17 增加了打印功能(不完善Q?br>18 ec:column属性增?ellipsis ,实现单元格内数据q长的时?自动截短q加"..."的功?ie only)
19 实现了跨列的列表?br>20 l计栏的标题格可跨列
21 增加了若q种cell ?headerCell,例如checkbox radio
22 取消了imagePath属?样式相关的图片信息全部提入css?br>23 重(W?壎ͼ用了js 和css Q很多功能用js来实?br>24 支持?font color=#ff9900>ajax页
25 支持预查询功?/font>Q在察看Wn늚时候,把n+1늚数据也查询出来(隐藏着Q备用,加快查看下一늚速度
26 导?strong>excel所使用的组件由poi切换成了 jxl
27 xls导出方式修改 原始的导出是导出的vo/map里的原始数?现在?strong>导出面实际昄的内?/font>
28 增加捷导出方?/strong> (通过ec:table?xlsFileName pdfFileName csvFileName属?
29 支持pdf中文导出?br>30 代码q行了大规模的重?br>31 增加了很多ajax相关Ҏ(gu)?br>32 实现?font color=#ff0000>可编辑列?/strong>功能 以及cell的映?/font>功能
... ...
更新日志Q?br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
新增加的Ҏ(gu)通常都在 demo.do.jspq个例子里进行演C?/p>
2007-01-21 15?br>===============================
对于以下更新Qdemo.do.jspq行了修改,大家看看例子可能会更好理?
了一?strong>单的标{?/font> 用来从map生成 select的option列表?br>
׃自动名U显C?font face=Arial>出来?br>2) ?/font>
3) ?strong>ec:extend标签做了扩充Q增加了位置讄属?location
top: form内列表主体前 ; bottom : form内列表主体后
toolbar或不讄location属?nbsp; 在toolbar的扩展位|?
4) 代码q行了一点点修改Q对使用没有影响?/p>
2007-01-20 9?nbsp; ECSIDE 1.0 RC1 发布?/font>
===============================
沉寂两天Q但一直没有闲着Q带来了大变?索性来?1.0 RC1 ?:) ?br>1) 实现?font color=#ff0000>灉|的可定制?#8220;可编辑列?#8221;功能 Q详见help.txt 200行左右的描述 以及CZQ?br>支持多种~辑方式Q文本框 下拉?来q会支持更多Q,可自定义模版Q用自定义的文本框 下拉框)Q还提供了:
对可~辑列进行标识,对编辑过的cellq行标识Q默认ؓ改变单元D景色Q,
使用ajax技术提交后収ͼ提交成功的cell清除编辑标?{脓(chung)心设计?br>2) 增加?高亮昄选中行的功能Q?ec:table属? selectlightRow="true"
3) L?fullnavigationD条,其与navigationD条合q?br>改ؓ为ec:table增加属?nearPageNum="数字" 用来讄D条前后显C的邻近| {于0?Z使用邻近c?br>4) 为ec:table增加?maxRowsExported="数字" 属性,用来限制导出大最大条敎ͼ 如果数据过q个数目Q则不执行导出操作?br>5) Z前增加的ec:table的pageSizeList属?增加了特?br>pageSizeList="max:200,10,15,30,50,100,all" 如果 10--100以及all中,某一大q了max?00?不在列表中显C?br>也可以只使用pageSizeList="max:200" 此时?使用默认讄Qƈq行max控制?br>6) 解决了pdf中文~码问题Q终于支持pdf导出?/font>?br>7) 恢复了对sitemesh的支持,用法见原版ec文Q我没有亲自没有试,因ؓ我不会用sitemesh :( Q?br>8) Ajax页优化Q同时增加了 ECSide.findAjaxZoneAtClien 属性,可设|?客户?q是 服务端进?html代码剪裁?br>默认推荐使用 服务器端?br>9) 再次对js和java代码q行了较大规模的重构,清理了一些无用代码,d了必要的协议信息?br>10) 一些细节的修改(例如Ҏ(gu)轮的支持更自?filterable="true"手动调节列宽功能屏蔽{?
q有对一些小bug的修正,但是׃变化较大Q肯定还会带来一些新bug?br>11) 整个CZ的应?font color=#ff0000>逐步发展?ecside 的最?jng)_?/font>Q加入了hsqldbQhsqldb的用参考了springsideQ,全新的例子?br>当然q不够好 会在以后的日子里l箋完善?br>12) 做了一个简单的logo :)?/font>
我用了 springside ?HsqlListener Q做了些修改 但绝对不涉及到核心)Qؓ什么在每次重启应用的时候L包下面的异常呢?Q?br>Exception in thread "HSQLDB Timer @15d63da" java.lang.NullPointerException
at org.hsqldb.lib.HsqlTimer.nextTask(Unknown Source)
at org.hsqldb.lib.HsqlTimer$TaskRunner.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
2007-01-16 14?br>===============================
1) 当?#8220;列表内部滚动?#8221;Ӟ可以使用癑ֈ?/strong>来设|列表的宽度了?br>(但还是徏议?zhn)使用像素QpxQ作为列表和列的宽度单位,因ؓ癑ֈq有一些小bug)
q有个徏?不管是用什么样的宽度,都要使用一?#8220;自动宽度”的columnQ?br>是说不要给所有的ec:column都指定widthQ给其中一个点“自由”Q这样很多已知的关于列宽调整的问题都可以解决?br>2) 对eccn.jsq行了大量的修改Q提供了更好(但不完美)的IE和FF兼容Q一_?/strong>Q这个工作差Ҏ(gu)我篏吐血Q?
ff和ie 在取得对象坐标和宽度的算法不?太郁闷了
3) 修正了一?font color=#ff9900>bug?/font>
===============================
2007-01-12 以及之前的一些更新日?/font>
===============================
1) ?#8220;列表内部滚动?#8221;增加了对鼠标滚轮的支?只在ie6和ff2下测试过,其他版本没有试)
2) 部?#8220;列表内部滚动?#8221;相关的代码从java中提?改用js实现.
3) 对js文g做了一些调整?br>4) 修正了一些小bug?
1) 修正了一?#8220;列表内部滚动?#8221;的bug
该bug表现为在 IE?有些windows的主题下Q纵向滚动条不可用。FT!!!!!
2) eccn.js做了一点小的改动Qؓ来做过~码支持打下了一点点基础.
1) 修正了改变页面大时“列表内部滚动?#8221;错ؕ的bug
2) 重构?#8220;列表内部滚动?#8221;相关的js和java代码
1) 修正了用ajax页?#8220;列表内部滚动?#8221;错ؕ的bug
2) 增加了当列表内容的实际宽度和高度于讄的宽度和高度的时候,
自动调整区域大小,同时自动隐藏滚动条(只隐藏横向的Q的功能?/p>
增加?#8220;固定列表_滚动列表?#8221;(“列表内部滚动?#8221;)的功?br>q个功能实现h比我一开始想像的复杂
不是单的使用一?div overflow:scroll可以搞定的
虽然功能是支持了 但是代码肯定q有很多bug或者是可以改进的地?br>Ƣ迎大家U极的提出宝늚意见 谢谢?/p>
listHeight="数字" 属?Q指定列表体的高度)
同时把要指定 width="数字" 不能省略 同时要用绝对大?而不要用百分比
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Q详见help.txtQ?/p>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
以后大家?ecside相关的问?可以?font color=#ff0000>圈子?/font>
我的 blog里问( http://fins.javaeye.com/blog/48723 )
别在发消息了 因ؓ发消息别人看不到 而有些问题可能别Z遇到q?或者是我回{的不对 别h也可以帮?
对吧?
谢谢大家
ecside圈子:
http://ecside.javaeye.com/
ecsidel合讨论专用?br>http://fins.javaeye.com/blog/48723
ecside_1.0_rc1_20070121b.zip
描述:
完整版,但不包括所依赖的WEB-INF/lib下的文g.依赖文g可以d子里下蝲, 也可以去javaeye ftp下蝲,也可以按照WEB-INF/lib下的filelist.txt文g所?自行下蝲.
下蝲
文g?
ecside_1.0_rc1_20070121b.zip
文g大小:
697 KB
下蝲q的:
文g被下载或查看 774 ?/span>
]]>
1.1 屏蔽键盘所有键
<script language="javascript">
<!--
function document.onkeydown(){
event.keyCode = 0;
event.returnvalue = false;
}
-->
</script>
1.2 屏蔽鼠标右键
在body标签里加上oncontextmenu=self.event.returnvalue=false
或?/font>
<script language="javascript">
<!--
function document.oncontextmenu()
{
return false;
}
-->
</script>
function nocontextmenu()
{
if(document.all) {
event.cancelBubble=true;
event.returnvalue=false;
return false;
}
}
或?/font>
<body onmousedown="rclick()" oncontextmenu= "nocontextmenu()">
<script language="javascript">
<!--
function rclick()
{
if(document.all) {
if (event.button == 2){
event.returnvalue=false;
}
}
}
-->
</script>
1.3 屏蔽 Ctrl+N、Shift+F10、F5h、退格键
<script language="javascript">
<!--
//屏蔽鼠标右键、Ctrl+N、Shift+F10、F5h、退格键
function window.onhelp(){return false} //屏蔽F1帮助
function KeyDown(){
if ((window.event.altKey)&&
((window.event.keyCode==37)|| //屏蔽 Alt+ 方向?nbsp;←
(window.event.keyCode==39))){ //屏蔽 Alt+ 方向?nbsp;→
alert("不准你用ALT+方向键前q或后退|页Q?);
event.returnvalue=false;
}
/* 注:q还不是真正地屏?nbsp;Alt+ 方向键,
因ؓ Alt+ 方向键弹告框Ӟ按住 Alt 键不放,
用鼠标点掉警告框Q这U屏蔽方法就失效了。以后若
有哪位高手有真正屏蔽 Alt 键的Ҏ(gu)Q请告知?/
if ((event.keyCode == 8) &&
(event.srcElement.type != "text" &&
event.srcElement.type != "textarea" &&
event.srcElement.type != "password") || //屏蔽退格删除键
(event.keyCode==116)|| //屏蔽 F5 h?br> (event.ctrlKey && event.keyCode==82)){ //Ctrl + R
event.keyCode=0;
event.returnvalue=false;
}
if ((event.ctrlKey)&&(event.keyCode==78)) //屏蔽 Ctrl+n
event.returnvalue=false;
if ((event.shiftKey)&&(event.keyCode==121)) //屏蔽 shift+F10
event.returnvalue=false;
if (window.event.srcElement.tagName == "A" && window.event.shiftKey)
window.event.returnvalue = false; //屏蔽 shift 加鼠标左键新开一|页
if ((window.event.altKey)&&(window.event.keyCode==115)){ //屏蔽Alt+F4
window.showModelessDialog("about:blank","","dialogWidth:1px;dialogheight:1px");
return false;}
}
/* 另外可以?nbsp;window.open 的方法屏?nbsp;IE 的所有菜?br>W一U方法:
window.open("你的.htm", "","toolbar=no,location=no,directories=no,menubar=no,scrollbars=no,resizable=yes,status=no,top=0,left=0")
W二U方法是打开一个全屏的面Q?br> window.open("你的.asp", "", "fullscreen=yes")
*/
//-->
</script>
1.4屏蔽览器右上角"最化""最大化""关闭"?/font>
<script language=javascript>
function window.onbeforeunload()
{
if(event.clientX>document.body.clientWidth&&event.clientY<0||event.altKey)
{
window.event.returnvalue = "";
}
}
</script>
或者用全屏打开面
<script language="javascript">
<!--
window.open(www.32pic.com,"32pic","fullscreen=3,height=100, width=400, top=0, left=0, toolbar=no, menubar=no, scrollbars=no, resizable=no,location=no, status=no");
-->
</script>
注:在body标签里加上onbeforeunload="javascript:return false"Q不能关闭H口Q?/p>
1.5屏蔽F5?/font>
<script language="javascript">
<!--
function document.onkeydown()
{
if ( event.keyCode==116)
{
event.keyCode = 0;
event.cancelBubble = true;
return false;
}
}
-->
</script>
1.6屏蔽IE后退按钮
在你链接的时候用 <a href="javascript:location.replace(url)">
1.7屏蔽ȝ口滚动条
在body标签里加?nbsp;style="overflow-y:hidden"
1.8 屏蔽拷屏,不断地清I剪贴板
在body标签里加上onload="setInterval('clipboardData.setData(\'Text\',\'\')',100)"
1.9 屏蔽|站的打印功?/font>
<style>
@media print {
* { display: none }
}
</style>
1.10 屏蔽IE6.0 囄上自动出现的保存图标
Ҏ(gu)一Q?br><META HTTP-EQUIV="imagetoolbar" CONTENT="no">
Ҏ(gu)二:
<img galleryimg="no">
1.11 屏蔽中所有的script
<noscrript></noscript>
2 >表单提交验证c?/strong>
2.1 表单不能ؓI?/font>
<script language="javascript">
<!--
function CheckForm()
{
if (document.form.name.value.length == 0) {
alert("误入?zhn)姓?");
document.form.name.focus();
return false;
}
return true;
}
-->
</script>
2.2 比较两个表单的值是否相?/font>
<script language="javascript">
<!--
function CheckForm()
if (document.form.PWD.value != document.form.PWD_Again.value) {
alert("(zhn)两ơ输入的密码不一P请重新输?");
document.ADDUser.PWD.focus();
return false;
}
return true;
}
-->
</script>
2.3 表单只能ؓ数字?_",用于?sh)?银行帐号验证?可扩展到域名注册{?/font>
<script language="javascript">
<!--
function isNumber(String)
{
var Letters = "1234567890-"; //可以自己增加可输入?br> var i;
var c;
if(String.charAt( 0 )=='-')
return false;
if( String.charAt( String.length - 1 ) == '-' )
return false;
for( i = 0; i < String.length; i ++ )
{
c = String.charAt( i );
if (Letters.indexOf( c ) < 0)
return false;
}
return true;
}
function CheckForm()
{
if(! isNumber(document.form.TEL.value)) {
alert("(zhn)的?sh)话L不合法!");
document.form.TEL.focus();
return false;
}
return true;
}
-->
</script>
2.4 表单输入数?长度限定
<script language="javascript">
<!--
function CheckForm()
{
if (document.form.count.value > 100 || document.form.count.value < 1)
{
alert("输入数g能小于零大于100!");
document.form.count.focus();
return false;
}
if (document.form.MESSAGE.value.length<10)
{
alert("输入文字于10!");
document.form.MESSAGE.focus();
return false;
}
return true;
}
//-->
</script>
2.5 中文/英文/数字/邮g地址合法性判?/font>
<SCRIPT LANGUAGE="javascript">
<!--
function isEnglish(name) //英文值检?br>{
if(name.length == 0)
return false;
for(i = 0; i < name.length; i++) {
if(name.charCodeAt(i) > 128)
return false;
}
return true;
}
function isChinese(name) //中文值检?br>{
if(name.length == 0)
return false;
for(i = 0; i < name.length; i++) {
if(name.charCodeAt(i) > 128)
return true;
}
return false;
}
function isMail(name) // E-mail值检?br>{
if(! isEnglish(name))
return false;
i = name.indexOf("@");
j = name.lastIndexOf("@");
if(i == -1)
return false;
if(i != j)
return false;
if(i == name.length)
return false;
return true;
}
function isNumber(name) //数值检?br>{
if(name.length == 0)
return false;
for(i = 0; i < name.length; i++) {
if(name.charAt(i) < "0" || name.charAt(i) > "9")
return false;
}
return true;
}
function CheckForm()
{
if(! isMail(form.Email.value)) {
alert("(zhn)的?sh)子邮g不合法!");
form.Email.focus();
return false;
}
if(! isEnglish(form.name.value)) {
alert("英文名不合法Q?);
form.name.focus();
return false;
}
if(! isChinese(form.cnname.value)) {
alert("中文名不合法Q?);
form.cnname.focus();
return false;
}
if(! isNumber(form.PublicZipCode.value)) {
alert("邮政~码不合法!");
form.PublicZipCode.focus();
return false;
}
return true;
}
//-->
</SCRIPT>
2.6 限定表单不能输入的字符
<script language="javascript">
<!--
function contain(str,charset)// 字符串包含测试函?br>{
var i;
for(i=0;i<charset.length;i++)
if(str.indexOf(charset.charAt(i))>=0)
return true;
return false;
}
function CheckForm()
{
if ((contain(document.form.NAME.value, "%\(\)><")) || (contain(document.form.MESSAGE.value, "%\(\)><")))
{
alert("输入了非法字W?);
document.form.NAME.focus();
return false;
}
return true;
}
//-->
</script>
2.7 屏蔽右键、刷新、退格等功能
<SCRIPT language=JavaScript>
<!--
if (window.Event)
document.captureEvents(Event.MOUSEUP);
function nocontextmenu()
{
event.cancelBubble = true
event.returnValue = false;
return false;
}
function norightclick(e)
{
if (window.Event)
{
if (e.which == 2 || e.which == 3)
return false;
}
else
if (event.button == 2 || event.button == 3)
{
event.cancelBubble = true
event.returnValue = false;
return false;
}
}
document.oncontextmenu = nocontextmenu; // for IE5+
document.onmousedown = norightclick; // for all others
//-->
</SCRIPT>
<SCRIPT language=javascript id=clientEventHandlersJS>
<!--
function document_onkeydown() {
if(((event.ctrlKey)&&(event.keyCode==69)) //Ctrl + E
||((event.ctrlKey)&&(event.keyCode==70)) //Ctrl + F
||((event.ctrlKey)&&(event.keyCode==72)) //Ctrl + H
||((event.ctrlKey)&&(event.keyCode==73)) //Ctrl + I
||((event.ctrlKey)&&(event.keyCode==78)) //Ctrl + N
||((event.ctrlKey)&&(event.keyCode==79)) //Ctrl + O
||((event.ctrlKey)&&(event.keyCode==80)) //Ctrl + P
||((event.ctrlKey)&&(event.keyCode==67)) //Ctrl + F
||((event.ctrlKey)&&(event.keyCode==86)) //Ctrl + F
||((event.ctrlKey)&&(event.keyCode==65)) //Ctrl + F
||((event.ctrlKey)&&(event.keyCode==83))){ //Ctrl + S
event.keyCode=0;
event.returnValue=false;
}
if(event.keyCode==8){ //BackSpace
if(!((event.srcElement.type=="text")||(event.srcElement.type=="password")||(event.srcElement.type=="textarea"))){
event.keyCode=0;
event.returnValue=false;
}
}
if((event.keyCode==116) //F5
||(event.keyCode==122)){ //F11
event.keyCode=0;
event.returnValue=false;
}
if(event.altKey){ //Alt + Left ; Alt + Right
if(((event.keyCode==37)||(event.keyCode==39))){
window.alert("不能q行此操?);
event.keyCode=0;
event.returnValue=false;
}
}
}
//-->
</SCRIPT>
<SCRIPT language=javascript event=onkeydown for=document>
<!--
document_onkeydown()
//-->
</SCRIPT>
2.8 今天做系l时Q用来判断radiobox选择的问?(1.29)
<script language="javascript">
function Detect()
{
total = examResultForm.sz.value ;
for(i=1;i<=total;i++)
{
var c = false;
var o = eval("document.all.op"+i);
for(j=0;j<o.length;j++)
{
if(o[j].checked)
{
c = true;
break;
}
}
if(!c)
{
document.all.lblWarning.innerHTML="W?+i+"题没有做?;
return false;
}
}
document.all.lblWarning.innerHTML="全部题目已经做完";
return true;
}
</script>
2.9 全屏打开H口、最大化H口...
//全屏
function fullScrn(url)
{
if(confirm("?"))
{
var win = window.open (url,"","fullscreen=yes,toolbar=no,scrollbars=yes");
win.focus();
}
return win;
}
//最大化
<script language="JavaScript">
<!--
self.moveTo(0,0)
self.resizeTo(screen.availWidth,screen.availHeight)
</script>
//鼠标Ud
function mouseovertd (o){
o.style.backgroundColor='#f2f2f2';
o.style.cursor='hand';
}
function mouseouttd (o){
o.style.backgroundColor='#FFFFFF';
o.style.cursor='hand';
}
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=273019
this.arr = new Array();
this.get = get;
this.put = put;
this.remove = remove;
this.size = size;
this.isEmpty = isEmpty;
}
</script>
<script>
var map = new Map();
map.put("re","redhacker");
map.put("do","douguoqiang");
map.put("gq","dougq");
alert("map的大ؓQ? + map.size())
alert("key为re的map中存储的对象为:" + map.get("re"));
map.remove("re");
alert("U除key为re的对象后Q获取key为re的map中存储的对象为:" + map.get("re"));
alert("mapU除一个元素后的大ؓQ? + map.size());
alert("map是否是一个空map:" + map.isEmpty());
</script>
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1550098
使用Ҏ(gu)Q?/p>
common-fileuploadlg是apache的一个开源项目之一Q可以从http://jakarta.apache.org/commons/fileupload/下蝲。该lg单易用,可实Cơ上传一个或多个文gQƈ可限制文件大?/p>
下蝲后解压zip包,commons-fileupload-1.0.jar复制到tomcat的webapps\你的webapp\WEB-INF\lib\下,如果目录不存在请自徏目录?/p>
新徏一个servlet: Upload.java用于文g上传Q?/p>
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.commons.fileupload.*;
public class Upload extends HttpServlet {
private String uploadPath = "C:\\upload\\"; // 用于存放上传文g的目?br> private String tempPath = "C:\\upload\\tmp\\"; // 用于存放临时文g的目?/font>
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
}
}
当servlet收到览器发出的Posth后,在doPost()Ҏ(gu)中实现文件上传。以下是CZ代码Q?/p>
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
try {
DiskFileUpload fu = new DiskFileUpload();
// 讄最大文件尺寸,q里?MB
fu.setSizeMax(4194304);
// 讄~冲区大,q里?kb
fu.setSizeThreshold(4096);
// 讄临时目录Q?br> fu.setRepositoryPath(tempPath);
// 得到所有的文gQ?br> List fileItems = fu.parseRequest(request);
Iterator i = fileItems.iterator();
// 依次处理每一个文Ӟ
while(i.hasNext()) {
FileItem fi = (FileItem)i.next();
// 获得文g名,q个文g名包括\径:
String fileName = fi.getName();
if(fileName!=null) {
// 在这里可以记录用户和文g信息
// ...
// 写入文ga.txtQ你也可以从fileName中提取文件名Q?br> fi.write(new File(uploadPath + "a.txt"));
}
}
// 跌{C传成功提C页?br> }
catch(Exception e) {
// 可以跌{出错面
}
}
如果要在配置文g中读取指定的上传文g夹,可以在init()Ҏ(gu)中执行:
public void init() throws ServletException {
uploadPath = ....
tempPath = ....
// 文g夹不存在p动创建:
if(!new File(uploadPath).isDirectory())
new File(uploadPath).mkdirs();
if(!new File(tempPath).isDirectory())
new File(tempPath).mkdirs();
}
~译该servletQ注意要指定classpathQ确保包含commons-upload-1.0.jar和tomcat\common\lib\servlet-api.jar?/p>
配置servletQ用C本打开tomcat\webapps\你的webapp\WEB-INF\web.xmlQ没有的话新Z个。典型配|如下:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"
<web-app>
<servlet>
<servlet-name>Upload</servlet-name>
<servlet-class>Upload</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Upload</servlet-name>
<url-pattern>/fileupload</url-pattern>
</servlet-mapping>
</web-app>
配置好servlet后,启动tomcatQ写一个简单的html试Q?/p>
注意action="fileupload"其中fileupload是配|servlet时指定的url-pattern?/p>
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=15991