Skip to content

Commit c216902

Browse files
committed
- Updated the CategoryPicker and CategoryTree with the ability to select the first option by default.
1 parent b50aa26 commit c216902

File tree

6 files changed

+101
-4
lines changed

6 files changed

+101
-4
lines changed

Rock.JavaScript.Obsidian.Blocks/src/Example/ControlGallery/categoryPickerGallery.partial.obs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,18 @@
33
:importCode="importCode"
44
:exampleCode="exampleCode"
55
enableReflection>
6-
<CategoryPicker label="Category Picker" v-model="value" :multiple="multiple" :entityTypeGuid="entityTypeGuid" />
6+
<CategoryPicker label="Category Picker"
7+
v-model="value"
8+
:multiple="multiple"
9+
:entityTypeGuid="entityTypeGuid"
10+
:selectFirstByDefault="selectFirstByDefault" />
711

812
<template #settings>
913

1014
<div class="row">
1115
<div class="col-md-6">
1216
<CheckBox label="Multiple" v-model="multiple" />
17+
<CheckBox label="Select First By Default" v-model="selectFirstByDefault" />
1318
</div>
1419
<div class="col-md-6">
1520
<EntityTypePicker label="For Entity Type" v-model="entityType" enhanceForLongLists showBlankItem />
@@ -39,7 +44,8 @@
3944
return toGuidOrNull(entityType?.value?.value) ?? undefined;
4045
});
4146
const multiple = ref(false);
47+
const selectFirstByDefault = ref(false);
4248
const value = ref(null);
4349
const importCode = getSfcControlImportPath("categoryPicker");
4450
const exampleCode = `<CategoryPicker label="Category Picker" v-model="value" :multiple="false" :entityTypeGuid="entityTypeGuid" />`;
45-
</script>
51+
</script>

Rock.JavaScript.Obsidian.Blocks/src/Example/ControlGallery/categoryTreeGallery.partial.obs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44
:exampleCode="exampleCode"
55
enableReflection>
66

7-
<CategoryTree v-model="value" :multiple="multiple" :entityTypeGuid="entityTypeGuid" :enableDeselect="enableDeselect" />
7+
<CategoryTree v-model="value"
8+
:multiple="multiple"
9+
:entityTypeGuid="entityTypeGuid"
10+
:enableDeselect="enableDeselect"
11+
:selectFirstByDefault="selectFirstByDefault" />
812

913
<template #settings>
1014
<div class="row">
@@ -13,6 +17,7 @@
1317
</div>
1418
<div class="col-md-4">
1519
<CheckBox label="Enable Deselection" v-model="enableDeselect" />
20+
<CheckBox label="Select First By Default" v-model="selectFirstByDefault" />
1621
</div>
1722
<div class="col-md-4">
1823
<EntityTypePicker label="For Entity Type" v-model="entityType" enhanceForLongLists showBlankItem />
@@ -96,6 +101,13 @@
96101
<td>200px</td>
97102
<td>CSS length value for defining how tall the box is.</td>
98103
</tr>
104+
<tr>
105+
<td><code>selectFirstByDefault</code></td>
106+
<td>Boolean</td>
107+
<td>false</td>
108+
<td>When true, the first item in the list will be automatically selected if no other item is
109+
currently selected.</td>
110+
</tr>
99111
</tbody>
100112
</table>
101113
</template>
@@ -120,7 +132,8 @@
120132

121133
const multiple = ref(false);
122134
const enableDeselect = ref(false);
135+
const selectFirstByDefault = ref(false);
123136
const value = ref(null);
124137
const importCode = getSfcControlImportPath("categoryTree");
125138
const exampleCode = computed(() => `<CategoryTree v-model="value"${multiple.value ? " multiple" : ""}${entityTypeGuid.value ? ` entityTypeGuid="${entityTypeGuid.value}"` : ""} />`);
126-
</script>
139+
</script>

Rock.JavaScript.Obsidian/Framework/Controls/categoryPicker.obs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
formGroupClasses="category-picker"
55
iconCssClass="ti ti-folder-open"
66
:provider="itemProvider"
7+
:selectFirstByDefault="selectFirstByDefault"
78
autoExpand
89
:multiple="multiple" />
910
</template>
@@ -46,6 +47,15 @@
4647
multiple: {
4748
type: Boolean as PropType<boolean>,
4849
default: false
50+
},
51+
52+
/**
53+
* When true, the first item in the list will be automatically selected
54+
* if no other item is currently selected.
55+
*/
56+
selectFirstByDefault: {
57+
type: Boolean as PropType<boolean>,
58+
default: false
4959
}
5060
});
5161

@@ -83,6 +93,8 @@
8393

8494
// Set the provider to the new one
8595
itemProvider.value = newProvider;
96+
97+
internalValue.value = null;
8698
});
8799

88100
watch(internalValue, () => {

Rock.JavaScript.Obsidian/Framework/Controls/categoryTree.obs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
@update:modelValue="onSelect"
99
:disableFolderSelection="disableFolderSelection"
1010
:showChildCount="showChildCount"
11+
:selectFirstByDefault="selectFirstByDefault"
1112
:enableDeselect="enableDeselect"
1213
autoExpand />
1314
</div>
@@ -90,6 +91,15 @@
9091
enableDeselect: {
9192
type: Boolean,
9293
default: false
94+
},
95+
96+
/**
97+
* When true, the first item in the list will be automatically selected
98+
* if no other item is currently selected.
99+
*/
100+
selectFirstByDefault: {
101+
type: Boolean as PropType<boolean>,
102+
default: false
93103
}
94104
});
95105

@@ -225,5 +235,13 @@
225235

226236
// Set the provider to the new one
227237
itemProvider.value = newProvider;
238+
239+
internalValues.value = [];
240+
if (props.multiple) {
241+
emit("update:modelValue", []);
242+
}
243+
else {
244+
emit("update:modelValue", null);
245+
}
228246
});
229247
</script>

Rock.JavaScript.Obsidian/Framework/Controls/treeItemPicker.obs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
:disableFolderSelection="disableFolderSelection"
1919
:autoExpand="autoExpand"
2020
:showChildCount="showChildCount"
21+
:selectFirstByDefault="selectFirstByDefault"
2122
:isVisible="internalShowPopup" />
2223

2324
<template #innerLabel><span class="selected-names">{{ selectedNames || blankValue }}</span></template>
@@ -131,6 +132,15 @@
131132
type: String as PropType<string>,
132133
default: ""
133134
},
135+
136+
/**
137+
* When true, the first item in the list will be automatically selected
138+
* if no other item is currently selected.
139+
*/
140+
selectFirstByDefault: {
141+
type: Boolean as PropType<boolean>,
142+
default: false
143+
}
134144
});
135145

136146
const emit = defineEmits<{

Rock.JavaScript.Obsidian/Framework/Controls/treeList.obs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,15 @@
9494
enableDeselect: {
9595
type: Boolean,
9696
default: false
97+
},
98+
99+
/**
100+
* When true, the first item in the list will be automatically selected
101+
* if no other item is currently selected.
102+
*/
103+
selectFirstByDefault: {
104+
type: Boolean as PropType<boolean>,
105+
default: false
97106
}
98107
});
99108

@@ -135,6 +144,7 @@
135144

136145
await nextTick();
137146
scrollToSelectedItem();
147+
trySelectFirst();
138148
}
139149
};
140150

@@ -211,11 +221,39 @@
211221
}
212222
};
213223

224+
/**
225+
* Attempts to select the first item if selectFirstByDefault is true and
226+
* no item is currently selected.
227+
*/
228+
const trySelectFirst = (): void => {
229+
if (!props.selectFirstByDefault || props.modelValue.length > 0 || internalItems.value.length === 0) {
230+
return;
231+
}
232+
233+
let itemToSelect: TreeItemBag | null = null;
234+
235+
for (const item of internalItems.value) {
236+
if (props.disableFolderSelection && (item.isFolder || item.hasChildren)) {
237+
continue;
238+
}
239+
240+
if (item.value) {
241+
itemToSelect = item;
242+
break;
243+
}
244+
}
245+
246+
if (itemToSelect && itemToSelect.value) {
247+
emit("update:modelValue", [itemToSelect.value]);
248+
}
249+
};
250+
214251
// Watch for a change in our passed items and update our internal list.
215252
watch(() => props.items, () => {
216253
// Only update if we don't have a provider.
217254
if (!props.provider) {
218255
internalItems.value = props.items ?? [];
256+
trySelectFirst();
219257
}
220258
});
221259

0 commit comments

Comments
 (0)