首页 > 代码库 > 移动端日期、地址控件的简单使用

移动端日期、地址控件的简单使用

首先申明一点,这个插件不是我写的,是网上一个大神写的,这是他的博客大家可以参考一下:http://www.cnblogs.com/xiangbing/p/mobile-select-area.html

===========================================分割线=========================

在下呢只是就这个插件做了一下简单的适应性改进,需要的朋友可以往下看:

刚开始我也是在网上各种找插件,但是遇到一个问题就是项目要求样式统一,但是各种五花八门的插件样式都不一样,于是索性就找一个插件然后稍作修改,就可以变成功能不同但是样式统一的控件了,废话不多讲,开始:

1、源码+demo

 

 

它的github地址:https://github.com/tianxiangbing/mobile-select-area

它的demo演示:http://www.lovewebgames.com/jsmodule/mobile-select-area.html

2、使用方法

 



<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <!--日期、地址控件 -->
    <script type="text/javascript" src="dist/jquery-1.12.3.min.js"></script>
    <link rel="stylesheet" type="text/css" href="dist/mobile-select-date.css">
    <link rel="stylesheet" type="text/css" href="dist/dialog.css">
    <script type="text/javascript" src="dist/dialog.js"></script>
    <script type="text/javascript" src="dist/mobile-select-date.js"></script>
</head>
<body>
    
    <div id="txt_date" style="width: 100px;height: 40px;background-color: #ccc;">
    </div>
    
    <script type="text/javascript">
        var selectDate = new MobileSelectDate();
           selectDate.init({trigger:#txt_date});
    </script>
    
</body>
</html>

/*注释一下:dialog.css和插件js等文件时,如果引入的是压缩版的,那么需要都引入压缩版,如果不是压缩版,那就都引入非压缩版,我也不知道为什么,我试出来的,

还要引入zepto.js或者jquery.js文件*/

3、介绍一下API

 

 

default:0||1

0为空,true时默认选中第一项,默认1

trigger:

触发弹窗的DOM元素 ,可以是input或其他

value:

初始值,

level: int

级别数,默认是3级的

separator: ,

id值分隔符

eventName:tap|click

触发事件名称,默认click,使用zeptojs的可以用tap事件

data:

当data为json对象时可以直接解析,此时直接接收数组
当data为string发送ajax请求后返回json,格式如下:
{
    "data": [{
        "id": 1,
        "name": "浙江省",
        "child": [{
            "id": "1",
            "name": "杭州市",
            "child": [{
                "id": 1,
                "name": "滨江区"
            }]
        }]
    }, {
        "id": 2,
        "name": "江苏省",
        "child": [{
            "id": "1",
            "name": "南京",
            "child": [{
                "id": 1,
                "name": "解放区"
            }]
        }]
    }, {
        "id": 3,
        "name": "湖北省"
    }]
}

callback:function(scroller,text,value)

第一个是容器,第二个是选中后的text值,第三个参数是选中后的id。
并且this指向当前对象。
选中后的回调,默认有填充trigger的value值,以及赋值它后面紧跟着的hidden的value值,以逗号分隔id,空格分隔文字
4、重点来了,以下是我个人对这个插件的一些修改

 

 

刚刚大家都应该注意到我上传的代码跟源码有些区别(源码就在文章标题的demo演示地址里)

源码默认的返回值是返回value,但有时候移动端里面需要将触发元素换成其他DOM元素,例如div什么的,但是只有表单元素才有value属性,当时我用这个插件的时候,直接把触发元素换成div,发现返回值无法显示,原因就是这个,div没有value属性,直接上代码,修改后的 mobile-select-date.js

  1 ;
  2 (function(root, factory) {
  3     //amd
  4     if (typeof define === ‘function‘ && define.amd) {
  5         define([‘$‘], factory);
  6     } else if (typeof exports === ‘object‘) { //umd
  7         module.exports = factory();
  8     } else {
  9         root.MobileSelectDate = factory(window.Zepto || window.jQuery || $);
 10     }
 11 })(this, function($) {
 12     //试图写个傻逼点的代码
 13     var MobileSelectDate = function() {
 14         var rnd = Math.random().toString().replace(‘.‘, ‘‘);
 15         this.id = ‘scroller_‘ + rnd;
 16         this.scroller;
 17         this.data;
 18         this.index = 0;
 19         this.value = http://www.mamicode.com/[0, 0, 0];> 20         this.oldvalue;
 21         this.oldtext;
 22         this.text = [‘‘, ‘‘, ‘‘];
 23         this.level = 3;
 24         this.mtop = 30;
 25         this.separator = ‘ ‘;
 26     };
 27     MobileSelectDate.prototype = {
 28         init: function(settings) {
 29             this.settings = $.extend({}, settings);
 30             this.separator = "/";
 31             var now = new Date();
 32             this.settings.value = http://www.mamicode.com/this.settings.value || $(this.settings.trigger).val() || now.getFullYear() +"/" + ("0" + (now.getMonth() + 1)).slice(-2) + ‘/‘ + ("0" + (now.getDate())).slice(-2);
 33             this.settings.value = http://www.mamicode.com/this.settings.value.replace(///g, ‘,‘);> 34             this.settings.text = this.settings.value.split(‘,‘)
 35             this.settings.default==undefined ? this.default=1:this.default = 0 ;//0为空,1时默认选中第一项
 36             this.trigger = $(this.settings.trigger);
 37             this.trigger.attr("readonly", "readonly");
 38             this.value = http://www.mamicode.com/(this.settings.value && this.settings.value.split(",")) || [0, 0, 0];
 39             this.text = this.settings.text || this.trigger.val().split(‘ ‘) || [‘‘, ‘‘, ‘‘];
 40             this.oldvalue = http://www.mamicode.com/this.value.concat([]);> 41             this.oldtext = this.text.concat([]);
 42             this.min = new Date(this.settings.min || "1900/01/01");
 43             this.settings.max ? this.max = new Date(this.settings.max) : this.max = new Date();
 44             this.getData();
 45             this.bindEvent();
 46         },
 47         //覆盖数据方法,so easy
 48         getData: function() {
 49             var json = [];
 50             for (var s = this.min.getFullYear(), l = this.max.getFullYear(); s <= l; s++) {
 51                 var obj = {};
 52                 obj[‘id‘] = obj[‘name‘] = s;
 53                 obj.child = [];
 54                 for (var m = 1; m <= 12; m++) {
 55                     var o = {};
 56                     o[‘id‘] = o[‘name‘] = ("0" + m).slice(-2);
 57                     o.child = [];
 58                     var days = new Date(s, m, 0).getDate();
 59                     for (var d = 1; d <= days; d++) {
 60                         var j = {};
 61                         j[‘id‘] = j[‘name‘] = ("0" + d).slice(-2);
 62                         if (!(m == this.max.getMonth() + 1 && s == this.max.getFullYear() && d > this.max.getDate())) {
 63                             o.child.push(j);
 64                         }
 65                     }
 66                     if (!(m > this.max.getMonth() + 1 && s == this.max.getFullYear())) {
 67                         obj.child.push(o);
 68                     }
 69                 }
 70                 json.push(obj)
 71             }
 72             this.data = http://www.mamicode.com/json;> 73         },
 74         bindEvent: function() {
 75             var _this = this;
 76             this.trigger.click(function(e) {
 77 
 78                 var settings,buttons;
 79                 if( _this.settings.position == "bottom"){
 80                     settings ={
 81                         position:"bottom",
 82                         width:"100%",
 83                         className:"ui-dialog-bottom",
 84                         animate:false
 85                     }
 86                     var buttons=[{
 87                             ‘no‘: ‘取消‘
 88                         },{
 89                             ‘yes‘: ‘确定‘
 90                         }];
 91                 }
 92                 
 93                 $.confirm(‘<div class="ui-scroller-mask"><div id="‘ + _this.id + ‘" class="ui-scroller"><div></div><div ></div><div></div><p></p></div></div>‘, buttons, function(t, c) {
 94                     if (t == "yes") {
 95                         _this.submit()
 96                     }
 97                     if (t == ‘no‘) {
 98                         _this.cancel();
 99                     }
100                     this.dispose();
101                 }, $.extend({
102                     width: 320,
103                     height: 215
104                 },settings));
105                 
106                 _this.scroller = $(‘#‘ + _this.id);
107                 _this.format();
108                 var start = 0,
109                     end = 0
110                 _this.scroller.children().bind(‘touchstart‘, function(e) {
111                     start = (e.changedTouches || e.originalEvent.changedTouches)[0].pageY;
112                 });
113                 _this.scroller.children().bind(‘touchmove‘, function(e) {
114                     end = (e.changedTouches || e.originalEvent.changedTouches)[0].pageY;
115                     var diff = end - start;
116                     var dl = $(e.target).parent();
117                     if (dl[0].nodeName != "DL") {
118                         return;
119                     }
120                     var top = parseInt(dl.css(‘top‘) || 0) + diff;
121                     dl.css(‘top‘, top);
122                     start = end;
123                     return false;
124                 });
125                 _this.scroller.children().bind(‘touchend‘, function(e) {
126                     end = (e.changedTouches || e.originalEvent.changedTouches)[0].pageY;
127                     var diff = end - start;
128                     var dl = $(e.target).parent();
129                     if (dl[0].nodeName != "DL") {
130                         return;
131                     }
132                     var i = $(dl.parent()).index();
133                     var top = parseInt(dl.css(‘top‘) || 0) + diff;
134                     if (top > _this.mtop) {
135                         top = _this.mtop;
136                     }
137                     if (top < -$(dl).height() + 60) {
138                         top = -$(dl).height() + 60;
139                     }
140                     var mod = top / _this.mtop;
141                     var mode = Math.round(mod);
142                     var index = Math.abs(mode) + 1;
143                     if (mode == 1) {
144                         index = 0;
145                     }
146                     _this.value[i] = $(dl.children().get(index)).attr(‘ref‘);
147                     _this.value[i] == 0 ? _this.text[i] = "" : _this.text[i] = $(dl.children().get(index)).html();
148                     for (var j = _this.level - 1; j > i; j--) {
149                         _this.value[j] = 0;
150                         _this.text[j] = "";
151                     }
152                     if (!$(dl.children().get(index)).hasClass(‘focus‘)) {
153                         _this.format();
154                     }
155                     $(dl.children().get(index)).addClass(‘focus‘).siblings().removeClass(‘focus‘);
156                     dl.css(‘top‘, mode * _this.mtop);
157                     return false;
158                 });
159                 return false;
160             });
161         },
162         format: function() {
163             var _this = this;
164             var child = _this.scroller.children();
165             this.f(this.data);
166         },
167         f: function(data) {
168             var _this = this;
169             var item = data;
170             if (!item) {
171                 item = [];
172             };
173             var str = ‘<dl><dd ref="0">——</dd>‘;
174             var focus = 0,
175                 childData, top = _this.mtop;
176             if (_this.index !== 0 && _this.value[_this.index - 1] == "0" && this.default == 0) {
177                 str = ‘<dl><dd ref="0" class="focus">——</dd>‘;
178                 _this.value[_this.index] = 0;
179                 _this.text[_this.index] = "";
180                 focus = 0;
181             } else {
182                 if (_this.value[_this.index] == "0") {
183                     str = ‘<dl><dd ref="0" class="focus">——</dd>‘;
184                     focus = 0;
185                 }
186                 if (item.length > 0 && this.default == 1) {
187                     str = ‘<dl>‘;
188                     var pid = item[0].pid || 0;
189                     var id = item[0].id || 0;
190                     focus = item[0].id;
191                     childData = http://www.mamicode.com/item[0].child;>192                     if(!_this.value[this.index ]){
193                         _this.value[this.index ] = id;
194                         _this.text[this.index] = item[0].name;
195                     }
196                     str += ‘<dd pid="‘ + pid + ‘" class="‘ + cls + ‘" ref="‘ + id + ‘">‘ + item[0].name + ‘</dd>‘;
197                 }
198                 for (var j = _this.default, len = item.length; j < len; j++) {
199                     var pid = item[j].pid || 0;
200                     var id = item[j].id || 0;
201                     var cls = ‘‘;
202                     if (_this.value[_this.index] == id) {
203                         cls = "focus";
204                         focus = id;
205                         childData = item[j].child;
206                         top = _this.mtop * (-(j - _this.default));
207                     };
208                     str += ‘<dd pid="‘ + pid + ‘" class="‘ + cls + ‘" ref="‘ + id + ‘">‘ + item[j].name + ‘</dd>‘;
209                 }
210             }
211             str += "</dl>";
212             var newdom = $(str);
213             newdom.css(‘top‘, top);
214             var child = _this.scroller.children();
215             $(child[_this.index]).html(newdom);
216             _this.index++;
217             if (_this.index > _this.level - 1) {
218                 _this.index = 0;
219                 return;
220             }
221             _this.f(childData);
222         },
223         submit: function() {
224             this.oldvalue = http://www.mamicode.com/this.value.concat([]);>225             this.oldtext = this.text.concat([]);
226             if (this.trigger[0].nodeType == 1) {
227                 //input
228                 this.trigger.text(this.text.join(this.separator));
229                 this.trigger.attr(‘data-value‘, this.value.join(‘,‘));
230             }
231             this.trigger.next(‘:hidden‘).val(this.value.join(‘,‘));
232             this.settings.callback && this.settings.callback(this.scroller);
233         },
234         cancel: function() {
235             this.value = http://www.mamicode.com/this.oldvalue.concat([]);>236             this.text = this.oldtext.concat([]);
237         }
238     }
239     return MobileSelectDate;
240 })

大家注意第228行,我把value值改成了text,就这,其实特别简单,但是当时一直没想到改源码就可以实现,费了点时间,

最后,介绍一下这个插件如何拓展为自己的插件

 

 

这个插件的数据来源就是那个 data.json文件,里面的数据大家可以参考上边介绍的书写格式就可以,然后引入的时候注意一下目录结构关系,

 

移动端日期、地址控件的简单使用