jquery的智能提示控件

福利到~分享一个基于jquery的智能提示控件intellSeach.js

一、需求

  我们经常会遇到【站内搜索】的需求,为了提高用户体验,我们希望能做到像百度那样的即时智能提示。例如:某公司人事管理系统,想搜索李XX,只要输入“李”,系统自然会提示一些姓李的员工,这样方便用户使用。说白了,就是用户边输入,系统会提示相关的结果;或者,当用户点击搜索框时,就推荐一些内容,如360、百度都会提示今天的主要新闻或搜索量大的内容。

  jquery 已经有一个这样的插件了,叫 autocomplete, 但我觉得不好用。关于autocomplete的介绍也很多,有兴趣的朋友可以去试试。

  看标题就知道,这里只是分享一个插件,不会讨论后台搜索的相关算法和过程,也就是说,后台返回特定格式的数据,控件负责渲染结果呈现。ok,先看一下效果图:

  效果一:

  

  效果图二:

  

  样式与控件无关,只需要一个 input text 就可以了。

二、参数说明

  控件以json格式作为传输格式。参数比较多,大部分都有默认值(具体看源码),有些可能不常用,保持默认即可。如下:

  url: 请求地址。如:Handler.ashx, 后台获取数据的地址

property: 要显示的json对象的属性。如果我们直接返回["tom","tom cat","tom2"] 这样的形式,那么该属性可以不用设置;但有时候我们会返回[{"Name":"tom","ID":"001"},{"Name":"tom cat","ID":"002"},{"Name":"tom2","ID":"003"}] 这样的形式,显示的是Name,那么设置该属性为"Name"即可。至于我们想在点击的时候获得点击的项的ID,通过点击事件即可。

itemNumber: 显示的项数目。

isEmptyRequest: focus时,空白是否发起请求。就像前面说的,如果点击搜索框时(此时没有内容),想要推荐一些内容,设置该属性为true,即会发起请求。

defaultValue: 默认值。通常会是:“请输入关键词...” 这类的提示。

width: 下拉列表宽度。

  aligner: 要对齐的元素。

maxHeight: 最大高度。如果设置该高度,超过时就会出现滚动条。

ajax:{
        timeout: 超时时间
            cache: 是否缓存
      },

  event:{          
           setData: 发送请求前触发。用于设置参数
           itemClick: 点击项触发
           enterKeydown: 按下enter键触发
           beforeRender: 所有项呈现前触发
           endRender: 所有项呈现后触发
           itemBeforeRender: 项呈现前触发
           itemAfterRender: 项呈现后触发            
           beforeSend: 发送请求前触发。用户设置请求头部参数等,相当于jquery ajax 的 beforeSend。
     }

  event 里的方法都会在适当的时候触发,需要注意的是,所有方法都接收一个参数,该参数是一个对象,有4个属性,某些情况如果没有该属性的,则为空。包括如下属性:

   jthis: input 的 jQuery 对象。

   jItem: 项的 jQuery 对象。

data: 返回的 json 字符串。如果在前台需要对返回 json 再进行处理,那么可以通过 data 属性获得,处理完成后,需要将 json 字符串 return。

  event: 事件对象,如按下 enter 时的事件对象。

三、例子

  使用例子:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

$("#search").intellSearch({

    url:"Handler.ashx",

    property:"Name",

    itemNumber:5,

    isEmptyRequest:false,

    defaultValue:"请输入关键字...",       

    width:$("#search").width() + 2,

    maxHeight:-1,

    event:{

        itemClick:function(obj){

            alert(obj.item.ID);

        },

        enterKeydown:function(obj){

            if(obj.item){

                alert("有当前项");

            }else{

                alert("没有当前项");

            }

        }

    }   

});

四、总结  

  如果你还有自己的逻辑需要处理,也支持链式调用,大可以这样写 $("#search").intellSearch({参数...}).focus(function(){你的处理...});

  分享该插件希望能帮助到有需要的朋友,主要用于学习。由于是v1.0,可能还有一些bug,有发现的朋友也可以告诉我,我会及时修正。  

附源代码

js代码


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

/*搜索智能提示 v1.0

  date:2015.09.08 

*/

;(function(w,$){

    $.fn.intellSearch = function(options){

        var jthis = this;

        var _dftOpts = {

            url:"",//请求地址或数组                    

            property:"",//要显示的json对象的属性

            itemNumber:5,//显示的条数

            isEmptyRequest:false,//focus空白是否发起请求

            defaultValue:"",//默认值

            width:0,//列表宽度

            aligner:jthis,//要对齐的元素

            maxHeight:-1,//最大高度                    

            ajax:{

                timeout:3000,//超时时间

                cache:true//是否缓存

            },

            event:{

                /*参数说明:parameter:{jthis:"jq input",jItem:"jq item",data:"json result",event:"event"}*/

                setData:null,//设置参数

                itemClick:null,//点击项触发

                enterKeydown:null,//按下enter键触发

                beforeRender:null,//所有项呈现前触发

                endRender:null,//所有项呈现后触发

                itemBeforeRender:null,//项呈现前触发

                itemAfterRender:null,//项呈现后触发

                beforeSend:null//发送请求前触发

            }

        };

        $.extend(_dftOpts,options);

        if(!_dftOpts.url){

            throw Error("url不能为空!");

        }

        var jResult;               

        var _value = "";       

        var _ajax = _dftOpts.ajax;

        var _event = _dftOpts.event;

        var _cache = [];

        var _focusCount = 0;//防止focus触发多次(sogou)

        

        /*on window*/

        window.intellObj = window.intellObj || {}; /*for global event*/

        window.intellDocumentClick = window.intellDocumentClick || function(e){

            if(!window.intellObj.jthis){

                return;

            }

            if(e.target !== window.intellObj.jthis[0]){

                setIntellObj(null);

            }

        }

        window.intellDocumentKeydown = window.intellDocumentKeydown || function(e){

            var jthis = window.intellObj.jthis;

            if(!jthis){

                return;

            }

            var code = e.keyCode;

            var value = window.intellObj.value;           

            var jResult,jCurItem,keyword;

            if(code === 13 || code === 38 || code === 40){

                jResult = window.intellObj.jResult;

                jItems = jResult.find("li");

                jCurItem = jResult.find("li.cur");

                if(code === 13){

                    if(jCurItem.length > 0){

                        jCurItem.click();

                    }else{

                        setIntellObj(null);                      

                        if(_event.enterKeydown){

                            _event.enterKeydown({"jthis":jthis,"event":e});

                        }

                    }

                    jthis.blur();

                }else if(jItems.length > 0){

                    if(code === 38){

                        if(jCurItem.length <= 0){

                            jCurItem = jItems.last();

                            jCurItem.addClass("cur");

                            keyword = jCurItem.text();

                        }else{

                            var index = jCurItem.index();

                            jCurItem.removeClass("cur");

                            if(index <= 0){

                                keyword = value;                           

                            }else{

                                jCurItem = jItems.eq(index-1);

                                jCurItem.addClass("cur");

                                keyword = jCurItem.text();

                            }

                        }

                        jthis.val(keyword);

                    }else{

                        if(jCurItem.length <= 0){

                            jCurItem = jItems.first();

                            jCurItem.addClass("cur");

                            keyword = jCurItem.text();

                        }else{

                            var index = jCurItem.index();

                            jCurItem.removeClass("cur");

                            if(index + 1 >= jItems.length){

                                keyword = value;

                            }else{

                                jCurItem = jItems.eq(index+1);

                                jCurItem.addClass("cur");

                                keyword = jCurItem.text();

                            }

                        }

                        jthis.val(keyword);

                    }

                }

            }

        }

        /*event handler*/

        $.fn.unintell = function(){

            remove();

        }

        $(document).unbind({click:window.intellDocumentClick,keydown:window.intellDocumentKeydown})

                   .bind({click:window.intellDocumentClick,keydown:window.intellDocumentKeydown});

        jthis.focus(function(){

            _focusCount++;

            if(_focusCount > 1){

                return;

            }

            if(window.intellObj.jthis && jthis !== window.intellObj.jthis){

                setIntellObj(null);

            }

            var keyword = attrValue();

            if(keyword === _dftOpts.defaultValue){

                keyword = "";

                attrValue(keyword);

            }

            if(keyword || _dftOpts.isEmptyRequest){

                sendRequest();

            }

        })

        jthis.blur(function(){           

            _focusCount = 0;

            if(!attrValue()){

                attrValue(_dftOpts.defaultValue);

            }           

        })

        jthis.keyup(function(e){

            if(e.keyCode === 38 || e.keyCode === 40){

                return;

            }

            var keyword = attrValue();

            if(!keyword){

                remove();

                window.intellObj.value = _value = "";

                return;

            }

            if(keyword !== _value){

                window.intellObj.value = _value = keyword;

                sendRequest();

            }

        });

        

        return initBox();

        

        /*function*/

        function initBox(){

            attrValue(_dftOpts.defaultValue);

            return jthis;

        }       

        function initIntell(){           

            generate();

            register();

            setIntellObj({jthis:jthis,jResult:jResult});

        }

        function generate(){

            var offset = _dftOpts.aligner.offset();

            var width = _dftOpts.width ? _dftOpts.width : _dftOpts.aligner.width();

            jResult = $("<ul>",{"class":"intellResult"});

            jResult.width(width).css({"position":"absolute","left":offset.left,"top":offset.top + jthis.outerHeight()});

            $("body").append(jResult);

            if(_dftOpts.maxHeight > 0){

                jResult.height(_dftOpts.maxHeight).css("overflowY","scroll");

            }

        }

        function remove(){

            if(jResult){

                jResult.remove();

                jResult = null;

            }

        }

        function register(){

            jResult.on("click","li",function(){

                var jItem = $(this);

                var index = jItem.index();

                var keyword = jItem.text();

                attrValue(keyword);               

                _value = keyword;               

                if(_event.itemClick){

                    _event.itemClick({"jthis":jthis,"jItem":jItem,"item":_cache[index]});

                }

            }).on("mouseenter","li",function(){

                $(this).siblings("li").removeClass("cur").end().addClass("cur");

            }).on("mouseleave","li",function(){

                $(this).removeClass("cur");

            });

        }

        function setIntellObj(obj){

            if(!obj){

                if(window.intellObj.jResult){

                    window.intellObj.jResult.remove();

                }

                window.intellObj.jthis = null;

                window.intellObj.jResult = null;

            }else{

                window.intellObj.jthis = obj.jthis;

                window.intellObj.jResult = obj.jResult;

            }

        }

        function sendRequest(){

            var data;

            if(_event.setData){               

                data = _event.setData({"jthis":jthis});

            }

            $.ajax({

                url:_dftOpts.url,

                data:data,

                cache:_ajax.cache,

                timeout:_ajax.timeout,

                beforeSend:function(xhr){

                    if(_event.beforeSend){

                        _event.beforeSend(xhr);

                    }

                },

                success:function(data){

                    remove();

                    showData(data);

                },

                error:null

            });

        }

        function showData(data){

            data = $.trim(data) ? $.parseJSON(data) : data;

            if(_event.beforeRender){

                var rs = _event.beforeRender({"jthis":jthis,"data":data});

                if(rs === false){

                    return;

                }

                if(rs !== undefined){

                    data = rs;

                }

            }

            if(!data){

                return;

            }

            var jItem,jA,jSpan,hasProp,item,text,otherTexts,isRender,index;

            var list = $.isArray(data) ? data : [data];

            var length = list.length;

            length = length > _dftOpts.itemNumber ? _dftOpts.itemNumber : list.length;

            if(length <= 0){

                return;

            }

            initIntell();

            _cache.length = 0;

            hasProp = list[0][_dftOpts.property];

            for(var i=0;i<length;i++){

                item = list[i];

                if(item === null || item === undefined){

                    continue;

                }

                text = hasProp ? item[_dftOpts.property] : item;

                text = $.trim(text.toString());

                if(text === ""){

                    continue;

                }

                jItem = $("<li>",{"class":"intellResult_item"});

                jA = $("<a>",{"title":text}).appendTo(jItem);

                jSpan = $("<span>").appendTo(jA);

                index = text.toLowerCase().indexOf(_value.toLowerCase());

                otherTexts = splitText(text,_value,index);

                if(otherTexts){

                    jSpan.text(text.substr(index,_value.length));

                    if(otherTexts.length > 1){

                        $("<b>",{"text":otherTexts[0]}).insertBefore(jSpan);

                        $("<b>",{"text":otherTexts[1]}).insertAfter(jSpan);

                    }else{

                        if(index === 0){

                            $("<b>",{"text":otherTexts[0]}).insertAfter(jSpan);

                        }else{

                            $("<b>",{"text":otherTexts[0]}).insertBefore(jSpan);

                        }

                    }

                }else{

                    jSpan.text(text);

                }

                isRender = true;

                if(_event.itemBeforeRender){

                    isRender = _event.itemBeforeRender({"jthis":jthis,"jItem":jItem,"item":item});

                }

                if(isRender !== false){

                    jResult.append(jItem);

                    if(_event.itemAfterRender){

                        _event.itemAfterRender({"jthis":jthis,"jItem":jItem,"item":item});

                    }

                }

                _cache.push(item);

            }

            if(_event.endRender){

                _event.endRender({"jthis":jthis});

            }

            jResult.show();

        }

        function attrValue(value){

            if(!value && value != ""){

                return $.trim(jthis.val());

            }

            jthis.val(value);

        }

        function splitText(text,value,index){

            var tlength = text.length;

            var vlength = value.length;

            if(index === -1){

                return null;

            }

            if(index === 0){

                if(index + vlength >= tlength){

                    return null;

       

福利到~分享一个基于jquery的智能提示控件intellSeach.js

一、需求

  我们经常会遇到【站内搜索】的需求,为了提高用户体验,我们希望能做到像百度那样的即时智能提示。例如:某公司人事管理系统,想搜索李XX,只要输入“李”,系统自然会提示一些姓李的员工,这样方便用户使用。说白了,就是用户边输入,系统会提示相关的结果;或者,当用户点击搜索框时,就推荐一些内容,如360、百度都会提示今天的主要新闻或搜索量大的内容。

  jquery 已经有一个这样的插件了,叫 autocomplete, 但我觉得不好用。关于autocomplete的介绍也很多,有兴趣的朋友可以去试试。

  看标题就知道,这里只是分享一个插件,不会讨论后台搜索的相关算法和过程,也就是说,后台返回特定格式的数据,控件负责渲染结果呈现。ok,先看一下效果图:

  效果一:

  

  效果图二:

  

  样式与控件无关,只需要一个 input text 就可以了。

二、参数说明

  控件以json格式作为传输格式。参数比较多,大部分都有默认值(具体看源码),有些可能不常用,保持默认即可。如下:

  url: 请求地址。如:Handler.ashx, 后台获取数据的地址

property: 要显示的json对象的属性。如果我们直接返回["tom","tom cat","tom2"] 这样的形式,那么该属性可以不用设置;但有时候我们会返回[{"Name":"tom","ID":"001"},{"Name":"tom cat","ID":"002"},{"Name":"tom2","ID":"003"}] 这样的形式,显示的是Name,那么设置该属性为"Name"即可。至于我们想在点击的时候获得点击的项的ID,通过点击事件即可。

itemNumber: 显示的项数目。

isEmptyRequest: focus时,空白是否发起请求。就像前面说的,如果点击搜索框时(此时没有内容),想要推荐一些内容,设置该属性为true,即会发起请求。

defaultValue: 默认值。通常会是:“请输入关键词...” 这类的提示。

width: 下拉列表宽度。

  aligner: 要对齐的元素。

maxHeight: 最大高度。如果设置该高度,超过时就会出现滚动条。

ajax:{
        timeout: 超时时间
            cache: 是否缓存
      },

  event:{          
           setData: 发送请求前触发。用于设置参数
           itemClick: 点击项触发
           enterKeydown: 按下enter键触发
           beforeRender: 所有项呈现前触发
           endRender: 所有项呈现后触发
           itemBeforeRender: 项呈现前触发
           itemAfterRender: 项呈现后触发            
           beforeSend: 发送请求前触发。用户设置请求头部参数等,相当于jquery ajax 的 beforeSend。
     }

  event 里的方法都会在适当的时候触发,需要注意的是,所有方法都接收一个参数,该参数是一个对象,有4个属性,某些情况如果没有该属性的,则为空。包括如下属性:

   jthis: input 的 jQuery 对象。

   jItem: 项的 jQuery 对象。

data: 返回的 json 字符串。如果在前台需要对返回 json 再进行处理,那么可以通过 data 属性获得,处理完成后,需要将 json 字符串 return。

  event: 事件对象,如按下 enter 时的事件对象。

三、例子

  使用例子:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

$("#search").intellSearch({

    url:"Handler.ashx",

    property:"Name",

    itemNumber:5,

    isEmptyRequest:false,

    defaultValue:"请输入关键字...",       

    width:$("#search").width() + 2,

    maxHeight:-1,

    event:{

        itemClick:function(obj){

            alert(obj.item.ID);

        },

        enterKeydown:function(obj){

            if(obj.item){

                alert("有当前项");

            }else{

                alert("没有当前项");

            }

        }

    }   

});

四、总结  

  如果你还有自己的逻辑需要处理,也支持链式调用,大可以这样写 $("#search").intellSearch({参数...}).focus(function(){你的处理...});

  分享该插件希望能帮助到有需要的朋友,主要用于学习。由于是v1.0,可能还有一些bug,有发现的朋友也可以告诉我,我会及时修正。  

附源代码

js代码


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

/*搜索智能提示 v1.0

  date:2015.09.08 

*/

;(function(w,$){

    $.fn.intellSearch = function(options){

        var jthis = this;

        var _dftOpts = {

            url:"",//请求地址或数组                    

            property:"",//要显示的json对象的属性

            itemNumber:5,//显示的条数

            isEmptyRequest:false,//focus空白是否发起请求

            defaultValue:"",//默认值

            width:0,//列表宽度

            aligner:jthis,//要对齐的元素

            maxHeight:-1,//最大高度                    

            ajax:{

                timeout:3000,//超时时间

                cache:true//是否缓存

            },

            event:{

                /*参数说明:parameter:{jthis:"jq input",jItem:"jq item",data:"json result",event:"event"}*/

                setData:null,//设置参数

                itemClick:null,//点击项触发

                enterKeydown:null,//按下enter键触发

                beforeRender:null,//所有项呈现前触发

                endRender:null,//所有项呈现后触发

                itemBeforeRender:null,//项呈现前触发

                itemAfterRender:null,//项呈现后触发

                beforeSend:null//发送请求前触发

            }

        };

        $.extend(_dftOpts,options);

        if(!_dftOpts.url){

            throw Error("url不能为空!");

        }

        var jResult;               

        var _value = "";       

        var _ajax = _dftOpts.ajax;

        var _event = _dftOpts.event;

        var _cache = [];

        var _focusCount = 0;//防止focus触发多次(sogou)

        

        /*on window*/

        window.intellObj = window.intellObj || {}; /*for global event*/

        window.intellDocumentClick = window.intellDocumentClick || function(e){

            if(!window.intellObj.jthis){

                return;

            }

            if(e.target !== window.intellObj.jthis[0]){

                setIntellObj(null);

            }

        }

        window.intellDocumentKeydown = window.intellDocumentKeydown || function(e){

            var jthis = window.intellObj.jthis;

            if(!jthis){

                return;

            }

            var code = e.keyCode;

            var value = window.intellObj.value;           

            var jResult,jCurItem,keyword;

            if(code === 13 || code === 38 || code === 40){

                jResult = window.intellObj.jResult;

                jItems = jResult.find("li");

                jCurItem = jResult.find("li.cur");

                if(code === 13){

                    if(jCurItem.length > 0){

                        jCurItem.click();

                    }else{

                        setIntellObj(null);                      

                        if(_event.enterKeydown){

                            _event.enterKeydown({"jthis":jthis,"event":e});

                        }

                    }

                    jthis.blur();

                }else if(jItems.length > 0){

                    if(code === 38){

                        if(jCurItem.length <= 0){

                            jCurItem = jItems.last();

                            jCurItem.addClass("cur");

                            keyword = jCurItem.text();

                        }else{

                            var index = jCurItem.index();

                            jCurItem.removeClass("cur");

                            if(index <= 0){

                                keyword = value;                           

                            }else{

                                jCurItem = jItems.eq(index-1);

                                jCurItem.addClass("cur");

                                keyword = jCurItem.text();

                            }

                        }

                        jthis.val(keyword);

                    }else{

                        if(jCurItem.length <= 0){

                            jCurItem = jItems.first();

                            jCurItem.addClass("cur");

                            keyword = jCurItem.text();

                        }else{

                            var index = jCurItem.index();

                            jCurItem.removeClass("cur");

                            if(index + 1 >= jItems.length){

                                keyword = value;

                            }else{

                                jCurItem = jItems.eq(index+1);

                                jCurItem.addClass("cur");

                                keyword = jCurItem.text();

                            }

                        }

                        jthis.val(keyword);

                    }

                }

            }

        }

        /*event handler*/

        $.fn.unintell = function(){

            remove();

        }

        $(document).unbind({click:window.intellDocumentClick,keydown:window.intellDocumentKeydown})

                   .bind({click:window.intellDocumentClick,keydown:window.intellDocumentKeydown});

        jthis.focus(function(){

            _focusCount++;

            if(_focusCount > 1){

                return;

            }

            if(window.intellObj.jthis && jthis !== window.intellObj.jthis){

                setIntellObj(null);

            }

            var keyword = attrValue();

            if(keyword === _dftOpts.defaultValue){

                keyword = "";

                attrValue(keyword);

            }

            if(keyword || _dftOpts.isEmptyRequest){

                sendRequest();

            }

        })

        jthis.blur(function(){           

            _focusCount = 0;

            if(!attrValue()){

                attrValue(_dftOpts.defaultValue);

            }           

        })

        jthis.keyup(function(e){

            if(e.keyCode === 38 || e.keyCode === 40){

                return;

            }

            var keyword = attrValue();

            if(!keyword){

                remove();

                window.intellObj.value = _value = "";

                return;

            }

            if(keyword !== _value){

                window.intellObj.value = _value = keyword;

                sendRequest();

            }

        });

        

        return initBox();

        

        /*function*/

        function initBox(){

            attrValue(_dftOpts.defaultValue);

            return jthis;

        }       

        function initIntell(){           

            generate();

            register();

            setIntellObj({jthis:jthis,jResult:jResult});

        }

        function generate(){

            var offset = _dftOpts.aligner.offset();

            var width = _dftOpts.width ? _dftOpts.width : _dftOpts.aligner.width();

            jResult = $("<ul>",{"class":"intellResult"});

            jResult.width(width).css({"position":"absolute","left":offset.left,"top":offset.top + jthis.outerHeight()});

            $("body").append(jResult);

            if(_dftOpts.maxHeight > 0){

                jResult.height(_dftOpts.maxHeight).css("overflowY","scroll");

            }

        }

        function remove(){

            if(jResult){

                jResult.remove();

                jResult = null;

            }

        }

        function register(){

            jResult.on("click","li",function(){

                var jItem = $(this);

                var index = jItem.index();

                var keyword = jItem.text();

                attrValue(keyword);               

                _value = keyword;               

                if(_event.itemClick){

                    _event.itemClick({"jthis":jthis,"jItem":jItem,"item":_cache[index]});

                }

            }).on("mouseenter","li",function(){

                $(this).siblings("li").removeClass("cur").end().addClass("cur");

            }).on("mouseleave","li",function(){

                $(this).removeClass("cur");

            });

        }

        function setIntellObj(obj){

            if(!obj){

                if(window.intellObj.jResult){

                    window.intellObj.jResult.remove();

                }

                window.intellObj.jthis = null;

                window.intellObj.jResult = null;

            }else{

                window.intellObj.jthis = obj.jthis;

                window.intellObj.jResult = obj.jResult;

            }

        }

        function sendRequest(){

            var data;

            if(_event.setData){               

                data = _event.setData({"jthis":jthis});

            }

            $.ajax({

                url:_dftOpts.url,

                data:data,

                cache:_ajax.cache,

                timeout:_ajax.timeout,

                beforeSend:function(xhr){

                    if(_event.beforeSend){

                        _event.beforeSend(xhr);

                    }

                },

                success:function(data){

                    remove();

                    showData(data);

                },

                error:null

            });

        }

        function showData(data){

            data = $.trim(data) ? $.parseJSON(data) : data;

            if(_event.beforeRender){

                var rs = _event.beforeRender({"jthis":jthis,"data":data});

                if(rs === false){

                    return;

                }

                if(rs !== undefined){

                    data = rs;

                }

            }

            if(!data){

                return;

            }

            var jItem,jA,jSpan,hasProp,item,text,otherTexts,isRender,index;

            var list = $.isArray(data) ? data : [data];

            var length = list.length;

            length = length > _dftOpts.itemNumber ? _dftOpts.itemNumber : list.length;

            if(length <= 0){

                return;

            }

            initIntell();

            _cache.length = 0;

            hasProp = list[0][_dftOpts.property];

            for(var i=0;i<length;i++){

                item = list[i];

                if(item === null || item === undefined){

                    continue;

                }

                text = hasProp ? item[_dftOpts.property] : item;

                text = $.trim(text.toString());

                if(text === ""){

                    continue;

                }

                jItem = $("<li>",{"class":"intellResult_item"});

                jA = $("<a>",{"title":text}).appendTo(jItem);

                jSpan = $("<span>").appendTo(jA);

                index = text.toLowerCase().indexOf(_value.toLowerCase());

                otherTexts = splitText(text,_value,index);

                if(otherTexts){

                    jSpan.text(text.substr(index,_value.length));

                    if(otherTexts.length > 1){

                        $("<b>",{"text":otherTexts[0]}).insertBefore(jSpan);

                        $("<b>",{"text":otherTexts[1]}).insertAfter(jSpan);

                    }else{

                        if(index === 0){

                            $("<b>",{"text":otherTexts[0]}).insertAfter(jSpan);

                        }else{

                            $("<b>",{"text":otherTexts[0]}).insertBefore(jSpan);

                        }

                    }

                }else{

                    jSpan.text(text);

                }

                isRender = true;

                if(_event.itemBeforeRender){

                    isRender = _event.itemBeforeRender({"jthis":jthis,"jItem":jItem,"item":item});

                }

                if(isRender !== false){

                    jResult.append(jItem);

                    if(_event.itemAfterRender){

                        _event.itemAfterRender({"jthis":jthis,"jItem":jItem,"item":item});

                    }

                }

                _cache.push(item);

            }

            if(_event.endRender){

                _event.endRender({"jthis":jthis});

            }

            jResult.show();

        }

        function attrValue(value){

            if(!value && value != ""){

                return $.trim(jthis.val());

            }

            jthis.val(value);

        }

        function splitText(text,value,index){

            var tlength = text.length;

            var vlength = value.length;

            if(index === -1){

                return null;

            }

            if(index === 0){

                if(index + vlength >= tlength){

                    return null;

                }

                return [text.substr(index + vlength)];

            }

            if(index + vlength >= tlength){

                return [text.substr(0,index)];

            }

            return [text.substr(0,index),text.substr(index + vlength)];

        }

    }

})(window,jQuery);

样式


1

2

3

.intellResult{margin:0;padding:0;background:#fff;border:1px solid #b6b6b6;clear:both;z-index:999;display:none;}

.intellResult li{margin:0;padding:0;padding:5px 15px;height:20px;line-height:20px;overflow:hidden;text-overflow:ellipsis;cursor:pointer;white-space:nowrap;}

.intellResult li.cur{background:#E5E0E0;}

分类: JQuery

         }

                return [text.substr(index + vlength)];

            }

            if(index + vlength >= tlength){

                return [text.substr(0,index)];

            }

            return [text.substr(0,index),text.substr(index + vlength)];

        }

    }

})(window,jQuery);

样式


1

2

3

.intellResult{margin:0;padding:0;background:#fff;border:1px solid #b6b6b6;clear:both;z-index:999;display:none;}

.intellResult li{margin:0;padding:0;padding:5px 15px;height:20px;line-height:20px;overflow:hidden;text-overflow:ellipsis;cursor:pointer;white-space:nowrap;}

.intellResult li.cur{background:#E5E0E0;}

分类: JQuery

时间: 2024-08-03 09:47:51

jquery的智能提示控件的相关文章

一个基于jquery的智能提示控件intellSeach.js

一.需求 我们经常会遇到[站内搜索]的需求,为了提高用户体验,我们希望能做到像百度那样的即时智能提示.例如:某公司人事管理系统,想搜索李XX,只要输入“李”,系统自然会提示一些姓李的员工,这样方便用户使用.说白了,就是用户边输入,系统会提示相关的结果:或者,当用户点击搜索框时,就推荐一些内容,如360.百度都会提示今天的主要新闻或搜索量大的内容. jquery 已经有一个这样的插件了,叫 autocomplete, 但我觉得不好用.关于autocomplete的介绍也很多,有兴趣的朋友可以去试试

福利到~分享一个基于jquery的智能提示控件intellSeach.js

一.需求 我们经常会遇到[站内搜索]的需求,为了提高用户体验,我们希望能做到像百度那样的即时智能提示.例如:某公司人事管理系统,想搜索李XX,只要输入“李”,系统自然会提示一些姓李的员工,这样方便用户使用.说白了,就是用户边输入,系统会提示相关的结果:或者,当用户点击搜索框时,就推荐一些内容,如360.百度都会提示今天的主要新闻或搜索量大的内容. jquery 已经有一个这样的插件了,叫 autocomplete, 但我觉得不好用.关于autocomplete的介绍也很多,有兴趣的朋友可以去试试

jquery messagetip信息语提示控件

编写原因: 作为提示框,jquery有个messagebox的控件,也就是弹出的提示框.但这个控件如果不是用在需要确认的时候,单单警告提示.消息提示.失败提示时,用户还需要去点下确认,有时这操作还是挺烦的(尽管可以设置timeout,会自动消失). 控件需求: 现在需要一个简洁消息提示控件,不需确认. 1.提示框可以从顶部或底部滑入,在失效后滑出. 2.可以设置滑入时间,内容停留时间.滑出时间. PS:比较简单的控件 效果如下 编写过程: 1.在无文档的情况下, 我建议将用户能传的参数的定义写在

jQuery打造智能提示插件二(可编辑下拉框)

在上一篇 jQuery打造智能提示插件 上改进,增加下拉按钮,修复点击下拉区域外不隐藏BUG 效果 下拉按钮素材: js封装,注意红色部分为BUG修复,然后传入boxwidth不带px: /* /// <reference path="jquery-autocomplete2.0.js" /> zhangs 20140516 */ (function($) { $.fn.combox = function(options) { var KEY = { UP: 38, DOW

jQuery打造智能提示插件

插件根据实际需要在单功能上封装的,实现传入后台数据地址,要保存值的input,前台要传入的参数(过滤条件),来返回下拉提示数据,数据过多可上下滚动选择,选择后显示文本与对应的值,供后台操作,如图: js封装: /* /// <reference path="jquery-autocomplete2.0.js" /> zhangs 20140516 */ (function($) { $.fn.combox = function(options) { var KEY = {

Eclipse 支持 HTML&amp;JSExtJS&amp;jQuery 代码智能提示

Eclipse支持HTML&JSExtJS&jQuery代码智能提示 安装HTML插件GEF和EclipseHTMLEditor 一. GEF下载安装 进到网页http://www.eclipse.org/gef/downloads/ 点6.2M的那个.会进入下载页面http://www.eclipse.org/downloads/download.php?file=/tools/gef/downloads/drops/3.7.2/R201201171043/GEF-ALL-3.7.2.z

Jquery easyui的validatebox控件和正则表达式

Validatebox是EasyUI的验证控件,它支持很多验证,比如说是否是email.是否是url等,保证我们输入的数据在进行处理前能够确保其完整性和正确性.验证可以实现在数据层和业务规则层,但应当在表现层进行前端的"保护",因此,我们通常在UI层为用户提供友好的.可以交互的验证体验,避免在应用程序中进行不必要的网络间的往返验证.在前期ASP.NET中,我们接触了六种验证控件,根据这六种验证控件,几乎能够实现所有的验证.那现在说的Validatebox是怎么实现验证的呢? 仔细观察j

jQuery之自定义pagination控件

slpagination 效果: slpagination.js (function($) { $.fn.slpagination = function(options, params) { $.extend($.fn.slpagination.defaults, options); $(this).attr({ "class" : $.fn.slpagination.defaults.css, style : $.fn.slpagination.defaults.style });

jQuery同时处理一个控件的click和dblclick事件

1 jQuery.fn.single_double_click = function(single_click_callback, double_click_callback, timeout) { 2 return this.each(function(){ 3 var clicks = 0, self = this; 4 jQuery(this).click(function(event){ 5 clicks++; 6 if (clicks == 1) { 7 setTimeout(func