Browse Source

support sorting on autocomplete

chenxin0723 1 year ago
parent
commit
c4a7a2e6c9

+ 16 - 6
vuetifyx/autocomplete-fix.go

@@ -18,7 +18,7 @@ func VXAutocomplete(children ...h.HTMLComponent) (r *VXAutocompleteBuilder) {
 	r = &VXAutocompleteBuilder{
 	r = &VXAutocompleteBuilder{
 		tag: h.Tag("vx-autocomplete").Children(children...),
 		tag: h.Tag("vx-autocomplete").Children(children...),
 	}
 	}
-	r.Multiple(true)
+	r.Multiple(true).Chips(true).DeletableChips(true).Clearable(true)
 
 
 	return
 	return
 }
 }
@@ -28,11 +28,6 @@ func (b *VXAutocompleteBuilder) ErrorMessages(v ...string) (r *VXAutocompleteBui
 	return b
 	return b
 }
 }
 
 
-func (b *VXAutocompleteBuilder) Items(v interface{}) (r *VXAutocompleteBuilder) {
-	b.items = v
-	return b
-}
-
 func (b *VXAutocompleteBuilder) FieldName(v string) (r *VXAutocompleteBuilder) {
 func (b *VXAutocompleteBuilder) FieldName(v string) (r *VXAutocompleteBuilder) {
 	b.tag.Attr(web.VFieldName(v)...)
 	b.tag.Attr(web.VFieldName(v)...)
 	return b
 	return b
@@ -43,6 +38,21 @@ func (b *VXAutocompleteBuilder) SelectedItems(v interface{}) (r *VXAutocompleteB
 	return b
 	return b
 }
 }
 
 
+func (b *VXAutocompleteBuilder) HasIcon(v bool) (r *VXAutocompleteBuilder) {
+	b.tag.Attr("has-icon", v)
+	return b
+}
+
+func (b *VXAutocompleteBuilder) Sorting(v bool) (r *VXAutocompleteBuilder) {
+	b.tag.Attr("sorting", v)
+	return b
+}
+
+func (b *VXAutocompleteBuilder) Items(v interface{}) (r *VXAutocompleteBuilder) {
+	b.items = v
+	return b
+}
+
 func (b *VXAutocompleteBuilder) SetDataSource(ds *AutocompleteDataSource) (r *VXAutocompleteBuilder) {
 func (b *VXAutocompleteBuilder) SetDataSource(ds *AutocompleteDataSource) (r *VXAutocompleteBuilder) {
 	b.tag.Attr("remote-url", ds.RemoteURL)
 	b.tag.Attr("remote-url", ds.RemoteURL)
 	b.tag.Attr("event-name", ds.EventName)
 	b.tag.Attr("event-name", ds.EventName)

File diff suppressed because it is too large
+ 0 - 0
vuetifyx/vuetifyxjs/dist/vuetifyxjs.umd.min.js


+ 115 - 64
vuetifyx/vuetifyxjs/src/components/Autocomplete.tsx

@@ -1,4 +1,5 @@
 import Vue, { CreateElement, VNode, VNodeData } from 'vue';
 import Vue, { CreateElement, VNode, VNodeData } from 'vue';
+import draggable from 'vuedraggable';
 import { VAutocomplete, VPagination } from 'vuetify/lib';
 import { VAutocomplete, VPagination } from 'vuetify/lib';
 import { Core, SelectedItems, slotTemplates } from './Helpers';
 import { Core, SelectedItems, slotTemplates } from './Helpers';
 
 
@@ -7,6 +8,7 @@ export default Vue.extend({
 	components: {
 	components: {
 		vpagination: VPagination,
 		vpagination: VPagination,
 		vautocomplete: VAutocomplete,
 		vautocomplete: VAutocomplete,
+		vdraggable: draggable,
 	},
 	},
 
 
 	props: {
 	props: {
@@ -17,6 +19,7 @@ export default Vue.extend({
 		cacheItems: Boolean,
 		cacheItems: Boolean,
 		hideSelected: Boolean,
 		hideSelected: Boolean,
 		hideDetails: Boolean,
 		hideDetails: Boolean,
+		sorting: Boolean,
 		items: {
 		items: {
 			type: Array,
 			type: Array,
 			default: () => ([]),
 			default: () => ([]),
@@ -71,6 +74,33 @@ export default Vue.extend({
 				this.loadRemoteItems();
 				this.loadRemoteItems();
 			}
 			}
 		},
 		},
+		changeStatus(vals: any) {
+			const cachedSelectedItems: any[] = [];
+			vals.forEach((val: any) => {
+				this.listItems.forEach((item: any) => {
+					if (val == item.value) {
+						cachedSelectedItems.push(item);
+						return;
+					}
+				})
+			})
+
+			this.cachedSelectedItems = (cachedSelectedItems) as [];
+			this.value = vals;
+			this.$emit("change", vals);
+		},
+		removeItem(v: any) {
+			return () => {
+				this.value = this.value.filter(element => element != v);
+				this.changeStatus(this.value);
+			}
+		},
+		changeOrder(vs: any){
+			this.cachedSelectedItems = vs
+			const vals = this.cachedSelectedItems.map((item: any) => item.value)
+			this.value = vals as any;
+			this.$emit('change', vals);
+		},
 	},
 	},
 
 
 	created() {
 	created() {
@@ -106,7 +136,6 @@ export default Vue.extend({
 	render(h: CreateElement): VNode {
 	render(h: CreateElement): VNode {
 		const {
 		const {
 			remoteUrl,
 			remoteUrl,
-			multiple,
 			hideDetails,
 			hideDetails,
 		} = this.$props;
 		} = this.$props;
 
 
@@ -116,6 +145,7 @@ export default Vue.extend({
 		} = this.$props
 		} = this.$props
 
 
 		const slots: VNode[] = slotTemplates(h, this.$slots);
 		const slots: VNode[] = slotTemplates(h, this.$slots);
+
 		if (remoteUrl) {
 		if (remoteUrl) {
 			hideSelected = true;
 			hideSelected = true;
 			cacheItems = false;
 			cacheItems = false;
@@ -170,84 +200,71 @@ export default Vue.extend({
 					</template>
 					</template>
 				)
 				)
 			}
 			}
+		}
 
 
-			if (this.hasIcon){
-				this.$scopedSlots["item"] = (props: any)  => {
-					const nodes: VNode[] = [];
-					nodes.push(
-						<v-list-item-avatar tile>
-							<img src={props.item.icon}/>
-						</v-list-item-avatar>
-					)
-					nodes.push(
-						<v-list-item-content>
-							<v-list-item-title v-html={props.item.text}>{props.item.text}</v-list-item-title>
-						</v-list-item-content>
-					)
-					return nodes;
-				}
+		if (this.hasIcon){
+			this.$scopedSlots["item"] = (props: any)  => {
+				const nodes: VNode[] = [];
+				nodes.push(
+					<v-list-item-avatar tile>
+						<img src={props.item.icon}/>
+					</v-list-item-avatar>
+				)
+				nodes.push(
+					<v-list-item-content>
+						<v-list-item-title v-html={props.item.text}>{props.item.text}</v-list-item-title>
+					</v-list-item-content>
+				)
+				return nodes;
+			}
+		}
 
 
-				this.$scopedSlots["selection"] = (props: any)  => {
-					const nodes: VNode[] = [];
-					const nodeData: VNodeData = {
-						props: {
-							...props.attrs,
-							close: true,
-						},
-						on: {
-							"click:close": () => {
-								this.value.splice(this.value.indexOf(props.item.value as never), 1)
-								this.$emit("change", this.value);
-							},
+		if (this.$attrs.chips && (this.hasIcon || remoteUrl)){
+			this.$scopedSlots["selection"] = (props: any)  => {
+				const nodes: VNode[] = [];
+				const nodeData: VNodeData = {
+					props: {
+						...props.attrs,
+						close: true,
+					},
+					on: {
+						"click:close": () => {
+							this.value.splice(this.value.indexOf(props.item.value as never), 1)
+							this.changeStatus(this.value);
 						},
 						},
-
-					}
-					nodes.push(
-					<v-chip {...nodeData}>
-						<v-avatar left>
-							<v-img src={props.item.icon}></v-img>
-						</v-avatar>
-						{props.item.text}
-					</v-chip>
-					)
-					return nodes;
+					},
 				}
 				}
+				nodes.push(
+				<v-chip {...nodeData}>
+					{ this.hasIcon ?
+					<v-avatar left>
+						<v-img src={props.item.icon}></v-img>
+					</v-avatar>
+					: null }
+					{props.item.text}
+				</v-chip>
+				)
+				return nodes;
 			}
 			}
 		}
 		}
 
 
-		const data: VNodeData = {
+		const autocompleteData: VNodeData = {
 			props: {
 			props: {
-				...{
-					// solo: true,
-					multiple,
-					chips: true,
-					deletableChips: multiple,
-					clearable: true,
-					hideSelected,
-					cacheItems,
-					hideDetails,
-				},
 				...this.$attrs,
 				...this.$attrs,
+				...this.$props,
 				...{
 				...{
 					items: this.listItems,
 					items: this.listItems,
 					value: this.value,
 					value: this.value,
 					loading: this.isLoading,
 					loading: this.isLoading,
+					hideSelected,
+					cacheItems,
+					hideDetails,
 				},
 				},
 			},
 			},
 
 
 			on: {
 			on: {
 				...{
 				...{
-					change: (vals: any) => {
-						const items: any[] = [];
-						this.listItems.forEach((item: any) => {
-							if (vals.includes(item.value)) {
-								items.push(item);
-							}
-						})
-						this.cachedSelectedItems = (items) as [];
-						this.value = vals;
-						this.$emit("change", vals);
-					},
+					change: this.changeStatus,
 					focus: (e: any) => {
 					focus: (e: any) => {
 						this.searchKeyword = '';
 						this.searchKeyword = '';
 					},
 					},
@@ -260,11 +277,45 @@ export default Vue.extend({
 				...this.$scopedSlots,
 				...this.$scopedSlots,
 			}
 			}
 		};
 		};
+
 		return (
 		return (
-			<vautocomplete {...data}>
-				{slots}
+		<div>
+			{(this.sorting && this.cachedSelectedItems.length>0)  ?
+			<v-card>
+				<v-list>
+					<vx-draggable animation='300' handle='.handle' value={this.cachedSelectedItems} onInput={this.changeOrder}>
+					{this.cachedSelectedItems.map((item: any, i) => {
+						return (
+						<div key={item.value}>
+							<v-list-item>
+							{this.hasIcon ?
+								<v-list-item-avatar tile>
+									<v-img src={item.icon}></v-img>
+								</v-list-item-avatar>
+								: null}
+								<v-list-item-content>
+									<v-list-item-title>{item.text}</v-list-item-title>
+								</v-list-item-content>
+								<v-list-item-icon>
+									<v-btn icon="true">
+										<v-icon onClick={this.removeItem(item.value)}>delete</v-icon>
+									</v-btn>
+									<v-icon class="handle">reorder</v-icon>
+								</v-list-item-icon>
+							</v-list-item>
+							{i < this.cachedSelectedItems.length - 1 ? <v-divider key={i}></v-divider> : null}
+						</div>
+						)
+					})}
+					</vx-draggable>
+				</v-list>
+			</v-card>
+			: null}
+			<vautocomplete {...autocompleteData}>
+			{slots}
 			</vautocomplete>
 			</vautocomplete>
+		</div>
 		);
 		);
 	},
 	},
-});
+})
 
 

Some files were not shown because too many files changed in this diff