# Componente
# Introducción
Este componente renderizará un input de tipo text field. El mismo se compone de dos partes, una de renderizado y otra de lógica (IrTextField Bone), esta ultima será la encargada de el manejo de los datos.
# Uso
Es importante recalcar el nombre del componente IrTextField a nivel de código, ya que este deberá usarse para llamar al componente para renderizarlo, ya sea individiualmente o en un IrForm.
# Ejemplo
# Propiedades
| Propiedad | Tipo | Default | Descripción |
| readonly | Boolean |
| El valor |
| linked | String | Boolean | false | Determina la actualización del formulario contenedor cuando se cambia de valor del componente. Valores posibles: |
| value | String | String que almacenará los valores ingresados en el componente. | |
| required | Boolean |
| En valor |
| placeholder | String |
| Establece el placeholder en el campo. |
| pattern | String |
| Un String que defina una expresión regular que deberá cumplir el input para ser válido. En caso de no poderse enviar |
| hint | Object | String |
| Genera un texto de ayuda para el componente, que podrá ser o no, clickeable para navegar a un link determinado.
En el caso de que se envíe un hint, la propiedad Propiedad con estructura de objeto con los siguientes keys: En la propiedad En la propiedad En la propiedad En la propiedad Las clases aplicables para las filas de la tabla podrán encontrarse en Vuetify en los siguientes enlaces:
|
| mask | String | | Determina un formato que cumplirá el texto introducido en el campo. Por ejemplo siendo mask = "999-999" el valor ingresado se forzará a ser algo como 333-333. El patron se define con los siguientes 3 caracteres: 9 para números, A para letras y S para alfanuméricos. El resto de los caracteres ingresados será tomado como tal. |
| money | Object | | Determina un formato que cumplirá el valor introducido en el campo. Este formato será definido por: |
# Código fuente
<template>
<ir-text-field-bone
v-bind="$attrs"
:value="value"
v-on="$listeners"
@input="(e) => $emit('input', e)"
>
<div
slot-scope="{
inputEvents,
placeholder,
vallocal,
readonly,
rules,
hideDetails,
label,
comportamientos,
comportamientosPositions,
valueType,
id_resolver,
comportamientoEvents,
disabled,
linked,
maskHandler
}"
>
<ir-label
v-if="isOutlined"
:label="label"
:error="hasError"
:disabled="disabled"
:readonly="readonly"
/>
<v-text-field
ref="irTextFieldDOM"
v-model="vallocal"
type="text"
:name="'text-field-' + label"
class="pt-0 align-center"
v-bind="getFilteredProps"
:placeholder="placeholder"
:hide-details="hideDetails"
:rules="rules"
:readonly="readonly"
:label="isOutlined ? undefined : label"
:disabled="readonly || disabled"
@input="maskHandler($event, irTextFieldDOM)"
@blur="emitLinked(linked, comportamientoEvents['change-linked-value'])"
@update:error="setError"
@keydown.enter.prevent="
enterManager(
comportamientos,
linked,
comportamientoEvents['change-linked-value']
)
"
v-on="inputEvents"
>
<template #message="{ message }">
<div v-html="message" />
</template>
<template
v-for="(position, k) in comportamientosPositions"
#[position]
>
<div
:key="'slot-comportamientos-tf-' + k"
class="d-flex align-center"
style="gap: 10px"
>
<template v-for="(comportamiento, i) in comportamientos">
<ir-comportamiento
v-if="
(typeof comportamiento.visible === 'undefined' ||
comportamiento.visible) &&
comportamiento.position === position
"
:key="'comportamiento-textfield-' + i"
:ref="'comportamiento' + i"
v-bind="comportamiento"
:value="vallocal"
:value_type="valueType"
:father_component_name="textFieldComponentName"
:current_id_resolver="id_resolver"
v-on="comportamientoEvents"
/>
</template>
</div>
</template>
<template
v-if="readonly && !localValue"
#prepend-inner
>
<div class="pr-2">
<v-icon color="warning"> mdi-alert-circle </v-icon>
</div>
</template>
</v-text-field>
</div>
</ir-text-field-bone>
</template>
<script>
import { ref, watch, onMounted, computed } from 'vue'
import IrTextFieldBone from './IrTextFieldBone.vue'
import { textFieldComponentName } from '../../../constants'
import { setHintTag } from '../../../helpers/hint'
import { isOutlined } from '../../../helpers/utils.js'
import focusAndScrollMixin from '../../../mixins/focusAndScroll'
import { filterProps } from '../../../helpers/filterProps'
export default {
name: textFieldComponentName,
components: {
IrTextFieldBone
},
inheritAttrs: false,
props: {
value: {
type: String,
required: true
},
isFocused: {
type: Boolean,
default: false
},
hint: {
type: [String, Object],
default: ''
}
},
setup(props, { emit, attrs }) {
const { focusAndScroll } = focusAndScrollMixin.methods
const isOutlinedHelper = isOutlined
const irTextFieldDOM = ref(null)
const comportamiento0 = ref(null) // Declaración de const para ref del DOM, no cambiar nombre.
const localValue = ref(props.value)
const otherProps = ref({})
const hasError = ref(false)
const previousValue = ref(props.value)
const filteredProps = filterProps(irTextFieldDOM.value, otherProps, [
'data-cy'
])
const updateLocalValue = (value) => {
localValue.value = value
emit('input', value)
}
const emitLinked = (linked, linkedEvent) => {
const isDifferentValue = previousValue.value !== props.value
previousValue.value = props.value
if (linked && linkedEvent && isDifferentValue) {
linkedEvent()
}
}
const enterManager = (comportamientos, linked, linkedEvent) => {
const isComps = comportamientos ? comportamientos.length === 1 : false
const comp = isComps ? comportamiento0.value : null
if (comp && comp[0] && comp[0].clickComportamiento) {
comp[0].clickComportamiento()
} else {
emitLinked(linked, linkedEvent)
}
}
const setError = (eventValue) => {
hasError.value = eventValue
}
watch(localValue, (newValue) => {
emit('input', newValue)
})
watch(
() => props.value,
(newValue) => {
localValue.value = newValue
}
)
onMounted(() => {
if (props.isFocused) {
const element = irTextFieldDOM.value.$el.querySelector('input')
focusAndScroll(element)
}
otherProps.value = { ...attrs.props }
if (otherProps.value.hint && typeof otherProps.value.hint === 'string') {
otherProps.value['hide-details'] = false
}
})
const isOutlinedLocal = computed(() => {
return isOutlinedHelper(otherProps.value.outlined)
})
const handledAttrs = computed(() => {
const hint = setHintTag(otherProps.value, props.hint)
let aux = { ...otherProps.value, ...attrs }
delete aux.hint
if (hint) {
aux = { ...aux, hint }
}
delete aux.placeholder
delete aux.readonly
delete aux.rules
delete aux.pattern
delete aux.required
delete aux.value
delete aux.type
delete aux.label
delete aux.name
return aux
})
const getFilteredProps = computed(() => {
return filterProps(irTextFieldDOM.value, handledAttrs.value, ['data-cy'])
})
return {
textFieldComponentName,
localValue,
irTextFieldDOM,
filteredProps,
hasError,
updateLocalValue,
emitLinked,
enterManager,
setError,
isOutlined: isOutlinedLocal,
handledAttrs,
getFilteredProps,
comportamiento0
}
}
}
</script>
<style scoped lang="scss"></style>