AutocompleteWithAPI.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <!--
  2. Liste déroulante avec autocompletion (les données sont issues
  3. d'une api)
  4. @see https://vuetifyjs.com/en/components/autocompletes/#usage
  5. -->
  6. <template>
  7. <main>
  8. <UiInputAutocomplete
  9. :field="field"
  10. :label="label"
  11. :data="remoteData ? remoteData : data"
  12. :items="items"
  13. :isLoading="isLoading"
  14. :item-text="itemText"
  15. :slotText="slotText"
  16. :item-value="itemValue"
  17. :multiple="multiple"
  18. :chips="chips"
  19. prependIcon="mdi-magnify"
  20. :return-object="returnObject"
  21. @research="search"
  22. :no-filter="noFilter"
  23. @update="$emit('update', $event, field)"
  24. />
  25. </main>
  26. </template>
  27. <script lang="ts">
  28. import {defineComponent, ref, Ref, watch, onUnmounted, toRefs, useContext, useFetch} from '@nuxtjs/composition-api'
  29. import {QUERY_TYPE} from "~/types/enums";
  30. import ModelsUtils from "~/services/utils/modelsUtils";
  31. export default defineComponent({
  32. props: {
  33. label: {
  34. type: String,
  35. required: false,
  36. default: null
  37. },
  38. field: {
  39. type: String,
  40. required: false,
  41. default: null
  42. },
  43. searchFunction: {
  44. type: Function,
  45. required: true
  46. },
  47. data: {
  48. type: [String, Number, Object, Array],
  49. required: false,
  50. default: null
  51. },
  52. remoteUri: {
  53. type: [Array],
  54. required: false,
  55. default: null
  56. },
  57. remoteUrl: {
  58. type: String,
  59. required: false,
  60. default: null
  61. },
  62. readonly: {
  63. type: Boolean,
  64. required: false
  65. },
  66. itemValue: {
  67. type: String,
  68. default: 'id'
  69. },
  70. itemText: {
  71. type: Array,
  72. required: true
  73. },
  74. slotText: {
  75. type: Array,
  76. required: false
  77. },
  78. returnObject: {
  79. type: Boolean,
  80. default: false
  81. },
  82. noFilter: {
  83. type: Boolean,
  84. default: false
  85. },
  86. multiple: {
  87. type: Boolean,
  88. default: false
  89. },
  90. chips: {
  91. type: Boolean,
  92. default: false
  93. }
  94. },
  95. setup(props) {
  96. const {data} = toRefs(props)
  97. const items = ref([])
  98. const remoteData:Ref<Array<string> | null> = ref(null)
  99. const isLoading = ref(false)
  100. const {$dataProvider} = useContext()
  101. if(props.data){
  102. items.value = props.multiple ? (data.value ?? []) : [data.value]
  103. }else if(props.remoteUri){
  104. const ids:Array<any> = []
  105. for(const uri of props.remoteUri){
  106. ids.push(ModelsUtils.extractIdFromUri(uri as string))
  107. }
  108. useFetch(async () => {
  109. isLoading.value = true
  110. const r = await $dataProvider.invoke({
  111. type: QUERY_TYPE.DEFAULT,
  112. url: props.remoteUrl,
  113. listArgs: {
  114. filters:[
  115. {key: 'id', value: ids.join(',')}
  116. ]
  117. }
  118. })
  119. isLoading.value = false
  120. remoteData.value = r.data
  121. items.value = r.data
  122. })
  123. }
  124. const search = async (research:string) => {
  125. isLoading.value = true
  126. const func: Function = props.searchFunction
  127. items.value = items.value.concat(await func(research, props.field))
  128. isLoading.value = false
  129. }
  130. const unwatch = watch(data,(d) => {
  131. items.value = props.multiple ? d : [d]
  132. })
  133. onUnmounted(() => {
  134. unwatch()
  135. })
  136. return {
  137. label_field: props.label ?? props.field,
  138. isLoading,
  139. items,
  140. remoteData,
  141. search
  142. }
  143. }
  144. })
  145. </script>