fix select
parent
832d13eb0c
commit
c44c425a67
|
@ -9,7 +9,6 @@ import { hasProp, getSlotOptions } from '../_util/props-util'
|
||||||
import getTransitionProps from '../_util/getTransitionProps'
|
import getTransitionProps from '../_util/getTransitionProps'
|
||||||
import { cloneElement, getClass, getPropsData, getValueByProp as getValue, getEvents } from '../_util/vnode'
|
import { cloneElement, getClass, getPropsData, getValueByProp as getValue, getEvents } from '../_util/vnode'
|
||||||
import BaseMixin from '../_util/BaseMixin'
|
import BaseMixin from '../_util/BaseMixin'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getPropValue,
|
getPropValue,
|
||||||
getValuePropValue,
|
getValuePropValue,
|
||||||
|
@ -62,7 +61,7 @@ export default {
|
||||||
dropdownMenuStyle: PropTypes.object.def({}),
|
dropdownMenuStyle: PropTypes.object.def({}),
|
||||||
optionFilterProp: SelectPropTypes.optionFilterProp.def('value'),
|
optionFilterProp: SelectPropTypes.optionFilterProp.def('value'),
|
||||||
optionLabelProp: SelectPropTypes.optionLabelProp.def('value'),
|
optionLabelProp: SelectPropTypes.optionLabelProp.def('value'),
|
||||||
notFoundContent: PropTypes.string.def('Not Found'),
|
notFoundContent: PropTypes.any.def('Not Found'),
|
||||||
backfill: PropTypes.bool.def(false),
|
backfill: PropTypes.bool.def(false),
|
||||||
showAction: SelectPropTypes.showAction.def(['click']),
|
showAction: SelectPropTypes.showAction.def(['click']),
|
||||||
combobox: PropTypes.bool.def(false),
|
combobox: PropTypes.bool.def(false),
|
||||||
|
@ -83,7 +82,7 @@ export default {
|
||||||
sValue = toArray(defaultValue)
|
sValue = toArray(defaultValue)
|
||||||
}
|
}
|
||||||
sValue = this.addLabelToValue(sValue)
|
sValue = this.addLabelToValue(sValue)
|
||||||
sValue = this.addTitleToValue($slots, sValue)
|
sValue = this.addTitleToValue($slots.default, sValue)
|
||||||
let inputValue = ''
|
let inputValue = ''
|
||||||
if (combobox) {
|
if (combobox) {
|
||||||
inputValue = sValue.length
|
inputValue = sValue.length
|
||||||
|
@ -115,7 +114,7 @@ export default {
|
||||||
const { combobox, $slots } = this
|
const { combobox, $slots } = this
|
||||||
let value = toArray(this.value)
|
let value = toArray(this.value)
|
||||||
value = this.addLabelToValue(value)
|
value = this.addLabelToValue(value)
|
||||||
value = this.addTitleToValue($slots, value)
|
value = this.addTitleToValue($slots.default, value)
|
||||||
this.setState({
|
this.setState({
|
||||||
sValue: value,
|
sValue: value,
|
||||||
})
|
})
|
||||||
|
@ -127,9 +126,7 @@ export default {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// this.adjustOpenState()
|
|
||||||
},
|
},
|
||||||
deep: true,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
updated () {
|
updated () {
|
||||||
|
@ -413,7 +410,7 @@ export default {
|
||||||
if (sValue.length) {
|
if (sValue.length) {
|
||||||
this.fireChange([])
|
this.fireChange([])
|
||||||
}
|
}
|
||||||
// this.setOpenState(false, true)
|
this.setOpenState(false, true)
|
||||||
if (inputValue) {
|
if (inputValue) {
|
||||||
this.setInputValue('')
|
this.setInputValue('')
|
||||||
}
|
}
|
||||||
|
@ -555,21 +552,51 @@ export default {
|
||||||
},
|
},
|
||||||
inputBlur (e) {
|
inputBlur (e) {
|
||||||
this.clearBlurTime()
|
this.clearBlurTime()
|
||||||
|
if (this.disabled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
this.blurTimer = setTimeout(() => {
|
this.blurTimer = setTimeout(() => {
|
||||||
if (!this.disabled) {
|
this._focused = false
|
||||||
this._focused = false
|
this.updateFocusClassName()
|
||||||
this.setOpenState(false, false)
|
const props = this.$props
|
||||||
|
let { sValue } = this
|
||||||
|
const { inputValue } = this
|
||||||
|
if (
|
||||||
|
isSingleMode(props) &&
|
||||||
|
props.showSearch &&
|
||||||
|
inputValue &&
|
||||||
|
props.defaultActiveFirstOption
|
||||||
|
) {
|
||||||
|
const options = this._options || []
|
||||||
|
if (options.length) {
|
||||||
|
const firstOption = findFirstMenuItem(options)
|
||||||
|
if (firstOption) {
|
||||||
|
sValue = [
|
||||||
|
{
|
||||||
|
key: firstOption.key,
|
||||||
|
label: this.getLabelFromOption(firstOption),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
this.fireChange(sValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (isMultipleOrTags(props) && inputValue) {
|
||||||
|
this.inputValue = this.getInputDOMNode().value = ''
|
||||||
}
|
}
|
||||||
|
this.__emit('blur', this.getVLForOnChange(sValue))
|
||||||
|
this.setOpenState(false)
|
||||||
}, 10)
|
}, 10)
|
||||||
},
|
},
|
||||||
inputFocus (e) {
|
inputFocus (e) {
|
||||||
this.clearBlurTime()
|
this.clearBlurTime()
|
||||||
|
this.clearFocusTime()
|
||||||
|
this.timeoutFocus()
|
||||||
},
|
},
|
||||||
_getInputElement () {
|
_getInputElement () {
|
||||||
const props = this.$props
|
const props = this.$props
|
||||||
const inputElement = props.getInputElement
|
const inputElement = props.getInputElement
|
||||||
? props.getInputElement()
|
? props.getInputElement()
|
||||||
: <input id={props.id} autoComplete='off' value='1111'/>
|
: <input id={props.id} autoComplete='off'/>
|
||||||
const inputCls = classnames(getClass(inputElement), {
|
const inputCls = classnames(getClass(inputElement), {
|
||||||
[`${props.prefixCls}-search__field`]: true,
|
[`${props.prefixCls}-search__field`]: true,
|
||||||
})
|
})
|
||||||
|
@ -638,9 +665,9 @@ export default {
|
||||||
return this.$refs.selectTriggerRef.getInnerMenu()
|
return this.$refs.selectTriggerRef.getInnerMenu()
|
||||||
},
|
},
|
||||||
|
|
||||||
setOpenState (open, needFocus, forceSet) {
|
setOpenState (open, needFocus) {
|
||||||
const { $props: props, openStatus } = this
|
const { $props: props, openStatus } = this
|
||||||
if (!forceSet && openStatus === open) {
|
if (openStatus === open) {
|
||||||
this.maybeFocus(open, needFocus)
|
this.maybeFocus(open, needFocus)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -785,6 +812,7 @@ export default {
|
||||||
this._focused = true
|
this._focused = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
console.log(activeElement)
|
||||||
if (activeElement !== this.$refs.selectionRef) {
|
if (activeElement !== this.$refs.selectionRef) {
|
||||||
this.$refs.selectionRef.focus()
|
this.$refs.selectionRef.focus()
|
||||||
this._focused = true
|
this._focused = true
|
||||||
|
@ -810,15 +838,15 @@ export default {
|
||||||
return value
|
return value
|
||||||
},
|
},
|
||||||
|
|
||||||
addTitleToValue ($slots, values) {
|
addTitleToValue (children = [], values) {
|
||||||
let nextValues = values
|
let nextValues = values
|
||||||
const keys = values.map(v => v.key)
|
const keys = values.map(v => v.key)
|
||||||
$slots.default.forEach(child => {
|
children.forEach(child => {
|
||||||
if (!child) {
|
if (!child) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (getSlotOptions(child).isSelectOptGroup) {
|
if (getSlotOptions(child).isSelectOptGroup) {
|
||||||
nextValues = this.addTitleToValue(child.$slots, nextValues)
|
nextValues = this.addTitleToValue(child.$slots.default, nextValues)
|
||||||
} else {
|
} else {
|
||||||
const value = getValuePropValue(child)
|
const value = getValuePropValue(child)
|
||||||
const valueIndex = keys.indexOf(value)
|
const valueIndex = keys.indexOf(value)
|
||||||
|
@ -1048,7 +1076,7 @@ export default {
|
||||||
return options
|
return options
|
||||||
},
|
},
|
||||||
|
|
||||||
renderFilterOptionsFromChildren (children, childrenKeys, menuItems) {
|
renderFilterOptionsFromChildren (children = [], childrenKeys, menuItems) {
|
||||||
const sel = []
|
const sel = []
|
||||||
const props = this.$props
|
const props = this.$props
|
||||||
const { inputValue } = this
|
const { inputValue } = this
|
||||||
|
@ -1320,11 +1348,14 @@ export default {
|
||||||
if (!this.disabled) {
|
if (!this.disabled) {
|
||||||
if (this._focused && this.openStatus) {
|
if (this._focused && this.openStatus) {
|
||||||
this._focused = false
|
this._focused = false
|
||||||
this.setOpenState(false, false, true)
|
this.setOpenState(false, false)
|
||||||
this.getInputDOMNode().blur()
|
this.getInputDOMNode().blur()
|
||||||
} else {
|
} else {
|
||||||
|
// this._focused = true
|
||||||
|
// this.updateFocusClassName()
|
||||||
|
// this.timeoutFocus()
|
||||||
this._focused = true
|
this._focused = true
|
||||||
this.setOpenState(true, true, true)
|
this.setOpenState(true, true)
|
||||||
this.getInputDOMNode().focus()
|
this.getInputDOMNode().focus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1338,12 +1369,25 @@ export default {
|
||||||
const { disabled, prefixCls, inputValue, sValue, $listeners } = this
|
const { disabled, prefixCls, inputValue, sValue, $listeners } = this
|
||||||
const { mouseenter = noop, mouseleave = noop, popupScroll = noop } = $listeners
|
const { mouseenter = noop, mouseleave = noop, popupScroll = noop } = $listeners
|
||||||
const ctrlNode = this.renderTopControlNode(openStatus)
|
const ctrlNode = this.renderTopControlNode(openStatus)
|
||||||
let extraSelectionProps = {}
|
const selectionProps = {
|
||||||
|
props: {},
|
||||||
|
attrs: {
|
||||||
|
role: 'combobox',
|
||||||
|
'aria-autocomplete': 'list',
|
||||||
|
'aria-haspopup': 'true',
|
||||||
|
'aria-expanded': openStatus.toString(),
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
click: this.selectionRefClick,
|
||||||
|
},
|
||||||
|
class: `${prefixCls}-selection ${prefixCls}-selection--${multiple ? 'multiple' : 'single'}`,
|
||||||
|
ref: 'selectionRef',
|
||||||
|
key: 'selection',
|
||||||
|
|
||||||
|
}
|
||||||
if (!isMultipleOrTagsOrCombobox(props)) {
|
if (!isMultipleOrTagsOrCombobox(props)) {
|
||||||
extraSelectionProps = {
|
selectionProps.on.keydown = this.onKeyDown
|
||||||
onKeyDown: this.onKeyDown,
|
selectionProps.attrs.tabIndex = props.disabled ? -1 : 0
|
||||||
tabIndex: props.disabled ? -1 : 0,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const rootCls = {
|
const rootCls = {
|
||||||
[prefixCls]: 1,
|
[prefixCls]: 1,
|
||||||
|
@ -1389,22 +1433,9 @@ export default {
|
||||||
ref='rootRef'
|
ref='rootRef'
|
||||||
// onBlur={this.onOuterBlur}
|
// onBlur={this.onOuterBlur}
|
||||||
// onFocus={this.onOuterFocus}
|
// onFocus={this.onOuterFocus}
|
||||||
// onClick={this.rootRefClick}
|
|
||||||
class={classnames(rootCls)}
|
class={classnames(rootCls)}
|
||||||
// tabindex='-1'
|
|
||||||
>
|
>
|
||||||
<div
|
<div {...selectionProps}>
|
||||||
ref='selectionRef'
|
|
||||||
key='selection'
|
|
||||||
class={`${prefixCls}-selection
|
|
||||||
${prefixCls}-selection--${multiple ? 'multiple' : 'single'}`}
|
|
||||||
role='combobox'
|
|
||||||
aria-autocomplete='list'
|
|
||||||
aria-haspopup='true'
|
|
||||||
aria-expanded={openStatus}
|
|
||||||
{...extraSelectionProps}
|
|
||||||
onClick={this.selectionRefClick}
|
|
||||||
>
|
|
||||||
{ctrlNode}
|
{ctrlNode}
|
||||||
{this.renderClear()}
|
{this.renderClear()}
|
||||||
{multiple || !props.showArrow ? null : (
|
{multiple || !props.showArrow ? null : (
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
<script>
|
||||||
|
import Select, { Option } from '../index'
|
||||||
|
import '../assets/index.less'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
disabled: false,
|
||||||
|
options: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onChange (value) {
|
||||||
|
console.log('onChange', value)
|
||||||
|
let options = []
|
||||||
|
if (value) {
|
||||||
|
if (value.indexOf('@') >= 0) {
|
||||||
|
options = <Option key={value}>{value}</Option>
|
||||||
|
} else {
|
||||||
|
options = ['gmail.com', 'yahoo.com', 'outlook.com'].map((domain) => {
|
||||||
|
const email = `${value}@${domain}`
|
||||||
|
return <Option key={email}>{email}</Option>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.options = options
|
||||||
|
},
|
||||||
|
onSelect (v) {
|
||||||
|
console.log('onSelect', v)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
render () {
|
||||||
|
return (<Select
|
||||||
|
combobox
|
||||||
|
notFoundContent={false}
|
||||||
|
style='width: 200px'
|
||||||
|
onChange={this.onChange}
|
||||||
|
onSelect={this.onSelect}
|
||||||
|
placeholder='请输入账户名'
|
||||||
|
>
|
||||||
|
{this.options}
|
||||||
|
</Select>)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,64 @@
|
||||||
|
<script>
|
||||||
|
import Select, { Option } from '../index'
|
||||||
|
import { fetch } from './tbFetchSuggest'
|
||||||
|
import '../assets/index.less'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
disabled: false,
|
||||||
|
data: [],
|
||||||
|
value: undefined,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onChange (value) {
|
||||||
|
console.log('select ', value)
|
||||||
|
// value.label = value.key
|
||||||
|
this.value = value
|
||||||
|
},
|
||||||
|
fetchData (value) {
|
||||||
|
if (value) {
|
||||||
|
fetch(value, (data) => {
|
||||||
|
this.data = data
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.data = []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleDisabled () {
|
||||||
|
this.disabled = !this.disabled
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const data = this.data
|
||||||
|
const options = data.map((d) => {
|
||||||
|
return <Option key={d.value}><i>{d.text}</i></Option>
|
||||||
|
})
|
||||||
|
return (<div>
|
||||||
|
<h2>force suggest</h2>
|
||||||
|
<p>
|
||||||
|
<button onClick={this.toggleDisabled}>toggle disabled</button>
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<Select
|
||||||
|
labelInValue
|
||||||
|
onSearch={this.fetchData}
|
||||||
|
disabled={this.disabled}
|
||||||
|
value={this.value}
|
||||||
|
optionLabelProp='children'
|
||||||
|
placeholder='placeholder'
|
||||||
|
defaultActiveFirstOption
|
||||||
|
style={{ width: '500px' }}
|
||||||
|
onChange={this.onChange}
|
||||||
|
filterOption={false}
|
||||||
|
>
|
||||||
|
{options}
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
</div>)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,35 @@
|
||||||
|
|
||||||
|
import jsonp from 'jsonp'
|
||||||
|
import querystring from 'querystring'
|
||||||
|
let timeout
|
||||||
|
let currentValue
|
||||||
|
|
||||||
|
export function fetch (value, callback) {
|
||||||
|
if (timeout) {
|
||||||
|
clearTimeout(timeout)
|
||||||
|
timeout = null
|
||||||
|
}
|
||||||
|
currentValue = value
|
||||||
|
|
||||||
|
function fake () {
|
||||||
|
const str = querystring.encode({
|
||||||
|
code: 'utf-8',
|
||||||
|
q: value,
|
||||||
|
})
|
||||||
|
jsonp(`http://suggest.taobao.com/sug?${str}`, (err, d) => { // eslint-disable-line
|
||||||
|
if (currentValue === value) {
|
||||||
|
const result = d.result
|
||||||
|
const data = []
|
||||||
|
result.forEach((r) => {
|
||||||
|
data.push({
|
||||||
|
value: r[0],
|
||||||
|
text: r[0],
|
||||||
|
})
|
||||||
|
})
|
||||||
|
callback(data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
timeout = setTimeout(fake, 300)
|
||||||
|
}
|
|
@ -19,7 +19,14 @@ export function getPropValue (child, prop) {
|
||||||
if (prop === 'value') {
|
if (prop === 'value') {
|
||||||
return getValuePropValue(child)
|
return getValuePropValue(child)
|
||||||
}
|
}
|
||||||
return child.props[prop]
|
if (prop === 'children') {
|
||||||
|
if (child.$slots) {
|
||||||
|
return child.$slots.default
|
||||||
|
} else {
|
||||||
|
return child.componentOptions.children
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return getPropsData(child)[prop]
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isMultiple (props) {
|
export function isMultiple (props) {
|
||||||
|
|
|
@ -3,7 +3,7 @@ const AsyncComp = () => {
|
||||||
const hashs = window.location.hash.split('/')
|
const hashs = window.location.hash.split('/')
|
||||||
const d = hashs[hashs.length - 1]
|
const d = hashs[hashs.length - 1]
|
||||||
return {
|
return {
|
||||||
component: import(`../components/spin/demo/index.vue`),
|
component: import(`../components/vc-select/demo/${d}.vue`),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export default [
|
export default [
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
"highlight.js": "^9.12.0",
|
"highlight.js": "^9.12.0",
|
||||||
"html-webpack-plugin": "^2.30.1",
|
"html-webpack-plugin": "^2.30.1",
|
||||||
"istanbul-instrumenter-loader": "^3.0.0",
|
"istanbul-instrumenter-loader": "^3.0.0",
|
||||||
|
"jsonp": "^0.2.1",
|
||||||
"karma": "^1.4.1",
|
"karma": "^1.4.1",
|
||||||
"karma-coverage": "^1.1.1",
|
"karma-coverage": "^1.1.1",
|
||||||
"karma-coverage-istanbul-reporter": "^1.3.0",
|
"karma-coverage-istanbul-reporter": "^1.3.0",
|
||||||
|
@ -67,6 +68,7 @@
|
||||||
"marked": "^0.3.7",
|
"marked": "^0.3.7",
|
||||||
"mocha": "^3.2.0",
|
"mocha": "^3.2.0",
|
||||||
"pre-commit": "^1.2.2",
|
"pre-commit": "^1.2.2",
|
||||||
|
"querystring": "^0.2.0",
|
||||||
"selenium-server": "^3.0.1",
|
"selenium-server": "^3.0.1",
|
||||||
"semver": "^5.3.0",
|
"semver": "^5.3.0",
|
||||||
"sinon": "^4.0.2",
|
"sinon": "^4.0.2",
|
||||||
|
|
Loading…
Reference in New Issue