Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug Fix+Feature] [IE10+] can't hide dropdown after using scrollbar, [Feature] inputProps #160

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"scripts": {
"start": "gulp",
"test": "mocha test/index.ls --compilers ls:livescript",
"coverage": "istanbul cover _mocha -- test/index.ls --require should --compilers ls:livescript",
"coverage": "istanbul cover node_modules/mocha/bin/_mocha -- test/index.ls --require should --compilers ls:livescript",
"coveralls": "istanbul cover _mocha -- test/index.ls --require should --compilers ls:livescript && cat coverage/lcov.info | coveralls"
},
"author": "Furqan Zafar",
Expand Down
20 changes: 10 additions & 10 deletions src/ReactSelectize.ls
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ module.exports = class ReactSelectize extends React.Component

# render :: () -> ReactElement
render: ->
this-ref = @
anchor-index =
| (typeof @props.anchor == \undefined) or @props.anchor == null => -1
| _ => (find-index (~> it `@is-equal-to-object` @props.anchor), @props.values) ? @props.values.length - 1
Expand Down Expand Up @@ -156,9 +157,9 @@ module.exports = class ReactSelectize extends React.Component

# SEARCH INPUT BOX
ResizableInput do
{disabled: @props.disabled} <<< @props.input-props <<< {
ref: \search
type: \text
{disabled: @props.disabled, type: \text } <<< @props.input-props <<< {
ref: (element) ->
this-ref.search-element = element
value: @props.search

# update the search text & highlight the first option
Expand All @@ -185,7 +186,7 @@ module.exports = class ReactSelectize extends React.Component

on-blur: (e) ~>
# to prevent closing the dropdown when the user tries to click & drag the scrollbar in IE
return if @refs.dropdown-menu and document.active-element == (find-DOM-node @refs.dropdown-menu)
return @.focus! if @refs.dropdown-menu and (document.active-element == (find-DOM-node @refs.dropdown-menu) or document.active-element.parent-node == (find-DOM-node @refs.dropdown-menu))

<~ @close-dropdown

Expand Down Expand Up @@ -428,24 +429,23 @@ module.exports = class ReactSelectize extends React.Component
callback

# blur :: () -> ()
blur: !-> @refs.search.blur!
blur: !-> @search-element.blur!

# focus :: () -> ()
focus: !-> @refs.search.focus!
focus: !-> @search-element.focus!

# move the cursor to the input field, without toggling the dropdown
# focus-on-input :: () -> ()
focus-on-input: !->
input = find-DOM-node @refs.search
if input != document.active-element
if @search-element != document.active-element
@focus-lock = true

# this triggers the DOM focus event on the input control, where we use @focus-lock to determine
# if the event was triggered by external action or by invoking @focus-on-input method.
input.focus!
@search-element.focus!

# move the cursor to the end of the search field
input.value = input.value
@search-element.value = @search-element.value

# highlights the first selectable option & moves the cursor to end of the search field
# highlight-and-focus :: () -> ()
Expand Down
50 changes: 32 additions & 18 deletions src/ResizableInput.ls
Original file line number Diff line number Diff line change
Expand Up @@ -5,61 +5,75 @@

module.exports = class ResizableInput extends React.PureComponent

# get-default-props :: () -> Props
@default-props =
type: \text

# constructor
(props) ->
super props
@autosize = @autosize.bind @
@focus = @focus.bind @
@blur = @blur.bind @

# render :: () -> ReactElement
render: ->
input {} <<< @props <<<
type: \input
class-name: \resizable-input
this-ref = @
input do
do
class-name: \resizable-input
ref: (element) ->
this-ref.input-element = element
<<< @props

# autosize :: () -> ()
autosize: ->

# reset the width
input-element = (find-DOM-node @)
..style.width = \0px
@input-element.style.width = \0px

if input-element.value.length == 0
if @input-element.value.length == 0

# the minimum width required for the cursor to be visible
input-element.style.width = if !!input-element?.current-style then \4px else \2px
@input-element.style.width = if !!@input-element?.current-style then \4px else \2px

else

# modern browsers
if input-element.scroll-width > 0
input-element.style.width = "#{2 + input-element.scroll-width}px"
if @input-element.scroll-width > 0
@input-element.style.width = "#{2 + @input-element.scroll-width}px"

# IE / Edge
else

# create a dummy input
dummpy-input = document.create-element \div
..innerHTML = input-element.value
..innerHTML = @input-element.value

# copy all the styles from search field to dummy input
(
if !!input-element.current-style
input-element.current-style
if !!@input-element.current-style
@input-element.current-style
else
document.default-view ? window .get-computed-style input-element
document.default-view ? window .get-computed-style @input-element
)
|> obj-to-pairs
|> each ([key, value]) -> dummpy-input.style[key] = value
|> -> dummpy-input.style <<< display: \inline-block, width: ""

# add the dummy input element to document.body and measure the text width
document.body.append-child dummpy-input
input-element.style.width = "#{4 + dummpy-input.client-width}px"
@input-element.style.width = "#{4 + dummpy-input.client-width}px"
document.body.remove-child dummpy-input

# component-did-mount :: () -> ()
component-did-mount: !-> @autosize!
component-did-mount: !-> @input-element and @autosize!

# component-did-update :: Props -> UIState -> ()
component-did-update: !-> @autosize!
component-did-update: !-> @input-element and @autosize!

# blur :: () -> ()
blur: -> find-DOM-node @ .blur!
blur: -> @input-element.blur!

# focus :: () -> ()
focus: -> find-DOM-node @ .focus!
focus: -> @input-element.focus!
13 changes: 8 additions & 5 deletions test/common-tests.ls
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,7 @@ module.exports = (select-class) !->
find-rendered-DOM-component-with-class select, \react-selectize-placeholder

specify "non empty select must not have placeholder", ->
{refs}:select = create-select!
input = find-DOM-node refs.select.refs.search
..value = \test
change input
{search-element}:select = create-select { search: \test }
component-with-class-must-not-exist select, \react-selectize-placeholder

specify "must default the list of options to an empty list", ->
Expand Down Expand Up @@ -391,8 +388,14 @@ module.exports = (select-class) !->
click-option find-highlighted-option select
component-with-class-must-not-exist select, \react-selectize-reset-button-container

specify "must use text as default type of search field", ->
select = create-select!
input = get-input select
assert input.type == \text

specify "must pass props.inputProps to search field", ->
select = create-select do
input-props: disabled: true
input-props: { disabled: true, type: \tel }
input = get-input select
assert input.disabled == true
assert input.type == \tel