ion-input component (required, size) properties not working - vue.js

Currently I am working on PWA project. In that I am using ionic-vue package. I am using ion-input for taking user input in form but required and size properties not working.
Code for vue component:
<template>
<div>
<ion-header>
<ion-toolbar>
<ion-icon name="close" class="close-icon" #click.prevent="redirectTo(close)"></ion-icon>
<ion-title>{{ title }}</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="occupie-field" padding>
{{ content }}
<div>
<ion-input class="modal-ion-input"
:placeholder="rootElement.$t('number-of-person')"
type="number" mode="ios" inputmode="decimal"
:value="total_person"
#input="total_person = $event.target.value"
></ion-input>
<ion-input class="modal-ion-input"
:placeholder="rootElement.$t('name')"
:value="booking_name"
#input="booking_name = $event.target.value"
></ion-input>
<ion-input class="modal-ion-input"
:placeholder="rootElement.$t('mobile-no')"
type="tel" inputmode="tel"
:value="contact_number"
#input="contact_number = $event.target.value"
></ion-input>
<ion-input class="modal-ion-input"
:placeholder="rootElement.$t('gstin-no')"
:value="gst_no" size="15" type="text"
#input="gst_no = $event.target.value"
></ion-input>
<!-- <tags-input
element-id="tags"
:existing-tags="available_table_list"
:typeahead="true"
:showAddedTags="true"
typeahead-style="dropdown"
:delete-on-backspace="false"
:only-existing-tags="true"
placeholder="Merge Table"
#tag-added="onTagAdded"
#tag-removed="onTagRemoved"
v-model="selectedTags"
></tags-input> -->
<!-- <ion-list> -->
<ion-item class="select-tablee">
<ion-label hidden>{{rootElement.$t('select-tables')}}</ion-label>
<ion-select :placeholder="rootElement.$t('merge-table')" multiple="true" value="merge_tables" #ionChange="selectChange($event)" :disabled="Object.keys(available_table_list).length === 0">
<ion-select-option v-for="(table, index) in available_table_list" :key="index" :value="index">{{ table }}</ion-select-option>
</ion-select>
</ion-item>
<!-- </ion-list> -->
</div>
<ion-button class="occupie-table-button" #click.prevent="submit" :disabled="disableBtn">{{rootElement.$t('occupie-table')}}</ion-button>
</ion-content>
When I add required property in ion-input then required property not working and form submitted without checking.

see this - https://gist.github.com/mlynch/2ff3692341276ba959fea96a620097f9
try
<IonInputVue v-model="contact_number" size="10"/>

Related

How to add icon beside the lable using Vue Bootstrap

I have this vue bootstrap input field:
<b-form-group label="Name" label-for="name">
<validation-provider
#default="{ errors }"
name="Mapping Name"
rules="required"
>
<b-form-input
v-model="mappingData.mapping_name"
:state="errors.length > 0 ? false : null"
id="mappingName"
placeholder="Enter a maping name"
/>
<small class="text-danger">{{ errors[0] }}</small>
</validation-provider>
</b-form-group>
The output is look like this :
Now, beside ( Right side of the name ) the Name label I want to add a icon which is:
<feather-icon
icon="AlertCircleIcon"
class="mr-50 my-icon"
v-b-tooltip.hover.top="'Some tooltip text'"
/>
So for that I have added this after the : <b-form-group label="Name" label-for="name">. Now it look like this:
But its should be beside the name label.
Is there any way to do this?
Yes. You can use the template slot label of b-form-group like this:
<b-form-group label-for="name">
<validation-provider
#default="{ errors }"
name="Mapping Name"
rules="required"
>
<template slot="label">
Name
<feather-icon
v-b-tooltip.hover.top="'Some tooltip text'"
icon="AlertCircleIcon"
class="mr-50 my-icon"
/>
</template>
<b-form-input
v-model="mappingData.mapping_name"
:state="errors.length > 0 ? false : null"
id="mappingName"
placeholder="Enter a maping name"
/>
<small class="text-danger">{{ errors[0] }}</small>
</validation-provider>
</b-form-group>

custom navigation for q-carousel not working

I am struggling solving my navigation q-carousel that I want, it is does not work.
It just shows default navigation only but not the custom one that I grab the code from the Quasar website.
My template:
<q-card-section class="q-pa-none" >
<div style="width:60%; padding-bottom: 250px"
class="bg-transparent text-center q-gutter-y-lg absolute-center ">
<q-carousel
animated
v-model="slide"
arrows
navigation
infinite
control-type="flat"
control-color="secondary"
class="bg-transparent text-center">
>
<template v-slot:navigation-icon="{ active, btnProps, onClick }">
<q-btn v-if="active" size="lg" icon="home" color="yellow" flat round dense #click="onClick" />
<q-btn v-else size="sm" :icon="btnProps.icon" color="white" flat round dense #click="onClick" />
</template>
<q-carousel-slide :name="1" >1</q-carousel-slide>
<q-carousel-slide :name="2">2</q-carousel-slide>
<q-carousel-slide :name="3">3</q-carousel-slide>
</q-carousel>
</q-card-section>
My script:
export default {
data() {
return {
slide : 1,
}
}
}
Your code is actually working, but you kind of mixed opening and closing tags.
There is no open tag for </q-card-section>
There is no closing tag for your leading <div>
The below code should work for you:
<div
style="width: 60%; padding-bottom: 250px"
class="bg-transparent text-center q-gutter-y-lg absolute-center"
>
<q-carousel
animated
v-model="slide"
arrows
navigation
infinite
control-type="flat"
control-color="secondary"
class="bg-transparent text-center"
>
<template v-slot:navigation-icon="{ active, btnProps, onClick }">
<q-btn
v-if="active"
size="lg"
icon="home"
color="yellow"
flat
round
dense
#click="onClick"
/>
<q-btn
v-else
size="sm"
:icon="btnProps.icon"
color="white"
flat
round
dense
#click="onClick"
/>
</template>
<q-carousel-slide :name="1">1</q-carousel-slide>
<q-carousel-slide :name="2">2</q-carousel-slide>
<q-carousel-slide :name="3">3</q-carousel-slide>
</q-carousel>
</div>
You should consider setting up auto formatting in your code editor/IDE to auto format your source code, if you are using VS Code you can do this quite easily: https://stackoverflow.com/a/29973358/13765033
This way, you shouldn't run into such trouble again (it also helps Stack Overflow users to read your source code).

Cannot execute scoped slot and function in the same event Vue

I have the following code which uses this VueTailwind package:
<t-dropdown>
<div
slot="trigger"
slot-scope="{mousedownHandler, focusHandler, blurHandler, keydownHandler}"
>
<button
id="reseller-menu"
aria-label="User menu"
aria-haspopup="true"
#mousedown="mousedownHandler"
#focus="focusHandler"
#blur="blurHandler"
#keydown="keydownHandler"
>
{{ $page.props.auth.user.reseller.name }}
<icon icon="chevron-down" class-name="ml-2" />
</button>
</div>
<div slot-scope="{ blurHandler }">
<span v-for="user in users" :key="reseller.id" role="menuitem" class="block px-6 cursor-pointer py-2 hover:bg-indigo-500 hover:text-white"
#click="changeUser(user.id); blurHandler">{{ user.name }}</span>
</div>
</t-dropdown>
However, the blurHandler is not executed whenever the changeUser(user.id) method (a method in the parent component which seems to execute fine) is added to the #click event. The only way I was able to solve this issue was to use two different events such as the following:
<span v-for="user in users" :key="reseller.id" role="menuitem" class="block px-6 cursor-pointer py-2 hover:bg-indigo-500 hover:text-white"
#click="changeUser(user.id)" #mouseup="blurHandler">{{ user.name }}</span>
How can I use both in the same event since this doesn't seem to work in this case?
When the v-on value is a function reference, the template compiler transforms it into a function call, passing the event argument:
<button #click="functionRef">
<!-- ...is transformed into: -->
<button #click="functionRef($event)">
But when the v-on value is an expression, the template compiler wraps it in a function:
<button #click="onClick(); functionRef">
<!-- ...is transformed into: -->
<button #click="() => { onClick(); functionRef; }">
Notice functionRef; is not a function call, and effectively does nothing. To actually invoke the function in that expression, add the parentheses to make it a call:
<button #click="onClick(); functionRef()">
So your markup should be:
<div slot-scope="{ blurHandler }">
<span v-for="user in users" ⋯ 👇
#click="changeUser(user.id); blurHandler()">
{{ user.name }}
</span>
</div>
Also note slot-scope has been deprecated for v-slot, as of 2.6.0.

Ionic 5 ng if showing empty card

When I portrait mode *ngIf it hides values what I want but when I make the device landscape it's showing empty cards between true values.
<ion-col sizeLg="4" sizeMd="4" sizeXs="12" *ngFor="let order of orders">
<ion-card *ngIf="order.status =='CL'">
<ion-card-title>
<h4>{{order.title}}</h4>
</ion-card-title>
<ion-card-content>
<ion-item>
<h4>{{order.description | filter:[200, '...']}}</h4>
</ion-item>
</ion-card-content>
<ion-button type="button" color="danger">Canceled</ion-button>
<ion-button type="button" color="primary">Delivered</ion-button>
</ion-card>
</ion-col>
The problem is that you're hiding the card but you're still leaving an empty column. Please try by hiding both the card and the column instead:
<ng-container *ngFor="let order of orders">
<ion-col sizeLg="4" sizeMd="4" sizeXs="12" *ngIf="order.status =='CL'">
<ion-card >
...
</ion-card>
</ion-col>
</ng-container>

VueJS dynamic adding form components

I'm trying to make dynamic form, so if i want to add another text or some other field i can do it through web and save that to some json file.
Here is my code so far:
<template>
<div class="q-pa-md" style="max-width: 800px">
<div class="col-2">
<q-btn color="primary" label="Add Field" #click="addField = true"/>
</div>
<q-dialog v-model="addField">
<q-card>
<q-card-section>
<div class="text-h6">Add Field</div>
</q-card-section>
<q-separator />
<q-card-section style="max-height: 50vh" class="scroll">
test
</q-card-section>
<q-separator />
<q-card-actions align="right">
<q-btn flat label="Cancel" color="primary" v-close-popup />
<q-btn flat label="Add" color="primary" v-close-popup />
</q-card-actions>
</q-card>
</q-dialog>
<q-separator spaced inset />
<q-list>
<q-item>
<q-item-section>
<s-input v-model="data.email" label="Email" required />
<q-item-label caption lines="2">Email field.</q-item-label>
</q-item-section>
<q-item-section side top>
<div>
<q-toggle
v-model="data.active"
checked-icon="check"
color="blue"
unchecked-icon="clear"
/>
<q-icon name="keyboard_arrow_up" color="blue" size="md"/>
<q-icon name="keyboard_arrow_down" color="blue" size="md"/>
</div>
</q-item-section>
</q-item>
<q-separator spaced inset />
<q-item>
<q-item-section>
<s-input v-model="data.username" label="Username" required />
<q-item-label caption lines="2">Username field.</q-item-label>
</q-item-section>
<q-item-section side top>
<div>
<q-toggle
v-model="data.active"
checked-icon="check"
color="blue"
unchecked-icon="clear"
/>
<q-icon name="keyboard_arrow_up" color="blue" size="md"/>
<q-icon name="keyboard_arrow_down" color="blue" size="md"/>
</div>
</q-item-section>
</q-item>
<q-separator spaced inset />
<q-item>
<q-item-section>
<s-input v-model="data.password" label="Password" type="password" required />
<q-item-label caption lines="2">Password field.</q-item-label>
</q-item-section>
<q-item-section side top>
<div>
<q-toggle
v-model="data.active"
checked-icon="check"
color="blue"
unchecked-icon="clear"
/>
<q-icon name="keyboard_arrow_up" color="blue" size="md"/>
<q-icon name="keyboard_arrow_down" color="blue" size="md"/>
</div>
</q-item-section>
</q-item>
</q-list>
</div>
</template>
<script>
export default {
data () {
return {
newItem: true,
titleAction: null,
title: null,
titleHideEvent: false,
addField: false,
data: {
active: true
}
}
}
}
</script>
these are all field i have. Now if user wants to add another checkbox he should open dialog with button Add Field and choose that type of component and after he confirm that new chekcbox should be added in form. But i don't know how to make it dynamic. This 3 field should be mandatory and show in all forms (email, username and password).
Can anyone please help with some advice about this?
That's a huge template you got ^^"
Think that you can success by adding counters in your component's data.
Each time the User want to add a checkbox, you increment one of your counter depending on his choices. If the User wants to add a field for name for example, increment counterOfNameFields. In your template you can loop over these counters to display the right amount of fields.
Also, make a function that will push the content of these fields in arrays for example. You should have the same amount of arrays as counters.
Hope this answer your problem, tell me if it's not the case :)
You can have a list for added fields
data: function {
return {
...
addedItems:[],
...
}
}
And in your template
<q-item v-for="item in addedItems>
some html, which depends on how you define your items in your code
</q-item>
When you add an item to the page you just push it into
addedItems
collection and when you remove it from the page you remove it from collection.
I think this may be helpful https://v2.vuejs.org/v2/guide/components.html#Dynamic-Components
You can use v-bind:is="'yourComponentName'"
And you can store list of dynamic components and their options in some array.
Something like this (of course it's only example)
<component v-for="component in components" v-bind:is="component.name" v-bind:someoptions="component.options">
</component>