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

首先申明一点,这个插件不是我写的,是网上一个大神写的,这是他的博客大家可以参考一下: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 = [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 = this.settings.value || $(this.settings.trigger).val() || now.getFullYear() + "/" + ("0" + (now.getMonth() + 1)).slice(-2) + ‘/‘ + ("0" + (now.getDate())).slice(-2);
 33             this.settings.value = 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 = (this.settings.value && this.settings.value.split(",")) || [0, 0, 0];
 39             this.text = this.settings.text || this.trigger.val().split(‘ ‘) || [‘‘, ‘‘, ‘‘];
 40             this.oldvalue = 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 = 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 = 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 = 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 = this.oldvalue.concat([]);
236             this.text = this.oldtext.concat([]);
237         }
238     }
239     return MobileSelectDate;
240 })

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

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

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

时间: 2024-10-13 00:51:42

移动端日期、地址控件的简单使用的相关文章

关于使用jqmobi前端框架在phonegap平台上开发时的日期时间选择控件

jqmobi(appframework)作为Intel的一款html5移动前端框架,以其自身轻量级和容易上手获得了很多移动HTML5开发者的喜爱,相对于jquerymobile,它可以说将jQuerymobile进行了重写,针对移动端做了很好的优化,(jQuerymobile太过于臃肿,实际在真机上效果较差),但是经过使用,发现jqmobi也有一些缺点,比如说bug较多,UI控件较少,插件较少,不能够满足大型应用开发需求.最不可接受的是它竟然没有提供日期和时间选择插件(日期时间选择功能很常用).

用c/c++混合编程方式为ios/android实现一个自绘日期选择控件(一)

本文为原创,如有转载,请注明出处:http://www.cnblogs.com/jackybu 前言 章节: 1.需求描述以及c/c++实现日期和月历的基本操作 2.ios实现自绘日期选择控件 3.android实现自绘日期选择控件 目的: 通过一个相对复杂的自定义自绘控件来分享: 1.ios以及android自定义自绘控件的开发流程 2.objc与c/c++混合编程 3.android ndk的环境配置,android studio ndk的编译模式,swig在android ndk开发中的作

js组件开发-移动端地区选择控件mobile-select-area

移动端地区选择控件mobile-select-area 由于之前的[js开源组件开发]js手机联动选择地区仿ios 开源git 很受欢迎,于是我又对其进行了一些优化,包括可选的范围变大了,添加了默认空首地址的功能,也添加了更多api参数,首先我们先来看下这次的效果图. 它的github地址请点击https://github.com/tianxiangbing/mobile-select-area 它的demo演示请点击 http://www.lovewebgames.com/jsmodule/m

Android UI组件之自定义控件实现IP地址控件

趁着时间挺充裕,就多写几篇博客.每一篇都是学习中的教训.今天在做东西的时候突然想到之前在MFC的时候都会有一个IP地址控件,可能是PC端用的比较多,但是在移动端好像基本没什么用处,但是偶尔也会有项目要用到,毕竟还是有些项目不需要接入互联网,只需要接入企业的内部网络.这个时候为了程序的通用性,我想到的第一个就是在程序中去配置一个网络环境,并将它保存到本地中,这样以后程序每次加载直接去本地中获取值.既然没有已有的控件,那么久自定义好了.存储在本地首先想到的就是sqlite和SharedPrefere

双日历日期选择控件

近期,需要在项目里使用日历,经过多方选择,最后决定使用 daterangepicker  (http://www.daterangepicker.com),代码下载地址 https://github.com/dangrossman/bootstrap-daterangepicker 但是,该控件是一个日期范围选择控件,使用singleDatePicker 可以变成单日期选择控件,但是只显示一个日期. 看了一下源代码,主要是在 daterangepicker.js 的有一段代码,注释掉即可:如下

高仿IOS7日期选择控件

高仿IOS7日期选择控件 高仿IOS7.QQ等日期选择控件,滑动选择,高端大气上档次,可直接运用于项目中... 下载地址:http://www.devstore.cn/code/info/965.html 运行截图:   

bootstrap-datetimepicker:基于twitter bootstrap的日期/时间选择控件

bootstrap-datetimepicker是一个基于twitter bootstrap的简单日期/时间选择控件. <!DOCTYPE HTML> <html> <head> <link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.2/css/bootstrap-combined.min.css" rel="stylesheet"> <

取消layUI中日期选择控件默认填充日期

input标签中使用日期选择控件填写,加载时默认填充当前日期, 标签设置了placeholder="请选择" autocomplete="off",但是并没有效果, 最后发现可以在绑定时将value一项设置为空,而非new Data()的值, laydate.render({    elem: '#param_monthid',    type: 'month',    format: 'yyyyMM',    value: '',    max: year + &

Android日期时间控件DatePickerDialog和TimePickerDialog

1.DatePickerDialog 在一些万年历.日程表等APP上我们经常可以看到日期选择控件,由于很少有用户会老老实实的手工输入日期,所以该控件的作用就是为了控制用户的输入格式,在Android中有一个日期选择控件叫DatePicker,但是该空间并非弹窗模式,而是在页面上占据一块区域,这种方式很影响布局的美观性,所以更多我们是采用弹窗作为日期控件的显示方式,这个以弹窗方式显示的日期控件叫做DatePickerDialog,显示效果如下 代码获取控件选择时间的方法如下: public cla