Difference between (answer, index) and answer, key - vue.js

Is there any difference between those two v-for approaches? One is (answer, index) and one is answer, key. Both of them work, however, the key one shows a red underscore in PHPStorm.
<label v-for="(answer, index) in questions[questionIndex]['answers']" :for="index">
<input type="radio" :id="index"/> {{ answer }}
</label>
<label v-for="answer, key in questions[questionIndex]['answers']" :for="key">
<input type="radio" :id="key"/> {{ answer }}
</label>
This is my setup
const questions = ref([
{
question: 'Question 1',
answers: [
"Answer 1",
"Answer 2",
"Answer 3",
"Answer 4"
],
},
{
question: 'Question 2',
answers: [
"Answer 1",
"Answer 2",
"Answer 3",
"Answer 4"
],
},
])
[PHPStorm error][1]
[1]: https://i.stack.imgur.com/drT7X.png

Related

How can I get access to an array of objects that placed to an array on Vue.js?

Please consider the codes below:
sidebar_components: [
{
title: "Admin Managment",
href: "javascript:void(0)",
idAcc: "accordion-1",
value: ["this is a test 1", "this is test 2", "this is test 3"],
to: ["/testi_1/1", "/testi_1/2", "/testi_1/3"],
classDiv: "active_div_1",
class: "item_link_1",
accordion: "myAccordion1",
icon: "fas fa-user-tie",
titleHoverClass: "sidebar_title"
},
{
title: "Admin Managment",
href: "javascript:void(0)",
idAcc: "accordion-2",
value: ["this is a test 1", "this is test 2", "this is test 3"],
to: ["/testi_2/1", "/testi_2/2", "/testi_2/3"],
classDiv: "active_div_2",
class: "item_link_2",
accordion: "myAccordion2",
icon: "fas fa-users",
titleHoverClass: "sidebar_title"
},
]
and :
<ul class="sidebar_components accordion" role="tablist">
<li v-for="(item, index) in sidebar_components" :key="index">
<a
:href="item.href"
v-b-toggle="item.idAcc"
:class="[item.class, 'item_link']"
>
<i :class="item.icon"></i>
<span
class="sidebar_title_active"
:class="item.titleHoverClass"
>{{ item.title }}</span
>
</a>
<b-collapse
:id="item.idAcc"
:accordion="item.accordion"
role="tabpanel"
:class="item.classDiv"
>
<nuxt-link
:to="val"
v-for="(val, index) in item.to"
:key="index"
>
{{ val }}
</nuxt-link>
</b-collapse>
</li>
</ul>
as you can see on this
<nuxt-link :to="val" v-for="(val, index) in item.to" :key="index">
{{ val }}
</nuxt-link>
I used of val that would be link address, I'm gonna have the value of sidebar_components that its name is value, I mean these: value: ["this is a test 1", "this is test 2", "this is test 3"],
how can I extract or get access to the value of it, these arrays are for sidebar sub-items everything working fine, but I don't know how can I implement or put these value of ‍‍‍‍sidebar_components on nuxt-link, it can be a span on it I know but, how can I extract it?
If you do not understand what I mean, please let me know in the
comments so that I can explain more.
Just use the index in v-for to access the sibling field value :
<nuxt-link
:to="val"
v-for="(val, index) in item.to"
:key="index"
>
{{ item.value[index] }}
</nuxt-link>

Problem with listing of radio inputs based on array

In my Laravel 2.6 application I need to show listing of radio inputs based on an array:
customerAccountTypeValueArray::[ { "key": "I", "label": "Individual" }, { "key": "B", "label": "Business" } ]
I do it as:
<div class="custom-control custom-radio m-3" v-for="nextCustomerAccountTypeValue, index in customerAccountTypeValueArray"
:key="nextCustomerAccountTypeValue.key">
<input
:id="'customer_account_type_' + nextCustomerAccountTypeValue.key"
type="radio"
name="radio_account_type"
class="custom-control-input"
v-model="customerRow.account_type"
:value="customerRow.account_type"
>
<label class="custom-control-label" :for="'customer_account_type_' + nextCustomerAccountTypeValue.key">{{ nextCustomerAccountTypeValue.label}}</label>
...
where customerRow is defined as:
customerRow: {
account_type: '',
...
As the result, I see my radio inputs, but selecting any of radio inputs, the customerRow.account_type value is not changed.
How can I fix it?
Replace
:value="customerRow.account_type"
with
:value="nextCustomerAccountTypeValue.key"
and it should work.

Input binding in v-for

I want to bind values from input radio button generated by v-for.
I have tried use v-model to bind them with variables question_1, question_2, question_3 in data().
<template>
<div id="radioButtons">
<div v-for="(question_obj, index) in questions" :key="index" class="form-group form-radio">
<span>{{ question_obj.question }} {{ question_obj.variable }}</span>
<br>
<label>
<input type="radio" :name="question_obj.variable" v-model="question_obj.variable" value="yes" >
<span>Yes</span>
</label>
<label>
<input type="radio" :name="question_obj.variable" v-model="question_obj.variable" value="no" >
<span>No</span>
</label>
</div>
</div>
</template>
<script>
export default {
name: 'radioButtons',
data () {
return {
question_1: '',
question_2: '',
question_3: '',
questions: [
{ question: 'Question 1', variable: 'question_1'},
{ question: 'Question 2', variable: 'question_2'},
{ question: 'Question 3', variable: 'question_3'},
]
}
}
}
</script>
I would like the value to be saved in data () after selecting the radio button.
Use index in v-for for v-model changes so it changes question object properties, not their instance:
new Vue({
el: '#app',
data () {
return {
//question_1: '', //don't need question_1, 2 and 3
// question_2: '',
// question_3: '',
questions: [
{ question: 'Question 1', variable: 'no'}, //notice that I have stored default values in question. Also consider renaming variable to answer to preserve good semantics.
{ question: 'Question 2', variable: 'yes'},
{ question: 'Question 3', variable: 'no'},
]
}
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div id="radioButtons">
<div v-for="(question_obj, index) in questions" :key="index" class="form-group form-radio">
<span>{{ question_obj.question }} {{ question_obj.variable }}</span>
<br>
<label>
<input type="radio" :name="'question-' + index" v-model="questions[index].variable" value="yes" :checked="question_obj.variable == 'yes'">
<span>Yes</span>
</label>
<label>
<input type="radio" :name="'question-' + index" v-model="questions[index].variable" value="no" :checked="question_obj.variable == 'no'">
<span>No</span>
</label>
</div>
</div>
</div>
Note: There is no need to store answers in question_1, question_2, question_3, since you might have more than 3 questions, and it won't be efficient.
Better way is to store answer in variable property value.
So in component it will look like this:
<template>
<div id="radioButtons">
<div v-for="(question_obj, index) in questions" :key="index" class="form-group form-radio">
<span>{{ question_obj.question }} {{ question_obj.variable }}</span>
<br>
<label>
<input type="radio" :name="'question-' + index" v-model="questions[index].variable" value="yes" :checked="question_obj.variable == 'yes'">
<span>Yes</span>
</label>
<label>
<input type="radio" :name="'question-' + index" v-model="questions[index].variable" value="no" :checked="question_obj.variable == 'no'">
<span>No</span>
</label>
</div>
</div>
</template>
<script>
export default {
name: 'radioButtons',
data () {
return {
//question_1: '', //don't need question_1, 2 and 3
// question_2: '',
// question_3: '',
questions: [
{ question: 'Question 1', variable: 'no'}, //notice that I have stored default values in question. Also consider renaming variable to answer to preserve good semantics.
{ question: 'Question 2', variable: 'yes'},
{ question: 'Question 3', variable: 'no'},
]
}
},
}
</script>
<style>
</style>
Try this code.
export default {
name: 'radioButtons',
data () {
return {
radio_data: {
'question_1': '',
'question_2': '',
'question_3': ''
},
questions: [
{ question: 'Question 1', variable: 'question_1'},
{ question: 'Question 2', variable: 'question_2'},
{ question: 'Question 3', variable: 'question_3'}
]
}
},
}
<template>
<div id="radioButtons">
<div v-for="(question_obj, index) in questions" :key="index" class="form-group form-radio">
<span>{{ question_obj.question }} {{ question_obj.variable }}</span>
<br>
<label>
<input type="radio" :name="'question-' + index" v-model="radio_data[questions[index].variable]" value="yes" :checked="question_obj.variable == 'yes'">
<span>Yes</span>
</label>
<label>
<input type="radio" :name="'question-' + index" v-model="radio_data[questions[index].variable]" value="no" :checked="question_obj.variable == 'no'">
<span>No</span>
</label>
</div>
</div>
</template>
Store your key, question, and answer in the same object in your array of questions. If you want to get the selected values as an object, use a method to reduce them into an appropriate value. In the example code below I've included such a method, as well as live JSON output to see the result.
<template>
<div id="radioButtons">
<div
v-for="row in questions"
:key="row.key"
class="form-group form-radio"
>
<span>{{ row.question }} {{ row.key }}</span>
<br />
<label>
<input
type="radio"
:name="row.key"
v-model="row.answer"
value="yes"
/>
<span>Yes</span>
</label>
<label>
<input
type="radio"
:name="row.key"
v-model="row.answer"
value="no"
/>
<span>No</span>
</label>
</div>
<pre>{{ JSON.stringify(getAnswers(), null, 2) }}</pre>
</div>
</template>
<script>
export default {
name: "radioButtons",
data() {
return {
questions: [
{ key: "question_1", question: "Question 1", answer: null },
{ key: "question_2", question: "Question 2", answer: null },
{ key: "question_3", question: "Question 3", answer: null },
],
};
},
methods: {
getAnswers() {
return this.questions.reduce((acc, cur) => {
acc[cur.key] = cur.answer;
return acc;
}, {});
},
},
};
</script>

How to add button in every table row? - VueJS 2.5 - good-table

I'm trying to add a button to replace the words "View Details" within the table cell for every row. I've tried implementing a template and every time I save changes, the table returns no results which is telling me something is broken.
This is what the table currently looks like:
Here is my code:
<vue-good-table
:columns="columns"
:rows="rows"
:globalSearch="true"
:paginate="true"
:responsive="true"
:lineNumbers="false"
class="styled"
styleClass="table">
<template slot="table-row" slot-scope="props">
<span v-if="props.column.field == 'Details'">
<button type="button" class="btn btn-primary">
View Details
</button>
</span>
<span v-else>
{{props.formattedRow[props.column.field]}}
</span>
</template>
</vue-good-table>
.
.
.
.
columns: [
{
label: "Date",
field: "date",
filterable: true
},
{
label: "Event",
field: "event",
filterable: true
},
{
label: "Details",
field: "details",
filterable: true
}
],
rows: [
{
event: "Thanksgiving Barrel Events",
details: "View Event",
date: "11/28/2018 at 6:34 PM"
},
{
event: "Christmas Barrel Events",
details: "View Event",
date: "12/25/2018 at 6:34 PM"
},
You've done everything right, except You left a typo in where You check if the column's field is "Details", while its 'details' (lowercase).
with strings, 'Details' does not equal to 'details' in javascript, as strings are case sensitive, never forget that.
So working code looks like this:
<vue-good-table
:columns="columns"
:rows="rows"
:globalSearch="true"
:paginate="true"
:responsive="true"
:lineNumbers="false"
class="styled"
styleClass="table">
<template slot="table-row" slot-scope="props">
<span v-if="props.column.field == 'details'">
<button type="button" class="btn btn-primary">
View Details
</button>
</span>
<span v-else>
{{props.formattedRow[props.column.field]}}
</span>
</template>
</vue-good-table>
Here's a working codepen:
https://codesandbox.io/s/nnpqpn6ll4?fontsize=14

Vue js cant drag input type file

If I upload an image then drag it. It seems that input[type='file'] was static. Because the other value will be drag to other row only the input[type='file'] was remained. How can I move/drag it together with other value?
This is the jsfiddle
This is the HTML
<div id="main">
<h1>Vue Draggable Image</h2>
<div class="drag">
<h2>List 1 Draggable</h2>
<draggable v-model="list" class="dragArea" :options="{group:{ name:'people', pull:'clone', put:false }}">
<form v-for="(element, index) in list" :key="index" method="POST" enctype="multipart/form-data">
<input type="text" v-model="element.name">
<input type="file" id="reference_image" #change="onFileChange($event,index)" name="reference_image" accept="image/*" />
<img class="small_image" :src="reference_image" name="reference_image" />
</form>
</draggable>
</div>
</div>
This is the script
var vm = new Vue({
el: "#main",
data: {
list: [{
reference_image: "",
name: "name 1"
},
{
reference_image: "",
name: "name 2"
},
{
reference_image: "",
name: "name 3"
},
{
reference_image: "",
name: "name 4"
},
{
reference_image: "",
name: "name 5"
},
],
}
});
get it working by changing :key="index" to :key="element.name"
fiddles :
https://jsfiddle.net/amherve/sqebLtzc/3/