<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300" creationComplete="init()">
<s:layout>
<s:BasicLayout/>
</s:layout>
<fx:Declarations>
<s:HTTPService id="httpService" result="success()" fault="failure()" resultFormat="text" method="POST" useProxy="false" showBusyCursor="true"/>
<s:HTTPService id="recordsService" result="recordsResult()" fault="failure()" resultFormat="text" method="POST" useProxy="false" showBusyCursor="true"/>
</fx:Declarations>
<fx:Script>
<![CDATA[
import com.adobe.serialization.json.JSONDecoder;
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.events.ListEvent;
import mx.managers.CursorManager;
import mx.managers.FocusManager;
import spark.events.IndexChangeEvent;
import spark.events.TextOperationEvent;
//计时器
private var timer:Timer;
[Bindable]
private var datas:ArrayCollection = new ArrayCollection();
private var label:String;
private var same:Boolean = false;
//可以直接传sql给此组件
private var _sql:String = "";
//页号
[Bindable]
private var start:int = 1;
//第页记录数
private var limit:int = 10;
//总页数
[Bindable]
private var totalPage:int = 0;
//总记录数
[Bindable]
private var records:int = 0;
//初始化方法
private function init():void {
//textinput的宽度,在这里设置一次,list和最下方的按钮栏则会同时改变
input.width = 150;
list.width = input.width;
list.x = input.x ;
list.height = 150;
list.depth = 100;
bbar.width = input.width;
bbar.visible = false;
list.visible = false;
//设置计算器为1秒后发送请求,只发一次
timer = new Timer(1000,1);
input.addEventListener(FocusEvent.FOCUS_IN,focusIn);
input.addEventListener(TextOperationEvent.CHANGE,onChange);
timer.addEventListener(TimerEvent.TIMER_COMPLETE,timerFinished);
list.addEventListener(IndexChangeEvent.CHANGE,clickItem);
addEventListener(MouseEvent.CLICK,outClick);
list.addEventListener(MouseEvent.CLICK,clickList);
list.addEventListener(FocusEvent.FOCUS_OUT,focusOut);
input.addEventListener(KeyboardEvent.KEY_UP,up);
//以下是设置按钮的宽和高属性
firstBtn.label = "|<";
firstBtn.setStyle("fontSize",9);
firstBtn.parent.width = firstBtn.parent.parent.width ;
firstBtn.width = ( firstBtn.parent.width / 4 ) ;
firstBtn.height= 20;
preBtn.label = "<";
preBtn.parent.width = preBtn.parent.parent.width ;
preBtn.width = (preBtn.parent.width / 4) ;
preBtn.height= 20;
nextBtn.label = ">";
nextBtn.parent.width = nextBtn.parent.parent.width ;
nextBtn.width = (nextBtn.parent.width / 4) ;
nextBtn.height= 20;
lastBtn.label = ">|";
lastBtn.setStyle("fontSize",9);
lastBtn.parent.width = lastBtn.parent.parent.width ;
lastBtn.width = ( lastBtn.parent.width / 4 ) ;
lastBtn.height= 20;
firstBtn.addEventListener(MouseEvent.CLICK,firstPage);
preBtn.addEventListener(MouseEvent.CLICK,prePage);
nextBtn.addEventListener(MouseEvent.CLICK,nextPage);
lastBtn.addEventListener(MouseEvent.CLICK,lastPage);
//sql的初始化,这里我在组件里写死了,加上get和set方法后应该可以外部传入,自己没有试。
sql = " select a0100,a0101 from person where 1 = 1 " ;
//获取总记录数的请求,根据业务要求可重新设置
recordsService.url = "http://localhost:8080/Test/getDatas.htm";
//获取list中数据的请求,根据业务要求可重新设置
httpService.url = "http://localhost:8080/Test/getDatas.htm";
}
//第一页
private function firstPage(e:MouseEvent):void {
start = 1;
httpService.send({"sql":this.getSQL(sql,start,limit)});
}
//上一页
private function prePage(e:MouseEvent):void {
if(start <= 1){
start = 1;
} else {
start --;
}
httpService.send({"sql":this.getSQL(sql,start,limit)});
}
//下一页
private function nextPage(e:MouseEvent):void {
if(start >= totalPage){
start = totalPage;
} else {
start ++;
}
httpService.send({"sql":this.getSQL(sql,start,limit)});
}
//最后一页
private function lastPage(e:MouseEvent):void {
start = totalPage;
httpService.send({"sql":this.getSQL(sql,start,limit)});
}
//键盘操作的处理
private function up(e:KeyboardEvent):void {
if(datas.length <= 0){
return;
}
if(!list.visible){
this.list.visible = true;
this.bbar.visible = true;
}
//向右
if(e.keyCode == Keyboard.RIGHT){
if(list.visible == false){
list.visible = true;
bbar.visible = true;
return;
}
this.input.selectRange(this.input.text.length,this.input.text.length);
if(start >= totalPage){
start = totalPage;
} else {
start ++;
}
httpService.send({"sql":this.getSQL(sql,start,limit)});
}else if(e.keyCode == Keyboard.LEFT){ //向左
if(!list.visible){
list.visible = true;
bbar.visible = true;
return;
}
//设置textinput中的鼠标始终在最左侧
this.input.selectRange(this.input.text.length,this.input.text.length);
if(start <= 1){
start = 1;
} else {
start --;
}
httpService.send({"sql":this.getSQL(sql,start,limit)});
}else if(e.keyCode == Keyboard.DOWN){//向下
this.cursorManager.hideCursor();
if(this.list.selectedIndex == datas.length - 1){
this.list.selectedIndex = 0;
this.list.ensureIndexIsVisible(this.list.selectedIndex);
} else {
this.list.selectedIndex ++;
this.list.ensureIndexIsVisible(this.list.selectedIndex);
}
this.list.visible = true;
this.bbar.visible = true;
if(same){
this.input.text = this.list.selectedItem.A0101;
}
this.input.selectRange(this.input.text.length,this.input.text.length);
} else if(e.keyCode == Keyboard.UP){//向上
this.cursorManager.hideCursor();
if(this.list.selectedIndex <= 0){
this.list.selectedIndex = datas.length - 1;
this.list.ensureIndexIsVisible(this.list.selectedIndex);
} else {
this.list.selectedIndex --;
//设置list的滚动条跟随滑动
this.list.ensureIndexIsVisible(this.list.selectedIndex);
}
this.list.visible = true;
this.bbar.visible = true;
if(same){
this.input.text = this.list.selectedItem.A0101;
}
this.input.selectRange(this.input.text.length,this.input.text.length);
} else if(e.keyCode == Keyboard.ENTER){//回车键
list.visible = false;
bbar.visible = false;
if(list.selectedItem != null){
//注意:此处的A0101为查询的字段
this.input.text = this.list.selectedItem.A0101;
this.input.selectRange(this.input.text.length,this.input.text.length);
}
}
}
private function clickItem(e:IndexChangeEvent):void {
this.focusManager.setFocus(this.input);
var item:Object = this.list.selectedItem;
//注意:此处的A0101为查询的字段
this.input.text = item.A0101;
this.list.visible = false;
this.bbar.visible = false;
}
private function outClick(e:MouseEvent):void {
var mex:Number = e.stageX;
var mey:Number = e.stageY;
if((mex > this.input.x && mex < (this.input.x + this.input.width)) && (mey > (this.list.y + this.input.height) && mey < (this.list.height + this.list.y))){
if(!(this.list.visible)){
return;
}
}
}
//计时器发送请求的操作
private function timerFinished(e:TimerEvent):void {
start = 1;
var tempsql:String = "";
if(input.text != ""){
tempsql = " and (a0101 like '" + input.text + "%' or a0100 like '" + input.text + "%') " ;
}
var csql:String = " select count(1) records from ( " + sql + tempsql + " ) ";
recordsService.send({"sql":csql});
}
//textinput改变时的操作
private function onChange(e:TextOperationEvent):void {
list.visible = true;
bbar.visible = true;
if(timer.running){
timer.reset();
timer.start();
} else {
timer.start();
}
}
//list点击时的操作
private function clickList(e:MouseEvent):void {
this.list.visible = true;
this.focusManager.setFocus(this.list);
}
//请求list中的数据完成时的回调
private function success():void {
var rs:String = httpService.lastResult.toString();
var json:JSONDecoder = new JSONDecoder(rs,true);
var list:Array = json.getValue();
datas = new ArrayCollection(list);
this.input.selectRange(this.input.text.length,this.input.text.length);
}
//请求总页数完成时的回调
private function recordsResult():void {
this.input.selectRange(this.input.text.length,this.input.text.length);
var rs:String = recordsService.lastResult.toString();
var json:JSONDecoder = new JSONDecoder(rs,true);
var list:Array = json.getValue();
records = list[0].RECORDS;
totalPage = Math.floor((records - 1) / limit) + 1;
httpService.send({"sql":this.getSQL(sql,start,limit)});
}
private function failure():void {
}
private function focusIn(e:FocusEvent):void {
if(!(this.list.visible)){
this.list.visible = true;
this.bbar.visible = true;
}
}
private function focusOut(e:FocusEvent):void {
this.list.visible = false;
this.bbar.visible = false;
}
//发送请求前,对sql的业务处理
private function getSQL(sql:String,start:int,limit:int):String {
var tempsql:String = "";
if(input.text != ""){
tempsql = " and (a0101 like '" + input.text + "%' or a0100 like '" + input.text + "%') " ;
}
var fsql:String = "";
fsql = "SELECT * FROM ";
fsql += "( ";
fsql += " SELECT A.*, ROWNUM RN FROM ";
fsql += " ( ";
fsql += sql + tempsql;
fsql += " ) A ";
fsql += " WHERE ROWNUM <= " + start * limit;
fsql += ") ";
fsql += "WHERE RN > " + ((start - 1) * limit);
return fsql;
}
public function get sql():String
{
return _sql;
}
public function set sql(value:String):void
{
_sql = value;
}
]]>
</fx:Script>
<s:VGroup gap="0">
<s:TextInput id="input"/>
<s:List id="list" dataProvider="{datas}" labelField="A0101"></s:List>
<s:BorderContainer id="bbar" height="22">
<s:HGroup gap="0" width="{this.parent.width}">
<mx:LinkButton id="firstBtn"/>
<mx:LinkButton id="preBtn"/>
<mx:LinkButton id="nextBtn"/>
<mx:LinkButton id="lastBtn"/>
<mx:Text id="pagerBtn" text="{ start + '/' + totalPage}"/>
</s:HGroup>
</s:BorderContainer>
</s:VGroup>
</s:Group>
后台的代码用spring mvc实现,具体代码如下:
@RequestMapping("/getDatas.htm")
public String getDatas(String sql,HttpServletResponse response){
System.out.println(sql);
List<Map<String,Object>> list = baseDao.queryForList(sql);
JSONArray json = new JSONArray();
json.addAll(list);
response.setCharacterEncoding("utf-8");
try {
response.getWriter().println(json.toString());
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
还有小bug,但基本没有太大的问题。希望感兴趣的朋友指正。
先做个总结,待以后参考。