How to do validation for <q-select> using vee-validate? - vuejs2

Below is the example on which I want to check the validation(select at least one of the option).
<q-select
multiple
inverted
color="dark"
stack-label="Roles"
separator
v-model="multipleSelect"
:options="options1"
v-validate="'required|in:x-builder,rt-builder,commune,matrix,blade-runner,optocoupler,admin'"
/>
<div class="containerError"> <i v-show="errors.has('role')" class="fa fa-warning"></i>
<span v-show="errors.has('role')" class="text-negative text-right">{{ errors.first('role') }}</span>
</div>

Related

Vue JS: How to make two Vue Instances to work together on the same page?

I created a recipe website, you can find it here https://hungry-vegetarian.com/.
The tab on the index page is a vue instance. I'm trying to create a search bar that is also a vue instance.
The problem occurs when I try to display searched recipes on the index page. It just shows the search result on top of the search bar.
Ideally, only searched recipes should appear on the tab just like they are now but without any indications on top of the tab like Breakfast, Salad, Bakery, etc.
I don't know how to make two objects work together. For now, they work separately without communicating with each other.
SEARCH
<div id="search">
<div class="main-search">
<h1 class="search-question">What are you in the mood for?</h1>
<div class="search-box">
<input type="text" v-model="searchQuery" class="input-search" placeholder="Bread">
<button class="btn-search"><i class="fa fa-search"></i></button>
</div>
</div>
<div class="container">
<div class="recipe" v-for="post in filteredList">
<div v-if="searchQuery">
<a v-bind:href="post.url" class="recipe-card__card-link" target="_blank">
<img v-bind:src="post.image" alt="" class="recipe-card__image"/>
<div class="recipe-card__text-wrapper">
<h2 class="recipe-card__title">{{post.name}}</h2>
<div class="recipe-card__details-wrapper">
<p class="recipe-card__excerpt">{{post.body}}</p>
<a v-bind:href="post.url" class="recipe-card__read-more">Read more <i class="fa fa-arrow-right"></i></a>
</div>
</div>
</a>
</div>
</div>
</div>
</div>
</div>
tab
<main id="tab">
<header>
<nav>
<ul>
<div id="arrow">
<span></span>
<span></span>
<span></span>
</div>
<li v-for="(tab, tabName) in tabs" :key="tabName">
<button class="tab" #click="setTabActive(tabName)" :class="{'active': tabName === activeTab}">
<span class="tab-copy">{{ tabName }}</span>
<span class="tab-background">
</span>
</button>
</li>
</ul>
</nav>
</header>
<article>
<div class="container">
<transition name="fade" mode="out-in" appear :duration="500">
<tab-content v-for="(tabContent, t) in tabs" :data="tabContent" :key="'content'+t" v-if="t === activeTab" inline-template>
<div class="content-wrapper">
<div class="recipes" v-for="(recipe, i) in data.recipes" :key="i">
<a v-bind:href="recipe.url" class="recipe-card__card-link"></a>
<img :src="recipe.image" alt="" class="recipe-card__image">
<div class="recipe-card__text-wrapper">
<h2 class="recipe-card__title">{{recipe.name}}</h2>
<div class="recipe-card__details-wrapper">
<p class="recipe-card__excerpt">{{recipe.body}}</p>
<a v-bind:href="recipe.url" class="recipe-card__read-more">Read more <i class="fa fa-arrow-right"></i></a>
</div>
</div>
</div>
</div>
</tab-content>
</transition>
</div>
</article>
</main>
I tried to combine instances search and tab into just one instance tab, but it always gives me a Vue warning:
[Vue warn]: Property or method "searchQuery" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.
Also, I feel like I can have just the wrong approach to this problem I am trying to solve. Please, any suggestions are welcome. I am stuck.

add an icon next to each row in the table using bootstrap vue?

I have a table that uses bootstrap Vue's table. Each row of the table corresponds to an item. My current problem is I need to add an icon next to each row, and display them every time I hover over that row, and then do some function when I click on this icon. But I can't find a way to add an icon. I have tried following the instructions on https://bootstrap-vue.org/docs/components/table with using slots but it only works for #head and #cell. Need an idea on this issue. This is my code and a picture describe my problem
<b-table
ref="table"
class="minh--30 mh--100 overflow-y-auto"
bordered
responsive
:items="items"
:fields="fields"
>
<template #head()="data">
<span>{{ $t(data.field.label) }}</span>
</template>
<template #cell(field)="data">
<span
v-if="data.item.isDrag"
class="d-block p-3"
>{{ data.item.field }}</span>
<b-dropdown
v-else
right
no-caret
variant="white"
class="minw--40 w-100"
menu-class="w-100 mh--24 overflow-auto minw-unset"
>
<template #button-content>
<div
class="flex-center minh--11 text-normal position-relative px-2"
>
<span class="pr-5 word-break text-line-clamp-1">{{ data.item.field }}</span>
<i
class="fas fa-chevron-down position-absolute top-50 end--1 translate-middle-y px-2"
/>
</div>
</template>
<b-dropdown-item
v-for="item in listField"
:key="item.id"
variant="normal py-2"
class="fs-12 fs-xl-15"
#click="selectField(item, data)"
>
<span class="word-break text-line-clamp-1">{{ $t(item.text) }}</span>
</b-dropdown-item>
</b-dropdown>
</template>
<template #cell(action)="data">
<b-dropdown
right
no-caret
variant="white"
class="minw--40 w-100"
menu-class="w-100 mh--24 overflow-auto minw-unset"
>
<template #button-content>
<div
class="flex-center minh--11 text-normal position-relative px-2"
>
<span class="pr-5 word-break text-line-clamp-1">{{ data.item.action }}</span>
<i
class="fas fa-chevron-down position-absolute top-50 end--1 translate-middle-y px-2"
/>
</div>
</template>
<b-dropdown-item
v-for="item in listDropdown"
:key="item.id"
variant="normal py-2"
class="fs-12 fs-xl-15"
#click="selectItem(item, data)"
>
<span class="word-break text-line-clamp-1">{{ $t(item.text) }}</span>
</b-dropdown-item>
</b-dropdown>
</template>
<template #cell(selectCharacter)="data">
<b-dropdown
right
no-caret
variant="white"
class="minw--40 w-100"
menu-class="w-100 mh--24 overflow-auto minw-unset"
>
<template #button-content>
<div
class="flex-center minh--11 text-normal position-relative px-2"
>
<span class="pr-5 word-break text-line-clamp-1">{{ data.item.selectCharacter }}</span>
<i
class="fas fa-chevron-down position-absolute top-50 end--1 translate-middle-y px-2"
/>
</div>
</template>
<b-dropdown-item
v-for="item in listCharacter"
:key="item.id"
variant="normal py-2"
class="fs-12 fs-xl-15"
#click="selectCharacter(item, data)"
>
<span class="word-break text-line-clamp-1">{{ $t(item.text) }}</span>
</b-dropdown-item>
</b-dropdown>
</template>
<template #cell(inputCharacter)="data">
<input
v-model="data.item.inputCharacter"
type="text"
class="form-control h--11 border-0"
>
</template>
<template #cell(startPosition)="data">
<input
v-model="data.item.startPosition"
type="number"
class="form-control h--11 border-0"
>
</template>
<template #cell(characterCount)="data">
<input
v-model="data.item.characterCount"
type="number"
class="form-control h--11 border-0"
>
</template>
<template #cell(needReplace)="data">
<input
v-model="data.item.needReplace"
type="text"
class="form-control h--11 border-0"
>
</template>
<template #cell(replace)="data">
<input
v-model="data.item.replace"
type="text"
class="form-control h--11 border-0"
>
</template>
<template #cell(delete)="data">
<div class="flex-center pt-1">
<input
v-if="!data.item.isDrag"
v-model="data.item.delete"
type="checkbox"
>
</div>
</template>
</b-table>
Based on reading the documentation, the table component wasn't designed for this use case because you are adding icons that are outside of the table itself.
One alternative would be to use the grid system https://bootstrap-vue.org/docs/components/layout#layout-and-grid-system to create one narrow column on the left for the icons and one wide column on the right for the table. In the narrow column, you could create rows that are exactly the height of each row of the table so that the items stay aligned with each row.
Another alternative would be to use the #cell slot, and put an element inside that uses CSS, possibly the transform property (https://www.w3schools.com/cssref/css3_pr_transform.asp), to make the element appear to the left of where it really is.

Added vuejs variable to html tag

I am trying to use this dropdown list
https://bootstrap-vue.js.org/docs/components/collapse/
<div>
<b-btn v-b-toggle.collapse1 variant="primary">Toggle Collapse</b-btn>
<b-collapse id="collapse1" class="mt-2">
<b-card>
<p class="card-text">Collapse contents Here</p>
</b-card>
</b-collapse>
</div>
but instead i'm using a v-for to create multiple drop down boxes. Obviously I need a unique identifier to distinguish which drop down was clicked. Which is this code v-b-toggle.collapse1 and id=collapse1.
I can get the id to work with v-bind:id but I don't know how (Or if it's possible) to add my custom variable to v-b-toggle.collapse1.
Here is what I am trying to do:
<div role="tablist" class="client_contacts">
<h2>Clients</h2>
<div v-for="clients in getClientContacts">
<b-btn block href="#" v-b-toggle.{{clients.id}} variant="info" role="button">
{{ clients.first_name }} {{ clients.last_name }}
</b-btn>
<b-collapse v-bind:id="clients.id" accordion="my-accordion" role="tabpanel">
<p class="card-text">
Some test text
</p>
</b-collapse>
</div>
</div>
Is it possible to use variables in tags without an id, class, href etc tag?
Thanks
This works for me.
<div v-for="clients in getClientContacts">
<b-btn block href="#" v-b-toggle="'accordion-' + clients.first_name" variant="info">
{{ clients.first_name }} {{ clients.last_name }}
</b-btn>
<b-collapse :id="'accordion-' + clients.first_name" accordion="my-accordion" role="tabpanel">
<p class="card-text">
I start opened because <code>visible</code> is <code>true</code>
</p>
</b-collapse>
</div>
https://github.com/bootstrap-vue/bootstrap-vue/issues/1420

How to autogenerate name using first name and last name using quasar

Here i have 2 names, firstname & lastname. How do i autogenerate a different name using first and last names
(eg: firstname.lastname or firstname_lastname)
<q-input name="firstname" v-model="first" float-label="First name"
v-validate="'required|alpha_spaces'" clearable/>
<i v-show="errors.has('firstname')" class="fa fa-warning "></i>
<div class="containerError">
<span v-show="errors.has('firstname')" class="text-negative text-right">{{ errors.first('firstname') }}</span>
</div>
<q-input name="lastname" required="required" v-model="last" float-label="Last name" v-validate="'required|alpha_spaces'" clearable />
<i v-show="errors.has('lasttname')" class="fa fa-warning "></i>
<div class="containerError"> <span v-show="errors.has('lastname')" class="text-negative text-right">{{ errors.first('lastname') }}</span>
</div>
<template>
<div v-if="this.last != ''" float-label="fullname">
User-name :{ {this.first}}.{{this.last}}
</div>
</template>

How to detect wheter search input focused or not in vue-instantsearch?

In my component Search.vue I need to detect whether search input focused or not in order to hide search results if cursor is elsewhere
I used vue-instantsearch
Here is the code of my custome component's template section
<template>
<ais-index index-name="getstarted_actors" :search-store="searchStore">
<div class="col-md-10 col-sm-9">
<ais-search-box :autofocus="true">
<div class="input-group" ref="searchInputGroup">
<ais-input placeholder="Find books..."
:class-names="{'ais-input': 'form-control'}" autofocus="true" >
</ais-input>
<span class="input-group-btn">
<ais-clear :class-names="{'ais-clear': 'btn btn-default'}">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</ais-clear>
<button class="btn btn-default" type="submit">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span>
</button>
</span>
</div>
</ais-search-box>
<ais-results v-show="searchStore.query.length > 0">
<template scope="{ result }">
<div v-on:click="searchResultClick(result)" class="found-item">
<a> <span>{{ result.name }}</span> <span>{{ result.rating }}</span></a><br/>
</div>
</template>
</ais-results>
</div>
</ais-index>
</template>
You can try:
<ais-input placeholder="Find books..."
:class-names="{'ais-input': 'form-control'}" autofocus="true"
#focus="onFocus"
>
</ais-input>
and your methods:
methods: {
onFocus() { console.log('Focused') }
}