Quasar v-money always setting to $0,00 - vue.js

I created a simple component
<template>
<div class="MoneyInput1 col-grow block">
<div class="block text-left q-py-md">
<label class="label-1">
{{ props.jLabel }}
</label>
</div>
<q-field
:model-value="props.modelValue"
borderless
#update:modelValue="e => {$emit('update:modelValue', e)}"
>
{{ props.modelValue }}
<template v-slot:control="{ id, emitValue }">
<input
:id="id"
v-money="moneyFormatForDirective"
class="input-1 money-input basis-medium"
model-value="modelValue"
#change.self="e => emitValue(e.target.value)"
>
</template>
</q-field>
</div>
</template>
with the moneyFormat as the following
const moneyFormatForDirective = {
decimal: ',',
thousands: '.',
prefix: '$ ',
precision: 2,
masked: false,
};
The problem is that it triggers two updates, one setting the value from the parent, which is sent with v-model. The following sets it to $0,00
I saw that it could be possible to be done with v-model.lazy, but with the #change I have no idea.

Related

how to create button group component in vue

I am trying to create button-group component in vue using typescript:
<template>
<slot>
<CButton
v-for="(vnode, index) in $slots.default || []"
:key="index"
:class="[
{ 'first-index': index === 0 },
{ 'last-index': index === ($slots.default ? $slots.default.length : 0) - 1 },
]"
>
{{ index }}
{{ vnode }}
</CButton>
</slot>
</div>
</template>
Here index comes null but I am expecting it turns as much as button I added.
Here is the parent:
<ButtonGroup>
<CustomButton>1</CustomButton>
<CustomButton>2</CustomButton>
<CustomButton>3</CustomButton>
</ButtonGroup>
Here is how you need to use slots in Vue:
<!-- ButtonGroup -->
<template>
<div class="button-group">
<slot></slot> <!-- Define the default slot -->
</div>
</template>
<template>
<ButtonGroup>
<!-- Fill in the slot with whatever you want -->
<CustomButton class="my-class">Test</CustomButton>
<button class="regular-button">Normal</button>
<CustomButton />
</div>
</template>
Example playground

Quasar: Why is QCheckbox selected all in QTable?

I check only one checkbox, but all of the other checkboxs are also checked. It seems like all checkbox has the same index or id, however, there is no way to figure out to fix this issue. I have googled, but could not find the way I am looking for.
Here is the code I wrote
QTable
<q-table
id="selection-table"
:title="undefined"
:data="curData"
:columns="columns"
#request="updateTableData"
:rows-per-page-options="[10, 20, 30, 40, 50]"
:pagination.sync="pagination"
:loading="isLoading"
row-key="name"
class="no-shadow q-pa-none"
selection="multiple"
:selected.sync="selected"
:selected-rows-label="getSelectedString"
>
<template v-slot:body="props">
<q-tr :props="props" class="q-pa-none">
<q-td>
<q-checkbox v-model="props.selected" />
{{ props }}
</q-td>
<q-td
v-for="col in props.cols"
:key="col.name"
:props="props"
class="q-pa-none"
row-key="name"
:auto-width="col.name == 'title' ? false : true"
>
<span v-if="col.name === 'title'">
{{ props.row.title }}
</span>
<span v-else-if="col.name === 'status'">
<span v-if="col.value === 0">... </span>
<span
v-else-if="
col.value === 200 && props.goodsStatusCode === 11
"
>...</span
>
<span v-else>
<span class="text-red">...)</span>
</span>
</span>
<span v-else> {{ col.value }} </span>
</q-td>
</q-tr>
</template>
</q-table>
Script
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
name: 'SelectionTable',
data() {
return {
selected: [],
};
},
methods: {
getSelectedString() {
return this.selected.length === 0
? ''
: `${this.selected.length} record${
this.selected.length > 1 ? 's' : ''
} `;
},
},
});
</script>
Would you let me know what I am missing?
Just in case someone needs this I have figured out what was missing.
What I needed to changed was this:
row-key="name"
to
row-key="_id"
since literally row-key means the key or id of the row I select.
Hope this would help someone like me!

Vue bootstrap form tags allowing duplicates

I'm trying to allow duplicates in Vue bootstrap's form tags.
I've tried using :tag-validator (in the example) and #tag-state to externally modify the v-model value. However it seems like it is getting rid of the duplicate somewhere. Is this impossible?
Jsfiddle of the example: https://jsfiddle.net/yts54fpd/.
<div id="app">
<template>
<div>
<b-form-group label="Tagged input using select" label-for="tags-component-select">
<!-- Prop `add-on-change` is needed to enable adding tags vie the `change` event -->
<b-form-tags
:tag-validator="tagValidator"
id="tags-component-select"
v-model="value"
size="lg"
class="mb-2"
add-on-change
no-outer-focus
>
<template v-slot="{ tags, inputAttrs, inputHandlers, disabled, removeTag }">
<ul v-if="tags.length > 0" class="list-inline d-inline-block mb-2">
<li v-for="tag in tags" :key="tag" class="list-inline-item">
<b-form-tag
#remove="removeTag(tag)"
:title="tag"
:disabled="disabled"
variant="info"
>{{ tag }}</b-form-tag>
</li>
</ul>
<b-form-select
v-bind="inputAttrs"
v-on="inputHandlers"
:disabled="disabled"
:options="options"
>
<template #first>
<!-- This is required to prevent bugs with Safari -->
<option disabled value="">Choose a tag...</option>
</template>
</b-form-select>
</template>
</b-form-tags>
</b-form-group>
</div>
</template>
</div>
window.onload = () => {
new Vue({
el: '#app',
data() {
return {
options: ['Apple', 'Orange', 'Banana', 'Lime', 'Peach', 'Chocolate', 'Strawberry'],
value: []
}
},
methods: {
tagValidator(tag) {
this.value.push(tag)
return true
}
}
})
}

TypeError: Invalid attempt to spread non-iterable instance in VueJS using Vuesax table

I'm starting to learn vue js and currently implementing a basic crud application. I successfully display 1 record in the table but having a problem when the record count is 2 or more.
I used vuesax serverside table to render the data and here's my code for the template
<vs-table
v-model="selected"
pagination
max-items="10"
search
:data="examiner">
<template slot="header">
<div class="d-flex align-items-center justify-content-between w-100 add-account">
<h3>
Examiner List
</h3>
</div>
</template>
<template slot="thead">
<vs-th sort-key="email">
Fullname
</vs-th>
<vs-th sort-key="Username">
Address
</vs-th>
<vs-th sort-key="User Role">
Email
</vs-th>
<vs-th sort-key="action">
Action
</vs-th>
</template>
<template slot-scope="{data}">
<vs-tr :data="row" :key="indextr" v-for="(row, indextr) in data" >
<vs-td :data="data[indextr].firstname">
{{ data[indextr].firstname }} {{ data[indextr].lastname }}
</vs-td>
<vs-td :data="data[indextr].address">
{{ data[indextr].address }}
</vs-td>
<vs-td :data="data[indextr].email">
{{data[indextr].email}}
</vs-td>
<vs-td>
<div class="d-flex">
<vs-button class="mr-1" color="primary" data-placement="top" data-toggle="tooltip"
title="Edit Examiner"
#click="editUser(row)"
vs-type="border" size="small" icon="edit"/>
<vs-button class="mr-1" color="danger" data-placement="top" data-toggle="tooltip"
title="Delete Examiner"
vs-type="border" size="small" icon="delete"/>
</div>
</vs-td>
</vs-tr>
</template>
</vs-table>
Here's my code for the script
<script>
import axios from "../../axios";
export default {
name: "examiner",
data() {
return {
host: window.location.host,
edit: false,
examiner: [],
selected: []
}
},
mounted() {
this.fetchUsers()
console.log(this.examiner)
},
methods: {
fetchUsers() {
axios.get('../api/getExaminer')
.then(response => {
this.examiner = response.data
})
.catch(error => console.log(error))
},
editUser(row) {
this.edit = true;
console.log(row)
}
}
}
</script>
Currently whenever I'm trying to load a data I'm receiving this error
I've just had this issue. it appears that if the :data prop is null or not iterable it will show this error.
In my case, the data prop became at some point null. for you I suggest the following:
First, use a computed value for data prop that returns an empty array in case there is an error.
make sure that your response.data is really an array or iterable object

V-for with template

I am using vue-bootstrap. I try to create dynamic a grid component that gets headers and datas. Since we will not know how many column passed to the component, we should check every item that are passed.
<template>
<b-table striped hover :items="items"></b-table>
<div v-for="title in items">
<template slot="title.key" slot-scope="data">
<input v-if="title.isActive" type="text" v-model="data.value">
<textarea v-else type="text" v-model="data.value"></textarea>
</template>
</div>
</b-table>
</template>
<script>
const items =[
{'label': 'Description', 'key': 'description'},
{'label': 'Name', 'key': 'name', 'isActive': true},
]
So, if isActive is true, then this template should be textarea(Column should be changed with textarea instead of input) However it is not working and no columns changed neither inputbox nor textarea and stay default template
Could you please help on these question.
Thank you
I think you should separate title in v-for and slot-scope variable to avoid confusing:
<template v-for="title in items" :key="title.key">
<template :slot="title.key" slot-scope="item">
<input v-if="item.isActive" type="text" v-model="item.value">
<textarea v-else type="text" v-model="item.value"></textarea>
</template>
</template>
Since, the isActive property is present inside the object in items array, you need to access it as a property of an iteratee.
So the code becomes:
<div v-for="title in items">
<template slot="{{title.key}}" slot-scope="{title}">
<input v-if="title.isActive" type="text" v-model="title.value">
<textarea v-else type="text" v-model="title.value"></textarea>
</template>
</div>
Thanks to ittus's answer,after minor modification following way is worked.
<template v-for="column in columns" :slot="column.key" slot-scope="item">
<input v-if="item.isSelect" type="text" v-model="item.value">
<textarea v-else type="text" v-model="item.value"></textarea>
</template>
Thank you all.
You can check out this example for dynamic columns.
new Vue({
el: "#app",
data: {
fields: [{
key: "id",
label: "Id",
colType: "span"
}, {
key: "name",
label: "Name",
colType: "button"
}, {
key: "uhh",
label: "uhh..",
colType: "idk"
}],
items: [{
id: 0,
name: "Test 0"
}, {
id: 1,
name: "Test 1"
}, {
id: 2,
name: "Test 2"
}]
}
});
<div id="app">
<b-table :items="items" :fields="fields">
<template v-for="(field, index) in fields" :slot="field.key" slot-scope="data">
<div v-if="field.colType === 'button'">
<h5>{{data.item.name}}</h5>
<b-button>Am Button</b-button>
</div>
<div v-else-if="field.colType === 'span'">
<h5>{{data.item.name}}</h5>
<span>Am Span</span>
</div>
<div v-else>
<h5>{{data.item.name}}</h5>
Am Confused
</div>
</template>
</b-table>
</div>
I didn't get these answers to work. Which actually helped me, was this:
https://forum.vuejs.org/t/how-to-pass-cell-templates-to-a-component-with-b-table/106283
and this fiddle:
https://jsfiddle.net/skirtle/6of9dnpz/
toCellName (slot) {
return `cell(${slot})`
}
The key is that the toCellName returns the correct slot name.
You have to use below snippet.
<input v-if="title.isActive" type="text" v-model="title.value">
<textarea v-else type="text" v-model="title.value"></textarea>