rails select级联

首先自定义input表单:

class TaxonSelectInput < SimpleForm::Inputs::CollectionSelectInput
  include ActionView::Helpers::FormTagHelper

  def input(wrapper_options = nil)
    data = options[:data] || {}
    class_name = self.class.name.underscore.dasherize

    template.content_tag(:div, class: "taxon-picker #{class_name}", data: data) do
      template.concat(
        select_tag(:"#{attribute_name}_taxonomies", nil, class: 'taxonomies')
      )
      template.concat(
        select_tag(:"#{attribute_name}_taxons", nil, class: 'taxons')
      )
      template.concat super(wrapper_options)
    end
  end
end

因为数据库设计问题,我这里需要2个不同的下拉


js开发

const Cache = {}
const root = ''

export default class TaxonPicker {
  static defaults = {
    taxonomiesUrl: '/api/xxx',
    taxonsUrl: '/api/xxx',
    taxonChildrenUrl: '/api/xxx'
  }

  /**
   * Creates a new instance of a china district picker.
   * @class
   * @param {jQuery} element - jQuery object to make into a picker.
   * @param {Object} options - Overrides to the default plugin settings.
   */
  constructor(element, options) {
    this.$element = element
    this.options = $.extend({}, TaxonPicker.defaults, this.$element.data(), options)
    this.taxon_id = `${this.options.taxon_id}`

    this.selectedData = {
      selectedTaxonomy: null,
      selectedTaxon: null,
      selectedTaxonChildren: null,
    }
    this.$taxonomies = this.$element.find('.taxonomies')
    this.$taxons = this.$element.find('.taxons')
    this.$taxonChildren = this.$element.find('.taxon_children')
  }

  init() {
    this.loadTaxonomies()
    this.attachEvents()
    this.$taxonChildren.addClass('hide')
    // this.test()
  }


  attachEvents() {
    this.$taxonomies.on('change', () => {
      this.selectedData.selectedTaxonomy = this.$taxonomies.val()
      this.selectedData.selectedTaxon = null
      this.selectedData.selectedTaxonChildren = null

      this.$taxons.empty()
      this.$taxonChildren.empty()
      this.loadTaxons(this.selectedData.selectedTaxonomy)
        .then(() => {
          this.$taxonChildren.empty()
        })
    })

    this.$taxons.on('change', () => {
      this.selectedData.selectedTaxon = this.$taxons.val()
      this.selectedData.selectedTaxonChildren = null

      this.$taxonChildren.empty()
      this.loadTaxonChildren(this.$taxons.val())
    })

    this.$taxonChildren.on('change', () => {
      this.selectedData.selectedTaxonChildren = this.$taxonChildren.val()
    })
  }


  loadTaxonomies = () => {
    let ret

    if (Cache[root]) {
      ret = Promise.resolve(Cache[root])
    } else {
      ret = $.get(this.options.taxonomiesUrl).then((divisions) => {
        Cache[root] = divisions
        return divisions
      })
    }

    return ret.then((taxonomies) => {
      this.resetOptions(
        this.$taxonomies,
        taxonomies,
        this.selectedData.selectedTaxonomy
      )
    })
  }

  loadTaxons = (taxonomyId) => {
    let ret

    if (Cache[taxonomyId]) {
      ret = Promise.resolve(Cache[taxonomyId])
    } else {
      ret = $.get(this.options.taxonsUrl, { id: taxonomyId }).then((divisions) => {
        Cache[taxonomyId] = divisions
        return divisions
      })
    }

    return ret.then((taxons) => {
      this.resetOptions(
        this.$taxons,
        taxons,
        this.selectedData.selectedTaxon
      )
    })
  }

  loadTaxonChildren = (parentId) => {
    let ret

    if (Cache[parentId]) {
      ret = Promise.resolve(Cache[parentId])
    } else {
      ret = $.get(this.options.taxonChildrenUrl, { id: parentId }).then((divisions) => {
        Cache[parentId] = divisions
        return divisions
      })
    }

    return ret.then((taxonChildren) => {
      this.resetOptions(
        this.$taxonChildren,
        taxonChildren,
        this.selectedData.selectedTaxonChildren
      )
    })
  }

  resetOptions = ($selector, divisions, selectedId) => {
    $selector.empty()

    let collection = divisions
    const isSubSelector = $selector

    if (isSubSelector && divisions.length === 0) {
      collection = Cache[root].filter((division) => division.id)
      $selector.addClass('hide')
    } else {
      $selector.removeClass('hide')
    }

    collection.forEach((division) => {
      const optionElement = $(document.createElement('option'))

      const attributes = {
        value: division.id,
        selected: `${selectedId}` === division.id
      }

      optionElement.attr(attributes).text(division.name)
      $selector.append(optionElement)
    })
  }
}

使用:

<%= f.input :taxon_id,
                    as: :taxon_select,
                    input_html: { class: "taxon_children" },
                    data: { 'taxon_id': f.object.taxon_id, 'level': 3 },
                    label_html: { for: "taxons" },
                    label: '产品分类' %>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值