AppAutoComplete.vue 2.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. <script setup>
  2. import { computed } from 'vue'
  3. import { Inertia } from '@inertiajs/inertia'
  4. const props = defineProps({
  5. label: {
  6. type: String,
  7. required: true,
  8. },
  9. labelClass: {
  10. type: String,
  11. },
  12. disabled: {
  13. type: Boolean,
  14. default: false,
  15. },
  16. placeholder: {
  17. type: String,
  18. required: true,
  19. },
  20. error: {
  21. type: String,
  22. default: null,
  23. },
  24. field: {
  25. type: String,
  26. required: true,
  27. },
  28. empty: {
  29. type: Boolean,
  30. default: false,
  31. },
  32. refreshData: {
  33. type: String,
  34. required: true,
  35. },
  36. suggestions: {
  37. type: Array,
  38. required: true,
  39. },
  40. modelValue: null,
  41. })
  42. const emit = defineEmits(['update:modelValue'])
  43. const isError = computed(() => (props.error ? true : false))
  44. const forLabel = computed(() => props.label.toLowerCase().replace(/\s+/g, '-'))
  45. const ariaDescribedbyLabel = computed(
  46. () => props.label.toLowerCase().replace(/\s+/g, '-') + '-error'
  47. )
  48. const onComplete = (event) => {
  49. Inertia.reload({
  50. data: {
  51. [props.refreshData.slice(0, -1)]: event.query,
  52. },
  53. only: [props.refreshData],
  54. })
  55. }
  56. const onSelect = (event) => {
  57. emit('update:modelValue', event.value)
  58. }
  59. </script>
  60. <template>
  61. <div class="field">
  62. <label :for="forLabel" :class="labelClass">{{ label }}</label>
  63. <AutoComplete
  64. forceSelection
  65. class="w-full"
  66. inputClass="w-full"
  67. :model-value="modelValue"
  68. :id="forLabel"
  69. :class="{ 'p-invalid': isError }"
  70. :field="field"
  71. :placeholder="placeholder"
  72. :suggestions="suggestions"
  73. :auto-highlight="true"
  74. :disabled="disabled"
  75. @input="$emit('update:modelValue', $event.target.value)"
  76. @item-select="onSelect"
  77. @complete="onComplete"
  78. >
  79. <template #item="slotProps">
  80. <slot name="item" :item="slotProps.item" />
  81. </template>
  82. </AutoComplete>
  83. <div class="flex flex-column">
  84. <small
  85. v-if="error"
  86. class="mt-1"
  87. :class="{
  88. 'mb-2': empty,
  89. 'p-error': isError,
  90. }"
  91. :id="ariaDescribedbyLabel"
  92. >
  93. {{ error }}
  94. </small>
  95. <small v-if="empty" class="mt-1">
  96. <slot name="empty" />
  97. </small>
  98. </div>
  99. </div>
  100. </template>