ï»??xml version="1.0" encoding="utf-8" standalone="yes"?>免播放器亚洲一区,婷婷国产在线,国产91久久精品一区二区http://www.aygfsteel.com/i369/category/22057.html北极心空zh-cnThu, 20 Mar 2008 22:51:30 GMTThu, 20 Mar 2008 22:51:30 GMT60围绕Ext JS 2.0çš„IDE、插件和工具 [转自javaeye]http://www.aygfsteel.com/i369/articles/187545.html芦苇芦苇Thu, 20 Mar 2008 10:25:00 GMThttp://www.aygfsteel.com/i369/articles/187545.htmlhttp://www.aygfsteel.com/i369/comments/187545.htmlhttp://www.aygfsteel.com/i369/articles/187545.html#Feedback0http://www.aygfsteel.com/i369/comments/commentRss/187545.htmlhttp://www.aygfsteel.com/i369/services/trackbacks/187545.html
 


]]>eXtremeComponents指南http://www.aygfsteel.com/i369/articles/149779.html芦苇芦苇Sun, 30 Sep 2007 01:49:00 GMThttp://www.aygfsteel.com/i369/articles/149779.htmlhttp://www.aygfsteel.com/i369/comments/149779.htmlhttp://www.aygfsteel.com/i369/articles/149779.html#Feedback0http://www.aygfsteel.com/i369/comments/commentRss/149779.htmlhttp://www.aygfsteel.com/i369/services/trackbacks/149779.html

Table of Contents

定制FilterCell
1. 引言
1.1. 定制Droplist˜q‡æ×o器Cell½CÞZ¾‹
定制FilterRowsCallback
1. 引言
1.1. 定制FilterRowsCallback½CÞZ¾‹
Form指南
1. 引言
1.1. JSP
1.1.1. Formç‰ÒŽ€§çš„æŠ€æœ¯è¯´æ˜?/a>
1.1.2. Checkbox
1.1.3. Custom Cell
1.1.4. JavaScript
1.2. Cell
1.3. Controller
1.3.1. 表标½{‘ÖŠ¨ä½œController
1.3.2. Form动作Controller
1.3.3. 重新得到Checkbox的�/a>
Html视图定制指南
1. 引言
1.1. View接口
1.2. Messages½CÞZ¾‹
拦截器ä‹É用指å?/a>
1. 引言
1.1. 拦截器列�/a>
1.2. 行拦截器½CÞZ¾‹
Limit指南
1. 引言
1.1. JSP
1.2. Controller
1.3. Service
1.3.1. 取得总行�/a>
1.3.2. 取得Collection
1.4. DAO
1.4.1. 定义Query字符�/a>
1.4.2. Filter �Sort Query 字符�/a>
1.4.3. Limit Query String
1.4.4. 取回总行数和Collection.
1.4.5. 默认的Sort™åºåº
Preferences 指南
1. 引言
1.1. Preferencesè¡?/a>
1.2. 指定Preference别名

定制FilterCell


1. å¼•言

列的filterCell属性控制过滤器如何昄¡¤ºåQŒå®ƒå’Œcellå±žæ€§éžå¸¸ç›¸åƒåÆˆä¸”ä¹Ÿæ˜¯å®žçŽ°Cell接口。马上要定义的是默认的和droplist˜q™ä¸¤ä¸ªè¿‡æ»¤å™¨cellsã€?默认的是一个输入框元素而droplist是一个下拉列表元素。当ç„Óž¼Œå¦‚果你需要进行一些定制你可以插接自己的实现ã€?/p>

最˜q‘,我被问到是否能够实现一个过滤器cellåQŒæ˜¾½Cºå·²¾lé€šè¿‡åˆ«çš„˜q‡æ×o器过滤得到数据子集。答案当然是肯定的,而且˜q™æ˜¯æˆ‘将在这里示范的。通常定制çš?cell可以很容易被创徏åQŒè¿™ä¸ªç¤ºä¾‹å°†å°è¯˜q™ç‚¹ã€‚在˜q™ä¸ª½CÞZ¾‹é‡Œlast name列里昄¡¤ºçš„将是通过first name˜q‡æ×o后的子集。如果没有通过 first name˜q‡æ×o那么所有值都ž®†è¢«æ˜„¡¤ºã€?/p>

1.1. å®šåˆ¶Droplist˜q‡æ×o器Cell½CÞZ¾‹

é€šå¸¸ä½ åªéœ€è¦äØ“˜q‡æ×o器cell实现CellæŽ¥å£ã€‚ç„¶è€Œï¼Œå› äØ“æˆ‘ä»¬è¦åˆ›å»ºçš„˜q‡æ×o器cell是一个下拉列表,我们可以通过扩展 FilterDroplistCell来获得它已经提供的很多功能,FilterDroplistCell是发行包已经提供的cells之一ã€?/p>

我们需要覆盖FilterDroplistCell的唯一æ–ÒŽ³•是getFilterDropList()。这是整个类的全部代码:

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;
}
}

如果你比较这个类和父¾c»ï¼Œä½ ä¼šå‘现它们只有微小的区别ã€?/p>

首先需要注意的是我们需要找出first name是否已经被过滤了�/p>

String firstNameFilter = model.getLimit().getFilterSet().getValue("firstName");

然后我们需要判断当前beançš„first name值是否和first name˜q‡æ×o器值相同。如果相同,ž®†å½“前的last nameå€?æ·ÕdŠ åˆ°droplist中ã€?/p>

String firstName = BeanUtils.getProperty(bean, "firstName");
if (StringUtils.isNotBlank(firstNameFilter) && !firstName.equals(firstNameFilter)) {
continue;
}

如果last namež®†æ·»åŠ åˆ°droplist中,我们需要检查droplist中是否已¾låŒ…含了˜q™ä¸ªå€¹{€‚如果没有,我们ž®±æŠŠå®ƒæ·»åŠ åˆ°droplist中ã€?

String lastName = BeanUtils.getProperty(bean, column.getProperty());
if ((lastName != null) && !droplist.contains(lastName)) {
droplist.add(lastName);
}

ä¸ÞZº†ä½¿ç”¨˜q™ä¸ªCell你应该在Preferences中声明一个别名ã€?当然åQŒä½ å¯ä»¥çœç•¥˜q™æ­¥è€Œåœ¨JSP中提供这个Cell实现¾cȝš„å…¨èµ\径,但是使用Preferences更简‹zã€?/em>

column.filterCell.filteredDroplist=org.extremesite.cell.FilteredDroplistCell

在ColumnTag通过讄¡½®filterCell属性来使用FilteredDroplistCellã€?/p>

<ec:column property="lastName" filterCell="filteredDroplist"/>

如果不清楚Preferences和ColumnTag定义语法请参考Preferences指南�

定制FilterRowsCallback


1. å¼•言

FilterRowsCallback被用来过滤传¾l™eXtremeTableçš„Beansçš„Collectionã€?FilterRowsCallback的默认实现是得到Beans或Mapsçš„CollectionåQŒç„¶åŽé€šè¿‡å®žçްjakarta Predicate接口来进行过滤。当ç„Óž¼Œå¦‚果你需要进行一些定制你可以插接自己的实现ã€?/p>

首先声明åQŒæœ¬½CÞZ¾‹ä»£ç åŒ…含一些从原包中剪切、粘贴的代码(虽然不是很多)。在 最初的最¾lˆå‘行包之后åQŒå€ÆD¿‡æ»¤å¾—到进一步改善ä‹Éå¾—æ›´å…·å¤ç”¨æ€§åÆˆæ›´å®¹æ˜“å®žçŽŽÍ¼Œå¯èƒ½å’Œå®šåˆ¶cell代码行数相同ã€?当然åQŒæˆ‘è¢«è¦æ±‚åÆˆéžå¸¸ä¹æ„½Cø™Œƒå¦‚何在当前代码基¼‹€ä¸Šå®žçŽ°å®šåˆ¶è¿‡æ»¤ã€‚è¿™æœ‰éžå¸¸æ¸…æ™°çš„hooks实现åQŒåƈ且很å®ÒŽ˜“实现ã€?/p>

æœ¬ç¤ºä¾‹ç¤ºèŒƒäº†å¦‚ä½•è°ƒæ•´ä»£ç ä¸ø™¿‡æ»¤å™¨æä¾›ä¸€ä¸ªç²¾¼‹®çš„æ¯”较功能。当前的实现是通过使用StringUtils.contains()æ–ÒŽ³•˜q›è¡Œæ¨¡ç³Šæ¯”较ã€?本示例将使用StringUtils.equals()æ–ÒŽ³•。你可以按照你的需要来调整代码˜q›è¡Œæ›´å¤šå®šåˆ¶ã€?/p>

1.1. å®šåˆ¶FilterRowsCallback½CÞZ¾‹

首先你需要做的是创徏一个实现Predicate接口的定制类。Predicate要求我们实现evaluate()æ–ÒŽ³•来判断是否包å?当前bean。因ä¸ÞZ½ ä»…仅调整现在已有的功能,首先得到filterPredicate的源代码åQˆåœ¨å‘行包的callback包下åQ‰ï¼Œ 拯‚´åˆîC½ çš„å·¥½E‹é‡Œã€‚然后向下面展示的一样将 StringUtils.contains()æ–ÒŽ³•修改为StringUtils.equals()æ–ÒŽ³•åQ?/p>

public final class ExactMatchFilterPredicate implements Predicate {
private boolean isSearchMatch(String value, String search) {

...

else if (StringUtils.equals(value, search)) {
return true;
}

...

}
}

然后我们需要实现和Predicate共同作用的FilterRowsCallback接口。再一‹Æ¡ä»Žå‘行包的callback包下拯‚´ProcessRowsCallback源代码到你的工程里ã€?请参照我们创建的定制的ExactMatchFilterPredicate ¾cÀL¥¼‹®è®¤ä»…仅实现了FilterRowsCallback和修改Predicateã€?/p>

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;
}

...

}
}

ä¸ÞZº†ä½¿ç”¨˜q™ä¸ªFilterRowsCallback你应该在Preferences中声明一个别名ã€?span class="emphasis">当然åQŒä½ å¯ä»¥çœç•¥˜q™æ­¥è€Œåœ¨JSP中提供这个FilterRowsCallback实现¾cȝš„å…¨èµ\径,但是使用Preferences更简‹zã€?/em>

table.filterRowsCallback.exactMatch=org.extremesite.callback.ExactMatchFilterRows

在TableTag通过讄¡½®filterRowsCallback属性来使用ExactMatchFilterRowsã€?/p>

<ec:table filterRowsCallback="exactMatch"/>

如果不清楚Preferences和ColumnTag定义语法请参考Preferences指南�/em>

Form指南


1. å¼•言

eXtremeTable本质上是一个form¾l„äšgåQŒæ‰€ä»¥æˆ‘假定表被包在formé‡Œï¼Œæ‰€æœ‰çš„åŠŸèƒ½éƒ½è¢«è®¤äØ“æ˜¯å¯¹form元素的操作。如果你惛_œ¨è¡¨ä½“中包含一些定制的form元素åQ?或者想ž®†eXtremeTable嵌入到另外的form中,那么你就要ä‹É用表标签的form属性用来参照最˜q‘çš„formã€?/p>

ä¸ÞZº†½Cø™Œƒformç‰ÒŽ€§ï¼Œæˆ‘们要做的工作将分解为JSPåQŒCellå’ŒControllerã€?/p>

1.1. JSP

下面列出的是checkbox½CÞZ¾‹çš„完整代码。想要强调的主要事情是表标签form属性设¾|®äØ“presFormåQŒå®ƒå‚照被称为presFormçš„form元素ã€?

同时è¯äh³¨æ„è¡¨æ ‡ç­¾çš„autoIncludeParameters属性。进行排序、过滤、分™å‰|—¶åQŒé»˜è®¤çš„eXtremeTablež®†ä¿æŒæ‰€æœ‰ä¼ è‡³JSP™åµé¢çš„参数ã€?˜q™ä¸ªç‰ÒŽ€§å¯¹äºŽå†…部其他的form˜q›è¡ŒæŽ’序、过滤、分™å‰|—¶åQŒç”¨äºŽé«˜æ•ˆå¤åˆ¶form元素同样有效。可以设¾|?autoIncludeParameterså±žæ€§äØ“false来固定它ã€?/p>

在这个form使用idå±žæ€§æ˜¯å› äØ“xhtm标准的要求,同时你也可以使用formçš„name属性ã€?

<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>

1.1.1. Formç‰ÒŽ€§çš„æŠ€æœ¯è¯´æ˜?/h4>

表标½{¾form属性参照最˜q‘çš„form是你使用˜q™ä¸ªç‰ÒŽ€§æ‰€å¿…须知道的,ä¸ÞZº†æ›´å¥½çš„理解这个特性,介绍更多的关于内部实现技术的¾l†èŠ‚æ˜¯å€¼å¾—çš„ã€?/p>

如果您不ç‰ÒŽ„æŒ‡å®šform属性,eXtremeTable自动在表附近包上一个form。所有表的动作例如:排序、过滤、分™åµå°†è‡ªåЍ¾l™ä¸€äº›éšè—çš„input元素赋å€û|¼Œç„¶åŽæäº¤˜q™ä¸ªform到表标签action属性设¾|®çš„Acitonã€?˜q™éžå¸¸æœ‰æ•ˆï¼Œé™¤éžæ‚¨æƒ³è¦å°†è‡ªå·±çš„form元素讄¡½®åˆ°è¡¨ä½“,或者想ž®†è¿™ä¸ªè¡¨æ”‘Öˆ°åˆ«çš„form里ã€?

表标½{¾form属性参照最˜q‘çš„formåQŒæ‰€æœ‰è¡¨çš„动作例如:排序、过滤、分™åµå°†è‡ªåЍ¾l™ä¸€äº›éšè—çš„input元素赋å€û|¼Œä½†æ˜¯çŽ°åœ¨ 最˜q‘formçš„action属性将要改变表标签的动作。这非常重要åQŒå› ä¸ºï¼šå½“排序、过滤、分™å‰|—¶åQŒeXtremeTable能够从一个controller得到数据集合 åQŒä½†æ˜¯æäº¤è¿™ä¸ªform到别的controller来处理这个formæ—‰™œ€è¦å¯¹ç”¨æˆ·çš„输入进行处理。然而,˜q™äº›å¯¹äºŽä½ ä‹É用表标签来说都是透明的ã€?ž®±åƒä½ çŽ°åœ¨åšçš„é‚£æ ïL®€å•地讄¡½®è¡¨æ ‡½{„¡š„action属性,然后讄¡½®ç›¸å…³çš„formåˆîC½ æƒÏxäº¤çš„位置ã€?/p>

1.1.2. Checkbox

½CÞZ¾‹çš„第一列是checkboxã€‚å› ä¸ø™¿™åˆ—不需要参照bean的属性,alias属性用来唯一地标识这列。你可以使用property 属性,但是alias属性ä‹É˜q™åˆ—如何使用更清楚。alias属性还被用来当同样的属性被多列使用时唯一地标识一列ã€?/p>

1.1.3. Custom Cell

您也许想知道定制的cell是如何通过名称selectedPresident被参照的(cell="selectedPresident")。这是一ä¸?对eXtremeTableçš„preferencesç‰ÒŽ€§æ›´å¼ºçš„使用。所有要做的ž®±æ˜¯åœ¨extremecomponents.propertiesæ–‡äšg中添加一个属性ã€?请参考Preferences来了解更多的信息

column.cell.selectedPresident=org.extremesite.cell.SelectedPresidentCell

column.cell.selectedPresidentž®±æ˜¯ä½ å®šä¹‰çš„用来参照˜q™ä¸ªcell的名¿U°ã€?/p>

当然你也可以使用˜q™ä¸ªCell的全名来˜q›è¡Œå‚ç…§ã€?/p>

<ec:column 
alias="checkbox"
title=" "
width="5px"
filterable="false"
sortable="false"
viewsAllowed="compact"
cell="org.extremesite.cell.SelectedPresidentCell"
/>

在属性文件中定义参照更方便,它可以被ä»ÖM½•JSPæ–‡äšg引用。如果类名或包名改变的话你只需要对一个地方进行修攏V€?/p>

1.1.4. JavaScript

JavaScriptçš„setPresidentState()æ–ÒŽ³•被定制cell用来讄¡½®æ¯ä¸ªcheckbox元素的是否被选中ã€?讄¡½®ä¸€ä¸ªéšè—å…ƒç´ çš„åŽŸå› æ˜¯äØ“äº†èŽ·å¾—æµè§ˆå™¨çš„åŠ¨ä½œè€Œä¸æäº¤æ²¡æœ‰é€‰ä¸­çš„checkbox。通过˜q™ä¸ªControllerž®†ä¸€ç›´çŸ¥é“一个元素是否别选中ã€?/p>

1.2. Cell

定制的cell被用来生成checkboxåQŒå¦å¤–它也创å»ÞZ¸€ä¸ªéšè—å…ƒç´ ç”¨æ¥è¡¨½Cø™¿™ä¸ªcheckbox元素是否被选中ã€?当用戯‚¿›è¡ŒæŽ’序、过滤、分™å‰|—¶åQŒè¢«é€‰ä¸­çš„æ•°æ®é›†åˆå°†è¢«æ”¾åˆ°session里ã€?/p>

getExportDisplay()æ–ÒŽ³•没有˜q”回å€û|¼Œå› äØ“æ²È†åªéœ€è¦Html昄¡¤ºã€?/p>

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();
}
}

1.3. Controller

提示åQšSpring框架的Controllerå’ŒStruts框架的Action非常相像ã€?/em>

当在另外的form中ä‹É用eXtremeTableæ—Óž¼Œä½ å¯èƒ½æœ‰1个或2个controllers。当form被提交时åQŒä½ éœ€è¦ä¸€ä¸ªcontroller 来处理用æˆïLš„输入òq‰™‡æ–°å®šå‘到另外的JSP™åµé¢ã€‚当排序、过滤、分™å‰|—¶åQŒä½ å¯èƒ½æœ‰å¦å¤–çš„controlleræ¥å¾—åˆ°è¡¨ä½¿ç”¨çš„æ•°æ®é›†åˆåÆˆé‡å®šå‘ä¼šæœ¬é¡µã€‚æˆ–è€…ä½ å¯ä»¥åœ¨åŒä¸€ä¸ªcontroller中分别处理ã€?

checkbox½CÞZ¾‹é‡Œæˆ‘使用一个controller来关联表标签的action属性。我也ä‹É用另外一个controller来关联form元素的动作ã€?/p>

1.3.1. è¡¨æ ‡½{‘ÖŠ¨ä½œController

˜q™ä¸ªcontroller负责调用SelectedPresidentsUtils来保存被选中的presidentIds到sessioné‡ŒåÆˆå›žåˆ°åŒä¸€™åüc€?

SelectedPresidentsUtils.saveSelectedPresidentsIDs(request);
Collection presidents = presidentsService.getPresidents();
request.setAttribute("presidents", presidents);

1.3.2. Form动作Controller

˜q™ä¸ªcontroller负责通过presidentIdså¾—åˆ°æ•°æ®é›†åÆˆé‡å®šå‘åˆ°ä¸‹ä¸€ä¸ªJsp™åµé¢

Collection selectedPresidentsIds = SelectedPresidentsUtils.saveSelectedPresidentsIDs(request);
Collection selectedPresidents = SelectedPresidentsUtils.getSelectedPresidents(presidentsService.getPresidents(), selectedPresidentsIds);
request.setAttribute("selected", selectedPresidents);
request.getSession().removeAttribute(SelectedPresidentsConstants.SELECTED_PRESIDENTS);

1.3.3. é‡æ–°å¾—到Checkboxçš„å€?/h4>

我将列出保存presidentIds到session的代码。我¾lå¸¸è¢«é—®åˆ°å¦‚何重新得到eXtremeTable中form元素的倹{€?它的原理是设¾|®form输入元素名字属性值前面加上一些东西来唯一标识元素

本示例中我关心的是以chkbx开头参数的元素。chkbx后面是唯一的关联到checkbox的presidentId。它被用来判断这个checkbox是否别选中�/p>

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;
}

Html视图定制指南


1. å¼•言

eXtremeTable使用View接口来生成HTML。你可以使用发行包已¾læä¾›çš„视图åQŒæˆ–者你可以插入自己的视囑֮žçްã€?现在åQŒåˆ›å»ÞZ½ è‡ªå·±çš„视囄¡›¸å¯Òޝ”较简单,但讨è®ÞZ¸€äº›è®¾è®¡æƒ³æ³•和如何着手实çŽîC¸€ä¸ªå®šåˆ¶çš„视图˜q˜æ˜¯æœ‰ä­h值的ã€?/p>

我想使创建定制视囄¡®€å•,但不是想构造一个更复杂的类似swing的模型,原因是那需要创建大量的对象来处理对应的内部工作ã€?eXtremeTableä»¥é«˜æ•ˆäØ“ç›®æ ‡åQŒæˆ‘也想在视囄¡š„实现上诏彻这¿Uæƒ³æ³•,所以我军_®šåˆ›å¾ä¸€¾pÕdˆ—的静态构造器¾cÀL¥å®žçŽ°åˆ†è§£çš„æœ€ž®åŠŸèƒ½ã€‚ä½ å¯ä»¥é€šè¿‡¾l„合˜q™äº›åŠŸèƒ½æ¥å®žçŽîC½ çš„定制视图ã€?

学习定制视图的最好途径是阅è¯Õd·²¾lå­˜åœ¨çš„视图的源代码åQŒä¿®æ”¹å®ƒæ¥æ»¡­‘³ä½ çš„需求。如果我½Cø™Œƒæ‰€æœ‰ä¸œè¥¿çš„话,˜q™ç¯‡æŒ‡å—ž®†å˜çš„非常冗é•ѝ€‚取而代之的是我ž®†ç›´æŽ¥ä¿®æ”šw»˜è®¤è§†å›„¡š„工具条作为定制视囄¡š„一个示例ã€?å¯¹äºŽä¸åŒæž„é€ å™¨çš„å…·ä½“ç»†èŠ‚æˆ‘å»ø™®®ä½ é˜…è¯ÀLºä»£ç ã€‚我也将ž®½é‡æ›´æ–°javadocs来提供更好的帮助ã€?/p>

1.1. View接口

实现View接口的类æœ?‹Æ¡æ’入内容的æœÞZ¼šã€‚beforeBody()æ–ÒŽ³•会被立刻调用åQŒbody()æ–ÒŽ³•在每一行的每一列处理的时候调用ã€?afterBody()æ–ÒŽ³•是被eXtremeTable调用的最后方法,它将˜q”回代表视图的一个对象。在˜q™ä¸ªHTML视图½CÞZ¾‹é‡Œï¼Œå®ƒå°†æ˜¯ä¸€ä¸ªå­—½W¦ä¸²ã€?/p>

public interface View {
public void beforeBody(TableModel model);
public void body(TableModel modelåQ?Column column);
public Object afterBody(TableModel model);
}

1.2. Messages½CÞZ¾‹

在这½‹‡æŒ‡å—里我将直接修改工具条来实现˜q™ç½‘站上Messages½CÞZ¾‹çš„定制视图ã€?/p>

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);
}
}

˜q™é‡Œä½¿ç”¨çš„æ˜¯é»˜è®¤è§†å›¾åQŒå› æ­¤å®ƒæ‰©å±•了虚拟视图来修改工具条和状态条。如何修改工å…äh¡å’Œï¼ˆæˆ–)状态条也是开发äh员问的最多问题ã€?

默认视图的工å…äh¡ä½äºŽè¡¨çš„上方包括¾˜»é¡µé“¾æŽ¥å’Œæ ‡é¢˜ã€‚å·¥å…äh¡ä½¿ç”¨TwoColumnTableLayoutåQŒå®ƒæ˜¯ä¸€ä¸ªç”¨äºŽæä¾›åœ¨è‡ªå·±è¡¨ä¸­å®žçŽ°å·¦å³ä¸¤åˆ—å¸ƒå±€çš„è™šæ‹Ÿç±»ã€?它将实现能够‹¹®åœ¨è¡¨ä¸Šæ–¹çš„完美布局。下面就是你需要关心的虚拟æ–ÒŽ³•åQŒåœ¨å®žé™…çš„html视图中已¾läؓ你完成了˜q™ä¸ªå¸ƒå±€ã€?/p>

public abstract class TwoColumnTableLayout {
protected abstract boolean showLayout(TableModel model);
protected abstract void columnLeft(HtmlBuilder htmlåQ?TableModel model);
protected abstract void columnRight(HtmlBuilder htmlåQ?TableModel model);
}

showLayout()æ–ÒŽ³•用来é˜ÀL­¢æˆ–导致布局的展现。在我的定制视图中如果翻™å‰|ˆ–åQˆå’ŒåQ‰å¯¼å‡ºæ˜¾½Cºé‚£ä¹ˆå·¥å…äh¡ž®†å±•现ã€?/p>

protected boolean showLayout(TableModel model) {
boolean showPagination = BuilderUtils.showPagination(model);
boolean showExports = BuilderUtils.showExports(model);
if (!showPagination && !showExports) {
return false;
}

return true;
}

下面昄¡¤ºäº†å·¦åˆ—和叛_ˆ—的部分代码。注意在我的定制视图中首™åµå’Œå‰ä¸€™åµä‹É用了文字来替代图片显½Cºã€‚我真正希望½Cø™Œƒçš„æ˜¯ä½ éœ€è¦åšçš„:扑ֈ°æ­£ç¡®çš„æž„造器¾cÕdƈ且仅仅是扩展HtmlBuilder的标½{¾ã€?构造器¾cÕd¯¹äºŽç¤ºèŒƒå¦‚何找到模型里的信息(以便你能够做比他们能够提供的更多的定制工作)也非常有用,ã€?/em>

protected void columnLeft(HtmlBuilder htmlåQ?TableModel model) {
html.td(2).close();
TableBuilder.title(htmlåQ?model);
html.tdEnd();
}

protected void columnRight(HtmlBuilder htmlåQ?TableModel model) {
boolean showPagination = BuilderUtils.showPagination(model);
...
if (showPagination) {
html.td(4).close();
ToolbarBuilder.firstPageItemAsText(htmlåQ?model);
html.tdEnd();

html.td(4).close();
ToolbarBuilder.prevPageItemAsText(htmlåQ?model);
html.tdEnd();
...
}
...
}

ä¸ÞZº†ä½¿ç”¨˜q™ä¸ªè§†å›¾ä½ éœ€è¦åœ¨Preferences定义一个别名ã€?你可以省略这部而在JSP直接¾l™å‡º˜q™ä¸ªè§†å›¾çš„完整有效的¾cÕdåQŒä¸˜q‡Preferencesæ›´äØ“½Ž€‹zã€?/em>

table.view.messages=org.extremesite.view.MessagesView

TableTag也将讄¡½®è§†å›¾å±žæ€§æ¥ä½¿ç”¨MessagesView视图ã€?/p>

<ec:table view="messages">

如果不清楚Preferences和TableTag定义语法请参考Preferences指南�/em>

拦截器ä‹É用指å?/h2>


1. å¼•言

拦截ç‰ÒŽ€§è¢«ç”¨åœ¨˜qè¡Œæ—‰™œ€è¦ä¿®æ”¹å±žæ€§å€¼çš„æ—¶å€™ï¼Œå®ƒä‹É得改变基于数据的eXtremeTable的行为成为可能。在阅读扩展标签属性时åQŒä½ ä¼šå‘现它和扩展标½{‘Ö±žæ€§å…·æœ‰åŒæ ïLš„æ¦‚念和方法标识ã€?区分使用他们的首要准则是åQšå¦‚果需要向TLD里已¾lå®šä¹‰çš„òq¶ä¸”能够在JSP中访问的标签æ·ÕdŠ æ–°çš„å±žæ€§æ—¶åQŒåº”该ä‹É用扩展标½{‘Ö±žæ€§ï¼›å¦‚果仅仅是需要修改已¾lå®šä¹‰å¥½çš„属性的值的时候,应该使用拦截器ã€?

你可能需要了解更多的eXtremeTable如何˜qä½œçš„æŠ€æœ¯èƒŒæ™¯æ‰èƒ½å®Œå…¨ç†è§£è¿™¿Uç‰¹æ€§ã€?eXtremeTable首先做的ž®±æ˜¯éåŽ†æ‰€æœ‰æ ‡½{‘ÖÆˆåˆ›å¾å¯¹åº”的模型beans (pojos)。beans是具有和标签一样属性,但是使用真实¾cÕdž‹æ¥æ›¿æ¢ä»…ä»…ä‹É用字½W¦ä¸²¾cÕdž‹çš„对象。beans是被模型使用òq¶ä¸”是你需要ä‹É用拦截特性修改的对象ã€?所有的拦截器接口都定义了一个addæ–ÒŽ³•åQ?addæ–ÒŽ³•被用来处理模型bean½W¬ä¸€‹Æ¡åˆ›å»ºæ—¶çš„属性。行和列的拦截器˜q˜æœ‰ä¸€ä¸ªmodify æ–ÒŽ³•。modifyæ–ÒŽ³•可以在当行和¾c»è¿›è¡Œå¤„ç†æ˜¯å¯¹å±žæ€§å€ÆD¿›è¡Œæ“ä½œã€?/p>

1.1. æ‹¦æˆªå™¨åˆ—è¡?/h3>

下面列出了具有拦截特性的标签和他们需要被实现的接口,Bean栏显½CÞZº†è¢«æ¨¡åž‹åˆ›å»ºçš„Beanã€?/p>

标签 接口 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

1.2. è¡Œæ‹¦æˆªå™¨½CÞZ¾‹

½Cø™Œƒæ‹¦æˆªç‰ÒŽ€§çš„完美½CÞZ¾‹ž®±æ˜¯æ ÒŽ®ä¸€å®šçš„æ ‡å‡†æ¥å¯¹è¡Œè¿›è¡Œé«˜äº®æ˜¾½Cºï¼Œ˜q™ä¹Ÿæ˜¯æˆ‘们将要完成的½CÞZ¾‹ã€‚它很短也很½Ž€å•,不过它实现的概念同样适用于每一个拦截器接口ã€?

我们需要做的第一件事ž®±æ˜¯å®žçްInterceptRow接口。你会注意到˜q™ä¸ªæŽ¥å£æœ‰ä¸¤ä¸ªæ–¹æ³•:addRowAttributes() å’ŒmodifyRowAttributes()。addRowAttributesæ–ÒŽ³•在行bean创徏的时候被调用åQ?modifyRowAttributesæ–ÒŽ³•在表处理当前™åµé¢è¡Œçš„æ—¶å€™è¢«è°ƒç”¨ã€?/p>

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("");
}
}
}

在Preferences里你应该定义˜q™ä¸ªè¡Œæ‹¦æˆªå™¨çš„别名ã€?/p>

row.intercept.marker=org.extremesite.intercept.MarkerIntercept

˜q™æ ·ž®±å¯ä»¥åœ¨è¡Œæ ‡½{¾ä¸­ä½¿ç”¨æ‹¦æˆªå™¨MarkerIntercept了ã€?/p>

<ec:row intercept="marker">

如果不清楚Preferences和TableTag定义语法请参考Preferences指南�/em>

Limit指南


1. å¼•言

在你需要处理大量数据时你应该考虑使用eXtremeTableçš„Limitç‰ÒŽ€§ã€‚Limit˜q™ä¸ªåå­—来自MySQLçš„limit 命ä×oåQŒLimit接口的目的就是如何对表的¾l“果集进行limit处理。Limit实现知道当排序、过滤、分™åüc€å¯¼å‡ºæ—¶åQŒç”¨æˆ·å¦‚ä½•ä¸Žè¡¨äº’ç›æ€½œç”¨ã€‚有了这些信息你 ž®†èƒ½å¤Ÿä‹É用可能是最有效的方式显½Cºæ­£¼‹®çš„˜q‡æ×o、排序后的请求页面ã€?/p>

ä¸ÞZº†½Cø™ŒƒLimitç‰ÒŽ€§ï¼Œæˆ‘将要做的工作将分解为JSP、Controller、Serviceå’ŒDAO。这½Cø™Œƒäº†ä¸€¿Uä‹É用分层的方式来处ç?Limit。你可以æ ÒŽ®è‡ªå·±çš„需要来增加或减ž®‘层。本½CÞZ¾‹ä¹Ÿä‹É用了Spring框架来重新得åˆîC‹É用Springçš„JDBC取得的数据,因此你的代码看è“v来可能有点不同。eXtremeTable的一个特点就是不依赖ä»ÖM½•框架和容器ã€?

1.1. JSP

ä¸ÞZº†ä½¿ç”¨Limitç‰ÒŽ€§ï¼ŒeXtremeTable需要ä‹É用limit特定的RetrieveRowsCallbackã€?FilterRowsCallbackå’ŒSortRowsCallback接口。eXtremeComponents提供了每个接口的一个实玎ͼŒå¯ä»¥½Ž€å•地通过讄¡½®æ¯ä¸ªå±žæ€§å€égØ“limit来简单来使用ã€?

<ec:table 
items="presidents"
retrieveRowsCallback="limit"
filterRowsCallback="limit"
sortRowsCallback="limit"
view="limit"
>
...

另外视图属性参照一个名为limit的定制视图。这是一个简单修攚w»˜è®¤eXtremeTable视图åQŒä¸åŒ…含最后页工具条的实现。这仅仅关系åˆîC½ æ˜¯å¦èƒ½å–得确切需要的行ã€?一些数据库例如Oracleå’ŒMySQL都提供了一¿Uå¾—到确定行的特性,但是åQŒå…¶ä»–的数据库例如:Sybase没有提供ç‰ÒŽ€§ã€‚在我的½CÞZ¾‹ä¸­æˆ‘考虑最坏的情况你的数据库不支持˜q™ç§ç‰ÒŽ€§ã€?/p>

即ä‹É你的数据库不提供取得特定行的ç‰ÒŽ€§ï¼Œå½“你考虑用户如何和表协同工作æ—Óž¼ŒLimit仍然非常有意义。用户通常会对一些数据进行排序、过滤和分页ã€?˜q™ä¸ªä¾‹å­ä¸?5条数据构成一™åµï¼Œ½W¬ä¸€™åµéœ€è¦?5条数据,½W¬äºŒ™åµéœ€è¦?0条数据,½W¬ä¸‰™åµéœ€è¦?5条数据,以此¾cÀLŽ¨ã€‚åœ¨¾lè¿‡ä¸€ŒD‰|—¶é—´åˆ†™åµåŽåQŒä»–们叏叿€‹É用过滤来提炼数据ã€?即ä‹É他们不这样做åQŒä»–们也必须在此之前对大量的数据˜q›è¡Œåˆ†é¡µåQŒè¿™ž®†åª„响效率。当然如果允许用æˆïL‚¹å‡ÀLœ€åŽé¡µåQŒé‚£ä¹ˆæ‰€æœ‰çš„æ•°æ®éƒ½å°†è¢«å–出,˜q™å°†éžå¸¸å½±å“æ•ˆçއã€?/p>

1.2. Controller

提示åQšSpring框架的Controllerå’ŒStruts框架的Action非常相像ã€?/em>

controller首先需要创å»ÞZ¸€ä¸ªLimitã€‚äØ“äº†å®Œæˆè¿™ä¸ªä½ éœ€è¦å¾—åˆîC¸€äº›å…³äºŽContextå’ŒLimitFactory的帮助ã€?/p>

Context context = new HttpServletRequestContext(request);
LimitFactory limitFactory = new TableLimitFactory(context);
Limit limit = new TableLimit(limitFactory);

Context是一个处理取得属性的接口åQŒLimitFactory使用Context来找出用户如何和eXtremeTable交互ã€?然后Limit使用LimitFactory来组装自己ã€?/p>

ä¸ÞZº†åˆå§‹åŒ–LimitåQŒå®ƒž®†åŒ…含所有的有用的信息。这些信息包括数据将被如何排序和˜q‡æ×oåQŒå“ªä¸€™åµå°†è¢«æ˜¾½Cºå’Œæ˜¯å¦å…è®¸è¢«å¯¼å‡ºã€?/p>

然而,Limit仍然需要得到行的信息,˜q™æ ·æ­£ç¡®çš„信息页面才能被昄¡¤º¾l™ç”¨æˆ—÷€‚行信息包括开始行、结束行、当前显½Cø™¡Œã€?controller必须从service得到˜q™äº›ä¿¡æ¯åQŒè€ŒServicež®†ä»Ždao中得到这些信息。这里我只给出Controller端的代码ã€?/p>

int totalRows = presidentsService.getTotalPresidents(limit.getFilterSet(), limit.isExported());
limit.setRowAttributes(totalRows, defaultRowsDisplayed);

limit需要得到所有的行来得到行的信息。service需要知道那些被˜q‡æ×oåQŒä¸½Ž¡è¿™äº›æ•°æ®æ˜¯å¦è¦å¯¼å‡ºã€‚äØ“äº†è®¾¾|®è¡Œä¿¡æ¯åQŒé»˜è®¤çš„一™å‰|˜¾½Cºçš„行数需要被讄¡½®ã€?˜q™å¯ä»¥é€šè¿‡å¯¹TableTagçš„rowsDisplayed属性设¾|®ä¸€ä¸ªç¡®å®šçš„æ•°å€¼æ¥å®žçްã€?/p>

现在我们只需要从services得到Collection数据�/p>

Collection presidents = presidentsService.getPresidents(limit.getFilterSet(), limit.getSort(), limit.getRowEnd());

因䨓limit已经包含所有信息,˜q™å°†ååˆ†å®ÒŽ˜“。所有需要做的就是传入过滤器åQŒæŽ’序和最后行的信息ã€?最后要做的是将Collectionså’ŒtotalRow˜q™äº›ä¿¡æ¯ä¼ é€å›žJSP以便eXtremeTable知道如何昄¡¤º˜q™äº›ä¿¡æ¯ã€?/p>

request.setAttribute("presidents", presidents);
request.setAttribute("totalRows", new Integer(totalRows));

1.3. Service

service需要和dao˜q›è¡Œäº¤äº’来得到总行数和Collectionã€?/p>

1.3.1. å–得总行æ•?/h4>

controller需要到½W¬ä¸€æ¡ä¿¡æ¯å°±æ˜¯æ€»è¡Œæ•°ã€?/p>

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;
}

serviceå’Œdao一èµäh¥˜q‡æ×o¾l“果集,它的工作方式是在Where语句后面增加更多的AND语句来修æ”ÒŽŸ¥è¯¢å­—½W¦ä¸²ã€‚äØ“æ­¤ï¼Œä½ éœ€è¦å’ŒLimit FilterSet一起工作ã€?/p>

FilterSet是一个过滤器对象数组åQŒä¸€ä¸ªè¿‡æ»¤å™¨åŒ…括一个bean property和这个过滤器的倹{€‚或者,½Ž€å•的说就是用æˆähƒ³è¦è¿‡æ»¤çš„行和他们输入的倹{€‚这使得它非常容易交互。service只需要è„P代所有的 FilterSetòq¶è°ƒç”¨dao来拼接查询语句。(译者注åQšè¿‡æ»¤çš„实现方式是:在Where后面增加And语句来改变查询语句以辑ֈ°å¯ÒŽ•°æ®è¿›è¡Œè¿‡æ»¤çš„æ•ˆæžœåQ?/p>

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;
}

query修改包括了filter信息åQŒæ€»è¡Œæ•°ã€‚在一些情况下˜q™å°±­‘›_¤ŸåQŒä½†æ˜¯å½“ç”¨æˆ·å¯¼å‡ºæ•°æ®æ—¶ä»ç„¶å­˜åœ¨ä¸€ä¸ªæ½œåœ¨çš„é—®é¢˜ã€‚äØ“äº†ä¿æŒé«˜æ•?serviceä¸å…è®¸å¯¼å‡ø™¶…å‡ÞZ¸€ä¸ªæœ€å¤§è¡Œæ•°çš„æ•°æ®ã€?/p>

1.3.2. å–å¾—Collection

controller需要到½W¬äºŒæ¡ä¿¡æ¯å°±æ˜¯Collectionã€?/p>

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);
}

å’Œå‰é¢ä¸€æ øP¼Œserviceå’Œdao一èµäh¥˜q‡æ×o¾l“果集ã€?/p>

另外query字符串需要扩展ORDER BY语句以便数据按照正确的方式进行排序。Sort包含一个bean propertyå’?sortOrderå€û|¼ˆæ­£åº˜q˜æ˜¯é€†åºåQ‰ã€‚service仅仅需要ä‹É用Sort来调用daoã€?/p>

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);
}

query字符串最后需要的修改ž®±æ˜¯å¢žåŠ æ•°æ®åº“ç‰¹åˆ«çš„æŒ‡ä×o来limitž®†è¦è¢«è¿”回的¾l“果集。这ž®±æ˜¯limitQuery() æ–ÒŽ³•的作用ã€?/p>

1.4. DAO

dao为service负责底层数据工作�/p>

1.4.1. å®šä¹‰Query字符ä¸?/h4>

ä¸ÞZº†çœŸæ­£ç†è§£daoåQŒquery字符串需要被展示ã€?/p>

˜q™å°±æ˜¯å¾—到数据的presidents query字符ä¸ÔŒ¼š

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 ";

˜q™æ˜¯å¾—到总行数的query字符ä¸ÔŒ¼š

private final static String totalPresidentsQuery = 
" SELECT count(*) FROM presidents ";

1.4.2. Filter å’?Sort Query 字符ä¸?/h4>

两个最有趣的方法就是过滤和排序�/p>

filter看è“v来像˜q™æ ·åQ?/p>

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();
}

filterQuery()æ–ÒŽ³•需要增加正¼‹®çš„AND语句到query字符丌Ӏ?/p>

sort看è“v来非常类ä¼û|¼š

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();
}

sortQuery()æ–ÒŽ³•需要增加正¼‹®çš„ORDER BY语句到query字符丌Ӏ?/p>

1.4.3. Limit Query String

现在query字符串修改能够正¼‹®çš„˜q›è¡Œfilterå’ŒsortåQŒå®ƒ˜q˜éœ€è¦ä¿®æ”¹ä»¥ä¾¿åªå–页面显½Cºç›¸å…³çš„æ•°æ®ã€‚MySQL为s the limit命ä×oã€?/p>

public String limitQuery(int rowEnd, String query) {
return query + " limit " + rowEnd;
}

1.4.4. å–回总行数和Collection.

service需要的唯一东西ž®±æ˜¯åQšæ€»è¡Œæ•°å’ŒCollectionã€?/p>

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);
}

ResultReader是一个帮助处理JDBC查询的Springç‰Òޮоc»ï¼Œä½œäؓ一个callback来处理JDBC ResultSet。jdbcTemplate是对JDBC˜qžæŽ¥çš„æŠ½è±¡ã€?/p>

1.4.5. é»˜è®¤çš„Sort™åºåº

最后,˜q™æ˜¯service需要的默认sort™åºåºåQ?/p>

public String getDefaultSortOrder() {
return " ORDER BY concat(first_name, ' ', last_name) ";
}

Preferences 指南


1. å¼•言

ä¸ÞZº†è®„¡½®å…¨å±€å±žæ€§å’Œè®„¡½®åQŒä½ éœ€è¦ä‹É用Preferencesç‰ÒŽ€§ï¼Œå®ƒçŽ°åœ¨ä‹É用一个属性文件来实现。本文档ž®†å¾ˆå¥½åœ°ä»‹ç»å¦‚何在web.xml里设¾|®PreferencesåQ?以及一些需要被定义的通用属性。在˜q™é‡Œæˆ‘éžå¸æ€¹æ„ä»‹¾lä¸€äº›å…³äºŽPreferences的进一步用法ã€?/p>

所有标½{‘Ö±žæ€§è¡¨½CÞZ¸€ä¸ªå¯æ’接的接口,它可以通过¾l™å‡ºå®žçŽ°çš„å…¨è·¯å¾„æ¥è®¾¾|®ã€‚è¿™ä¸ºæ’æŽ¥å®žçŽ°æä¾›äº†ä¸€æ¡ä¾¿åˆ©çš„é€”å¾„ã€‚å½“ç„¶è¿™å­˜åœ¨ä¸€äº›äØ“˜q‡é•¿æœ¯è¯­çš„设计和¾l´æŠ¤çš„考虑ã€?½W¬ä¸€åQŒå¯¹ä½ çš„æŽ¥å£å®žçް˜q›è¡Œ¼‹¬ç¼–码;½W¬äºŒåQŒå¦‚果你需要在别的JSP中用到同一个接口实玎ͼŒä½ éœ€è¦æ‹·è´ä½ å…¨èµ\径。解册™¿™ä¸¤ä¸ªé—®é¢˜çš„æœ‰æ•ˆåŠžæ³•å°±æ˜¯åœ¨Preferences中声明一切ã€?/p>

1.1. Preferencesè¡?/h3>

下面列出的是可以在Preferences中申明的所有接口。Tag列展½Cºçš„æ˜¯eXtremeTable的标½{¾ï¼ŒAttribute 列展½Cºçš„æ˜¯ç›¸å…Ïx ‡½{„¡š„对应属性。Interface列展½Cºçš„æ˜¯éœ€è¦è¢«å®žçŽ°çš„Java接口。Preference Key列展½Cºçš„æ˜?Preferences里对应的健ã€?/p>

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

提示åQšå½“在写作本指南的时候,我意识到我忘è®îCº†è®©æ ‡½{¾ColumnsTagçš„autoGenerateColumns 属性和Preferences协同工作。这ž®†åœ¨ä¸‹ä¸€ç‰ˆä¿®æ­£ã€?/em>

1.2. æŒ‡å®šPreference别名

上表展示了如何声明preference键,但是没有解释如何指定有意义的别名。如果你注意到preference键提供了一致的语法 tag.attributeåQŒæŒ‡å®šé”®çš„别名仅仅是在它的基¼‹€ä¸Šè¿›è¡Œæ‰©å±•ã€‚å®ƒçš„è¯­æ³•äØ“åQ?tag.attribute.aliasã€?/p>

eXtremeTable提供了一个名为RowCountCell定制的cellåQŒå®ƒçš„作用是现实当前的行数。我ž®†åœ¨Preferences里ä‹É用ColumnTag cell声明来示范RowCountCellçš„ä‹É用ã€?/p>

首先通过实现Cell接口或者扩展AbstractCell来编写具体的实现¾c…R€?/p>

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);
}
}

然后在Preferences (属性文ä»?˜q›è¡Œå£°æ˜Žòq¶ç»™å‡ºåˆ«åã€?span class="emphasis">eXtremeTable在一个Preferences里保存所有的配置信息åQŒä½ å¯ä»¥é€šè¿‡ä½¿ç”¨æœ¬åœ° Preferences的来覆盖ä»ÖM½•的这些属性ã€?/em>

RowCountCell默认的别名是rowCountåQ?/p>

column.cell.rowCount=org.extremecomponents.table.cell.RowCountCell

在ColumnTag中通过别名引用CellåQ?/p>

<ec:column alias="count" cell="rowCount"/>

现在你可以通过rowCount来引用这个CellåQŒå¦‚果包名改变了你只需要对Preferences˜q›è¡Œä¿®æ”¹ã€?/p>

提示åQšæœ¬½CÞZ¾‹ä¸­æˆ‘使用了ColumnTag的别名属性。别名属性应用在有两列ä‹É用同æ ïLš„propertyåQŒä¹Ÿåº”用在列不直接和列的 bean propertyå…Œ™”的情况下。本½CÞZ¾‹ž®±å±žäºŽè¿™¿Uæƒ…å†üc€?/em>



]]>
使用dtree构徏动态树型菜å?http://www.aygfsteel.com/i369/articles/149776.html芦苇芦苇Sun, 30 Sep 2007 01:48:00 GMThttp://www.aygfsteel.com/i369/articles/149776.htmlhttp://www.aygfsteel.com/i369/comments/149776.htmlhttp://www.aygfsteel.com/i369/articles/149776.html#Feedback0http://www.aygfsteel.com/i369/comments/commentRss/149776.htmlhttp://www.aygfsteel.com/i369/services/trackbacks/149776.htmldtree是一个免费的javascript脚本åQŒåªéœ€å®šä¹‰æœ‰é™çš„几个参敎ͼŒž®±å¯ä»¥åšå‡ºæ¼‚亮的树型菜单。下载目录:http://www.destroydrop.com/javascripts/tree/
 ä»¥ä¸‹æ˜¯dtree的用法示例:
 1åQ‰åˆå§‹åŒ–菜单
 <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>
 2åQ‰è°ƒç”¨å‡½æ•?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>
 
2。jsp动态实çŽ?br />    åˆ†ä»¥ä¸‹æ­¥éª¤å®žçŽ°åŠ¨æ€çš„æ ‘åž‹èœå•åQ?br />    1åQ‰åœ¨æ•°æ®åº“徏tree_info表,有nodeIdåQŒparentNodeIdåQŒnodeNameåQŒnodeUrl四个字段åQŒæ¥å­˜å‚¨èŠ‚ç‚¹ä¿¡æ¯ã€?br />    2åQ‰ç¼–写java¾c»ï¼Œç”¨äºŽä»Žæ•°æ®åº“扑ևºèŠ‚ç‚¹ä¿¡æ¯åQŒåƈ且生成javascript脚本ã€?br />    3åQ‰ç¼–写tag¾c…R€‚用于封装逻辑åQŒç®€åŒ–jsp的开发ã€?br />    4åQ‰å¾ä¸€ä¸ªweb½E‹åº˜q›è¡Œ‹¹‹è¯•ã€?/div>
3。详¾l†è¿‡½E?br />    1åQ‰åœ¨æ•°æ®åº“徏表,脚本如下åQ?br />    CREATE TABLE `test`.`tree_info` (
   `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 />     æŒ‰ç…§ä¸Šé¢çš„dTree½CÞZ¾‹æ’入数据
   2åQ‰ç¼–写TreeInfo.javaåQŒè¿™ä¸ªç±»ç”¨äºŽž®è£…节点信息
     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
   public int getNodeId() {
    return nodeId;
   }
   public void setNodeId(int nodeId) {
    this.nodeId = nodeId;
   }
   public int getParentId() {
    return parentId;
   }
   public void setParentId(int parentId) {
    this.parentId = parentId;
   }
   public String getNodeName() {
    return nodeName;
   }
   public void setNodeName(String nodeName) {
    this.nodeName = nodeName;
   }
   public String getUrl() {
    return url;
   }
   public void setUrl(String url) {
    this.url = url;
   }
  }
   ¾~–写TreeUtil.javaåQŒç”¨äºŽä»Žæ•°æ®åº“得到节点信息,ž®è£…到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 driverName = "com.mysql.jdbc.Driver";
    String host = "localhost";
    String port = ":3306";
    String serverID = "test";
    String userName = "root";
    String userPwd = "root";
    String url = "jdbc:mysql://" + host + port + "/" + serverID ;
    Connection conn = null ;
    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();
     TreeInfo info = null;
     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://-->");
    return contents.toString();
   }
   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));
   }
  }
 3)¾~–写标签¾c?br />  InitTreeTag.java
 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{
  public int doEndTag() throws JspException {
   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();
  }
 }
 ShowTreeTag.java : 
 package com.diegoyun.web.taglibs;
 import javax.servlet.jsp.tagext.TagSupport;
 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(TreeåQ?åQ?);\n");
   sb.append("http://-->\n");
   sb.append("</script>\n");
   sb.append("</div>\n");
   return sb;
  }   
 }
 æ ‡ç­¾çš„tld如下åQ?br />  <?xml version="1.0" encoding="ISO-8859-1" ?>
 <!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>
 4åQ‰å¾ç«‹web˜q‡ç¨‹åQŒç¼–写jsp˜q›è¡Œ‹¹‹è¯•ã€?/div>
 index.jsp如下åQ?br />  <%@ page language="java"%>
 <%@ 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>
 <body>

 <b>Tree example :</b><br /><br />
 <tree:show/>
 <br /><br />
 
 </body>
 </html>
]]>dtree右键菜单 http://www.aygfsteel.com/i369/articles/149778.html芦苇芦苇Sun, 30 Sep 2007 01:48:00 GMThttp://www.aygfsteel.com/i369/articles/149778.htmlhttp://www.aygfsteel.com/i369/comments/149778.htmlhttp://www.aygfsteel.com/i369/articles/149778.html#Feedback0http://www.aygfsteel.com/i369/comments/commentRss/149778.htmlhttp://www.aygfsteel.com/i369/services/trackbacks/149778.html<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 += "&nbsp;";
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\">&nbsp;</td></tr>";
}
else if (this.type == "separator")
{
strShow += "<tr><td class=\"ltdexit\">&nbsp;</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>
]]>
Jsp中ä‹É用EL表达式不解析(无效)的问é¢?http://www.aygfsteel.com/i369/articles/135855.html芦苇芦苇Fri, 10 Aug 2007 08:03:00 GMThttp://www.aygfsteel.com/i369/articles/135855.htmlhttp://www.aygfsteel.com/i369/comments/135855.htmlhttp://www.aygfsteel.com/i369/articles/135855.html#Feedback0http://www.aygfsteel.com/i369/comments/commentRss/135855.htmlhttp://www.aygfsteel.com/i369/services/trackbacks/135855.html原样把tomcat çš„jsp例子拯‚¿‡æ¥è¿˜æ˜¯å¦‚此。web.xml里和lib里的配置都配好了。找了很久才发现web.xmlæ–‡äšg使用的是servlet 2.3版本的声明的问题。el在servlet 2.3中默认是不启用的ã€?

servlet 2.3çš?br>

<?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">

tomcat自带�servlet 2.4的�br>

<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">

把web.xml的声明部分改ä¸?.4的即可ã€?br>˜q˜æœ‰ž®±æ˜¯å¦‚果使用äº?lt;taglib>标签ž®±éœ€è¦åŠ <jsp-config>父标½{¾ã€‚具体内容看jsp2.0å’Œservlet2.4规范

 <jsp-config>
  <taglib>
    <taglib-uri>/tags/struts-bean.tld</taglib-uri>
    <taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
  </taglib>
  </jsp-config>

 



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1667667



]]>
[2007-01-21 18时发布]ecside 1.0rc1: 列表¾l„äšgeXtremeComponents全面增强ç‰?/title><link>http://www.aygfsteel.com/i369/articles/135464.html</link><dc:creator>芦苇</dc:creator><author>芦苇</author><pubDate>Thu, 09 Aug 2007 05:20:00 GMT</pubDate><guid>http://www.aygfsteel.com/i369/articles/135464.html</guid><wfw:comment>http://www.aygfsteel.com/i369/comments/135464.html</wfw:comment><comments>http://www.aygfsteel.com/i369/articles/135464.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/i369/comments/commentRss/135464.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/i369/services/trackbacks/135464.html</trackback:ping><description><![CDATA[<strong><font color=#0000ff>ecside介绍åQ?br></font></strong>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <p>ecside是一个开源的<strong><font color=#ff0000>列表¾l„äšg</font></strong>ã€?br>他源自著名开源列表组ä»?eXtremeComponents åQˆhttp://www.extremecomponents.orgåQ‰ï¼Œ<br>但现在已¾lè„±¼›»eXtremeComponents,独立发展åQˆä»æœ‰å¤§é‡ä»£ç æ¥è‡?eXtremeComponentsåQ‰ã€?br>“<strong><font color=#ff9900>做最实用易用的列表组ä»?/font></strong>”是ecside最¾lˆçš„目标ã€?/p> <p><font face=Arial>作者: fins ( name: Wei Zijun    email:fins@163.com   blog:http://fins.javaeye.com )<br></font><font face=Arial></font></p> <p><font face=Arial>在ä‹É用前åQŒè¯·é˜…读一下以下信息,以帮助您了解您要使用的将是一个多么不成熟的东è¥?但它会有成熟的一天,而且那天不会˜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 拥有无数未知的bugåQŒè¯·è§è°…ã€?/font></p> <p><br><strong><font color=#0000ff>ecside发布地址åQ?/font></strong><br>http://fins.javaeye.com/blog/40190 </p> <p><font face=Arial><font color=#3366ff><strong>ecside发布地址åQ?br></strong><font color=#000000>http://fins.javaeye.com/blog/40190 <br></font><strong>ecside圈子:<br></strong><font color=#000000>http://ecside.javaeye.com/</font><br><strong>ecside¾l¼åˆè®¨è®ºä¸“用å¸?br></strong><a ><font color=#000000><u>http://fins.javaeye.com/blog/48723</u></font></a></font>  <br></font></p> <p><br><strong><font color=#0000ff>其他凸™‰²çš„列表组ä»?有些是收费的)åQ?br></font></strong>eXtremeComponents原始ç‰?( http://www.extremecomponents.org )<br>dhtmlXGrid ( http://scbr.com/docs/products/dhtmlxGrid/ )<br>displaytag ( http://displaytag.sourceforge.net )<br>nitobi grid ( http://www.nitobi.com/products/grid/ ) <br>ActiveWidgets gird ( http://www.activewidgets.com/grid/ )<br>rico livegrid ( http://openrico.org/rico/livegrid.page )</p> <p> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br><strong><font color=#ff0000>主要增强的功能:<br></font></strong>1 可设¾|®å·¥å…äh¡ä½ç½®åQˆä¸Š ä¸?æˆ?不显½Cºï¼‰<br>2 可设¾|®å·¥å…äh¡å†…容åQˆæ˜¾½Cºå“ªäº?不显½Cºå“ªäº›ï¼‰<br>3 可设¾|®å·¥å…äh¡ä¸Šå„个功能按钮的相对位置<br>4 增加äº?strong><font color=#ff9900>调整™åµå¤§ž®çš„选择框,òq¶å¯è‡ªå®šä¹‰é€‰æ‹©æ¡†å†…的内å®?/font></strong><br>5 增加了带有邻˜q‘é¡µé¢çš„å¯ÆDˆªæ?br>6 增加了可跌™{到指定页面的跌™{æ¡?br><font face=Arial>7 增加了当å‰?font color=#ff9900><strong>选中行高äº?/strong></font></font><br>8 为ec:table 增加äº?excludeParameters å’?includeParameters 属性,可以实现更快æïL®€ä¾¿çš„“参数保留/不保ç•?#8221;功能<br>9 可添加自定义的html代码到工å…äh¡å†?或其他位¾|?br>10 <font color=#ff9900><strong>可手动调整列å®?/strong><br></font>11 增加äº?#8220;<strong><font color=#ff9900>列表内部滚动æ?/font></strong>”(实现<font color=#ff9900>列表头固å®?/font>åQŒåˆ—表体滚动的功èƒ?<br>12 为ec:rowå’Œec:column æ·ÕdŠ æ›´å¤šçš„html事äšg支持åQŒçŽ°æ”¯æŒåQšonmouserover onmouserout onclick ondbclick<br>13 为ec:table ec:row ec:column增加了自定义扩展属性功èƒ?br>14 增加 ec:extendrow 标签åQŒå®žçŽ°åˆ—è¡¨æ‰©å±•è¡Œçš„åŠŸèƒ?br>15 增加<strong><font color=#ff9900>shadowRow(影子è¡?功能</font></strong>åQšæ¯è¡Œä¸‹é¢å¯ä»¥å†åŠ ä¸€ä¸ªå­è¡?˜q™ä¸ªè¡Œé‡Œæ˜„¡¤ºä»€ä¹ˆå¯ä»¥ç”±å¤§å®¶è‡ªå·±å®šä¹‰<br>16 增加™åµé¢å˜é‡ <strong><font color=#ff9900>${TOTALROWCOUNT}</font></strong> 用来标示当前¾Uªå½•在全部记录中的行æ•?br>17 增加了打印功能(ž®šä¸å®Œå–„åQ?br>18 ec:column属性增åŠ?ellipsis ,实现单元格内数据˜q‡é•¿çš„æ—¶å€?自动截短òq¶åŠ "..."的功èƒ?ie only)<br>19 实现了跨列的列表å¤?br>20 <font color=#ff9900><strong>¾lŸè®¡æ çš„æ ‡é¢˜æ ¼å¯è·¨åˆ—</strong><br></font>21 增加了若òq²ç§cell å’?headerCell,例如checkbox radio<br>22 取消了imagePath属æ€?样式相关的图片信息全部提入csså†?br>23 重(½W?壎ͼ‰ç”¨äº†js å’Œcss åQŒå¾ˆå¤šåŠŸèƒ½ç”¨js来实çŽ?br>24 支持äº?font color=#ff9900><strong>ajax¾˜»é¡µ</strong></font><br>25 支持<strong><font color=#ff9900>预查询功èƒ?/font></strong>åQŒåœ¨å¯Ÿçœ‹½W¬n™å늚„时候,把n+1™å늚„数据也查询出来(隐藏着åQ‰å¤‡ç”¨ï¼ŒåŠ å¿«æŸ¥çœ‹ä¸‹ä¸€™å늚„速度<br>26 ž®†å¯¼å‡?strong><font color=#ff9900>excel</font></strong>所使用的组件由<font color=#ff9900><strong>poi切换成了 jxl</strong></font><br>27 xls导出方式修改 原始的导出是导出的vo/map里的原始数å€?现在æ˜?strong><font color=#ff9900>导出™åµé¢å®žé™…昄¡¤ºçš„内å®?/font></strong><br><font face=Arial>28 增加<font color=#ff9900><strong>½Ž€æ·å¯¼å‡ºæ–¹å¼?/strong></font> (通过ec:tableçš?xlsFileName pdfFileName csvFileName属æ€?<br>29 支持<font color=#ff9900><strong>pdf中文导出</strong></font>ã€?br>30 代码˜q›è¡Œäº†å¤§è§„模的重æž?br>31 增加了很多ajax相关ç‰ÒŽ€?br><font face=Arial>32 实现äº?font color=#ff0000><strong>可编辑列è¡?/strong></font>功能 以及<strong><font color=#ff0000>cell的映ž®?/font></strong>功能</font></font><font face=Arial><br>... ...</font></p> <font face=Arial> <p><br>更新日志åQ?br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>新增加的ç‰ÒŽ€§é€šå¸¸éƒ½åœ¨ <strong><font color=#ff0000>demo.do.jsp</font></strong>˜q™ä¸ªä¾‹å­é‡Œè¿›è¡Œæ¼”½Cºã€?/p> <p><font face=Arial>===============================<br>2007-01-21 15ç‚?br>===============================<br>对于以下更新åQŒdemo.do.jsp˜q›è¡Œäº†ä¿®æ”¹ï¼Œå¤§å®¶çœ‹çœ‹ä¾‹å­å¯èƒ½ä¼šæ›´å¥½ç†è§?</font></p> <p><font face=Arial><font face=Arial>1) 实现äº?strong><font color=#ff0000>cell的映ž®„功èƒ?/font></strong>åQˆè¯¦è§ç¤ºä¾‹çš„æ€§åˆ« å’?角色列),用法:<br></font>了一ä¸?strong><font color=#ff0000>½Ž€å•çš„ž®æ ‡½{?/font></strong> 用来从map生成 selectçš„option列表ã€?br><ec:options items="MAP在context内的key" defaultkey="默认选中的optionçš„value" tagattributes="附加的html属æ€?></ec:options></font></p> <div id="wmqeeuq" class=code_title>xml 代码</div> <div id="wmqeeuq" class=dp-highlighter> <div id="wmqeeuq" class=bar></div> <ol class=dp-xml> <li id="wmqeeuq" class=alt><span><span id="wmqeeuq" class=tag><</span><span id="wmqeeuq" class=tag-name>ec:column</span><span> </span><span id="wmqeeuq" class=attribute>mappingItem</span><span>=</span><span id="wmqeeuq" class=attribute-value>"用来映射的MAP在context内的key"</span><span> </span><span id="wmqeeuq" class=attribute>mappingDefaultValue</span><span>=</span><span id="wmqeeuq" class=attribute-value>"当找不到映射值时要ä‹É用的默认å€?</span><span>...</span><span id="wmqeeuq" class=tag>/></span><span>  </span></span> </li> </ol> </div> <p>例如åQŒåœ¨½CÞZ¾‹ä¸­ï¼Œè§’色的信息以 “标识--名称”çš„åŞ式放åˆîCº†ä¸€ä¸?mapå†?br>在actionä¸?把这个map攑ֈ°äº?request.setAttribute("USERROLE_MAP", CommonDictionary.USERROLE);å†?br>在页面ä‹Éç”?br></p> <div id="wmqeeuq" class=code_title>xml 代码</div> <div id="wmqeeuq" class=dp-highlighter> <div id="wmqeeuq" class=bar></div> <ol class=dp-xml> <li id="wmqeeuq" class=alt><span><span id="wmqeeuq" class=tag><</span><span id="wmqeeuq" class=tag-name>ec:column</span><span> </span><span id="wmqeeuq" class=attribute>property</span><span>=</span><span id="wmqeeuq" class=attribute-value>"USERROLE"</span><span> </span><span id="wmqeeuq" class=attribute>title</span><span>=</span><span id="wmqeeuq" class=attribute-value>"角色"</span><span> </span><span id="wmqeeuq" class=attribute>mappingItem</span><span>=</span><span id="wmqeeuq" class=attribute-value>"USERROLE_MAP"</span><span> </span><span id="wmqeeuq" class=attribute>mappingDefaultValue</span><span>=</span><span id="wmqeeuq" class=attribute-value>"[错误的角色]"</span><span id="wmqeeuq" class=tag>/></span><span>  </span></span> </li> </ol> </div> <p><br>ž®×ƒ¼šè‡ªåЍž®†å¿U°æ˜¾½C?font face=Arial>出来ã€?br>2) å?/font></p> <div id="wmqeeuq" class=code_title>xml 代码</div> <div id="wmqeeuq" class=dp-highlighter> <div id="wmqeeuq" class=bar></div> <ol class=dp-xml> <li id="wmqeeuq" class=alt><span><span id="wmqeeuq" class=tag><</span><span id="wmqeeuq" class=tag-name>ec:options</span><span> </span><span id="wmqeeuq" class=attribute>items</span><span>=</span><span id="wmqeeuq" class=attribute-value>"MAP在context内的key"</span><span> </span><span id="wmqeeuq" class=attribute>defaultKey</span><span>=</span><span id="wmqeeuq" class=attribute-value>"默认选中的optionçš„value"</span><span> </span><span id="wmqeeuq" class=attribute>tagAttributes</span><span>=</span><span id="wmqeeuq" class=attribute-value>"附加的html属æ€?</span><span id="wmqeeuq" class=tag>/></span><span>  </span></span> </li> </ol> </div> <p><br>3) å¯?strong><font color=#ff0000>ec:extend</font></strong>标签做了扩充åQŒå¢žåŠ äº†ä½ç½®è®„¡½®å±žæ€?<strong><font color=#ff0000>location</font></strong><br>top: form内列表主体前  ; bottom : form内列表主体后  <br>toolbar或不讄¡½®location属æ€?nbsp; 在toolbar的扩展位¾|?<br>4) 代码˜q›è¡Œäº†ä¸€ç‚¹ç‚¹ä¿®æ”¹åQŒå¯¹ä½¿ç”¨æ²¡æœ‰å½±å“ã€?/p> <p><font face=Arial>===============================<br><font color=#ff0000>2007-01-20 9ç‚?nbsp;  ECSIDE 1.0 RC1 发布å•?/font><br>===============================<br>沉寂两天åQŒä½†ä¸€ç›´æ²¡æœ‰é—²ç€åQŒå¸¦æ¥äº†å¤§å˜åŒ?索性来ä¸?1.0 RC1 ç‰?:) ã€?br>1) 实现äº?font color=#ff0000><strong>灉|´»çš„可定制çš?#8220;可编辑列è¡?#8221;功能</strong></font> åQˆè¯¦è§help.txt 200行左右的描述 以及½CÞZ¾‹åQ?br>支持多种¾~–辑方式åQˆæ–‡æœ¬æ¡† 下拉æ¡?ž®†æ¥˜q˜ä¼šæ”¯æŒæ›´å¤šåQ‰ï¼Œå¯è‡ªå®šä¹‰æ¨¡ç‰ˆåQˆä‹É用自定义的文本框 下拉框)åQŒè¿˜æä¾›äº†ï¼š<br>对可¾~–辑列进行标识,对编辑过的cell˜q›è¡Œæ ‡è¯†åQˆé»˜è®¤äØ“æ”¹å˜å•å…ƒæ ÆDƒŒæ™¯è‰²åQ‰ï¼Œ<br>使用ajax技术提交后収ͼŒæäº¤æˆåŠŸçš„cellž®†æ¸…除编辑标è¯?½{‰è„“心设计ã€?br>2) 增加äº?<font color=#ff0000><strong>高亮昄¡¤ºé€‰ä¸­è¡Œçš„功能</strong></font>åQŒä‹Éç”?ec:table属æ€? selectlightRow="true"<br>3) åŽÀLމäº?fullnavigation坯Dˆªæ¡ï¼Œž®†å…¶ä¸Žnavigation坯Dˆªæ¡åˆòq?br>æ”¹äØ“ä¸ºec:table增加属æ€?<font color=#ff0000><strong>nearPageNum="æ•°å­—"</strong></font> 用来讄¡½®å¯ÆDˆªæ¡å‰åŽæ˜¾½Cºçš„邻近™å‰|•° ½{‰äºŽ0æ—?ä¸ÞZ¸ä½¿ç”¨é‚»è¿‘™åüc€?br>4) 为ec:table增加äº?maxRowsExported="æ•°å­—" 属性,用来限制导出大最大条敎ͼŒ 如果数据­‘…过˜q™ä¸ªæ•°ç›®åQŒåˆ™ä¸æ‰§è¡Œå¯¼å‡ºæ“ä½œã€?br>5) ä¸ÞZ¹‹å‰å¢žåŠ çš„ec:tableçš„pageSizeList属æ€?增加了特æ€?br>pageSizeList="<font color=#ff0000><strong>max:200</strong></font>,10,15,30,50,100,all" 如果 10--100以及all中,某一™å¹å¤§˜q‡äº†maxçš?00åˆ?不在列表中显½Cºã€?br>也可以只使用pageSizeList="max:200" 此时ž®?使用默认讄¡½®åQŒåƈ˜q›è¡Œmax控制ã€?br>6) <strong><font color=#ff0000>解决了pdf中文¾~–码问题åQŒç»ˆäºŽæ”¯æŒpdf导出äº?/font></strong>ã€?br>7) 恢复了对sitemesh的支持,用法见原版ec文档åQˆæˆ‘没有亲自没有‹¹‹è¯•,å› äØ“æˆ‘ä¸ä¼šç”¨sitemesh :( åQ‰ã€?br>8) <font color=#ff0000>Ajax¾˜»é¡µä¼˜åŒ–</font>åQŒåŒæ—¶å¢žåŠ äº† ECSide.findAjaxZoneAtClien 属性,可设¾|?<strong><font color=#ff0000>客户ç«?˜q˜æ˜¯ 服务端进è¡?html代码剪裁</font></strong>ã€?br>默认推荐使用 服务器端ã€?br>9) 再次对jså’Œjava代码˜q›è¡Œäº†è¾ƒå¤§è§„模的重构,清理了一些无用代码,æ·ÕdŠ äº†å¿…è¦çš„åè®®ä¿¡æ¯ã€?br>10) 一些细节的修改(例如å¯ÒŽ»šè½®çš„æ”¯æŒæ›´è‡ªç„?filterable="true"手动调节列宽功能屏蔽½{? <br>˜q˜æœ‰å¯¹ä¸€äº›å°bug的修正,但是ç”׃ºŽå˜åŒ–较大åQŒè‚¯å®šè¿˜ä¼šå¸¦æ¥ä¸€äº›æ–°bugã€?br>11) 整个½CÞZ¾‹çš„应ç”?font color=#ff0000>逐步发展ä¸?ecside 的最佛_®žè·?/font>åQŒåŠ å…¥äº†<font color=#ff0000>hsqldb</font>åQˆhsqldbçš„ä‹É用参考了springsideåQ‰ï¼Œå…¨æ–°çš„例子ã€?br>当然˜q˜ä¸å¤Ÿå¥½ 会在以后的日子里¾l§ç®‹å®Œå–„ã€?br>12) 做了一个简单的<font color=#ff0000>logo</font> :)ã€?/font></p> <p><font face=Arial><strong><font color=#3366ff>™åÞZ¾¿é—®ä¸€ä¸‹ï¼š</font><br>我ä‹É用了 springside çš?HsqlListener åQˆåšäº†äº›ä¿®æ”¹ 但绝对不涉及到核心)åQŒäؓ什么在每次重启应用的时候æ€ÀL˜¯åŒ…下面的异常呢?åQ?br></strong>Exception in thread "HSQLDB Timer @15d63da" java.lang.NullPointerException<br> at org.hsqldb.lib.HsqlTimer.nextTask(Unknown Source)<br> at org.hsqldb.lib.HsqlTimer$TaskRunner.run(Unknown Source)<br> at java.lang.Thread.run(Unknown Source)<br></font></p> <p><font face=Arial>===============================<br>2007-01-16 14ç‚?br>===============================<br>1) 当ä‹Éç”?#8220;列表内部滚动æ?#8221;æ—Óž¼Œå¯ä»¥ä½¿ç”¨<font color=#ff9900><strong>癑ֈ†æ¯?/strong></font>来设¾|®åˆ—表的宽度了ã€?br>(但还是徏议您使用像素åQˆpxåQ‰ä½œä¸ºåˆ—表和列的宽度单位,å› äØ“ç™‘Öˆ†˜q˜æœ‰ä¸€äº›å°bug)<br>˜q˜æœ‰ä¸ªå¾è®?不管是ä‹Éç”¨ä»€ä¹ˆæ ·çš„å®½åº¦ï¼Œå»ø™®®éƒ½è¦ä½¿ç”¨ä¸€ä¸?#8220;自动宽度”çš„columnåQ?br>ž®±æ˜¯è¯´ä¸è¦ç»™æ‰€æœ‰çš„ec:column都指定widthåQŒç»™å…¶ä¸­ä¸€ä¸ªç‚¹“自由”åQŒè¿™æ ·å¾ˆå¤šå·²çŸ¥çš„关于列宽调整的问题都可以解决ã€?br>2) 对eccn.js˜q›è¡Œäº†å¤§é‡çš„修改åQŒæä¾›äº†<font color=#ff9900><strong>更好(但不完美)çš„IEå’ŒFF兼容åQˆä¸€è‡ß_¼‰æ€?/strong></font>åQˆè¿™ä¸ªå·¥ä½œå·®ç‚ÒŽŠŠæˆ‘ç¯åè¡€åQ?<br>ffå’Œie 在取得对象坐标和宽度的算法不å?太郁闷了<br>3) 修正了一äº?font color=#ff9900><strong>bug</strong></font>ã€?/font></p> <p><br><font face=Arial>===============================<br>2007-01-12 以及之前的一些更新日å¿?/font><br>===============================<br>1) ä¸?#8220;列表内部滚动æ?#8221;增加了对鼠标滚轮的支æŒ?只在ie6å’Œff2下测试过,其他版本没有‹¹‹è¯•)<br>2) ž®†éƒ¨åˆ?#8220;列表内部滚动æ?#8221;相关的代码从java中提å‡?改用js实现.<br>3) 对jsæ–‡äšg做了一些调整ã€?br>4) 修正了一些小bugã€?</p> <p>===============================<br>1) 修正了一ä¸?#8220;列表内部滚动æ?#8221;çš„bug<br>该bug表现为在 IEé‡?有些windows的主题下åQŒçºµå‘滚动条不可用。FT!!!!!<br>2) eccn.js做了一点小ž®çš„æ”¹åЍåQŒäØ“ž®†æ¥åšè¿‡¾~–码支持打下了一点点基础.</p> <p>===============================<br>1) 修正了改变页面大ž®æ—¶“列表内部滚动æ?#8221;é”™äØ•çš„bug<br>2) 重构äº?#8220;列表内部滚动æ?#8221;相关的jså’Œjava代码</p> <p>===============================<br>1) 修正了ä‹É用ajax¾˜»é¡µæ—?#8220;列表内部滚动æ?#8221;é”™äØ•çš„bug<br>2) 增加了当列表内容的实际宽度和高度ž®äºŽè®„¡½®çš„宽度和高度的时候,<br>   自动调整区域大小,同时自动隐藏滚动条(只隐藏横向的åQ‰çš„功能ã€?/p> <p>===============================<br>增加äº?#8220;固定列表å¤ß_¼Œæ»šåŠ¨åˆ—è¡¨ä½?#8221;(“列表内部滚动æ?#8221;)的功èƒ?br>˜q™ä¸ªåŠŸèƒ½å®žçŽ°èµäh¥æ¯”我一开始想像的复杂<br>不是½Ž€å•的使用一ä¸?div overflow:scrollž®±å¯ä»¥æžå®šçš„<br>虽然功能是支持了 但是代码肯定˜q˜æœ‰å¾ˆå¤šbug或者是可以改进的地æ–?br>‹Æ¢è¿Žå¤§å®¶¿U¯æžçš„æå‡ºå®è´ëŠš„意见 谢谢äº?/p> <p>使用æ–ÒŽ³•åQ?br>ec:table标签å†?增加<br>listHeight="æ•°å­—" 属æ€?åQˆæŒ‡å®šåˆ—表体的高度)<br>同时把要指定 width="æ•°å­—" 不能省略 同时要ä‹É用绝对大ž®?而不要ä‹É用百分比<br></p> <p>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p> <p>部分增强功能½Ž€ä»‹ï¼š<br>åQˆè¯¦è§help.txtåQ?/p> <p>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br></p> <p><font face=Arial color=#3366ff><strong>我们有自å·Þqš„圈子äº?<br>以后大家æœ?ecside相关的问é¢?可以åŽ?font color=#ff0000>圈子é‡?/font><br>我的 <font color=#ff0000>blog里问</font>( http://fins.javaeye.com/blog/48723 )  <br>别在发消息了 å› äØ“å‘æ¶ˆæ¯åˆ«äººçœ‹ä¸åˆ° 而有些问题可能别äºÞZ¹Ÿé‡åˆ°˜q?或者是我回½{”的不对 别äh也可以帮å¿?<br>对吧? <br>谢谢大家</strong></font></p> <p><font face=Arial><font color=#3366ff><strong>ecside发布地址åQ?br>http://fins.javaeye.com/blog/40190 <br>ecside圈子:<br>http://ecside.javaeye.com/<br>ecside¾l¼åˆè®¨è®ºä¸“用å¸?br>http://fins.javaeye.com/blog/48723</strong></font>  <br></font></p> <p> </p> <p>我申请了<font face=Arial><font color=#ff0000><strong>javascud</strong></font>™å¹ç›® 而且也申请了svn 但是<strong><font color=#ff0000>不会用啊  :'( 谁来教教我啊</font></strong></font></p> <p> </p> <p> <font face=Arial color=#ff0000 size=4><strong>依赖包已¾lä¸Šä¼ åˆ° 圈子的共享空间里äº?/strong></font></p> <p>å…?ä¸?误‚§£åŽ‹ç¾ƒåŽæ”¾åˆ?WEB-INF/libä¸?如果不导出pdf可以不下载pdf相关的包 å’?字体文äšg ˜q™ä¸¤ä¸ªæ¯”较大 <font face=Arial></font> </p> </font> <div style="PADDING-RIGHT: 10px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 15px 0px 0px 10px; PADDING-TOP: 10px"> <table class=attach cellSpacing=0 cellPadding=2 width="95%" align=center border=1> <tbody> <tr> <td class=attachrow style="BACKGROUND: #d1d7dc" align=middle width="100%" colSpan=3><strong><span id="wmqeeuq" class=gen>ecside_1.0_rc1_20070121b.zip</span></strong></td> </tr> <tr> <td class=attachrow width="15%"><span id="wmqeeuq" class=genmed> æè¿°:</span></td> <td class=attachrow width="75%"> å®Œæ•´ç‰ˆï¼Œä½†ä¸åŒ…括所依赖的WEB-INF/lib下的文äšg.依赖文äšg可以åŽÕdœˆå­é‡Œä¸‹è², 也可以去javaeye ftp下蝲,也可以按照WEB-INF/lib下的filelist.txtæ–‡äšg所åˆ?自行下蝲. </td> <td class=attachrow align=middle width="10%" rowSpan=4><img alt="" src="http://fins.javaeye.com/images/forum/icon_clip.gif" border=0><br><a ><strong><u><font color=#0000ff>下蝲</font></u></strong></a> </td> </tr> <tr> <td class=attachrow width="15%"><span id="wmqeeuq" class=genmed> æ–‡äšgå?</span></td> <td class=attachrow width="75%"><span id="wmqeeuq" class=genmed> ecside_1.0_rc1_20070121b.zip</span></td> </tr> <tr> <td class=attachrow width="15%"><span id="wmqeeuq" class=genmed> æ–‡äšg大小:</span></td> <td class=attachrow width="75%"><span id="wmqeeuq" class=genmed> 697 KB</span></td> </tr> <tr> <td class=attachrow width="15%"><span id="wmqeeuq" class=genmed> ä¸‹è²˜q‡çš„:</span></td> <td class=attachrow width="75%"><span id="wmqeeuq" class=genmed> æ–‡äšg被下载或查看 774 ‹Æ?/span></td> </tr> </tbody> </table> </div> <img src ="http://www.aygfsteel.com/i369/aggbug/135464.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/i369/" target="_blank">芦苇</a> 2007-08-09 13:20 <a href="http://www.aygfsteel.com/i369/articles/135464.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>攉™›†çš„éžå¸æ€¸é”™çš„js脚本http://www.aygfsteel.com/i369/articles/134639.html芦苇芦苇Mon, 06 Aug 2007 02:55:00 GMThttp://www.aygfsteel.com/i369/articles/134639.htmlhttp://www.aygfsteel.com/i369/comments/134639.htmlhttp://www.aygfsteel.com/i369/articles/134639.html#Feedback0http://www.aygfsteel.com/i369/comments/commentRss/134639.htmlhttp://www.aygfsteel.com/i369/services/trackbacks/134639.html1 >屏蔽功能¾c?/strong>

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、F5åˆäh–°ã€é€€æ ¼é”®

<script language="javascript">
<!--
  //屏蔽鼠标右键、Ctrl+N、Shift+F10、F5åˆäh–°ã€é€€æ ¼é”®
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 é”®çš„æ–ÒŽ³•å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 å›„¡‰‡ä¸Šè‡ªåŠ¨å‡ºçŽ°çš„ä¿å­˜å›¾æ ‡

æ–ÒŽ³•一åQ?br><META HTTP-EQUIV="imagetoolbar" CONTENT="no">
æ–ÒŽ³•二:
<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("误‚¾“入您姓名!");
   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("您两‹Æ¡è¾“å…¥çš„å¯†ç ä¸ä¸€æ øP¼è¯·é‡æ–°è¾“å…?");
   document.ADDUser.PWD.focus();
   return false;
}
   return true;
}
-->
</script>

2.3 è¡¨å•™å¹åªèƒ½äؓ数字å’?_",用于电话/银行帐号验证ä¸?可扩展到域名注册½{?/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("您的电话åï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("您的电子邮äš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>

//é¼ æ ‡¿UÕdЍ
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



]]>
Js实现Map对象 http://www.aygfsteel.com/i369/articles/134638.html芦苇芦苇Mon, 06 Aug 2007 02:54:00 GMThttp://www.aygfsteel.com/i369/articles/134638.htmlhttp://www.aygfsteel.com/i369/comments/134638.htmlhttp://www.aygfsteel.com/i369/articles/134638.html#Feedback0http://www.aygfsteel.com/i369/comments/commentRss/134638.htmlhttp://www.aygfsteel.com/i369/services/trackbacks/134638.html<script> 
function Map() {
 var struct = function(key, value) {
  this.key = key;
  this.value = value;
 }
 
 var put = function(key, value){
  for (var i = 0; i < this.arr.length; i++) {
   if ( this.arr[i].key === key ) {
    this.arr[i].value = value;
    return;
   }
  }
   this.arr[this.arr.length] = new struct(key, value);
 }
 
 var get = function(key) {
  for (var i = 0; i < this.arr.length; i++) {
   if ( this.arr[i].key === key ) {
     return this.arr[i].value;
   }
  }
  return null;
 }
 
 var remove = function(key) {
  var v;
  for (var i = 0; i < this.arr.length; i++) {
   v = this.arr.pop();
   if ( v.key === key ) {
    continue;
   }
   this.arr.unshift(v);
  }
 }
 
 var size = function() {
  return this.arr.length;
 }
 
 var isEmpty = function() {
  return this.arr.length <= 0;
 }

 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("map¿U»é™¤ä¸€ä¸ªå…ƒç´ åŽçš„大ž®äØ“åQ? + map.size());
 alert("map是否是一个空map:" + map.isEmpty());
</script>

 


Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1550098



]]>JavaScript çš?BASE64 ½Ž—法http://www.aygfsteel.com/i369/articles/131446.html芦苇芦苇Fri, 20 Jul 2007 05:00:00 GMThttp://www.aygfsteel.com/i369/articles/131446.htmlhttp://www.aygfsteel.com/i369/comments/131446.htmlhttp://www.aygfsteel.com/i369/articles/131446.html#Feedback0http://www.aygfsteel.com/i369/comments/commentRss/131446.htmlhttp://www.aygfsteel.com/i369/services/trackbacks/131446.html/**
* æˆ‘在¾|‘上看到˜q‡å¾ˆå¤šBASE64çš„JavaScript½Ž—法åQŒéƒ½è§‰å¾—不满意,于是自己写了一个,在这里分享一下ã€?br>* æˆ‘的代码在质量的效率都较高,没有一些冗余的操作。æ€ÖM½“æ¥è®²æˆ‘è§‰å¾—éžå¸æ€¸é”™ã€?br>* å¦‚果大家有什么不懂的地方可以问我ã€?br>
*/
var BASE64={
    
/**
     * æ­¤å˜é‡äØ“¾~–码的keyåQŒæ¯ä¸ªå­—½W¦çš„下标相对应于它所代表的编码ã€?br>     
*/
    enKey: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
+/',
    
/**
     * æ­¤å˜é‡äؓ解码的keyåQŒæ˜¯ä¸€ä¸ªæ•°¾l„,BASE64的字½W¦çš„ASCII值做下标åQŒæ‰€å¯¹åº”的就是该字符所代表的编码倹{€?br>     
*/
    deKey: 
new Array(
        
-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1,
        
-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1,
        
-1-1-1-1-1-1-1-1-1-1-162-1-1-163,
        
52535455565758596061-1-1-1-1-1-1,
        
-1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  91011121314,
        
1516171819202122232425-1-1-1-1-1,
        
-1262728293031323334353637383940,
        
4142434445464748495051-1-1-1-1-1
    ),
    
/**
     * ¾~–码
     
*/
    encode: 
function(src){
        
//用一个数¾l„来存放¾~–码后的字符åQŒæ•ˆçŽ‡æ¯”ç”¨å­—½W¦ä¸²ç›¸åŠ é«˜å¾ˆå¤šã€?/span>
        var str=new Array();
        
var ch1, ch2, ch3;
        
var pos=0;
       
//每三个字½W¦è¿›è¡Œç¼–码ã€?/span>
        while(pos+3<=src.length){
            ch1
=src.charCodeAt(pos++);
            ch2
=src.charCodeAt(pos++);
            ch3
=src.charCodeAt(pos++);
            str.push(
this.enKey.charAt(ch1>>2), this.enKey.charAt(((ch1<<4)+(ch2>>4))&0x3f));
            str.push(
this.enKey.charAt(((ch2<<2)+(ch3>>6))&0x3f), this.enKey.charAt(ch3&0x3f));
        }
        
//¾l™å‰©ä¸‹çš„字符˜q›è¡Œ¾~–码ã€?/span>
        if(pos<src.length){
            ch1
=src.charCodeAt(pos++);
            str.push(
this.enKey.charAt(ch1>>2));
            
if(pos<src.length){
                ch2
=src.charCodeAt(pos);
                str.push(
this.enKey.charAt(((ch1<<4)+(ch2>>4))&0x3f));
                str.push(
this.enKey.charAt(ch2<<2&0x3f), '=');
            }
else{
                str.push(
this.enKey.charAt(ch1<<4&0x3f), '==');
            }
        }
       
//¾l„合各编码后的字½W¦ï¼Œ˜qžæˆä¸€ä¸ªå­—½W¦ä¸²ã€?/span>
        return str.join('');
    },
    
/**
     * è§£ç ã€?br>     
*/
    decode: 
function(src){
        
//用一个数¾l„来存放解码后的字符ã€?/span>
        var str=new Array();
        
var ch1, ch2, ch3, ch4;
        
var pos=0;
       
//˜q‡æ×o非法字符åQŒåƈåŽÀLމ'='ã€?/span>
        src=src.replace(/[^A-Za-z0-9\+\/]/g, '');
        
//decode the source string in partition of per four characters.
        while(pos+4<=src.length){
            ch1
=this.deKey[src.charCodeAt(pos++)];
            ch2
=this.deKey[src.charCodeAt(pos++)];
            ch3
=this.deKey[src.charCodeAt(pos++)];
            ch4
=this.deKey[src.charCodeAt(pos++)];
            str.push(String.fromCharCode(
                (ch1
<<2&0xff)+(ch2>>4), (ch2<<4&0xff)+(ch3>>2), (ch3<<6&0xff)+ch4));
        }
        
//¾l™å‰©ä¸‹çš„字符˜q›è¡Œè§£ç ã€?/span>
        if(pos+1<src.length){
            ch1
=this.deKey[src.charCodeAt(pos++)];
            ch2
=this.deKey[src.charCodeAt(pos++)];
            
if(pos<src.length){
                ch3
=this.deKey[src.charCodeAt(pos)];
                str.push(String.fromCharCode((ch1
<<2&0xff)+(ch2>>4), (ch2<<4&0xff)+(ch3>>2)));
            }
else{
                str.push(String.fromCharCode((ch1
<<2&0xff)+(ch2>>4)));
            }
        }
       
//¾l„合各解码后的字½W¦ï¼Œ˜qžæˆä¸€ä¸ªå­—½W¦ä¸²ã€?/span>
        return str.join('');
    }
};

使用æ–ÒŽ³•åQ?/p>

var str='hello world!';
var enstr=BASE64.encode(str);
alert(enstr);
var destr=BASE64.decode(enstr);
alert(destr);


]]>
使用FileUpload¾l„äšg实现文äšg上传 http://www.aygfsteel.com/i369/articles/125608.html芦苇芦苇Thu, 21 Jun 2007 08:44:00 GMThttp://www.aygfsteel.com/i369/articles/125608.htmlhttp://www.aygfsteel.com/i369/comments/125608.htmlhttp://www.aygfsteel.com/i369/articles/125608.html#Feedback0http://www.aygfsteel.com/i369/comments/commentRss/125608.htmlhttp://www.aygfsteel.com/i369/services/trackbacks/125608.htmlæ–‡äšg上传在web应用中非常普遍,要在servlet/jspçŽ¯å¢ƒä¸­å®žçŽ°æ–‡ä»¶ä¸Šä¼ åŠŸèƒ½éžå¸¸å®¹æ˜“ï¼Œå› äØ“¾|‘上已经有许多用java开发的¾l„äšg用于文äšg上传åQŒæœ¬æ–‡ä»¥commons-fileupload¾l„äšgä¸ÞZ¾‹åQŒäØ“servlet/jsp应用æ·ÕdŠ æ–‡äšg上传功能ã€?/p>

common-fileupload¾l„äšg是apache的一个开源项目之一åQŒå¯ä»¥ä»Žhttp://jakarta.apache.org/commons/fileupload/下蝲。该¾l„äšg½Ž€å•易用,可实çŽîC¸€‹Æ¡ä¸Šä¼ ä¸€ä¸ªæˆ–多个文äšgåQŒåƈ可限制文件大ž®ã€?/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收到‹¹è§ˆå™¨å‘出的Postè¯äh±‚后,在doPost()æ–ÒŽ³•中实现文件上传。以下是½CÞZ¾‹ä»£ç å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);

        // 得到所有的文äšgåQ?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.txtåQŒä½ ä¹Ÿå¯ä»¥ä»ŽfileName中提取文件名åQ?br>                fi.write(new File(uploadPath + "a.txt"));
            }
        }
        // è·Œ™{åˆîC¸Šä¼ æˆåŠŸæ½Cºé¡µé?br>    }
    catch(Exception e) {
        // 可以跌™{出错™åµé¢
    }
}

如果要在配置文äšg中读取指定的上传文äšg夹,可以在init()æ–ÒŽ³•中执行:

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();
}

¾~–译该servletåQŒæ³¨æ„è¦æŒ‡å®šclasspathåQŒç¡®ä¿åŒ…含commons-upload-1.0.jarå’Œtomcat\common\lib\servlet-api.jarã€?/p>

配置servletåQŒç”¨è®îCº‹æœ¬æ‰“å¼€tomcat\webapps\ä½ çš„webapp\WEB-INF\web.xmlåQŒæ²¡æœ‰çš„话新å»Þ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后,启动tomcatåQŒå†™ä¸€ä¸ªç®€å•çš„html‹¹‹è¯•åQ?/p>

<form action="fileupload" method="post"
enctype="multipart/form-data" name="form1">
  <input type="file" name="file">
  <input type="submit" name="Submit" value="upload">
</form>

注意action="fileupload"其中fileupload是配¾|®servlet时指定的url-patternã€?/p>

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=15991



]]>
javascript弹出½H—口æ€È»“ http://www.aygfsteel.com/i369/articles/120198.html芦苇芦苇Sat, 26 May 2007 10:10:00 GMThttp://www.aygfsteel.com/i369/articles/120198.htmlhttp://www.aygfsteel.com/i369/comments/120198.htmlhttp://www.aygfsteel.com/i369/articles/120198.html#Feedback0http://www.aygfsteel.com/i369/comments/commentRss/120198.htmlhttp://www.aygfsteel.com/i369/services/trackbacks/120198.html//关闭,父窗口弹出对话框,子窗口直接关é—?br>this.Response.Write("<script language=javascript>window.close();</script>");

//关闭,父窗口和子窗口都不弹出对话框,直接关闭
this.Response.Write("<script>");
this.Response.Write("{top.opener =null;top.close();}");
this.Response.Write("</script>");

//弹出½H—口åˆäh–°å½“前™åµé¢width=200 height=200菜单。菜单栏,工具æ?地址æ ?状态栏全没æœ?br>this.Response.Write("<script language=javascript>window.open('rows.aspx','newwindow','width=200,height=200')</script>");

//弹出½H—口åˆäh–°å½“前™åµé¢
this.Response.Write("<script language=javascript>window.open('rows.aspx')</script>");
this.Response.Write("<script>window.open('WebForm2.aspx','_blank');</script>");

//弹出提示½H—口跛_ˆ°webform2.aspx™å?在一个IE½H—口ä¸?
this.Response.Write(" <script language=javascript>alert('注册成功');window.window.location.href='WebForm2.aspx';</script> ");

//关闭当前子窗å?åˆäh–°çˆ¶çª—å?br>this.Response.Write("<script>window.opener.location.href=window.opener.location.href;window.close();</script>");
this.Response.Write("<script>window.opener.location.replace(window.opener.document.referrer);window.close();</script>");

//子窗口刷新父½H—口
this.Response.Write("<script>window.opener.location.href=window.opener.location.href;</script>");
this.Response.Write("<script>window.opener.location.href='WebForm1.aspx';</script>");

//弹出提示½H—口.¼‹®å®šåŽå¼¹å‡ºå­½H—口(WebForm2.aspx)
this.Response.Write("<script language='javascript'>alert('发表成功åQ?);window.open('WebForm2.aspx')</script>");

//弹出提示½H—口,¼‹®å®šå?åˆäh–°çˆ¶çª—å?br>this.Response.Write("<script>alert('发表成功åQ?);window.opener.location.href=window.opener.location.href;</script>");

//弹出相同的一™å?br><INPUT type="button" value="Button" onclick="javascript:window.open(window.location.href)">

//
Response.Write("parent.mainFrameBottom.location.href='yourwebform.aspx?temp=" +str+"';");


<SCRIPT LANGUAGE="javascript"> 
<!-- 
window.open ('page.html', 'newwindow', 'height=100, width=400, top=0, left=0, toolbar=no, menubar=no, scrollbars=no, resizable=no,location=n o, status=no') //˜q™å¥è¦å†™æˆä¸€è¡?br>--> 
</SCRIPT>  
  
  参数解释åQ?nbsp;
  
  <SCRIPT LANGUAGE="javascript"> js脚本开始; 
  window.open å¼¹å‡ºæ–°çª—口的命ä×oåQ?nbsp;
  'page.html' å¼¹å‡º½H—口的文件名åQ?nbsp;
  'newwindow' å¼¹å‡º½H—口的名字(不是文äšg名)åQŒéžå¿…é¡»åQŒå¯ç”¨ç©º''代替åQ?nbsp;
  height=100 ½H—口高度åQ?nbsp;
  width=400 ½H—口宽度åQ?nbsp;
  top=0 ½H—口距离屏幕上方的象素å€û|¼› 
  left=0 ½H—口距离屏幕左侧的象素å€û|¼› 
  toolbar=no æ˜¯å¦æ˜„¡¤ºå·¥å…·æ ï¼Œyes为显½Cºï¼› 
  menubaråQŒscrollbars è¡¨ç¤ºèœå•栏和滚动栏ã€?nbsp;
  resizable=no æ˜¯å¦å…è®¸æ”¹å˜½H—口大小åQŒyes为允许; 
  location=no æ˜¯å¦æ˜„¡¤ºåœ°å€æ ï¼Œyes为允许; 
  status=no æ˜¯å¦æ˜„¡¤ºçŠ¶æ€æ å†…çš„ä¿¡æ¯åQˆé€šå¸¸æ˜¯æ–‡ä»¶å·²¾læ‰“å¼€åQ‰ï¼Œyes为允许; 
  </SCRIPT> js脚本¾l“束

'newwin':隐藏菜单栏地址栏工å…äh¡
width=50:宽度
height=50:高度
scrollbars=yes/n滚动æ?br>top=50:½H—口距离屏幕上方
left=50:½H—口距离屏幕左侧
ä¾?window.open('detail.aspx?ID="+e.Item.Cells[1].Text+"','newwin','width=750,height=600,scrollbars=yes,top=50,left=50');"); 
this.Response.Write("<Script>window.open('WebForm2.aspx','','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,width=750,height=470,left=80,top=40');</script>");

ä¾?
this.Response.Write("<script>alert('发表成功åQ?);window.opener.location.href=window.opener.location.href;</script>");
this.Response.Write("<script>");
this.Response.Write("{top.opener =null;top.close();}");
this.Response.Write("</script>");

ä¾? linkcolumn1.DataNavigateUrlFormatString="javascript:varwin=window.open('edit_usr.aspx?actid={0}','newwin','width=750,height=600,scrollbars=yes,top=50,left=50');window.close()"; 


]]>
Ö÷Õ¾Ö©Öë³ØÄ£°å£º ÁÉÖÐÏØ| ²ÊƱ| ÎÐÑôÏØ| ÇßË®ÏØ| ¾ÃÖÎÏØ| ÑôË·ÏØ| ÑÓ½òÏØ| ÌÆº£ÏØ| ¼ÎÐËÊÐ| ÁùÖ¦ÌØÇø| áÓãôÏØ| ·ÚÎ÷ÏØ| »´±õÏØ| Çà´¨ÏØ| ÂåÔúÏØ| µæ½­ÏØ| ÑÎÍ¤ÏØ| Ë«½­| ÈÚË®| á³á°ÏØ| Î÷¹±Çø| ÇåË®ºÓÏØ| ¶«ÑôÊÐ| ¹ÅÀËÏØ| ÂÞ¶¨ÊÐ| ºÊÔóÊÐ| ºÏ·ÊÊÐ| ÐÏÌ¨ÏØ| ãäÁêÏØ| òÔºÓÊÐ| ¶¡ÇàÏØ| °²ÑôÏØ| ³É°²ÏØ| ±£¾¸ÏØ| ÒËÀ¼ÏØ| ´¾°²ÏØ| ¾¸°²ÏØ| ÎÚÀ¼ÏØ| ¹ãÁéÏØ| ÎåºÓÏØ| ÐÂÏçÏØ|