Disable button based on text input - vue.js

I have 2 fields, email and password and a button:
The button is disabled based on password.length, but I also want it to be disabled based on valid email address.
I tried doing:
Template:
<v-btn
class="btn white--text"
:disabled="password.length <= 6 && isValidEmail"
#click="onSignIn"
>Sign In</v-btn>
Script:
computed: {
isValidEmail() {
return validateEmail(this.email);
},
},
But it doesn't work, only password.length works.
What am I missing?

Found how to do it, Like Liel Fridman said you need simple expressions in v-bind( no && ||):
computed: {
isValidForm() {
return (this.password.length > 6 && validateEmail(this.email));
},
}

You can add another computed property and use that. Only simple expressions work inside v-bind

I think you should use OR instead of && operator, so whenever one of the condition return false, its disabled
<v-btn
class="btn white--text"
:disabled="password.length <= 6 || !isValidEmail"
#click="onSignIn"
>Sign In</v-btn>

you can use direct bind data :
:disabled="password.length <= 10

Related

v-mask not working correctly with veutifyjs input

I'm using veutifyjs text-input to show phone number. I have a button to assign phone number to v-model. But after assign it not change there text input. if I enter some think on text-input v-mask work. But if I assign value to v-model it not working. Also i'm tying next trick but its not have any difference.
<v-text-field
v-model="form.phone_number"
v-mask="'(###) ###-####'"
dense
outlined
autocomplete="new-password"
hide-details="auto"
label="Phone Number"
placeholder="Phone Number"
></v-text-field>
<v-btn color="warning" #click="dataupdate()">Add</v-btn>
dataupdate() {
this.$nextTick(() => {
this.form.phone_number = '4032223344'
})
},
You have to set the v-mask dynamically after you set the value of form.phone_number, so we could create a phoneNumberMask variable:
data() {
return {
phoneNumberMask: '',
};
}
Set it as the v-mask value:
<v-text-field
v-model="form.phone_number"
v-mask="phoneNumberMask"
...
then at dataupdate():
dataupdate() {
this.form.phone_number = '4032223344'
this.$nextTick(() => {
this.phoneNumberMask = '(###) ###-####'
})
/*
* you'd just have to deal with calling this funcition
* when phoneNumberMask has already a value
* and that depends on your business rules
*/
},
I had the same issue after migration to Vuetify 2 and fixed it so: Just replaced v-mask library with vue-input-facade as mentioned here.
It works exactly the same as the old mask from the first Vuetify but you should use the parameter "v-facade" instead.

Vuetify combobox - How to disable typing in vuetify's combobox

The vuetify combobox is allowing the user to type inside the combobox. Any clue on how to disable this.
This is how I have implemented my combobox.
<v-combobox
:loading="isSurveyBeingPopulated"
class="static--inputs"
color="red"
box
:items="folders"
:rules="[rules.required]"
item-text="value"
dense
placeholder="Select Survey Folder"
item-value="key"
slot="input"
v-model="selectedSurveyFolder">
</v-combobox>
Combobox:
The v-combobox component is a v-autocomplete that allows the user to
enter values that do not exist within the provided items. Created
items will be returned as strings.
So if you want to disable the typing you should use a select: https://vuetifyjs.com/en/components/selects
Select fields components are used for collecting user provided
information from a list of options.
You can just delete new item after changed.
<v-combobox
v-model="selected"
:items="[...selected, ...items]"
multiple
#change="onChangeCombobox"
/>
onChangeCombobox(items) {
this.selected = items.filter((item) => this.items.includes(item))
}
I had the same problem, I used v-select instead of v-combobox, it works fine:
<v-select
return-object
></v-select>
I've gone thru the same, i need combobox to list item and custom values but i must disable typing, my solutions was to use key events and "change"its behavior like:
#keydown="$event.target.blur()"
#keypress="$event.target.blur()"
#keyup="$event.target.blur()"
Yes, you can achieve filtering of a combobox by using the rules code, e.g.
<v-combobox
v-model="selection"
:items="items"
:search-input.sync="input"
:rules="intRule"
chips
clearable
dense
multiple
small-chips
item-text="title"
autocomplete="off"
return-object
>
</v-combobox>
and then in your script section in data, sth like
data() {
return {
selection: [],
input: null,
items: [],
valid: false,
intRule: [
function(v) {
if (!v || v.length < 0) {
return false
} else if (v.length > 0) {
for (let i = 0; i < v.length; i++) {
if (/[^0-9]/g.test(v[i].id)) {
v.splice(-1, 1)
return false
}
}
return false
} else {
return true
}
}
]
}
}
the input could be used to overwrite a no results slot and show for what input are no results found.
hope this is helping

Datatable vuetify select multiple rows (Shift+Click)

I am using Datatable from Vuetify 1.5.x
Have enabled the checkboxes so that multiple rows can be selected, I would like to be able to select with Shift + Click so that I don't have to click on each checkbox exact same as Gmail works.
It wouldn't be difficult to do if I had a row id that changes by the sort or if the rows array was reordered when the data table is sorted. But none of these seem to work.
Has anyone achieve this with vuetify datatable?
<template v-slot:items="props">
<tr :active="props.selected" #click="selectRow(props);">
<td>
<v-layout>
<v-flex>
<v-checkbox
:input-value="props.selected"
primary
hide-details
:class="{ 'red--text': props.item.was_modified_recently == 1 }"
></v-checkbox>
</v-flex>
</td>
</tr>
</template>
Vuetify documentation example
I actually had to solve this today.
My solution relied on using the item-selected hook and method that performs the bulk selection.
methods: {
bulkSelect({ item: b, value }) {
const { selectedRows, current, shiftKeyOn } = this;
if (selectedRows.length == 1 && value == true && shiftKeyOn) {
const [a] = selectedRows;
let start = current.findIndex((item) => item == a);
let end = current.findIndex((item) => item == b);
if (start - end > 0) {
let temp = start;
start = end;
end = temp;
}
for (let i = start; i <= end; i++) {
selectedRows.push(current[i]);
}
}
},
}
So that's the meat of it. There's other housekeeping details like keeping track of when shift is being held down, and preventing the browser from highlighting the text of the table when holding down shift and clicking the second row.
I made a codepen showing this functioning here.
https://codepen.io/ryancwynar/pen/jOWoXZw
In the new version of vuetify i.e. 2.0
You question is solved easily the following way
I have put the answer in the following Stack Overflow question link
Vuetify added prepend-item slot that lets you add a custom item before listing items by which we can add "select all"
Please check the example in codepen on pretend-item for select all checkboxes
I've got the same case as you faced.
First of all, you got to add another events (keyboard events) on the <tr>
tag and pass the props as argument.
And then use slice to the items array for determined range of the selected items you want.
In my case, i've stored the selected array inside vuex store.
hoped i can helped ;)
<template v-slot:items="props">
<tr :active="props.selected" #click.shift="useShift(props)" #click="selectRow(props)">
<td>
<v-layout>
<v-flex>
<v-checkbox
:input-value="props.selected"
primary
hide-details
:class="{ 'red--text': props.item.was_modified_recently == 1 }"
></v-checkbox>
</v-flex>
</td>
</tr>
</template>
export default {
methods:{
...mapMutations(["setSelected"]),
useShift({ index }) {
this.setSelected(
this.items.slice(
this.items.findIndex(el => {
return this.selected.find(v => v.track.id == el.track.id);
}),
index
)
);
},
}
}

Vue + Vue-Paginate: Array will not refresh once empty

I am using vue-paginate in my app and I've noticed that once my array is empty, refreshing its value to an array with contents does not display.
<paginate
name="recipes"
:list="recipes"
:per="16"
class="p-0"
>
<transition-group name="zoom">
<div v-for="recipe in paginated('recipes')" :key="recipe.id">
<recipe class=""
:recipe="recipe"
:ref="recipe.id"
></recipe>
</div>
</transition-group>
</paginate>
This is how things get displayed, and my recipe array changes depending on a search. If I type in "b" into my search, results for banana, and bbq would show. If I typed "ba" the result for bbq is removed, and once I backspace the search to "b" it would re-appear as expected.
If I type "bx" every result is removed and when I backspace the search to "b", no results re-appear.
Any idea why this might happen?
UPDATE
When I inspect the component in chrome I see:
currentPage:-1
pageItemsCount:"-15-0 of 222"
Even though the list prop is:
list:Array[222]
Paginate needs a key in order to know when to re-render after the collection it's looking at reaches a length of zero. If you add a key to the paginate element, things should function as expected.
<paginate
name="recipes"
:list="recipes"
:per="16"
class="p-0"
:key="recipes ? recipes.length : 0" // You need some key that will update when the filtered result updates
>
See "Filtering the paginated list" is not working on vue-paginate node for a slightly more in depth answer.
I found a hacky workaround that fixed it for my app. First, I added a ref to my <paginate></paginate> component ref="paginator". Then I created a computed property:
emptyArray () {
return store.state.recipes.length == 0
}
then I created a watcher that looks for a change from length == 0 to length != 0:
watch: {
emptyArray: function(newVal, oldVal) {
if ( newVal === false && oldVal === true ) {
setTimeout(() => {
if (this.$refs.paginator) {
this.$refs.paginator.goToPage(page)
}
}, 100)
}
}
}
The timeout was necessary otherwise the component thought there was no page 1.
Using :key in the element has certain bugs. It will not work properly if you have multiple search on the table. In that case input will lose focus by typing single character. Here is the better alternative:
computed:{
searchFilter() {
if(this.search){
//Your Search condition
}
}
},
watch:{
searchFilter(newVal,oldVal){
if ( newVal.length !==0 && oldVal.length ===0 ) {
setTimeout(() => {
if (this.$refs.paginator) {
this.$refs.paginator[0].goToPage(1)
}
}, 50)
}
}
},

bind switch and form input in vuejs

I'm looking for the VueJS best practice for synchronizing between the input element and the switch element in the following piece of code:
<div class="filter panel">
<div class="field_title">Device</div>
<el-switch v-model="switches.device_switch" name="device"></el-switch>
<b-form-input v-model="device" placeholder="Device"></b-form-input>
</div>
If the input field contains any text I would like to set the v-model="switches.device_switch" to true.
How can I achieve this?
Set a watcher for the device property bound to the input. In the watcher, you can set the value of switches.device_switch based on the length of the device string:
watch: {
device: function(value) {
this.switches.device_switch = value.length !== 0;
}
}