# Componente

# Introducción

La funcionalidad del componente repeater es crear un input con una estructura repetible, la cual estará compuesta de otros inputs que podrán editarse. Cada repetición de esta estructura se mostrará como una fila. Podrán agregarse y eliminarse filas según se determine mediante sus propiedades.

# Uso

Es importante recalcar el nombre del componente IrRepeater a nivel de código, ya que este deberá usarse para llamar al componente para renderizarlo, ya sea individiualmente o en un IrForm. El repeater funciona normalmente bajo el uso de propiedades, por medio de estas se establecerá el funcionamiento del mismo.

# Ejemplo

# Propiedades

Propiedad Tipo Default Descripción
items_fcn String

undefined

Define una función de la capa de datos, a la cual se consultará la información para completar la propiedad items. Es de vital importancia mantener la integridad de los datos de la propiedad item con la respuesta de esta propiedad.

args_items_fcn Array

[]

Define un arreglo con los argumentos de la función items_fcn. Esta propiedad solo es útil si items_fcn está definida.

item Array

Array con la estructura de input que se repetirán, ejemplo:

[
    {
      "type": "v-text-field",
      "props": {
        "key": "/_0005",
        "readonly": false,
        "label": "Text input de prueba",
        "hint": "",
        "value": "",
        "required": true,
        "pattern": "",
        "placeholder": "",
        "title": "",
        "visible": true,
        "width": 2
      }
    },
    {
      "type": "v-text-field",
      "props": {
        "key": "/_0005",
        "readonly": false,
        "label": "Text input de prueba",
        "hint": "",
        "value": "",
        "required": true,
        "pattern": "",
        "placeholder": "",
        "title": "",
        "visible": true,
        "width": 2
      }
    },
  ]

items Array

[]

Propiedad donde se almacena el valor del repeater, es decir, que las repeticiones de la propiedad item se almacenarán aquí. Se ignora si está definida la propiedad items_fcn.

max Integer

-1

Maxima cantidad de repeticiones admisibles en items. Valor -1 quita el limite (se podrán agregar infinitas entradas). Valor 0 no permite agregar filas.

min Integer

0

Mínima cantidad de repeticiones admisibles en items, valor 0 permite no tener filas.

readonly Boolean

false

Inhabilita la opción de editar los campos en el repeater, también se inhabilita la capacidad de agregar o eliminar items.
hint String

``

Establece un texto de ayuda para el campo.
duplicate Boolean

false

Determina si se pueden duplicar o no los items. Los items duplicados se ubican al final de la lista.

# Código fuente

<template>
  <ir-repeater-bone v-bind="$attrs">
    <div slot-scope="{ hint, items, deleteItem, addButtonEvent, columnNumber, readonly, loading, moveItem, duplicateItem, duplicate, label, comportamientos, comportamientoEvents, id_resolver, valueType}"
    >
      <label v-if="label && label !== ''"
        class="v-label" style="font-size:12px;"
      >
        {{label}}
      </label>
      <template v-for="comportamiento, i in comportamientos">
        <ir-comportamiento :key="'comportamiento-repeater-prep-'+i"
          v-if="(typeof comportamiento.visible === 'undefined' || comportamiento.visible) && comportamiento.position === 'prepend'"
          :value="items"
          class="mb-2"
          v-bind="comportamiento"
          v-on="comportamientoEvents"
          :value_type="valueType"
          :father_component_name="repeaterComponentName"
          :current_id_resolver="id_resolver"
        />
      </template>
      <div style="border-radius: 4px; border: 1px solid #dddddd;">
        <table data-cy="repeater" class="rounded-lg repeater-table">
          <thead style="width: 100%">
            <tr>
              <th style="width:52px"></th>
              <th style="width: max-content;"
                valign="middle">
              </th>
              <th v-if="!readonly" style="width: 52px;">
              </th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="fila, i in items" :key="fila[0].key">
              <td :style="i == 0 ? 'border-top: none !important; border-left: none !important;' : 'border-left: none !important;'">
                <span >{{i + 1}}</span>
              </td>
              <td style="overflow:hidden;" :style="i == 0 ? 'border-top: none !important;' : ''">
              <div class="pt-2" :style="'grid-template-columns: repeat(' + columnNumber + ', minmax(0,1fr)); display: grid; grid-gap: 15px 10px;'">
                <template v-for="campo, x in fila">
                  <ir-component-resolver :json_resolver="{id_usuario: $iclstore.state.id_usuario}" :dev_components="[campo]" v-on="$listeners" v-if="campo.props.visible" :key="x" :style="'grid-column: span ' + campo.props.width+ ' / span ' + campo.props.width+ ' !important;'"/>
                </template>
              </div>
              </td>
              <td v-if="!readonly" style="position: relative;" :style="i == 0 ? 'border-top: none !important; border-right: none !important;' : 'border-right: none !important;'">
                <v-tooltip v-if="duplicate" bottom>
                  <template v-slot:activator="{ on, attrs }">
                    <v-icon v-bind="attrs" v-on="on" @click="duplicateItem(fila)">mdi-card-multiple-outline</v-icon>
                  </template>
                  <span>Duplicar item</span>
                </v-tooltip>
                <v-tooltip v-if="i !== 0" bottom>
                  <template v-slot:activator="{ on, attrs }">
                    <v-icon v-bind="attrs" v-on="on" @click="moveItem(i, fila)">mdi-arrow-up-circle</v-icon>
                  </template>
                  <span>Subir item</span>
                </v-tooltip>
                <v-tooltip bottom>
                  <template v-slot:activator="{ on, attrs }">
                    <v-icon v-bind="attrs" v-on="on" @click="deleteItem(i)" data-cy="remove-item">mdi-minus-circle</v-icon>
                  </template>
                  <span>Borrar item</span>
                </v-tooltip>
                <v-tooltip v-if="i !== items.length - 1" bottom>
                  <template v-slot:activator="{ on, attrs }">
                    <v-icon v-bind="attrs" v-on="on" @click="moveItem(i, fila, false)">mdi-arrow-down-circle</v-icon>
                  </template>
                  <span>Bajar item</span>
                </v-tooltip>
              </td>
            </tr>
          </tbody>
          <tfoot style="width: 100%" v-if="!readonly">
            <tr @click="addButtonEvent()" data-cy="add-item" style="cursor: pointer;">
              <td style="width:52px"></td>
              <td v-if="!readonly" valign="middle">
                <div class="d-flex justify-center">
                  <v-icon small class="mr-2">mdi-plus-thick</v-icon>
                  <span class="font-weight-bold">Agregar item</span>
                </div>
              </td>
              <td >
              </td>
            </tr>
          </tfoot>
        </table>
      </div>
      <template v-for="comportamiento, i in comportamientos">
        <ir-comportamiento :key="'comportamiento-repeater-append-'+i"
          v-if="(typeof comportamiento.visible === 'undefined' || comportamiento.visible) && comportamiento.position === 'append'"
          class="mt-2"
          :value="items"
          v-bind="comportamiento"
          v-on="comportamientoEvents"
          :value_type="valueType"
          :father_component_name="repeaterComponentName"
          :current_id_resolver="id_resolver"
        />
      </template>
      <v-progress-linear
        v-if="loading"
        indeterminate
        style="width:100%;"
        color="primary"
      ></v-progress-linear>
      <p v-if="hint!==''" class="tw-text-secondary tw-text-xs">
      {{hint}}
      </p>
    </div>
  </ir-repeater-bone>
</template>

<script>
import { repeaterComponentName } from '../../../constants'
import IrInputResolver from '../IrInputResolver/IrInputResolver.vue'
import IrRepeaterBone from './IrRepeaterBone.vue'
export default {
  name:repeaterComponentName,
  components: {
    IrRepeaterBone,
    IrInputResolver,
  },
  data(){
    return{
      repeaterComponentName: repeaterComponentName
    }
  }
}
</script>

<style>
.repeater-table tbody td{
  border: solid 1px #dddddd !important;
}
.repeater-table th{
  padding: 0px;
}
.repeater-table tfoot td{
  border-top: solid 1px #dddddd !important;
}
.repeater-table tfoot tr:hover td{
  background: #f5f5f5 !important;
}
.repeater-table tfoot tr:hover td:last-child{
  background: #f5f5f5 !important;
  border-radius: 0px 0px 4px 0px;
}
.repeater-table tfoot tr:hover td:first-child{
  background: #f5f5f5 !important;
  border-radius: 0px 0px 0px 4px;
}
.repeater-table{
  border-radius: 4px !important;
  border-collapse: collapse !important;
  width: 100%;
}
</style>
Last Updated: 4/5/2024, 4:52:19 PM