Properties behind an if statement within vuejs - vue.js

Sometimes I don't want to have a "rules" option/property in some input fields, is it possible within vuejs3 to set up a kind of if statement so that the property "rules" are only presented on certain fields? Because now i just do an empty array[]. But would rather see this differently.
So that I dont need to apply "rules" option in my form scheme when I dont need it.
This is my template code:
<div v-for="(prop, key) in formSchema" :key="key">
<q-input v-if="prop.component === 'input'"
outlined
v-model="dataRef[key]"
:type="prop.type"
:label="prop.label"
maxlength="12"
class="super-small"
hint="Name and surname"
lazy-rules
:rules="prop.rules" (want this behind an if statement if not needed)
>
</q-input>
<q-select v-else-if="prop.component === 'select'"
outlined
v-model="dataRef[key]"
:type="prop.type"
:options="prop.options"
:label="prop.label">
</q-select>
</div>

Add a ternary condition within your attribute. When the attribute is set to null or undefined it gets omitted.
:rules="addRule ? prop.rules : null"

Related

vue-gettext translate text

I am applying translation in vue 2.x and I am using "vue-gettext" but I am having a problem in some cases eg:
<settings-group label="is a label" >
<settings-field label="is a label">
In those cases I can't find a way to translate the label, I was looking for info and there is nothing, but maybe someone here could solve it...
Things I tried:
<settings-field v-translate label="is a label">
Doesn't work
<settings-field label="{{<translate>is a label</translate>}}">
Throw an error: Interpolation inside attributes has been removed. Use v-bind or the colon shorthand instead. For example, instead of , use <div :id="val".
thank you.
First option (preferred, since in vue3-gettext translate tag would be eventually removed):
<settings-group :label="$gettext('is a label')" />
Second option -- create slot label in settings-group component. Could be useful if you going to interpolate string based on some data from settings-group
# settings-group.vue
<div class="settings-group">
<span class="label">
<slot name="label" v-bind="{ count }" />
</span>
...
# pages/settings.vue
<settings-group>
<template v-slot:label="{ count }">
<translate
:translate-n="count"
:translate-plural="%{count} elements"
:translate-params="{ count }"
>
%{count} element
</translate>
</template>
</settings-group>

How to disable a single v-expansion-header

(I'm using Vue 2.6) - I read the documentation on v-expansion-panels on vuetify which says it has disabled property to set, but it sets the whole v-expansion-panel disabled, and I want to disable a single v-expansion occurency or more, because I use a for to fill all expansion panels, like 10 occurencies for example, and I want to disable the occurency that has a certain condition. Can someone help? I already tried to use #click.stop inside expansion header, expansion content, but it does not work. I wanted to do like this. On number === 1, don't expand. Or I could even execute a function to return a false, and a message on screen.
<v-expansion-panels>
<v-expansion-panel
#click.stop="number === 1"
>
<v-expansion-header />
<v-expansion-content />
</v-expansion-panel>
</v-expansion-panels>
The v-expansion-panel takes a disabled prop and you can use with a condition to select the panel you want to disable.
<v-expansion-panel
v-for="(item,i) in 5"
:key="i"
:disabled="i === 2"
>
Demo: https://codepen.io/fu7zed/pen/GRQbbVx
API reference: https://vuetifyjs.com/en/api/v-expansion-panel/

vee-validate: Is it possible to change the fields-bag-name without changing the current name?

So I want to adapt the Autofill naming for Birthdays. However, this leads to several problems. Now I need to find out if I can force vee-validate to change the name of the field.
To understand it better. This is how it currently looks like:
<select
v-model="day"
id="day"
name="day"
:class="{'invalid' : errors.has('day')}"
v-validate="'required|excluded:0'"
>
<option
:disabled="true"
value="0"
v-text="trans('food.Day')"
/>
<option
v-for="n in 31"
:key="n"
:value="n"
v-text="n"
/>
</select>
<span
class="bar"
:class="{'invalid' : errors.has('day')}"
/>
The name for the select field is "day".
However, according to this, it should be named: "bday-day".
Since I'm using vee-validate, this leads to a rename of the field name to "bday-day". Now errors.has('day')} won't work anymore.
But even if I change this to errors.has('bday-day'), I cannot use my internal watcher for changes in values. I get the error:
Failed watching path: "bday-day" Watcher only accepts simple dot-delimited paths. For full control, use a function instead.
This is because I have to force the same name of the v-model name and vee-validate name. v-model="bday-day" cannot work.
To make it short. My end goal is something like this:
<select
v-model="day"
id="day"
name="bday-day"
:class="{'invalid' : errors.has('day')}"
v-validate="{required: true, excluded: 0, name: 'day'}"
>
<option
:disabled="true"
value="0"
v-text="trans('food.Day')"
/>
<option
v-for="n in 31"
:key="n"
:value="n"
v-text="n"
/>
</select>
<span
class="bar"
:class="{'invalid' : errors.has('day')}"
/>
I would use the name="bday-day" for autofill, but I would set the field name for vee validate to name: 'day'.
Use the data-vv-name attribute
Vee-validate has you covered and you can setup the attribute data-vv-name to achieve precisely this:
<select
v-model="day"
id="day"
name="bday-day"
:class="{'invalid' : errors.has('day')}"
v-validate="'required|excluded:0'"
data-vv-name="day"
>
Now the errors and fields members provided by vee-validate will have a day entry, instead of using the input name bday-day. Thus, if you have a watcher on errors.day, you won't have that nasty problem with the bday-day watching path.
With VeeValidate v3, you have two relevant options you can pass to ValidationProvider, name and vid.
VeeValidate's docs specify that:
name specifies a field name to be used in error messages.
vid is an identifier used for target/cross-field based rules.
From my tests though, vid is also used as the key for fields and errors in the ValidationObserver if provided, and if not, it falls back to name.
As a result, if you have multiple of the same fields in one form, and you're looking to have a unique key name (so that they don't clash and break), then use name purely just for the field name in error messages, and vid to provide a unique ID to be used by ValidationObserver in the fields and errors objects. For example:
<ValidationProvider
name="hours" // used for error messages
:vid="hours-${unique-part}" // unique key to stop clashes
rules="required"
v-slot="{ errors }"
>...</ValidationProvider>
If you're using VeeValidate v3, you can set "name" attribute for the ValidationProvider
<ValidationProvider name="day" rules="required|excluded:0" v-slot="{ errors }">

Vuejs adding conditional style fails

I wuld like to add the following style iwhich workss in html
<div style="text-decoration: line-through">
Now am trying this in vuejs2
<div :style="{'text-decoration: line-through':true}">
But the above doesnt work
Where am i going wrong?
Binding an object to the style attribute is done by providing key / value pairs.
I suspect what you want is
<div :style="{'text-decoration': condition ? 'line-through' : 'initial'}">

vue.js - Change text based on default/clicked class

Given the following:
<div id="#my-container">
<div class="title">Companies</div>
<div class="tab active tab-apple">Apple</div>
<div class="tab tab-google">Google</div>
</div>
When page is loaded without any tab clicks yet, whichever tab with the default active class, needs to go in the .title div. For the example above, <div class="title">Apple</div>
On click of a tab, the class is switched to active, and vue.js needs to update the .title div once again.
How can this be done with vue.js? I've tried but not able to get it to work as intended.
The answer by David is one way to do it. But Vuejs offers in-line computations for this. So, no need to hook into any CSS event. Here's some code to explain:
Create a data property active_tab, just like David mentioned. And then bind it's value just like he's done it. In your tabs, add an click event and at that event, assign appropriate value to active_tab.
<div class="tab active tab-apple" #click="active_tab = Apple">Apple</div>
<div class="tab tab-google" #click="active_tab = Google">Google</div>
Now, to dynamically assign the active class to the respective tab, make the class attribute, a computed property, like this:
<div
:class="['tab', active_tab == 'Apple' ? 'active' : '', 'tab-apple']"
>
Apple
</div>
What this code is basically doing is, :class makes class a computed property. Then the commas in the array divide the statement. So, the computation will always add tab and tab-apple classes. But, only if active_tab == 'Apple' then ? add 'active' else : add ''
Not sure which CSS framework you are using, but normally I hook into the events thrown by the tab switching (many CSS frameworks provide this access). Once hooked into it, you can write a Vue custom directive that will take that event and use it to update a VM attribute that indicates which tab is active.
Then you can use normal mustache templating to get it into your template:
<div class="title">{{ active_tab }}</div>