Jemt / Fit.UI

Fit.UI is a JavaScript based UI framework built on Object Oriented principles
http://fitui.org
GNU Lesser General Public License v3.0
19 stars 7 forks source link

DropDown: Assigning value while controls is hidden and focusing control programmatically when visible results in render bug #117

Closed FlowIT-JIT closed 3 years ago

FlowIT-JIT commented 3 years ago

See JSFiddle demonstrating the problem: https://jsfiddle.net/rjzsxnqc/1/

In the example above, we create a DropDown control, assign a value, and place focus in the control, when the user clicks a button. But notice the performance optimization made which temporarily hides the control while adding selected items. This is known to cause reflows, and since this is expensive - especially if you have hundreds of selected items in a huge DOM - it makes sense to hide the control in this case. Unfortunately this results in a bug which is triggered if the control is focused programmatically immediately after.

This happens because the control internally performs optimization related to tab flow which is not possible to perform while the control is hidden. Therefore it postpones this operation til later, when the control is made visible again (using a Mutation Observer). But the mutation observer does not fire in time to do the optimization needed, so when Focused(true) is called, an input field which is hidden due to the length of the selected item, and the narrow width of the control, gains focus, which causes the browser to "scroll" the input into view, hence causing a render bug. This is what the DropDown looks like after clicking the "Select users" button:

image

This is the expected result: image

FlowIT-JIT commented 3 years ago

SetInputValue(..) also has some issues if set while control is hidden. If an item has been added which is wider than the control, the DropDown's right side input field is moved "out of view" due to overflow. But since SetInputValue(..) cannot detect this while hidden, the input value is assigned to the right side input field. Obviously this is useless as the input value will not be visible to the user in this case. If control on the other hand is visible while SetInputValue(..) is called, and control has a partially hidden item, the value provided is assigned to the DropDown's left side input field as expected. But when the control receives focus the first time, it is supposed to clear the input value, which it does not. In addition, there seems to be a mutation observer set in SetInputValue which is not disconnected if control is disposed.