用ES6语法写的btnSelect下拉按钮

btnSelect下拉按钮

按钮支持多个按钮关联,带联想功能
// 下拉选择按钮 btnSelect
/* 暴露btnSelect类,假定全局存在jQuery */
export default class btnSelect {
  constructor () {
    this.btnSelectClass = ".btn__select"
  }
  init () {
    var btnSelectList = {}
    $(this.btnSelectClass).each(function(){
      var name = $(this).children('input[type="hidden"]').attr("name");
      var btnSelect = new btnSelectClass($(this))
      btnSelectList[name] = btnSelect
      btnSelect.init()
    })
    window.btnSelectList = btnSelectList
    var btnSelectRelations = new btnSelectRelation(["province","city"])
    btnSelectRelations.init()
  }
}

/**
 * 注册的组件放在window.btnSelectList下 取input[type='hidden']的name值为键名
    <span class="btn__select">
      <input type="text" placeholder="专业">
      <input type="hidden" name="qwe">
      <button type="button"></button>
      <ul>
        <li name="caa">123</li>
        <li name="tafa">456</li>
        <li name="xafa">789</li>
      </ul>
    </span>
 *
 * 简写 在实例化的时候会补全,不过这样是没有初始数据的
    <span class="btn__select">
      <input type="text" placeholder="专业">
      <input type="hidden" name="qwe">
    </span>
 * 
 * 导入数据
    window.btnSelectList.qwe.set({
      caa: "中国美术学院",
      tafa: "天津美术学院",
      xafa: "西安美术学院"
    })
 *
 * 获取
    window.btnSelectList.qwe.get()
 *   
 */
class btnSelectClass {
  constructor (element, data = null){
    this.btn__select = element
    this.data = data
    this.preText = ""
    this.name = undefined
    this.btnSelectRelation = null
    this.set = data => {
      this.data = data
      this.reBuildDom(data)
    }
    this.get = () => this.btn__select.children("input[type='hidden']").val()
  }

  init () {
    var _this = this
    this.data == null && this.buildBtnSelect()
    // 选择 取值
    this.btn__select.on("click","li",function(){
      _this.setValue($(this).attr("name"), $(this).text())
      typeof _this.btnSelectRelation === "function" && _this.btnSelectRelation(_this.name,$(this).attr("name"))
    })
    // 监听输入动作,触发搜索功能
    this.btn__select.children("input[type='text']").keyup(e => {
      var val = $(e.target).val()
      val !== this.preText && this.search(val)
    })
    this.setName()
  }

  setValue (name, value) {
    this.btn__select.children("input[type='text']").val(value)
    this.btn__select.children("input[type='hidden']").val(name)
  }

  setName () {
    this.name = this.btn__select.children('input[type="hidden"]').attr("name")
  }

  buildBtnSelect () {
    var ul = this.btn__select.children("ul")
    var button = this.btn__select.children("button")
    button.length == 0 && this.btn__select.children("input[type='hidden']").after('<button type="button"></button>')
    if(ul.length == 0){
      this.btn__select.append("<ul></ul>")
      this.data = {}
    }else{
      var data = {}
      var items = this.btn__select.find("li")
      items.each(function(){
        data[$(this).attr("name")] = $(this).text()
      })
      this.data = data
    }
  }

  reBuildDom (data) {
    var ul = this.btn__select.children("ul")
    ul.empty()
    var items = ""
    $.each(data, function (k,v) {
      items += `<li name="${k}">${v}</li>`
    })
    ul.append(items)
  }

  search (val) {
    this.preText = val
    var data = {}
    if(val != ""){
      $.each(this.data,(k, v) => {
        (v.indexOf(val) > -1) && (data[k] = v)
      })
      this.reBuildDom(data)
    }else{
      this.reBuildDom(this.data)
    }
  }
}

/*["province","city"]*/
/**
 * btnSelect关联器
 * 在btnSelect初始化之后 才能 将关联器调用初始化
 *
 * 在实例化关联器是传入与关联按钮的name数组,按关联顺序排序
 * 如下:province的下一级是city
 * 
 * 关于初始化的板栗:
    var btnSelectRelations = new btnSelectRelation(["province","city"])
    btnSelectRelations.init()
 *
 * 设置数据:
    window.btnSelectList.province.setSource({
      zj: "浙江省",
      hn: "湖南省",
      sc: "四川省"
    })

    window.btnSelectList.city.setSource({
      zj: {
        hz:"杭州市",
        sx:"绍兴市",
        jh:"金华市"
      },
      hn: {
        cs:"长沙市",
        yy:"岳阳市",
        cd:"常德市"
      },
      sc: {
        cd:"成都市",
        my:"绵阳市",
        dy:"德阳市"
      }
    })
 * 
 */
class btnSelectRelation {
  constructor (relationType) {
    this.relationType = relationType
    this.relationData = []
    this.set = (childName, data) => {
      var index = this.getChildIndex(childName)
      this.relationData[index] = data
      index == 0 && this.setChildData(index, data)
    }
  }
  init () {
    $.each(this.relationType,(k, v) => {
      window.btnSelectList[v].setSource = data => {
        var name = v
        this.set(name,data)
      }
      window.btnSelectList[v].btnSelectRelation = (btnName,key) => {
        var index = this.getChildIndex(btnName) + 1
        index > 0 && index < this.relationData.length && this.filter(index, key)
      }
    })
  }

  getChildIndex (childName) {
    return this.relationType.indexOf(childName)
  }

  filter (index, key) {
    this.setChildData(index, this.relationData[index][key])
  }

  setChildData (index, data) {
    window.btnSelectList[this.relationType[index]].set(data)
  }
}

补上css,这里是用stylus语法

/* 清除按钮样式 */
btn-clean()
  border none
  outline none
  box-shadow none
  background none

/* 下拉按钮样式 */
dropDown()
  padding 0
  border-left 6px solid transparent
  border-right 6px solid transparent
  border-top 10px solid mt-orange

.btn__select
  btn-clean()
  border 1px solid #ccc
  border-radius 2px
  font-size 14px
  color gray-a7
  padding 0.5em 0.7em
  position relative
  input,
  button
    btn-clean()
    &:focus~ul
      display block
  button
    dropDown()
  ul
    position absolute
    top 100%
    left 0
    width 100%
    border-radius 0 0 2px 2px
    box-shadow 0 2px 2px rgba(0,0,0,.3)
    display none
    &:hover
      display block
  li
    padding 0.5em 0.3em
    border 1px solid #ccc
    &:not(:last-child)
      border-bottom none
    &:last-child
      border-radius 0 0 2px 2px

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,743评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,296评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,285评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,485评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,581评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,821评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,960评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,719评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,186评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,516评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,650评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,936评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,757评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,991评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,370评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,527评论 2 349

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,065评论 4 62
  • 《拖延心理学》作者是简·博克、莱诺拉·袁。读完整本书,我知道什么是拖延?拖延的根源及其本质是什么?有哪些方法应对拖...
    ICE蝈蝈阅读 495评论 0 2
  • 第六章 卢比肯号 维克崔克斯·索若拉上的混沌信徒显然发现内政部是一个绝佳的藏身之处,作为帝国最庞大最刻板的组织之一...
    Geo魏巍阅读 878评论 0 4
  • 玥玥,性别:女,今年7岁零3个月,读一年级,是个爱唱爱跳的小姑娘。她在幼儿园大班最后一学期接触了一下英语,...
    Jane的心愿阅读 231评论 0 1
  • 2016.12.24 Morning Dormitary 难道是没有写作素材了?还是说你有心结?...
    beyound20阅读 129评论 4 0