Search code examples
vue.jsvuejs3blurquasar-framework

How to react to blur/unfocus in a QCard?


I have a QCard and would like to trigger an action when it becomes inactive (loses focus)

<q-card bordered flat v-for="pill in loadedPerson?.Pills" :key="pill.ID" class="pill text-center bg-blue-1"
    @blur="updatePill">
    <q-card-section class="q-pb-none">
        <div class="text-h4 text-bold">{{ pill.Name }}</div>
    </q-card-section>
    <q-card-section class="flex row q-pt-none flex-center items-center">
        <q-input maxlength="2" size="2" dense borderless v-model="pill.Amount"
            class="text-h4 text-bold amountPills"></q-input>
        <q-icon size="xl" name="las la-plus-circle" class="cursor-pointer" @click="pill.Amount++"></q-icon>
        <q-icon size="xl" name="las la-minus-circle" class="cursor-pointer" @click="pill.Amount--"></q-icon>
    </q-card-section>
</q-card>

I expected @blur to trigger updatePill when I leave the QCard but no, nothing happens (and no relevant message is emitted either). I also tried onfocusout="updatePill" but again - no reaction.


Solution

  • None-input HTML elements do not accept focus by default. To make them focusable, specify their tabindex prop.

    <div> not focusable </div>
    <div tabindex="0"> focusable </div>
    

    At the end of the day, q-card is a div, so you can leverage the same mechanism:

    <template>
    <q-card
      bordered
      flat
      v-for="pill in loadedPerson?.Pills" :key="pill.ID"
      class="pill text-center bg-blue-1"
      @blur="updatePill(pill)"
      tabindex="0"
    >
      <q-card-section class="q-pb-none">
        <div class="text-h4 text-bold">{{ pill.Name }}</div>
      </q-card-section>
      <q-card-section class="flex row q-pt-none flex-center items-center">
        <q-input maxlength="2" size="2" dense borderless v-model="pill.Amount"
                 class="text-h4 text-bold amountPills"></q-input>
        <q-icon size="xl" name="las la-plus-circle" class="cursor-pointer" @click="pill.Amount++"></q-icon>
        <q-icon size="xl" name="las la-minus-circle" class="cursor-pointer" @click="pill.Amount--"></q-icon>
      </q-card-section>
    </q-card>
    </template>
    
    <script setup>
    const loadedPerson = {
      Pills: [
        {
          ID: '1',
          Name: 'Name 1',
          Amount: 11,
        },
        {
          ID: '2',
          Name: 'Name 2',
          Amount: 12,
        },
      ],
    };
    
    function updatePill(pill) {
      console.log('-> updatePill', pill);
    }
    </script>