Fixed #2902 - Add selectOnFocus property to Overlay components

pull/2910/head
mertsincan 2022-08-30 12:05:10 +01:00
parent 7bdbeecf69
commit c391fa4268
16 changed files with 111 additions and 28 deletions

View File

@ -179,6 +179,12 @@ const AutoCompleteProps = [
default: "true",
description: "Whether to focus on the first visible or selected element when the overlay panel is shown."
},
{
name: "selectOnFocus",
type: "boolean",
default: "false",
description: "When enabled, the focused option is selected."
},
{
name: "searchLocale",
type: "string",

View File

@ -119,6 +119,12 @@ const CascadeSelectProps = [
default: "true",
description: "Whether to focus on the first visible or selected element when the overlay panel is shown."
},
{
name: "selectOnFocus",
type: "boolean",
default: "false",
description: "When enabled, the focused option is selected/opened."
},
{
name: "searchLocale",
type: "string",

View File

@ -191,6 +191,12 @@ const DropdownProps = [
default: "true",
description: "Whether to focus on the first visible or selected element when the overlay panel is shown."
},
{
name: "selectOnFocus",
type: "boolean",
default: "false",
description: "When enabled, the focused option is selected."
},
{
name: "filterMessage",
type: "string",

View File

@ -119,6 +119,12 @@ const ListboxProps = [
default: "true",
description: "Whether to focus on the first visible or selected element."
},
{
name: "selectOnFocus",
type: "boolean",
default: "false",
description: "When enabled, the focused option is selected."
},
{
name: "filterMessage",
type: "string",

View File

@ -202,6 +202,11 @@ export interface AutoCompleteProps {
* Default value is true.
*/
autoOptionFocus?: boolean | undefined;
/**
* When enabled, the focused option is selected.
* Default value is false.
*/
selectOnFocus?: boolean | undefined;
/**
* Locale to use in searching. The default locale is the host environment's current locale.
*/

View File

@ -95,7 +95,7 @@ export default {
type: String,
default: 'blank'
},
autoHighlight: { // TODO: Deprecated since v3.16.0
autoHighlight: { // TODO: Deprecated since v3.16.0. Use selectOnFocus property instead.
type: Boolean,
default: false
},
@ -154,6 +154,10 @@ export default {
type: Boolean,
default: true
},
selectOnFocus: {
type: Boolean,
default: false
},
searchLocale: {
type: String,
default: undefined
@ -193,7 +197,6 @@ export default {
overlay: null,
virtualScroller: null,
searchTimeout: null,
selectOnFocus: false,
focusOnHover: false,
dirty: false,
data() {
@ -464,7 +467,7 @@ export default {
this.$emit('dropdown-click', { originalEvent: event, query });
},
onOptionSelect(event, option) {
onOptionSelect(event, option, isHide = true) {
const value = this.getOptionValue(option);
if (this.multiple) {
@ -480,7 +483,7 @@ export default {
this.$emit('item-select', { originalEvent: event, value: option });
this.hide(true);
isHide && this.hide(true);
},
onOptionMouseMove(event, index) {
if (this.focusOnHover) {
@ -788,7 +791,7 @@ export default {
this.scrollInView();
if (this.selectOnFocus || this.autoHighlight) {
this.updateModel(event, this.getOptionValue(this.visibleOptions[index]));
this.onOptionSelect(event, this.visibleOptions[index], false);
}
}
},
@ -807,8 +810,7 @@ export default {
autoUpdateModel() {
if ((this.selectOnFocus || this.autoHighlight) && this.autoOptionFocus && !this.hasSelectedOption) {
this.focusedOptionIndex = this.findFirstFocusedOptionIndex();
const value = this.getOptionValue(this.visibleOptions[this.focusedOptionIndex]);
this.updateModel(null, this.multiple ? [value] : value);
this.onOptionSelect(null, this.visibleOptions[this.focusedOptionIndex], false);
}
},
updateModel(event, value) {

View File

@ -121,6 +121,11 @@ export interface CascadeSelectProps {
* Default value is true.
*/
autoOptionFocus?: boolean | undefined;
/**
* When enabled, the focused option is selected/opened.
* Default value is false.
*/
selectOnFocus?: boolean | undefined;
/**
* Locale to use in searching. The default locale is the host environment's current locale.
*/

View File

@ -79,6 +79,10 @@ export default {
type: Boolean,
default: true
},
selectOnFocus: {
type: Boolean,
default: false
},
searchLocale: {
type: String,
default: undefined
@ -122,7 +126,6 @@ export default {
overlay: null,
searchTimeout: null,
searchValue: null,
selectOnFocus: false,
focusOnHover: false,
data() {
return {
@ -141,6 +144,8 @@ export default {
},
mounted() {
this.id = this.$attrs.id || this.id;
this.autoUpdateModel();
},
beforeUnmount() {
this.unbindOutsideClickListener();
@ -185,7 +190,7 @@ export default {
show(isFocus) {
this.$emit('before-show');
this.overlayVisible = true;
this.activeOptionPath = this.findOptionPathByValue(this.modelValue);
this.activeOptionPath = this.hasSelectedOption ? this.findOptionPathByValue(this.modelValue) : this.activeOptionPath;
if (this.hasSelectedOption && ObjectUtils.isNotEmpty(this.activeOptionPath)) {
const processedOption = this.activeOptionPath[this.activeOptionPath.length - 1];
@ -286,7 +291,10 @@ export default {
}
},
onOptionChange(event) {
const { originalEvent, processedOption, isFocus } = event;
const { originalEvent, processedOption, isFocus, isHide } = event;
if (ObjectUtils.isEmpty(processedOption)) return;
const { index, level, parentKey, children } = processedOption;
const grouped = ObjectUtils.isNotEmpty(children);
@ -296,15 +304,15 @@ export default {
this.focusedOptionInfo = { index, level, parentKey };
this.activeOptionPath = activeOptionPath;
grouped ? this.onOptionGroupSelect(originalEvent, processedOption) : this.onOptionSelect(originalEvent, processedOption);
grouped ? this.onOptionGroupSelect(originalEvent, processedOption) : this.onOptionSelect(originalEvent, processedOption, isHide);
isFocus && this.$refs.focusInput.focus();
},
onOptionSelect(event, processedOption) {
onOptionSelect(event, processedOption, isHide = true) {
const value = this.getOptionValue(processedOption.option);
this.activeOptionPath.forEach(p => p.selected = true);
this.updateModel(event, value);
this.hide(true);
isHide && this.hide(true);
},
onOptionGroupSelect(event, processedOption) {
this.dirty = true;
@ -634,7 +642,7 @@ export default {
this.scrollInView();
if (this.selectOnFocus) {
this.updateModel(event, this.getOptionValue(this.visibleOptions[index]));
this.onOptionChange({ originalEvent: event, processedOption: this.visibleOptions[index], isHide: false });
}
}
},
@ -648,8 +656,9 @@ export default {
autoUpdateModel() {
if (this.selectOnFocus && this.autoOptionFocus && !this.hasSelectedOption) {
this.focusedOptionInfo.index = this.findFirstFocusedOptionIndex();
const value = this.getOptionValue(this.visibleOptions[this.focusedOptionInfo.index]);
this.updateModel(null, value);
this.onOptionChange({ processedOption: this.visibleOptions[this.focusedOptionInfo.index], isHide: false });
!this.overlayVisible && (this.focusedOptionInfo = { index: -1, level: 0, parentKey: '' });
}
},
updateModel(event, value) {
@ -713,7 +722,7 @@ export default {
if (this.hasSelectedOption) {
const activeOptionPath = this.findOptionPathByValue(this.modelValue);
const processedOption = activeOptionPath.length ? activeOptionPath[activeOptionPath.length - 1] : null;
const processedOption = ObjectUtils.isNotEmpty(activeOptionPath) ? activeOptionPath[activeOptionPath.length - 1] : null;
return processedOption ? this.getOptionLabel(processedOption.option) : label;
}

View File

@ -178,6 +178,11 @@ export interface DropdownProps {
* Default value is true.
*/
autoOptionFocus?: boolean | undefined;
/**
* When enabled, the focused option is selected.
* Default value is false.
*/
selectOnFocus?: boolean | undefined;
/**
* Text to be displayed in hidden accessible field when filtering returns any results. Defaults to value from PrimeVue locale configuration.
* Default value is '{0} results are available'.

View File

@ -140,6 +140,10 @@ export default {
type: Boolean,
default: true
},
selectOnFocus: {
type: Boolean,
default: false
},
filterMessage: {
type: String,
default: null
@ -182,7 +186,6 @@ export default {
searchTimeout: null,
searchValue: null,
isModelValueChanged: false,
selectOnFocus: false,
focusOnHover: false,
data() {
return {
@ -391,11 +394,11 @@ export default {
onLastHiddenFocus() {
this.$refs.firstHiddenFocusableElementOnOverlay.focus();
},
onOptionSelect(event, option) {
onOptionSelect(event, option, isHide = true) {
const value = this.getOptionValue(option);
this.updateModel(event, value);
this.hide(true);
isHide && this.hide(true);
},
onOptionMouseMove(event, index) {
if (this.focusOnHover) {
@ -744,7 +747,7 @@ export default {
this.scrollInView();
if (this.selectOnFocus) {
this.updateModel(event, this.getOptionValue(this.visibleOptions[index]));
this.onOptionSelect(event, this.visibleOptions[index], false);
}
}
},
@ -763,8 +766,7 @@ export default {
autoUpdateModel() {
if (this.selectOnFocus && this.autoOptionFocus && !this.hasSelectedOption) {
this.focusedOptionIndex = this.findFirstFocusedOptionIndex();
const value = this.getOptionValue(this.visibleOptions[this.focusedOptionIndex]);
this.updateModel(null, value);
this.onOptionSelect(null, this.visibleOptions[this.focusedOptionIndex], false);
}
},
updateModel(event, value) {

View File

@ -122,6 +122,11 @@ export interface ListboxProps {
* Default value is true.
*/
autoOptionFocus?: boolean | undefined;
/**
* When enabled, the focused option is selected.
* Default value is false.
*/
selectOnFocus?: boolean | undefined;
/**
* Text to be displayed in hidden accessible field when filtering returns any results. Defaults to value from PrimeVue locale configuration.
* Default value is '{0} results are available'.

View File

@ -96,6 +96,10 @@ export default {
type: Boolean,
default: true
},
selectOnFocus: {
type: Boolean,
default: false
},
filterMessage: {
type: String,
default: null
@ -135,7 +139,6 @@ export default {
startRangeIndex: -1,
searchTimeout: null,
searchValue: '',
selectOnFocus: false,
focusOnHover: false,
data() {
return {
@ -598,7 +601,7 @@ export default {
this.scrollInView();
if (this.selectOnFocus && !this.multiple) {
this.updateModel(event, this.getOptionValue(this.visibleOptions[index]));
this.onOptionSelect(event, this.visibleOptions[index]);
}
}
},
@ -613,10 +616,9 @@ export default {
}
},
autoUpdateModel() {
if (this.selectOnFocus && this.autoOptionFocus && !this.hasSelectedOption) {
if (this.selectOnFocus && this.autoOptionFocus && !this.hasSelectedOption && !this.multiple) {
this.focusedOptionIndex = this.findFirstFocusedOptionIndex();
const value = this.getOptionValue(this.visibleOptions[this.focusedOptionIndex]);
this.updateModel(null, this.multiple ? [value] : value);
this.onOptionSelect(null, this.visibleOptions[this.focusedOptionIndex]);
}
},
updateModel(event, value) {

View File

@ -328,6 +328,12 @@ export default {
<td>true</td>
<td>Whether to focus on the first visible or selected element when the overlay panel is shown.</td>
</tr>
<tr>
<td>selectOnFocus</td>
<td>boolean</td>
<td>false</td>
<td>When enabled, the focused option is selected.</td>
</tr>
<tr>
<td>searchLocale</td>
<td>string</td>

View File

@ -267,6 +267,12 @@ data() &#123;
<td>true</td>
<td>Whether to focus on the first visible or selected element when the overlay panel is shown.</td>
</tr>
<tr>
<td>selectOnFocus</td>
<td>boolean</td>
<td>false</td>
<td>When enabled, the focused option is selected/opened.</td>
</tr>
<tr>
<td>searchLocale</td>
<td>string</td>

View File

@ -324,6 +324,12 @@ export default {
<td>true</td>
<td>Whether to focus on the first visible or selected element when the overlay panel is shown.</td>
</tr>
<tr>
<td>selectOnFocus</td>
<td>boolean</td>
<td>false</td>
<td>When enabled, the focused option is selected.</td>
</tr>
<tr>
<td>filterMessage</td>
<td>string</td>

View File

@ -249,6 +249,12 @@ export default {
<td>true</td>
<td>Whether to focus on the first visible or selected element.</td>
</tr>
<tr>
<td>selectOnFocus</td>
<td>boolean</td>
<td>false</td>
<td>When enabled, the focused option is selected.</td>
</tr>
<tr>
<td>filterMessage</td>
<td>string</td>