Autocomplete 自动完成
简介
自动完成是指在编辑input表单控件时可根据输入文本自动给出输入提示,当用户不明确目标时自动完成可以辅助输入。
特点
本插件没有复杂功能,主要提供模糊/精确匹配列表,支持功能如下:
- 支持多关键字模糊检索和精确检索,默认是模糊检索即尽可能多的匹配
- 支持对一个属性和多个属性检索,默认是从label检索
- 支持对检索列表按权重排序
- 支持限制检索列表条数
- 支持自定义列表模板
- 支持关键字高亮显示
- 支持关自定义结果提示位置
使用方法
插件运行方式有两种:
- ax*属性:对input标签使用
axComplete
属性和content
属性即可按默认参数运行插件。 - js实例:通过
new axComplete('#ID')
方式创建实例运行。
-
<div class="ax-form-group"> <div class="ax-flex-row"> <div class="ax-form-label">名称</div> <div class="ax-form-con"> <div class="ax-form-input"> <input type="text" axComplete='content:"Apple苹果,Banana香蕉,Tomato西红柿,Grape葡萄,Haw山楂,Lemon柠檬,Orange橙子"' /> 输入字符“a”看看! </div> </div> </div> </div> <div class="ax-break"></div> <div class="ax-form-group"> <div class="ax-flex-row"> <div class="ax-form-label">名称</div> <div class="ax-form-con"> <div class="ax-form-input"> <input type="text" id="jsIns" /> 输入字符“a”看看! </div> </div> </div> </div>
-
let jsInstance = new axComplete('#jsIns',{ content: 'Apple苹果,Banana香蕉,Tomato西红柿,Grape葡萄,Haw山楂,Lemon柠檬,Orange橙子', });
以上展示了纯文本数据源,纯文本数据源需要用英文逗号将选项隔开。
数据源
除了纯文本数据源,还可使用如下几种数据源:
- 从
datalist
节点获取数据,content可填入datalist节点的#id - 使用数组数据源,包括纯文本数组和对象数组。
- 使用异步json数据和异步sql数据。使用异步数据需要设置async参数
-
<div class="ax-form-group"> <div class="ax-flex-row"> <div class="ax-form-label">从datalist获取</div> <div class="ax-form-con"> <div class="ax-form-input"> <input type="text" axComplete='content:"#list01"' /> 输入“a”看看! </div> </div> </div> </div> <datalist id="list01"> <option>Apple苹果</option> <option>Banana香蕉</option> <option>Tomato西红柿</option> <option>Grape葡萄</option> <option>Haw山楂</option> <option>Lemon柠檬</option> <option>Orange橙子</option> </datalist> <div class="ax-break"></div> <div class="ax-form-group"> <div class="ax-flex-row"> <div class="ax-form-label">从对象数组获取</div> <div class="ax-form-con"> <div class="ax-form-input"> <input type="text" id="arrayIns" /> 输入“a”看看! </div> </div> </div> </div> <div class="ax-break"></div> <div class="ax-form-group"> <div class="ax-flex-row"> <div class="ax-form-label">从字符串数组获取</div> <div class="ax-form-con"> <div class="ax-form-input"> <input type="text" id="stringIns" /> 输入“a”看看! </div> </div> </div> </div> <div class="ax-break"></div> <div class="ax-form-group"> <div class="ax-flex-row"> <div class="ax-form-label">从异步json获取</div> <div class="ax-form-con"> <div class="ax-form-input"> <input type="text" id="jsonIns" /> 输入“a”看看! </div> </div> </div> </div> <div class="ax-break"></div> <div class="ax-form-group"> <div class="ax-flex-row"> <div class="ax-form-label">从异步sql获取</div> <div class="ax-form-con"> <div class="ax-form-input"> <input type="text" id="sqlIns" /> 输入“a”看看! </div> </div> </div> </div>
-
new axComplete('#arrayIns', { content: [{ label: "Apple苹果" }, { label: "Banana香蕉" }, { label: "Tomato西红柿" }, { label: "Grape葡萄" }, { label: "Haw山楂" }, { label: "Lemon柠檬" }, { label: "Orange橙子" }] }); new axComplete('#stringIns', { content: ["Apple苹果", "Banana香蕉", "Tomato西红柿", "Grape葡萄", "Haw山楂", "Lemon柠檬", "Orange橙子"] }); new axComplete('#jsonIns', { content: 'ajax/foods.json', async: 'json' }); new axComplete('#sqlIns', { limit:6, fuzzy:false, ignore:false, content: 'ajax/foodsSql.php', async: 'sql' });
-
[ { "id": 0, "label": "Chinese Hamburger肉夹馍", "value": "肉夹馍", "tip": "中式汉堡" }, { "id": 1, "label": "Stinky tofu臭豆腐", "value": "臭豆腐", "tip": "很臭也很香" }, { "id": 2, "label": "Oyster Omelet蚵仔煎", "value": "蚵仔煎", "tip": "台湾招牌" }, { "id": 3, "label": "Rice Noodle Rolls肠粉", "value": "肠粉", "tip": "Q弹爽滑" }, { "id": 4, "label": "Shredded Pancake手抓饼", "value": "手抓饼", "tip": "层薄如纸" }, { "id": 5, "label": "Candied Gourd on a Stick冰糖葫芦", "value": "冰糖葫芦", "tip": "开胃养颜" }, { "id": 6, "label": "Egg Puffs鸡蛋仔", "value": "鸡蛋仔", "tip": "变种华夫饼" }, { "id": 7, "label": "Rolling Soybean Cake驴打滚", "value": "驴打滚", "tip": "撒上黄豆面" }, { "id": 8, "label": "Spicy Crayfish麻辣小龙虾", "value": "麻辣小龙虾", "tip": "夜市经典" }, { "id": 9, "label": "Chinese Crepes煎饼果子", "value": "煎饼果子", "tip": "上班族必备" }, { "id": 10, "label": "Spicy Hot Pot麻辣烫", "value": "麻辣烫", "tip": "既麻又辣还烫" }, { "id": 11, "label": "Rice and vegetable roll饭团", "value": "饭团", "tip": "酥脆软糯" }, { "id": 12, "label": "Plum juice酸梅汁", "value": "酸梅汁", "tip": "老北京传统" }, { "id": 13, "label": "Egg fried rice蛋炒饭", "value": "蛋炒饭", "tip": "简单便宜" }, { "id": 14, "label": "Plain noodles阳春面", "value": "阳春面", "tip": "汤清味鲜" }, { "id": 15, "label": "Sliced noodles刀削面", "value": "刀削面", "tip": "面食之王" }, { "id": 16, "label": "Milk custard双皮奶", "value": "双皮奶", "tip": "顺德经典甜品" } ]
-
<?php header("Content-Type:text/plain;charset=utf-8"); //连接数据库,数据库用户自己定义 $server="服务器地址"; $username="用户名"; $password="密码"; $database="数据库名"; $table = '表名'; $connect = mysql_connect($server,$username,$password) or die("数据库链接错误"); mysql_select_db($database,$connect); mysql_query("set names 'utf8'"); //创建变量 $value = $_POST[value];//value='我,A',是字符串 $values = explode(',', $value);//转成字符串数组 $keys = ' concat('.$_POST[keys].') ';//keys='label,id',是key字符串 $fuzzy = $_POST[fuzzy]?' or ':' and ';//fuzzy=true/false //$reorder = $_POST[reorder];//reorder=true/false,本页面用不上 $ignore = !$_POST[ignore]?' binary ':' ';//ignore=true/false $limit = !empty($_POST[limit])?' limit '.$_POST[limit]:''; $condition = ' where '; if(empty($value)){ //没有值 $condition = ''; }else{ //关键字数组循环,拼接检索条件 foreach($values as $v) { if($v != end($values)) { //不是最后一项 $condition = $condition.$keys.'like'.$ignore.'"%'.$v.'%"'.$fuzzy; } else { //最后一项 $condition = $condition.$keys.'like'.$ignore.'"%'.$v.'%"'; } } //最后拼接条数 $condition = $condition.$limit; } //检索最终数据 $sqlString="select id,label,value,tip from {$table} $condition"; $sql=mysql_query($sqlString); //根据数据生成对象数组 $result = array(); while ($row = mysql_fetch_object($sql)){ array_push($result,$row); } $success = json_encode($result); echo $success; ?>
点击这里下载“中国特色食品”的sql文件
特别说明下,获取sql异步数据,插件将向后台传递数据对象,包含属性如下:有:value、keys、fuzzy,limit、reorder、ignore
- value:检索值,字符串格式,多个字符串用英文逗号隔开,如'北京人,在纽约'
- keys:对比字段,字符串格式,多个字符串用英文逗号隔开,同参数keys,即value将要匹配数据库中的字段,默认传label
- fuzzy:是否使用模糊检索,默认true,同参数fuzzy
- limit:获取信息条数,同参数limit,默认传20
- reorder:获取信息后是否需要排序,同参数reorder,默认传false
- ignore:是否忽略大小写,同参数ignore,默认传true
结果提示
插件默认显示结果提示,可通过msgShow:false
不予显示;结果提示默认放在浮窗中,可通过使用msgPlace
参数可改变存放位置,参数如下:
- inside:在popup中显示
- newline:在input下方显示
- #id或节点:在某外部容器中显示
<div class="ax-form-group"> <div class="ax-flex-row"> <div class="ax-form-label">不显示</div> <div class="ax-form-con"> <div class="ax-form-input"> <input type="text" axComplete='content:"Apple苹果,Banana香蕉,Tomato西红柿,Grape葡萄,Haw山楂,Lemon柠檬,Orange橙子",msgShow:false' /> </div> </div> </div> </div> <div class="ax-break"></div> <div class="ax-form-group"> <div class="ax-flex-row"> <div class="ax-form-label">input下方</div> <div class="ax-form-con"> <div class="ax-form-input"> <input type="text" axComplete='content:"Apple苹果,Banana香蕉,Tomato西红柿,Grape葡萄,Haw山楂,Lemon柠檬,Orange橙子",msgPlace:"newline"' /> </div> </div> </div> </div> <div class="ax-break"></div> <div class="ax-form-group"> <div class="ax-flex-row"> <div class="ax-form-label">外部容器</div> <div class="ax-form-con"> <div class="ax-form-input"> <input type="text" axComplete='content:"Apple苹果,Banana香蕉,Tomato西红柿,Grape葡萄,Haw山楂,Lemon柠檬,Orange橙子",msgPlace:"#tips"' /> </div> </div> <span class="ax-form-txt ax-color-ignore" id="tips"></span> </div> </div>
自定义模板
默认的列表模板是简单的文字列表,如果用户想自定义模板格式可通过以下方法创建:
- 第一步:通过
content
参数定义数据源,比如:[{id:'',label:''},{id:'',label:''}] - 第二步:通过
template
参数定义模板,模板中所使用的字段必须是数据源中的字段。 - 第三步:通过
keys
参数定义检索的字段,keys为字符串格式,多个属性用英文逗号隔开,默认是“label”。
如果是从文本或datalist获得数据,默认是带上了id、label和value属性的;检索一般是从字面检索,而keys默认是label,所以第三步可不用做。
-
<div class="ax-form-group"> <div class="ax-flex-row"> <div class="ax-form-label">自定义模板</div> <div class="ax-form-con"> <div class="ax-form-input"> <input type="text" id="tplIns" /> 输入"英国"看看! </div> </div> </div> </div>
-
new axComplete('#tplIns', { content: [{ label: "南航与英航签署联营合作协议代码共享", img: '<?=$public?>images/head02.jpg', num: '985' }, { label: "12月,到英国大城小镇看“亮灯”", img: '<?=$public?>images/head02.jpg', num: '985' }, { label: "英国人喝茶不再流行贵族范", img: '<?=$public?>images/head03.jpg', num: '234', }, { label: "西班牙斗牛与逗牛,精彩各不同", img: '<?=$public?>images/head04.jpg', num: '98', }], template: `<a href="###" class="ax-bulletin ax-hover"> <span image><img src="<# this.img #>" /></span> <span class="ax-bulletin-body"><i caption><# this.label #></i></span> <i count><# this.num #>次</i> </a>`, });
自定义模板的时候数据源可选择使用datalist
,option的文本将被默认定义为label
,value值定义为value
,其他的可用属性还有legend、image、tip。
-
<div class="ax-form-group"> <div class="ax-flex-row"> <div class="ax-form-label">datalist数据源</div> <div class="ax-form-con"> <div class="ax-form-input"> <input type="text" id="tplIns02" /> 输入“a”看看! </div> </div> </div> </div> <datalist id="tplList"> <option tip="215" image="<?=$public?>images/head01.jpg" value="Apple苹果">Apple苹果</option> <option tip="105" image="<?=$public?>images/head02.jpg" value="Banana香蕉">Banana香蕉</option> <option tip="1278" image="<?=$public?>images/head03.jpg" value="Tomato西红柿">Tomato西红柿</option> <option tip="384" image="<?=$public?>images/head04.jpg" value="Grape葡萄">Grape葡萄</option> <option tip="24" image="<?=$public?>images/head05.jpg" value="Haw山楂">Haw山楂</option> <option tip="567" image="<?=$public?>images/head06.jpg" value="Lemon柠檬">Lemon柠檬</option> <option tip="193" image="<?=$public?>images/head07.jpg" value="Orange橙子">Orange橙子</option> </datalist>
-
new axComplete('#tplIns02', { content: '#tplList', template: `<a href="###" class="ax-bulletin ax-hover"> <span image><img src="<# this.image #>" /></span> <span class="ax-bulletin-body"><i caption><# this.label #></i></span> <i count><# this.tip #>次</i> </a> `, });
用按钮打开选项
下拉菜单是在input编辑时自动弹出和关闭的,如果需要手动打开下拉菜单可使用popup自身的rel
参数绑定一个或多个按钮,借助这些按钮打开popup,详细请参考axPopup.options.rel
参数。
<div class="ax-form-group"> <div class="ax-flex-row"> <div class="ax-form-label">名称</div> <div class="ax-form-con"> <div class="ax-form-input"> <input type="text" axComplete='popup:{rel:"#open"},content:"Apple苹果,Banana香蕉,Tomato西红柿,Grape葡萄,Haw山楂,Lemon柠檬,Orange橙子"' /> <span class="ax-pos-right"><a href="###" class="ax-iconfont ax-icon-down" id="open"></a></span> 输入“a”看看! </div> </div> </div> </div>
填入其他值
插件默认项input填入项目label
属性值,可通过fill
参数改变填入的值,比如value。
<div class="ax-form-group"> <div class="ax-flex-row"> <div class="ax-form-label">名称</div> <div class="ax-form-con"> <div class="ax-form-input"> <input type="text" axComplete='fill:"value",content:"#valueList",popup:{rel:"#open02"}'> <span class="ax-pos-right"><a href="###" class="ax-iconfont ax-icon-down" id="open02"></a></span> 输入“a”看看! </div> </div> </div> </div> <datalist id="valueList"> <option value="fruit01">Apple苹果</option> <option value="fruit02">Banana香蕉</option> <option value="fruit03">Tomato西红柿</option> <option value="fruit04">Grape葡萄</option> <option value="fruit05">Haw山楂</option> <option value="fruit06">Lemon柠檬</option> <option value="fruit07">Orange橙子</option> </datalist>
变量和操作方法
本插件有系列内部成员变量和内部操作方法,用户根据这些变量和方法可以自由操作实例,据此可方便与其他组件进行交互。请按下F12按键打开浏览器控制台来观摩以下实例。
内部成员变量如下:
this.inputDom
:input表单控件节点this.rawData
:原始列表数组数据,包含的主要属性如下:- id:编号,数字或字符串
- label:字面文本
- value:label对应的值,通常两者是一致的
- dom:列表中的项目节点,即li节点
this.sliceData
:根据limit参数裁减后的数据,是this.rawData的子集this.filterData
:使用检索后的数组,带有kyes、weight等属性this.popupIns
:下拉菜单实例this.wrapperDom
:自动完成父节点this.listDom
:自动完成列表节点,ul节点this.msgDom
:自动完成信息结果节点this.destroyed
:销毁状态
内部操作方法如下:
this.search(value, callback)
:关键字搜索,支持两个参数:- value:文本值
- callback:回调函数,支持一个参数即检索结果数组
this.reset(callback)
:重置归零,支持回调函数,回调无参数this.update(data,callback)
:更新数据并重新渲染节点,参数说明如下:- data:值类型同options.content
- callback:回调函数,支持一个参数即当前列表
this.destroy(callback)
:销毁实例,支持回调函数,回调无参数
-
<input type="text" id="methodIns"> <div class="ax-break"></div> <a href="###" class="ax-btn" id="searchBtn">检索“a”</a> <a href="###" class="ax-btn" id="resetBtn">重置</a> <a href="###" class="ax-btn" id="updateBtn">更新数据</a> <a href="###" class="ax-btn" id="viewBtn">查看数据</a>
-
let methodIns = new axComplete('#methodIns', { content: 'Apple苹果,Banana香蕉,Tomato西红柿,Grape葡萄,Haw山楂,Lemon柠檬,Orange橙子' }), searchBtn = document.querySelector('#searchBtn'), resetBtn = document.querySelector('#resetBtn'), updateBtn = document.querySelector('#updateBtn'), viewBtn = document.querySelector('#viewBtn'); searchBtn.onclick = () => { methodIns.search('a'); } resetBtn.onclick = () => { methodIns.reset(function () { this.popupIns.show(); }); } updateBtn.onclick = () => { methodIns.update('Train火车,Ship轮船,Car轿车,Aircraft飞机'); } viewBtn.onclick = () => { console.log('原始数据',methodIns.rawData) console.log('检索数据',methodIns.filterData) }
监听事件
本插件有若干监听方法,以on为关键字,参数中监听格式为:new instance({onShow:function(){}})
;实例后监听格式是:instance.on('show',function(){})
。在参数中监听和实例后监听效果相同。具体事件说明如下:
onInit/init
初始化后执行,无参数onSearch/search
输入文字检索后执行,支持一个参数即结果数据onSelected/selected
点击列表赋值后执行,支持一个参数即点击项onUpdated/updated
内容更新后执行,支持一个参数即当前列表数据onDestroy/destroy
销毁后执行,无参数
演示实例显示结果使用了console.log方法,请按下F12按键打开开发者工具中的“控制台”查看监听效果。
-
<div class="ax-form-group"> <div class="ax-flex-row"> <div class="ax-form-label">名称</div> <div class="ax-form-con"> <div class="ax-form-input"> <input type="text" id="on" /> 输入“a”看看! </div> </div> </div> </div>
-
let onInstance = new axComplete('#on', { content: 'Apple苹果,Banana香蕉,Tomato西红柿,Grape葡萄,Haw山楂,Lemon柠檬,Orange橙子' }); onInstance.on('selected', function (item) { console.log('赋值了', item); }).on('search', function (items) { console.log('检索了', items); });
销毁实例
通过使用this.destroy(callback)
方法销毁实例,支持回调函数,回调无参数;销毁后可通过init
初始化重新启用。
-
<div class="ax-form-group"> <div class="ax-flex-row"> <div class="ax-form-label">名称</div> <div class="ax-form-con"> <div class="ax-form-input"> <input type="text" id="destroyIns" /> 输入“a”看看! <div class="ax-break"></div> <a href="###" class="ax-btn" id="destroyBtn">销毁</a> <a href="###" class="ax-btn" id="initBtn">初始化</a> </div> </div> </div> </div>
-
let destroyIns = new axComplete('#destroyIns', { content: 'Apple苹果,Banana香蕉,Tomato西红柿,Grape葡萄,Haw山楂,Lemon柠檬,Orange橙子' }), destroyBtn = document.querySelector('#destroyBtn'), initBtn = document.querySelector('#initBtn'); destroyBtn.onclick = () => { destroyIns.destroy(); } initBtn.onclick = () => { destroyIns.init(); }
参数选项
document.addEventListener("DOMContentLoaded", function() { var demo1 = new axComplete('#id',{ content: '',//检索数据源 async: '',//是否为异步获取数据,可填json或sql ajaxType: 'post',//异步类型,默认post,可填get fuzzy: true,//是否模糊检索,默认为true,以空格区分多个关键字,只要满足匹配到一个关键字便可;如果需要精确检索可设为false,此时input的value文本将作为一个关键字 reorder: false,//检索结果是否需要排序,默认false不重排,可设为true,此时将按权重进行先后排序 limit: 20,//检索结果显示条数,默认为20,可自定义展示结果条数,为0表示不限制 ignore: true,//是否忽略英文大小写,默认true忽略,可选择false不忽略 keys: 'label',//检索字段(属性),默认从label文本检索,多个字段(属性)用英文逗号隔开 template: '',//生成检索结果列表的模板,变量使用<# this.xxxx #>表示 className: '',//生成检索结果列表的类名 breakShow: true,//检索结果是否使用分割线 msgShow: true,//是否显示检索结果,默认true显示,可选择false不显示 msgPlace: 'inside',//结果提示存放在哪里,默认放在结果列表顶部,可以使用#id,dom或newline highlight: true,//是否让关键字高亮,默认高亮 fill: 'label',//填入到input的值,默认为label,可以填id、value或者自定义的属性 idStart: 0,//生成的标准数据数组的id从那个值开始,默认为0 language: { message: '共有<# this.value #>个结果符合要求', }, popup: { rel: '', triggerRel: 'click' },//自定义下拉菜单popup的参数 breakpoints: {},//使用断点以适配终端,详情查看ax-utils-other.php页面 onInit: '',//回调函数,初始化后执行,无参数 onSearch: '',//回调函数,检索后执行,支持一个参数即获得的检索结果 onSelected: '',//回调函数,点选项目后执行,支持一个参数即当前点击项目 onUpdate: '',//回调函数,更新内容后执行,支持一个参数即当前列表数据 onDestroy: '',//回调函数,销毁后执行,无参数 }); });