Browse Source

Moving files to dir and adding support to multiple control

djhvscf 7 years ago
parent
commit
ec965c24e8

+ 3 - 3
src/bootstrap-table.js

@@ -7,9 +7,9 @@
 import Constants from './constants/index.js'
 import Utils from './utils/index.js'
 import VirtualScroll from './virtual-scroll/index.js'
-import {isNumeric, isEmptyObject} from './types.js'
-import Sort from './sort.js'
-import Polyfill from './polyfill.js'
+import {isNumeric, isEmptyObject} from './utils/types.js'
+import Sort from './utils/sort.js'
+import Polyfill from './dom/polyfill.js'
 
 class BootstrapTable {
   constructor (el, options) {

+ 88 - 0
src/dom/dom.js

@@ -0,0 +1,88 @@
+import {isString, isUndefined, isJQueryObject} from '../utils/types'
+import {showHide} from './helpers'
+
+export const createText = (text) => document.createTextNode(text)
+
+export const getText = (node) => {
+  if (isUndefined(node.textContent)) {
+    return node.innerText.trim()
+  }
+  return node.textContent.trim()
+}
+
+export const createElem = (...args) => {
+  const tag = args[0]
+  if (!isString(tag)) {
+    return null
+  }
+
+  const el = document.createElement(tag)
+  for (let i = 0; i < args.length; i++) {
+    const arg = args[i]
+
+    if (Array.isArray(arg) && arg.length === 2) {
+      el.setAttribute(arg[0], arg[1])
+    }
+  }
+  return el
+}
+
+export const removeElem = (node) => node.parentNode.removeChild(node)
+
+export const hasClass = (ele, cls) => {
+  if (isUndefined(ele)) {
+    return false
+  }
+
+  return ele.classList.contains(cls)
+}
+
+export const addClass = (ele, cls) => ele.classList.add(cls)
+
+export const removeClass = (ele, cls) => ele.classList.remove(cls)
+
+export const createOpt = (text, value, isSel) => {
+  const isSelected = isSel ? true : false
+  const opt = isSelected ?
+    createElem('option', ['value', value.trim()], ['selected', 'true']) :
+    createElem('option', ['value', value.trim()])
+  opt.appendChild(createText(text.trim()))
+  return opt
+}
+
+export const is = (ele, tag) => {
+  tag = tag.toLowerCase()
+  if (isJQueryObject(ele)) {
+    ele = ele[0]
+  }
+
+  if (tag === ':focus') {
+    return ele === document.activeElement
+  }
+
+  if (tag === ':checkbox') {
+    return ele.type === 'checkbox'
+  }
+
+  if (tag === ':radio') {
+    return ele.type === 'radio'
+  }
+
+  if (tag === 'input[type=text]') {
+    return ele.type === 'text' && ele.nodeName.toLowerCase() === 'input'
+  }
+
+  ele.nodeName.toLowerCase() === tag
+}
+
+export const find = (ele, selector) => {
+  if (isJQueryObject(ele)) {
+    ele = ele[0]
+  }
+
+  return ele.querySelectorAll(selector)
+}
+
+export const show = (elements) => showHide(elements, true)
+
+export const hide = (elements) => showHide(elements)

+ 50 - 0
src/dom/helpers.js

@@ -0,0 +1,50 @@
+export const defaultDisplay = (tag) => {
+  const iframe = document.createElement('iframe')
+  iframe.setAttribute('frameborder', 0)
+  iframe.setAttribute('width', 0)
+  iframe.setAttribute('height', 0)
+  document.documentElement.appendChild(iframe)
+
+  const doc = (iframe.contentWindow || iframe.contentDocument).document
+
+  // IE support
+  doc.write()
+  doc.close()
+
+  const testEl = doc.createElement(tag)
+  doc.documentElement.appendChild(testEl)
+  const display = (window.getComputedStyle ? getComputedStyle(testEl, null) : testEl.currentStyle).display
+  iframe.parentNode.removeChild(iframe)
+  return display
+}
+
+export const showHide = (elements, show) => {
+  let display
+  let elem
+  let computedDisplay
+  const values = []
+  const length = elements.length
+
+  for (let index = 0; index < length; index++) {
+    elem = elements[index]
+    if ( !elem.style ) {
+      continue
+    }
+
+    values[index] = elem.getAttribute('data-olddisplay')
+    display = elem.style.display
+    computedDisplay = (window.getComputedStyle ? getComputedStyle(elem, null) : elem.currentStyle).display
+
+    if (show) {
+      if (!values[index] && display === 'none') elem.style.display = ''
+      if (elem.style.display === '' && (computedDisplay === 'none')) values[index] = values[index] || defaultDisplay(elem.nodeName)
+    } else {
+      if (display && display !== 'none' || !(computedDisplay === 'none'))
+        elem.setAttribute('data-olddisplay', (computedDisplay === 'none') ? display : computedDisplay)
+    }
+    if (!show || elem.style.display === 'none' || elem.style.display === '')
+      elem.style.display = show ? values[index] || '' : 'none'
+  }
+
+  return elements
+}

+ 21 - 0
src/dom/polyfill.js

@@ -0,0 +1,21 @@
+function closest () {
+  if (!Element.prototype.matches) {
+    Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector
+  }
+
+  if (!Element.prototype.closest) {
+    Element.prototype.closest = function (s) {
+      var el = this
+
+      do {
+        if (el.matches(s)) return el
+        el = el.parentElement || el.parentNode
+      } while (el !== null && el.nodeType === 1)
+      return null
+    }
+  }
+}
+
+export default function Polyfill () {
+  closest()
+}

+ 21 - 11
src/extensions/filter-control/bootstrap-table-filter-control.js

@@ -4,9 +4,9 @@
  * @version: v3.0.0
  */
 
-import {createElem, createOpt, is, find, hide, show} from '../../dom.js'
-import Sort from '../../sort.js'
-import {isEmptyObject, isJQueryObject} from '../../types.js'
+import {createElem, createOpt, is, find, hide, show} from '../../dom/dom.js'
+import Sort from '../../utils/sort.js'
+import {isEmptyObject, isJQueryObject} from '../../utils/types.js'
 import Utils from '../../utils/index.js'
 
 const UtilsFilterControl = {
@@ -50,12 +50,22 @@ const UtilsFilterControl = {
     // If we get here, the value is valid to add
     return false
   },
-  fixHeaderCSS ({ $tableHeader }) {
+  fixHeaderCSS ({ $tableHeader, options }) {
+    let header = $tableHeader
+    let useMultipleControl = false
     if (isJQueryObject($tableHeader)) {
-      $tableHeader[0].style.height = '77px'
-    } else {
-      $tableHeader.style.height = '77px'
+      header = $tableHeader[0]
     }
+
+    options.columns.forEach((columns, i) => {
+      columns.forEach((_column, j) => {
+        if (_column.filterControl === 'multiple') {
+          useMultipleControl = true
+        }
+      })
+    })
+
+    header.style.height = useMultipleControl ? '123px' : '77px'
   },
   getCurrentHeader ({ $header, options, $tableHeader }) {
     let header = $header
@@ -255,12 +265,12 @@ const UtilsFilterControl = {
         }
       }
 
-      find(header, 'th').forEach((tr, i) => {
-        if (tr.getAttribute('data-field') === column.field) {
-          const div = find(tr, '.fht-cell')
+      find(header, 'th').forEach((th, i) => {
+        if (th.getAttribute('data-field') === column.field) {
+          const div = find(th, '.th-inner')
 
           if (div && div.length > 0) {
-            div[0].appendChild(controls)
+            div[0].parentNode.insertBefore(controls, div[0])
           }
 
           return false

+ 1 - 1
src/utils/index.js

@@ -1,4 +1,4 @@
-import {isFunction, isPlainObject} from '../types.js'
+import {isFunction, isPlainObject} from './types.js'
 
 export default {
   // it only does '%s', and return '' when arguments are undefined

+ 44 - 0
src/utils/sort.js

@@ -0,0 +1,44 @@
+import {isNumeric} from './types.js'
+
+export default function Sort (a, b, order, sortStable) {
+  if (a === undefined || a === null) {
+    a = ''
+  }
+  if (b === undefined || b === null) {
+    b = ''
+  }
+
+  if (sortStable && a === b) {
+    a = a._position
+    b = b._position
+  }
+
+  // IF both values are numeric, do a numeric comparison
+  if (isNumeric(a) && isNumeric(b)) {
+    // Convert numerical values form string to float.
+    a = parseFloat(a)
+    b = parseFloat(b)
+    if (a < b) {
+      return order * -1
+    }
+    if (a > b) {
+      return order
+    }
+    return 0
+  }
+
+  if (a === b) {
+    return 0
+  }
+
+  // If value is not a string, convert to string
+  if (typeof a !== 'string') {
+    a = a.toString()
+  }
+
+  if (a.localeCompare(b) === -1) {
+    return order * -1
+  }
+
+  return order
+}

+ 30 - 0
src/utils/types.js

@@ -0,0 +1,30 @@
+// eslint-disable-next-line no-void
+const UNDEFINED = void 0
+
+export const EMPTY_FN = function () {}
+
+export const isObject = (obj) => Object.prototype.toString.call(obj) === '[object Object]'
+
+export const isFunction = (obj) => Object.prototype.toString.call(obj) === '[object Function]'
+
+export const isString = (obj) => Object.prototype.toString.call(obj) === '[object String]'
+
+export const isNumeric = (obj) => Object.prototype.toString.call(obj) === '[object Number]'
+
+export const isBoolean = (obj) => Object.prototype.toString.call(obj) === '[object Boolean]'
+
+export const isUndefined = (obj) => obj === UNDEFINED
+
+export const isNull = (obj) => obj === null
+
+export const isEmptyObject = (obj) => isUndefined(obj) || isNull(obj) || obj.length === 0
+
+export const isPlainObject = (obj) => Object.prototype.toString.call(obj) === '[object Object]'
+
+export const isJQueryObject = (obj) => {
+  if (window.jQuery) {
+    return obj instanceof jQuery
+  }
+
+  return false
+}