blogjava-凯发k8网页登录

blogjava-凯发k8网页登录http://www.blogjava.net/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.blogjava.net/i369/articles/187545.html芦苇芦苇thu, 20 mar 2008 10:25:00 gmthttp://www.blogjava.net/i369/articles/187545.htmlhttp://www.blogjava.net/i369/comments/187545.htmlhttp://www.blogjava.net/i369/articles/187545.html#feedback0http://www.blogjava.net/i369/comments/commentrss/187545.htmlhttp://www.blogjava.net/i369/services/trackbacks/187545.html
 
1.下载并安装aptana studio;
2.打开你的aptana程序目录(我这儿是c:\aptana),复制jar格式的文件到plugins目录;
3.重启aptana;
4.进入window -> preferences -> aptana -> editors -> javascript -> code assist选择ext 2.0(或要反选ext.1.1)。


aptana studio with ext 2.0 code assist


spket eclipse插件与ide
    是目前支持ext 2.0最为出色的ide。 它采用.jsb project file 文件并将继承于基类和所有文档的内容嵌入到生成代码提示的script doc中。
    由于spket只是一个单纯的编辑器,没有其它格式的支持(如css),所以我的做法是用它的eclipse插件形式,安装到aptana。安装办法如下:
    1.下载安装aptana studio(包含有eclipse);
    2.启动aptana并打开程序菜单到:help → software updates → find and install… → search for new features to install → new remote site…
    3.名称: “spket”,地址url是
    4.重启aptana;
    5.观看一下这个sketide的,看看ext代码提示的功能有多省事(你可以修改/src/ext.jsb 保持最新版的ext),基本步骤如下:
  1. window → preferences → spket → javascript profiles → new ;
  2. 输入“extjs”点击ok;
  3. 选择“extjs” 并点击“add library”然后在下拉条中选取“extjs”;
  4. 选择 “extjs”并点击“add file”,然后在你的./ext-2.x/source目录中选取“ext.jsb” 文件;
  5. 设置新的extjs profile,选中并点击“javascript profiles” 对话框右手边的“defalut”按钮;
  6. 重启aptana;
  7. 创建新的js文件并输入: ext这样就可设置ext code代码自动完成的功能。

    由于你是在aptana中安装插件的,aptana还是你默认的js编辑器,所以要试用spket,你要在那个文件上选中“open with”-> spket javascript editor 。

spket in aptana with full documentation and code assist


komodo edit
    为众多格式文件提供支持,包括perl、php、python、ruby和tcl。亦支持浏览器方面的代码包括有javascript、css、html和xml。windows、mac os和linux平台都可用。
    安装ext支持下的komodo:

    1.下载和安装komodo edit;
    2.下载;
    3.进入edit -> preferences -> code intelligence 并选择位于“api catalog”下方的按钮“add an api catalog” ;
    4.选择刚才下载的extjs api catalog cix 。


komodo with ext js code intelligence


dreamweaver
    对于dreamweaver的用户,有两种可用的插件(dreamweaver 2004或新版)和(dreamweaver cs3)。两者都是spket团队开发的(刚才提及的),因此也同样精确和出色。另外dreamweaver插件的一大特点是很好地支持配置项的代码提示。

 


members code assist





 

 



config option code assist





 


 

 

 

 

 

 

 

 

 

 

 


 



 

 

   要下载和安装,请浏览他们的。

其它的ide
    还有其它的ide,像由社区发起的正在工作着的intellij和。

总结
    当工作中需要到ext 2.0,的确有一些工具能辅助你提升工作效率,这真的要比较一番(check them out、check out、checkout...)。如果你也发现有其它更好的工具,不妨雁过留声,与我们分享。



芦苇 2008-03-20 18:25
]]>
extremecomponents指南http://www.blogjava.net/i369/articles/149779.html芦苇芦苇sun, 30 sep 2007 01:49:00 gmthttp://www.blogjava.net/i369/articles/149779.htmlhttp://www.blogjava.net/i369/comments/149779.htmlhttp://www.blogjava.net/i369/articles/149779.html#feedback0http://www.blogjava.net/i369/comments/commentrss/149779.htmlhttp://www.blogjava.net/i369/services/trackbacks/149779.html

table of contents

1.
1.1.
1.
1.1.
1.
1.1.
1.1.1.
1.1.2.
1.1.3.
1.1.4.
1.2.
1.3.
1.3.1.
1.3.2.
1.3.3.
1.
1.1.
1.2.
1.
1.1.
1.2.
1.
1.1.
1.2.
1.3.
1.3.1.
1.3.2.
1.4.
1.4.1.
1.4.2.
1.4.3.
1.4.4.
1.4.5.
1.
1.1.
1.2.

定制filtercell


1. 引言

列的filtercell属性控制过滤器如何显示,它和cell属性非常相像并且也是实现cell接口。马上要定义的是默认的和droplist这两个过滤器cells。 默认的是一个输入框元素而droplist是一个下拉列表元素。当然,如果你需要进行一些定制你可以插接自己的实现。

最近,我被问到是否能够实现一个过滤器cell,显示已经通过别的过滤器过滤得到数据子集。答案当然是肯定的,而且这是我将在这里示范的。通常定制的 cell可以很容易被创建,这个示例将印证这点。在这个示例里last name列里显示的将是通过first name过滤后的子集。如果没有通过 first name过滤那么所有值都将被显示。

1.1. 定制droplist过滤器cell示例

通常你只需要为过滤器cell实现cell接口。然而,因为我们要创建的过滤器cell是一个下拉列表,我们可以通过扩展 filterdroplistcell来获得它已经提供的很多功能,filterdroplistcell是发行包已经提供的cells之一。

我们需要覆盖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;
}
}

如果你比较这个类和父类,你会发现它们只有微小的区别。

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

string firstnamefilter = model.getlimit().getfilterset().getvalue("firstname");

然后我们需要判断当前bean的first name值是否和first name过滤器值相同。如果相同,将当前的last name值 添加到droplist中。

string firstname = beanutils.getproperty(bean, "firstname");
if (stringutils.isnotblank(firstnamefilter) && !firstname.equals(firstnamefilter)) {
continue;
}

如果last name将添加到droplist中,我们需要检查droplist中是否已经包含了这个值。如果没有,我们就把它添加到droplist中。

string lastname = beanutils.getproperty(bean, column.getproperty());
if ((lastname != null) && !droplist.contains(lastname)) {
droplist.add(lastname);
}

为了使用这个cell你应该在preferences中声明一个别名。 当然,你可以省略这步而在jsp中提供这个cell实现类的全路径,但是使用preferences更简洁。

column.filtercell.filtereddroplist=org.extremesite.cell.filtereddroplistcell

在columntag通过设置filtercell属性来使用filtereddroplistcell。

如果不清楚preferences和columntag定义语法请参考preferences指南。

定制filterrowscallback


1. 引言

filterrowscallback被用来过滤传给extremetable的beans的collection。 filterrowscallback的默认实现是得到beans或maps的collection,然后通过实现jakarta predicate接口来进行过滤。当然,如果你需要进行一些定制你可以插接自己的实现。

首先声明,本示例代码包含一些从原包中剪切、粘贴的代码(虽然不是很多)。在 最初的最终发行包之后,值过滤得到进一步改善使得更具复用性并更容易实现,可能和定制cell代码行数相同。 当然,我被要求并非常乐意示范如何在当前代码基础上实现定制过滤。这有非常清晰的hooks实现,并且很容易实现。

本示例示范了如何调整代码为过滤器提供一个精确的比较功能。当前的实现是通过使用stringutils.contains()方法进行模糊比较。 本示例将使用stringutils.equals()方法。你可以按照你的需要来调整代码进行更多定制。

1.1. 定制filterrowscallback示例

首先你需要做的是创建一个实现predicate接口的定制类。predicate要求我们实现evaluate()方法来判断是否包含 当前bean。因为你仅仅调整现在已有的功能,首先得到filterpredicate的源代码(在发行包的callback包下), 拷贝到你的工程里。然后向下面展示的一样将 stringutils.contains()方法修改为stringutils.equals()方法:

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 类来确认仅仅实现了filterrowscallback和修改predicate。

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

...

}
}

为了使用这个filterrowscallback你应该在preferences中声明一个别名。当然,你可以省略这步而在jsp中提供这个filterrowscallback实现类的全路径,但是使用preferences更简洁。

table.filterrowscallback.exactmatch=org.extremesite.callback.exactmatchfilterrows

在tabletag通过设置filterrowscallback属性来使用exactmatchfilterrows。

如果不清楚preferences和columntag定义语法请参考preferences指南。

form指南


1. 引言

extremetable本质上是一个form组件,所以我假定表被包在form里,所有的功能都被认为是对form元素的操作。如果你想在表体中包含一些定制的form元素, 或者想将extremetable嵌入到另外的form中,那么你就要使用表标签的form属性用来参照最近的form。

为了示范form特性,我们要做的工作将分解为jsp,cell和controller。

1.1. jsp

下面列出的是checkbox示例的完整代码。想要强调的主要事情是表标签form属性设置为presform,它参照被称为presform的form元素。

同时请注意表标签的autoincludeparameters属性。进行排序、过滤、分页时,默认的extremetable将保持所有传至jsp页面的参数。 这个特性对于内部其他的form进行排序、过滤、分页时,用于高效复制form元素同样有效。可以设置 autoincludeparameters属性为false来固定它。

在这个form使用id属性是因为xhtm标准的要求,同时你也可以使用form的name属性。

" method="post">

enter your name:
type="text"
name="username"
style="font-family:verdana,arial,helvetica,sans-serif;font-size:11px;"
value=""
/>

items="presidents"
action="${pagecontext.request.contextpath}/selectedpresidentscontroller.run"
view="compact"
imagepath="${pagecontext.request.contextpath}/images/table/compact/*.gif"
rowsdisplayed="8"
autoincludeparameters="false"
form="presform"
>
filename="output.pdf"
tooltip="export pdf"
headercolor="black"
headerbackgroundcolor="#b6c2da"
headertitle="presidents"
/>

alias="checkbox"
title=" "
width="5px"
filterable="false"
sortable="false"
viewsallowed="compact"
cell="selectedpresident"
/>






type="button"
name="sel"
class="button"
value="list selected presidents"
onclick="document.forms.presform.submit();"
/>



1.1.1. form特性的技术说明

表标签form属性参照最近的form是你使用这个特性所必须知道的,为了更好的理解这个特性,介绍更多的关于内部实现技术的细节是值得的。

如果您不特意指定form属性,extremetable自动在表附近包上一个form。所有表的动作例如:排序、过滤、分页将自动给一些隐藏的input元素赋值,然后提交这个form到表标签action属性设置的aciton。 这非常有效,除非您想要将自己的form元素设置到表体,或者想将这个表放到别的form里。

表标签form属性参照最近的form,所有表的动作例如:排序、过滤、分页将自动给一些隐藏的input元素赋值,但是现在 最近form的action属性将要改变表标签的动作。这非常重要,因为:当排序、过滤、分页时,extremetable能够从一个controller得到数据集合 ,但是提交这个form到别的controller来处理这个form时需要对用户的输入进行处理。然而,这些对于你使用表标签来说都是透明的。 就像你现在做的那样简单地设置表标签的action属性,然后设置相关的form到你想提交的位置。

1.1.2. checkbox

示例的第一列是checkbox。因为这列不需要参照bean的属性,alias属性用来唯一地标识这列。你可以使用property 属性,但是alias属性使这列如何使用更清楚。alias属性还被用来当同样的属性被多列使用时唯一地标识一列。

1.1.3. custom cell

您也许想知道定制的cell是如何通过名称selectedpresident被参照的(cell="selectedpresident")。这是一个 对extremetable的preferences特性更强的使用。所有要做的就是在extremecomponents.properties文件中添加一个属性。 请参考preferences来了解更多的信息

column.cell.selectedpresident=org.extremesite.cell.selectedpresidentcell

column.cell.selectedpresident就是你定义的用来参照这个cell的名称。

当然你也可以使用这个cell的全名来进行参照。


alias="checkbox"
title=" "
width="5px"
filterable="false"
sortable="false"
viewsallowed="compact"
cell="org.extremesite.cell.selectedpresidentcell"
/>

在属性文件中定义参照更方便,它可以被任何jsp文件引用。如果类名或包名改变的话你只需要对一个地方进行修改。

1.1.4. javascript

javascript的setpresidentstate()方法被定制cell用来设置每个checkbox元素的是否被选中。 设置一个隐藏元素的原因是为了获得浏览器的动作而不提交没有选中的checkbox。通过这个controller将一直知道一个元素是否别选中。

1.2. cell

定制的cell被用来生成checkbox,另外它也创建一个隐藏元素用来表示这个checkbox元素是否被选中。 当用户进行排序、过滤、分页时,被选中的数据集合将被放到session里。

getexportdisplay()方法没有返回值,因为治理只需要html显示。

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

提示:spring框架的controller和struts框架的action非常相像。

当在另外的form中使用extremetable时,你可能有1个或2个controllers。当form被提交时,你需要一个controller 来处理用户的输入并重新定向到另外的jsp页面。当排序、过滤、分页时,你可能有另外的controller来得到表使用的数据集合并重定向会本页。或者你可以在同一个controller中分别处理。

checkbox示例里我使用一个controller来关联表标签的action属性。我也使用另外一个controller来关联form元素的动作。

1.3.1. 表标签动作controller

这个controller负责调用selectedpresidentsutils来保存被选中的presidentids到session里并回到同一页。

selectedpresidentsutils.saveselectedpresidentsids(request);
collection presidents = presidentsservice.getpresidents();
request.setattribute("presidents", presidents);

1.3.2. form动作controller

这个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的值

我将列出保存presidentids到session的代码。我经常被问到如何重新得到extremetable中form元素的值。 它的原理是设置form输入元素名字属性值前面加上一些东西来唯一标识元素

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

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。你可以使用发行包已经提供的视图,或者你可以插入自己的视图实现。 现在,创建你自己的视图相对比较简单,但讨论一些设计想法和如何着手实现一个定制的视图还是有价值的。

我想使创建定制视图简单,但不是想构造一个更复杂的类似swing的模型,原因是那需要创建大量的对象来处理对应的内部工作。 extremetable以高效为目标,我也想在视图的实现上贯彻这种想法,所以我决定创建一系列的静态构造器类来实现分解的最小功能。你可以通过组合这些功能来实现你的定制视图。

学习定制视图的最好途径是阅读已经存在的视图的源代码,修改它来满足你的需求。如果我示范所有东西的话,这篇指南将变的非常冗长。取而代之的是我将直接修改默认视图的工具条作为定制视图的一个示例。 对于不同构造器的具体细节我建议你阅读源代码。我也将尽量更新javadocs来提供更好的帮助。

1.1. view接口

实现view接口的类有3次插入内容的机会。beforebody()方法会被立刻调用,body()方法在每一行的每一列处理的时候调用。 afterbody()方法是被extremetable调用的最后方法,它将返回代表视图的一个对象。在这个html视图示例里,它将是一个字符串。

public interface view {
public void beforebody(tablemodel model);
public void body(tablemodel model, column column);
public object afterbody(tablemodel model);
}

1.2. messages示例

在这篇指南里我将直接修改工具条来实现这网站上messages示例的定制视图。

public class messagesview extends abstracthtmlview { 
protected void toolbar(tablemodel model) {
twocolumntablelayout toolbar = new messagestoolbar();
toolbar.layout(gethtmlbuilder(), model);
}

protected void statusbar(tablemodel model) {
twocolumnrowlayout statusbar = new messagesstatusbar();
statusbar.layout(gethtmlbuilder(), model);
}
}

这里使用的是默认视图,因此它扩展了虚拟视图来修改工具条和状态条。如何修改工具条和(或)状态条也是开发人员问的最多问题。

默认视图的工具条位于表的上方包括翻页链接和标题。工具条使用twocolumntablelayout,它是一个用于提供在自己表中实现左右两列布局的虚拟类。 它将实现能够浮在表上方的完美布局。下面就是你需要关心的虚拟方法,在实际的html视图中已经为你完成了这个布局。

public abstract class twocolumntablelayout {
protected abstract boolean showlayout(tablemodel model);
protected abstract void columnleft(htmlbuilder html, tablemodel model);
protected abstract void columnright(htmlbuilder html, tablemodel model);
}

showlayout()方法用来阻止或导致布局的展现。在我的定制视图中如果翻页或(和)导出显示那么工具条将展现。

protected boolean showlayout(tablemodel model) {
boolean showpagination = builderutils.showpagination(model);
boolean showexports = builderutils.showexports(model);
if (!showpagination && !showexports) {
return false;
}

return true;
}

下面显示了左列和右列的部分代码。注意在我的定制视图中凯发k8网页登录首页和前一页使用了文字来替代图片显示。我真正希望示范的是你需要做的:找到正确的构造器类并且仅仅是扩展htmlbuilder的标签。 构造器类对于示范如何找到模型里的信息(以便你能够做比他们能够提供的更多的定制工作)也非常有用,。

protected void columnleft(htmlbuilder html, tablemodel model) {
html.td(2).close();
tablebuilder.title(html, model);
html.tdend();
}

protected void columnright(htmlbuilder html, tablemodel model) {
boolean showpagination = builderutils.showpagination(model);
...
if (showpagination) {
html.td(4).close();
toolbarbuilder.firstpageitemastext(html, model);
html.tdend();

html.td(4).close();
toolbarbuilder.prevpageitemastext(html, model);
html.tdend();
...
}
...
}

为了使用这个视图你需要在preferences定义一个别名。 你可以省略这部而在jsp直接给出这个视图的完整有效的类名,不过preferences更为简洁。

table.view.messages=org.extremesite.view.messagesview

tabletag也将设置视图属性来使用messagesview视图。

如果不清楚preferences和tabletag定义语法请参考preferences指南。

拦截器使用指南


1. 引言

拦截特性被用在运行时需要修改属性值的时候,它使得改变基于数据的extremetable的行为成为可能。在阅读扩展标签属性时,你会发现它和扩展标签属性具有同样的概念和方法标识。 区分使用他们的首要准则是:如果需要向tld里已经定义的并且能够在jsp中访问的标签添加新的属性时,应该使用扩展标签属性;如果仅仅是需要修改已经定义好的属性的值的时候,应该使用拦截器。

你可能需要了解更多的extremetable如何运作的技术背景才能完全理解这种特性。 extremetable首先做的就是遍历所有标签并创建对应的模型beans (pojos)。beans是具有和标签一样属性,但是使用真实类型来替换仅仅使用字符串类型的对象。beans是被模型使用并且是你需要使用拦截特性修改的对象。 所有的拦截器接口都定义了一个add方法, add方法被用来处理模型bean第一次创建时的属性。行和列的拦截器还有一个modify 方法。modify方法可以在当行和类进行处理是对属性值进行操作。

1.1. 拦截器列表

下面列出了具有拦截特性的标签和他们需要被实现的接口,bean栏显示了被模型创建的bean。

标签 接口 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. 行拦截器示例

示范拦截特性的完美示例就是根据一定的标准来对行进行高亮显示,这也是我们将要完成的示例。它很短也很简单,不过它实现的概念同样适用于每一个拦截器接口。

我们需要做的第一件事就是实现interceptrow接口。你会注意到这个接口有两个方法:addrowattributes() 和modifyrowattributes()。addrowattributes方法在行bean创建的时候被调用, modifyrowattributes方法在表处理当前页面行的时候被调用。

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里你应该定义这个行拦截器的别名。

row.intercept.marker=org.extremesite.intercept.markerintercept

这样就可以在行标签中使用拦截器markerintercept了。

如果不清楚preferences和tabletag定义语法请参考preferences指南。

limit指南


1. 引言

在你需要处理大量数据时你应该考虑使用extremetable的limit特性。limit这个名字来自mysql的limit 命令,limit接口的目的就是如何对表的结果集进行limit处理。limit实现知道当排序、过滤、分页、导出时,用户如何与表互相作用。有了这些信息你 将能够使用可能是最有效的方式显示正确的过滤、排序后的请求页面。

为了示范limit特性,我将要做的工作将分解为jsp、controller、service和dao。这示范了一种使用分层的方式来处理 limit。你可以根据自己的需要来增加或减少层。本示例也使用了spring框架来重新得到使用spring的jdbc取得的数据,因此你的代码看起来可能有点不同。extremetable的一个特点就是不依赖任何框架和容器。

1.1. jsp

为了使用limit特性,extremetable需要使用limit特定的retrieverowscallback、 filterrowscallback和sortrowscallback接口。extremecomponents提供了每个接口的一个实现,可以简单地通过设置每个属性值为limit来简单来使用。


items="presidents"
retrieverowscallback="limit"
filterrowscallback="limit"
sortrowscallback="limit"
view="limit"
>
...

另外视图属性参照一个名为limit的定制视图。这是一个简单修改默认extremetable视图,不包含最后页工具条的实现。这仅仅关系到你是否能取得确切需要的行。 一些数据库例如oracle和mysql都提供了一种得到确定行的特性,但是,其他的数据库例如:sybase没有提供特性。在我的示例中我考虑最坏的情况你的数据库不支持这种特性。

即使你的数据库不提供取得特定行的特性,当你考虑用户如何和表协同工作时,limit仍然非常有意义。用户通常会对一些数据进行排序、过滤和分页。 这个例子中15条数据构成一页,第一页需要15条数据,第二页需要30条数据,第三页需要45条数据,以此类推。在经过一段时间分页后,他们常常使用过滤来提炼数据。 即使他们不这样做,他们也必须在此之前对大量的数据进行分页,这将影响效率。当然如果允许用户点击最后页,那么所有的数据都将被取出,这将非常影响效率。

1.2. controller

提示:spring框架的controller和struts框架的action非常相像。

controller首先需要创建一个limit。为了完成这个你需要得到一些关于context和limitfactory的帮助。

context context = new httpservletrequestcontext(request);
limitfactory limitfactory = new tablelimitfactory(context);
limit limit = new tablelimit(limitfactory);

context是一个处理取得属性的接口,limitfactory使用context来找出用户如何和extremetable交互。 然后limit使用limitfactory来组装自己。

为了初始化limit,它将包含所有的有用的信息。这些信息包括数据将被如何排序和过滤,哪一页将被显示和是否允许被导出。

然而,limit仍然需要得到行的信息,这样正确的信息页面才能被显示给用户。行信息包括开始行、结束行、当前显示行。 controller必须从service得到这些信息,而service将从dao中得到这些信息。这里我只给出controller端的代码。

int totalrows = presidentsservice.gettotalpresidents(limit.getfilterset(), limit.isexported());
limit.setrowattributes(totalrows, defaultrowsdisplayed);

limit需要得到所有的行来得到行的信息。service需要知道那些被过滤,不管这些数据是否要导出。为了设置行信息,默认的一页显示的行数需要被设置。 这可以通过对tabletag的rowsdisplayed属性设置一个确定的数值来实现。

现在我们只需要从services得到collection数据。

collection presidents = presidentsservice.getpresidents(limit.getfilterset(), limit.getsort(), limit.getrowend());

因为limit已经包含所有信息,这将十分容易。所有需要做的就是传入过滤器,排序和最后行的信息。 最后要做的是将collections和totalrow这些信息传送回jsp以便extremetable知道如何显示这些信息。

request.setattribute("presidents", presidents);
request.setattribute("totalrows", new integer(totalrows));

1.3. service

service需要和dao进行交互来得到总行数和collection。

1.3.1. 取得总行数

controller需要到第一条信息就是总行数。

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一起来过滤结果集,它的工作方式是在where语句后面增加更多的and语句来修改查询字符串。为此,你需要和limit filterset一起工作。

filterset是一个过滤器对象数组,一个过滤器包括一个bean property和这个过滤器的值。或者,简单的说就是用户想要过滤的行和他们输入的值。这使得它非常容易交互。service只需要迭代所有的 filterset并调用dao来拼接查询语句。(译者注:过滤的实现方式是:在where后面增加and语句来改变查询语句以达到对数据进行过滤的效果)

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信息,总行数。在一些情况下这就足够,但是当用户导出数据时仍然存在一个潜在的问题。为了保持高效 service不允许导出超出一个最大行数的数据。

1.3.2. 取得collection

controller需要到第二条信息就是collection。

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

和前面一样,service和dao一起来过滤结果集。

另外query字符串需要扩展order by语句以便数据按照正确的方式进行排序。sort包含一个bean property和 sortorder值(正序还是逆序)。service仅仅需要使用sort来调用dao。

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字符串最后需要的修改就是增加数据库特别的指令来limit将要被返回的结果集。这就是limitquery() 方法的作用。

1.4. dao

dao为service负责底层数据工作。

1.4.1. 定义query字符串

为了真正理解dao,query字符串需要被展示。

这就是得到数据的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 ";

这是得到总行数的query字符串:

private final static string totalpresidentsquery = 
" select count(*) from presidents ";

1.4.2. filter 和 sort query 字符串

两个最有趣的方法就是过滤和排序。

filter看起来像这样:

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字符串。

sort看起来非常类似:

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字符串。

1.4.3. limit query string

现在query字符串修改能够正确的进行filter和sort,它还需要修改以便只取页面显示相关的数据。mysql为s the limit命令。

public string limitquery(int rowend, string query) {
return query " limit " rowend;
}

1.4.4. 取回总行数和collection.

service需要的唯一东西就是:总行数和collection。

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特殊类,作为一个callback来处理jdbc resultset。jdbctemplate是对jdbc连接的抽象。

1.4.5. 默认的sort顺序

最后,这是service需要的默认sort顺序:

public string getdefaultsortorder() {
return " order by concat(first_name, ' ', last_name) ";
}

preferences 指南


1. 引言

为了设置全局属性和设置,你需要使用preferences特性,它现在使用一个属性文件来实现。本文档将很好地介绍如何在web.xml里设置preferences, 以及一些需要被定义的通用属性。在这里我非常乐意介绍一些关于preferences的进一步用法。

所有标签属性表示一个可插接的接口,它可以通过给出实现的全路径来设置。这为插接实现提供了一条便利的途径。当然这存在一些为过长术语的设计和维护的考虑。 第一,对你的接口实现进行硬编码;第二,如果你需要在别的jsp中用到同一个接口实现,你需要拷贝你全路径。解决这两个问题的有效办法就是在preferences中声明一切。

1.1. preferences表

下面列出的是可以在preferences中申明的所有接口。tag列展示的是extremetable的标签,attribute 列展示的是相关标签的对应属性。interface列展示的是需要被实现的java接口。preference key列展示的是 preferences里对应的健。

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

提示:当在写作本指南的时候,我意识到我忘记了让标签columnstag的autogeneratecolumns 属性和preferences协同工作。这将在下一版修正。

1.2. 指定preference别名

上表展示了如何声明preference键,但是没有解释如何指定有意义的别名。如果你注意到preference键提供了一致的语法 tag.attribute,指定键的别名仅仅是在它的基础上进行扩展。它的语法为: tag.attribute.alias

extremetable提供了一个名为rowcountcell定制的cell,它的作用是现实当前的行数。我将在preferences里使用columntag cell声明来示范rowcountcell的使用。

首先通过实现cell接口或者扩展abstractcell来编写具体的实现类。

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 (属性文件)进行声明并给出别名。extremetable在一个preferences里保存所有的配置信息,你可以通过使用本地 preferences的来覆盖任何的这些属性。

rowcountcell默认的别名是rowcount:

column.cell.rowcount=org.extremecomponents.table.cell.rowcountcell

在columntag中通过别名引用cell:

现在你可以通过rowcount来引用这个cell,如果包名改变了你只需要对preferences进行修改。

提示:本示例中我使用了columntag的别名属性。别名属性应用在有两列使用同样的property,也应用在列不直接和列的 bean property关联的情况下。本示例就属于这种情况。



芦苇 2007-09-30 09:49
]]>
使用dtree构建动态树型菜单 http://www.blogjava.net/i369/articles/149776.html芦苇芦苇sun, 30 sep 2007 01:48:00 gmthttp://www.blogjava.net/i369/articles/149776.htmlhttp://www.blogjava.net/i369/comments/149776.htmlhttp://www.blogjava.net/i369/articles/149776.html#feedback0http://www.blogjava.net/i369/comments/commentrss/149776.htmlhttp://www.blogjava.net/i369/services/trackbacks/149776.htmldtree是一个免费的javascript脚本,只需定义有限的几个参数,就可以做出漂亮的树型菜单。下载目录:
 以下是dtree的用法示例:
 1)初始化菜单
 
  
 
 2)调用函数
 
  
  
  
 
 
2。jsp动态实现
   分以下步骤实现动态的树型菜单:
   1)在数据库建tree_info表,有nodeid,parentnodeid,nodename,nodeurl四个字段,来存储节点信息。
   2)编写java类,用于从数据库找出节点信息,并且生成javascript脚本。
   3)编写tag类。用于封装逻辑,简化jsp的开发。
   4)建一个web程序进行测试。
3。详细过程
   1)在数据库建表,脚本如下:
   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数据库,如果脚本细节有出入,请自行修改
    按照上面的dtree示例插入数据
   2)编写treeinfo.java,这个类用于封装节点信息
     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 get {
    return url;
   }
   public void set {
    this.url = url;
   }
  }
   编写treeutil.java,用于从数据库得到节点信息,封装到treeinfo对象,并生成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(/uploads/image/ic/22057.html/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("");
    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)编写标签类
 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("\n");
   tree.append(treeutil.createtreeinfo(treeutil.retrievenodeinfos()));
   tree.append("\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("\n");
   sb.append("\n");
   sb.append("\n");
   sb.append("\n");
   sb.append("
\n");
   return sb;
  }   
 }
 标签的tld如下:
 
     public "-//sun microsystems, inc.//dtd jsp tag library 1.2//en"
   "">
 
  1.0
  1.2
  tree
  
  
   init
   com.diegoyun.web.taglibs.inittreetag
   empty
  

  
  
   show
   com.diegoyun.web.taglibs.showtreetag
   empty
  

 
 4)建立web过程,编写jsp进行测试。
 index.jsp如下:
 <%@ page language="java"%>
 <%@ taglib uri="/web-inf/tlds/tree.tld" prefix="tree"%>

 
 
  tree example
  
  
  
  
 
 

 tree example :
 
 
 
 
 


芦苇 2007-09-30 09:48
]]>
dtree右键菜单 http://www.blogjava.net/i369/articles/149778.html芦苇芦苇sun, 30 sep 2007 01:48:00 gmthttp://www.blogjava.net/i369/articles/149778.htmlhttp://www.blogjava.net/i369/comments/149778.htmlhttp://www.blogjava.net/i369/articles/149778.html#feedback0http://www.blogjava.net/i369/comments/commentrss/149778.htmlhttp://www.blogjava.net/i369/services/trackbacks/149778.html














超酷的xp风格的网页右键菜单特效代码


关闭右键菜单







芦苇 2007-09-30 09:48
]]>
jsp中使用el表达式不解析(无效)的问题 http://www.blogjava.net/i369/articles/135855.html芦苇芦苇fri, 10 aug 2007 08:03:00 gmthttp://www.blogjava.net/i369/articles/135855.htmlhttp://www.blogjava.net/i369/comments/135855.htmlhttp://www.blogjava.net/i369/articles/135855.html#feedback0http://www.blogjava.net/i369/comments/commentrss/135855.htmlhttp://www.blogjava.net/i369/services/trackbacks/135855.html原样把tomcat 的jsp例子拷过来还是如此。web.xml里和lib里的配置都配好了。找了很久才发现web.xml文件使用的是servlet 2.3版本的声明的问题。el在servlet 2.3中默认是不启用的。

servlet 2.3的

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

<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的声明部分改为2.4的即可。
还有就是如果使用了标签就需要加父标签。具体内容看jsp2.0和servlet2.4规范

 
 
    /tags/struts-bean.tld
    /web-inf/struts-bean.tld
 

 

 



trackback: http://tb.blog.csdn.net/trackback.aspx?postid=1667667



芦苇 2007-08-10 16:03
]]>
[2007-01-21 18时发布]ecside 1.0rc1: 列表组件extremecomponents全面增强版http://www.blogjava.net/i369/articles/135464.html芦苇芦苇thu, 09 aug 2007 05:20:00 gmthttp://www.blogjava.net/i369/articles/135464.htmlhttp://www.blogjava.net/i369/comments/135464.htmlhttp://www.blogjava.net/i369/articles/135464.html#feedback0http://www.blogjava.net/i369/comments/commentrss/135464.htmlhttp://www.blogjava.net/i369/services/trackbacks/135464.htmlecside介绍:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

ecside是一个开源的列表组件
他源自著名开源列表组件 extremecomponents (http://www.extremecomponents.org),
但现在已经脱离extremecomponents,独立发展(仍有大量代码来自 extremecomponents)。
做最实用易用的列表组件”是ecside最终的目标。

作者: fins ( name: wei zijun    email:fins@163.com   blog:http://fins.javaeye.com )

在使用前,请阅读一下以下信息,以帮助您了解您要使用的将是一个多么不成熟的东西(但它会有成熟的一天,而且那天不会远 呵呵):
1 ecside不能和原始版本的 extremecomponents 同时使用,且不保证能与原先使用 extremecomponents 的系统兼容,请见谅。
2 目前只支持gbk编码的应用,请见谅。
3 目前只在ie6 和firefox2 上进行过测试,不保证兼容其他(版本)浏览器,请见谅。
4 目前提供的样式风格巨丑无比,请见谅。
5 目前没有完备的文档和例子,请见谅。
6 代码没有注释,没有测试用例,请见谅。
7 没有很好的版本控制,没有构建脚本,请见谅。
8 拥有无数未知的bug,请见谅。


ecside发布地址:
http://fins.javaeye.com/blog/40190

ecside发布地址:
http://fins.javaeye.com/blog/40190
ecside圈子:
http://ecside.javaeye.com/
ecside综合讨论专用帖
 


其他出色的列表组件(有些是收费的):
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 可设置工具条位置(上 下 或 不显示)
2 可设置工具条内容(显示哪些 不显示哪些)
3 可设置工具条上各个功能按钮的相对位置
4 增加了调整页大小的选择框,并可自定义选择框内的内容
5 增加了带有邻近页面的导航条
6 增加了可跳转到指定页面的跳转框
7 增加了当前选中行高亮
8 为ec:table 增加了 excludeparameters 和 includeparameters 属性,可以实现更快捷简便的“参数保留/不保留”功能
9 可添加自定义的html代码到工具条内 或其他位置
10 可手动调整列宽
11 增加了“列表内部滚动条”(实现列表头固定,列表体滚动的功能)
12 为ec:row和ec:column 添加更多的html事件支持,现支持:onmouserover onmouserout onclick ondbclick
13 为ec:table ec:row ec:column增加了自定义扩展属性功能
14 增加 ec:extendrow 标签,实现列表扩展行的功能
15 增加shadowrow(影子行)功能:每行下面可以再加一个子行 这个行里显示什么可以由大家自己定义
16 增加页面变量 ${totalrowcount} 用来标示当前纪录在全部记录中的行数
17 增加了打印功能(尚不完善)
18 ec:column属性增加 ellipsis ,实现单元格内数据过长的时候 自动截短并加"..."的功能(ie only)
19 实现了跨列的列表头
20 统计栏的标题格可跨列
21 增加了若干种cell 和 headercell,例如checkbox radio
22 取消了imagepath属性,样式相关的图片信息全部提入css内
23 重(第4声)用了js 和css ,很多功能用js来实现
24 支持了ajax翻页
25 支持预查询功能,在察看第n页的时候,把n 1页的数据也查询出来(隐藏着)备用,加快查看下一页的速度
26 将导出excel所使用的组件由poi切换成了 jxl
27 xls导出方式修改 原始的导出是导出的vo/map里的原始数值 现在是导出页面实际显示的内容
28 增加简捷导出方式 (通过ec:table的 xlsfilename pdffilename csvfilename属性)
29 支持pdf中文导出
30 代码进行了大规模的重构
31 增加了很多ajax相关特性
32 实现了可编辑列表功能 以及cell的映射功能

... ...


更新日志:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
新增加的特性通常都在 demo.do.jsp这个例子里进行演示。

===============================
2007-01-21 15点
===============================
对于以下更新,demo.do.jsp进行了修改,大家看看例子可能会更好理解.

1) 实现了cell的映射功能(详见示例的性别 和 角色列),用法:
了一个简单的小标签 用来从map生成 select的option列表。

xml 代码
  1. <ec:column mappingitem="用来映射的map在context内的key" mappingdefaultvalue="当找不到映射值时要使用的默认值".../>  

例如,在示例中,角色的信息以 “标识--名称”的形式放到了一个 map内
在action中 把这个map放到了 request.setattribute("userrole_map", commondictionary.userrole);内
在页面使用

xml 代码
  1. <ec:column property="userrole" title="角色" mappingitem="userrole_map" mappingdefaultvalue="[错误的角色]"/>  


就会自动将名称显示出来。
2) 做

xml 代码
  1. <ec:options items="map在context内的key" defaultkey="默认选中的option的value" tagattributes="附加的html属性"/>  


3) 对ec:extend标签做了扩充,增加了位置设置属性 location
top: form内列表主体前  ; bottom : form内列表主体后 
toolbar或不设置location属性  在toolbar的扩展位置.
4) 代码进行了一点点修改,对使用没有影响。

===============================
2007-01-20 9点   ecside 1.0 rc1 发布啦
===============================
沉寂两天,但一直没有闲着,带来了大变化 索性来个 1.0 rc1 版 :) 。
1) 实现了灵活的可定制的“可编辑列表”功能 (详见help.txt 200行左右的描述 以及示例)
支持多种编辑方式(文本框 下拉框 将来还会支持更多),可自定义模版(使用自定义的文本框 下拉框),还提供了:
对可编辑列进行标识,对编辑过的cell进行标识(默认为改变单元格背景色),
使用ajax技术提交后台,提交成功的cell将清除编辑标识 等贴心设计。
2) 增加了 高亮显示选中行的功能,使用 ec:table属性: selectlightrow="true"
3) 去掉了 fullnavigation导航条,将其与navigation导航条合并
改为为ec:table增加属性 nearpagenum="数字" 用来设置导航条前后显示的邻近页数 等于0时 为不使用邻近页。
4) 为ec:table增加了 maxrowsexported="数字" 属性,用来限制导出大最大条数, 如果数据超过这个数目,则不执行导出操作。
5) 为之前增加的ec:table的pagesizelist属性 增加了特性
pagesizelist="max:200,10,15,30,50,100,all" 如果 10--100以及all中,某一项大过了max的200则 不在列表中显示。
也可以只使用pagesizelist="max:200" 此时将 使用默认设置,并进行max控制。
6) 解决了pdf中文编码问题,终于支持pdf导出了
7) 恢复了对sitemesh的支持,用法见原版ec文档(我没有亲自没有测试,因为我不会用sitemesh :( )。
8) ajax翻页优化,同时增加了 ecside.findajaxzoneatclien 属性,可设置 客户端 还是 服务端进行 html代码剪裁
默认推荐使用 服务器端。
9) 再次对js和java代码进行了较大规模的重构,清理了一些无用代码,添加了必要的协议信息。
10) 一些细节的修改(例如对滚轮的支持更自然,filterable="true"手动调节列宽功能屏蔽等)
还有对一些小bug的修正,但是由于变化较大,肯定还会带来一些新bug。
11) 整个示例的应用逐步发展为 ecside 的最佳实践,加入了hsqldb(hsqldb的使用参考了springside),全新的例子。
当然还不够好 会在以后的日子里继续完善。
12) 做了一个简单的logo :)。

顺便问一下:
我使用了 springside 的 hsqllistener (做了些修改 但绝对不涉及到核心),为什么在每次重启应用的时候总是包下面的异常呢??
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点
===============================
1) 当使用“列表内部滚动条”时,可以使用百分比来设置列表的宽度了。
(但还是建议您使用像素(px)作为列表和列的宽度单位,因为百分还有一些小bug)
还有个建议 不管是使用什么样的宽度,建议都要使用一个“自动宽度”的column,
就是说不要给所有的ec:column都指定width,给其中一个点“自由”,这样很多已知的关于列宽调整的问题都可以解决。
2) 对eccn.js进行了大量的修改,提供了更好(但不完美)的ie和ff兼容(一致)性(这个工作差点把我累吐血).
ff和ie 在取得对象坐标和宽度的算法不同 太郁闷了
3) 修正了一些bug


===============================
2007-01-12 以及之前的一些更新日志

===============================
1) 为“列表内部滚动条”增加了对鼠标滚轮的支持(只在ie6和ff2下测试过,其他版本没有测试)
2) 将部分“列表内部滚动条”相关的代码从java中提出,改用js实现.
3) 对js文件做了一些调整。
4) 修正了一些小bug。

===============================
1) 修正了一个“列表内部滚动条”的bug
该bug表现为在 ie里 有些windows的主题下,纵向滚动条不可用。ft!!!!!
2) eccn.js做了一点小小的改动,为将来做过编码支持打下了一点点基础.

===============================
1) 修正了改变页面大小时“列表内部滚动条”错乱的bug
2) 重构了“列表内部滚动条”相关的js和java代码

===============================
1) 修正了使用ajax翻页时“列表内部滚动条”错乱的bug
2) 增加了当列表内容的实际宽度和高度小于设置的宽度和高度的时候,
   自动调整区域大小,同时自动隐藏滚动条(只隐藏横向的)的功能。

===============================
增加了“固定列表头,滚动列表体”(“列表内部滚动条”)的功能
这个功能实现起来比我一开始想像的复杂
不是简单的使用一个 div overflow:scroll就可以搞定的
虽然功能是支持了 但是代码肯定还有很多bug或者是可以改进的地方
欢迎大家积极的提出宝贵的意见 谢谢了

使用方法:
ec:table标签内 增加
listheight="数字" 属性 (指定列表体的高度)
同时把要指定 width="数字" 不能省略 同时要使用绝对大小 而不要使用百分比

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

部分增强功能简介:
(详见help.txt)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

我们有自己的圈子了
以后大家有 ecside相关的问题 可以去圈子里
我的 blog里问( http://fins.javaeye.com/blog/48723 ) 
别在发消息了 因为发消息别人看不到 而有些问题可能别人也遇到过 或者是我回答的不对 别人也可以帮忙
对吧?
谢谢大家

ecside发布地址:
http://fins.javaeye.com/blog/40190
ecside圈子:
http://ecside.javaeye.com/
ecside综合讨论专用帖
http://fins.javaeye.com/blog/48723
 

 

我申请了javascud项目 而且也申请了svn 但是不会用啊  :'( 谁来教教我啊

 

 依赖包已经上传到 圈子的共享空间里了

共3个 请解压缩后放到 web-inf/lib下 如果不导出pdf可以不下载pdf相关的包 和 字体文件 这两个比较大  

ecside_1.0_rc1_20070121b.zip
 描述:  完整版,但不包括所依赖的web-inf/lib下的文件.依赖文件可以去圈子里下载, 也可以去javaeye ftp下载,也可以按照web-inf/lib下的filelist.txt文件所列,自行下载.
 文件名:  ecside_1.0_rc1_20070121b.zip
 文件大小:  697 kb
 下载过的:  文件被下载或查看 774 次


芦苇 2007-08-09 13:20
]]>
收集的非常不错的js脚本http://www.blogjava.net/i369/articles/134639.html芦苇芦苇mon, 06 aug 2007 02:55:00 gmthttp://www.blogjava.net/i369/articles/134639.htmlhttp://www.blogjava.net/i369/comments/134639.htmlhttp://www.blogjava.net/i369/articles/134639.html#feedback0http://www.blogjava.net/i369/comments/commentrss/134639.htmlhttp://www.blogjava.net/i369/services/trackbacks/134639.html1 >屏蔽功能类

1.1 屏蔽键盘所有键


1.2 屏蔽鼠标右键

在body标签里加上oncontextmenu=self.event.returnvalue=false

或者



function nocontextmenu()

    if(document.all) {
        event.cancelbubble=true;
        event.returnvalue=false; 
        return false; 
    }
}

或者




1.3 屏蔽 ctrl n、shift f10、f5刷新、退格键



1.4屏蔽浏览器右上角"最小化""最大化""关闭"键


function window.onbeforeunload()
{
  if(event.clientx>document.body.clientwidth&&event.clienty<0||event.altkey)
  {
    window.event.returnvalue = "";
  }
}

或者使用全屏打开页面



注:在body标签里加上onbeforeunload="javascript:return false"(使不能关闭窗口)

1.5屏蔽f5键



1.6屏蔽ie后退按钮

在你链接的时候用 

1.7屏蔽主窗口滚动条

在body标签里加上 style="overflow-y:hidden"

1.8 屏蔽拷屏,不断地清空剪贴板

在body标签里加上onload="setinterval('clipboarddata.setdata(\'text\',\'\')',100)"

1.9 屏蔽网站的打印功能

1.10 屏蔽ie6.0 图片上自动出现的保存图标

方法一:

方法二:

1.11 屏蔽页中所有的script

2 >表单提交验证类

 

2.1 表单项不能为空



2.2 比较两个表单项的值是否相同



2.3 表单项只能为数字和"_",用于电话/银行帐号验证上,可扩展到域名注册等




2.4 表单项输入数值/长度限定



2.5 中文/英文/数字/邮件地址合法性判断



2.6 限定表单项不能输入的字符





2.7 屏蔽右键、刷新、退格等功能



2.8 今天做系统时,用来判断radiobox选择的问题.(1.29)

2.9 全屏打开窗口、最大化窗口...
//全屏
function fullscrn(url)
{
 if(confirm("?"))
 {
  var win = window.open (url,"","fullscreen=yes,toolbar=no,scrollbars=yes");
  win.focus();  
 }
 return win;
}

//最大化


//鼠标移动
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



芦苇 2007-08-06 10:55
]]>
js实现map对象 http://www.blogjava.net/i369/articles/134638.html芦苇芦苇mon, 06 aug 2007 02:54:00 gmthttp://www.blogjava.net/i369/articles/134638.htmlhttp://www.blogjava.net/i369/comments/134638.htmlhttp://www.blogjava.net/i369/articles/134638.html#feedback0http://www.blogjava.net/i369/comments/commentrss/134638.htmlhttp://www.blogjava.net/i369/services/trackbacks/134638.html

 


trackback: http://tb.blog.csdn.net/trackback.aspx?postid=1550098



芦苇 2007-08-06 10:54
]]>
javascript 的 base64 算法http://www.blogjava.net/i369/articles/131446.html芦苇芦苇fri, 20 jul 2007 05:00:00 gmthttp://www.blogjava.net/i369/articles/131446.htmlhttp://www.blogjava.net/i369/comments/131446.htmlhttp://www.blogjava.net/i369/articles/131446.html#feedback0http://www.blogjava.net/i369/comments/commentrss/131446.htmlhttp://www.blogjava.net/i369/services/trackbacks/131446.html/**
* 我在网上看到过很多base64的javascript算法,都觉得不满意,于是自己写了一个,在这里分享一下。
* 我的代码在质量的效率都较高,没有一些冗余的操作。总体来讲我觉得非常不错。
* 如果大家有什么不懂的地方可以问我。
*/
var base64={
    
/**
     * 此变量为编码的key,每个字符的下标相对应于它所代表的编码。
     
*/
    enkey: 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789
/',
    
/**
     * 此变量为解码的key,是一个数组,base64的字符的ascii值做下标,所对应的就是该字符所代表的编码值。
     
*/
    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){
        
//用一个数组来存放编码后的字符,效率比用字符串相加高很多。
        var str=new array();
        
var ch1, ch2, ch3;
        
var pos=0;
       
//每三个字符进行编码。
        while(pos3<=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));
        }
        
//给剩下的字符进行编码。
        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), '==');
            }
        }
       
//组合各编码后的字符,连成一个字符串。
        return str.join('');
    },
    
/**
     * 解码。
     
*/
    decode: 
function(src){
        
//用一个数组来存放解码后的字符。
        var str=new array();
        
var ch1, ch2, ch3, ch4;
        
var pos=0;
       
//过滤非法字符,并去掉'='。
        src=src.replace(/[^a-za-z0-9\\/]/g, '');
        
//decode the source string in partition of per four characters.
        while(pos4<=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));
        }
        
//给剩下的字符进行解码。
        if(pos1<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)));
            }
        }
       
//组合各解码后的字符,连成一个字符串。
        return str.join('');
    }
};

使用方法:

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


芦苇 2007-07-20 13:00
]]>
使用fileupload组件实现文件上传 http://www.blogjava.net/i369/articles/125608.html芦苇芦苇thu, 21 jun 2007 08:44:00 gmthttp://www.blogjava.net/i369/articles/125608.htmlhttp://www.blogjava.net/i369/comments/125608.htmlhttp://www.blogjava.net/i369/articles/125608.html#feedback0http://www.blogjava.net/i369/comments/commentrss/125608.htmlhttp://www.blogjava.net/i369/services/trackbacks/125608.html文件上传在web应用中非常普遍,要在servlet/jsp环境中实现文件上传功能非常容易,因为网上已经有许多用java开发的组件用于文件上传,本文以commons-fileupload组件为例,为servlet/jsp应用添加文件上传功能。

common-fileupload组件是apache的一个开源项目之一,可以从下载。该组件简单易用,可实现一次上传一个或多个文件,并可限制文件大小。

下载后解压zip包,将commons-fileupload-1.0.jar复制到tomcat的webapps\你的webapp\web-inf\lib\下,如果目录不存在请自建目录。

新建一个servlet: upload.java用于文件上传:

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\\"; // 用于存放上传文件的目录
    private string temppath = "c:\\upload\\tmp\\"; // 用于存放临时文件的目录

    public void dopost(httpservletrequest request, httpservletresponse response)
        throws ioexception, servletexception
    {
    }
}

当servlet收到浏览器发出的post请求后,在dopost()方法中实现文件上传。以下是示例代码:

public void dopost(httpservletrequest request, httpservletresponse response)
    throws ioexception, servletexception
{
    try {
        diskfileupload fu = new diskfileupload();
        // 设置最大文件尺寸,这里是4mb
        fu.setsizemax(4194304);
        // 设置缓冲区大小,这里是4kb
        fu.setsizethreshold(4096);
        // 设置临时目录:
        fu.setrepositorypath(temppath);

        // 得到所有的文件:
        list fileitems = fu.parserequest(request);
        iterator i = fileitems.iterator();
        // 依次处理每一个文件:
        while(i.hasnext()) {
            fileitem fi = (fileitem)i.next();
            // 获得文件名,这个文件名包括路径:
            string filename = fi.getname();
            if(filename!=null) {

                // 在这里可以记录用户和文件信息
                // ...
                // 写入文件a.txt,你也可以从filename中提取文件名:
                fi.write(new file(uploadpath "a.txt"));
            }
        }
        // 跳转到上传成功提示页面
    }
    catch(exception e) {
        // 可以跳转出错页面
    }
}

如果要在配置文件中读取指定的上传文件夹,可以在init()方法中执行:

public void init() throws servletexception {
    uploadpath = ....
    temppath = ....
    // 文件夹不存在就自动创建:
    if(!new file(uploadpath).isdirectory())
        new file(uploadpath).mkdirs();
    if(!new file(temppath).isdirectory())
        new file(temppath).mkdirs();
}

编译该servlet,注意要指定classpath,确保包含commons-upload-1.0.jar和tomcat\common\lib\servlet-api.jar。

配置servlet,用记事本打开tomcat\webapps\你的webapp\web-inf\web.xml,没有的话新建一个。典型配置如下:


    public "-//sun microsystems, inc.//dtd web application 2.3//en"
    "">


   
        upload
        upload
   

   
        upload
        /fileupload
   


配置好servlet后,启动tomcat,写一个简单的html测试:

enctype="multipart/form-data" name="form1">
 
 

注意action="fileupload"其中fileupload是配置servlet时指定的url-pattern。



trackback: http://tb.blog.csdn.net/trackback.aspx?postid=15991



芦苇 2007-06-21 16:44
]]>
javascript弹出窗口总结 http://www.blogjava.net/i369/articles/120198.html芦苇芦苇sat, 26 may 2007 10:10:00 gmthttp://www.blogjava.net/i369/articles/120198.htmlhttp://www.blogjava.net/i369/comments/120198.htmlhttp://www.blogjava.net/i369/articles/120198.html#feedback0http://www.blogjava.net/i369/comments/commentrss/120198.htmlhttp://www.blogjava.net/i369/services/trackbacks/120198.html//关闭,父窗口弹出对话框,子窗口直接关闭
this.response.write("window.close();");

//关闭,父窗口和子窗口都不弹出对话框,直接关闭
this.response.write("");

//弹出窗口刷新当前页面width=200 height=200菜单。菜单栏,工具条,地址栏,状态栏全没有
this.response.write("window.open('rows.aspx','newwindow','width=200,height=200')");

//弹出窗口刷新当前页面
this.response.write("window.open('rows.aspx')");
this.response.write("");

//弹出提示窗口跳到webform2.aspx页(在一个ie窗口中)
this.response.write(" alert('注册成功');window.window.location.href='webform2.aspx'; ");

//关闭当前子窗口,刷新父窗口
this.response.write("");
this.response.write("");

//子窗口刷新父窗口
this.response.write("");
this.response.write("");

//弹出提示窗口.确定后弹出子窗口(webform2.aspx)
this.response.write("alert('发表成功!');window.open('webform2.aspx')");

//弹出提示窗口,确定后,刷新父窗口
this.response.write("");

//弹出相同的一页


//
response.write("parent.mainframebottom.location.href='yourwebform.aspx?temp="  str "';");


 
 
  
  
  参数解释: 
  
   js脚本开始; 
  window.open 弹出新窗口的命令; 
  'page.html' 弹出窗口的文件名; 
  'newwindow' 弹出窗口的名字(不是文件名),非必须,可用空''代替; 
  height=100 窗口高度; 
  width=400 窗口宽度; 
  top=0 窗口距离屏幕上方的象素值; 
  left=0 窗口距离屏幕左侧的象素值; 
  toolbar=no 是否显示工具栏,yes为显示; 
  menubar,scrollbars 表示菜单栏和滚动栏。 
  resizable=no 是否允许改变窗口大小,yes为允许; 
  location=no 是否显示地址栏,yes为允许; 
  status=no 是否显示状态栏内的信息(通常是文件已经打开),yes为允许; 
   js脚本结束

'newwin':隐藏菜单栏地址栏工具条
width=50:宽度
height=50:高度
scrollbars=yes/n滚动条
top=50:窗口距离屏幕上方
left=50:窗口距离屏幕左侧
例:window.open('detail.aspx?id=" e.item.cells[1].text "','newwin','width=750,height=600,scrollbars=yes,top=50,left=50');"); 
this.response.write("");

例:
this.response.write("");
this.response.write("");

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


芦苇 2007-05-26 18:10
]]>
网站地图