building a hyperlink in a Vuetify Datatable - maybe v-bind? - vue.js

I'm close to where I need to go but not close enough. This is my code
<td>
<a href="https://www.ncbi.nlm.nih.gov/pubmed/"
{{item.pmid}} target="_blank">{{ item.pmid }}</a>
</td>
<td>{{ item.year }}</td>
<td>{{ item.title }}</td>
<td>{{ item.authors }}</td>
<td>{{ item.article }}</td>
<td>{{ item.journal }}</td>
<td>{{ item.rcr }}</td>
<td class="text-xs-right">{{ item.percentile }}</td>
If I take out the href {{item.pmid}} it will go to the web page in a new window. However I need to add the item.pmid value to the end of the href string so it will go to an exact page. If I leave it the way it is now I get an error saying 'Element': '{{' is not a valid attribute name. Is there someway that I can get the value concatenated to the string?
OK-- I've found this:
How to put variable in a href on the vue js 2?
But still not sure about how to us v-bind

The best way to do this, if anyone is still wondering, is to use dynamic rows
They work like this:
<v-data-table
:headers="tableHeaders"
:items="tableItems"
>
<template v-slot:item.link="{ item }">
<a :href="item.link">Link</a>
</template>
</v-data-table>

got it--
<td>
<a
:href="'https://www.ncbi.nlm.nih.gov/pubmed/' + item.pmid"
target="_blank"
>{{ item.pmid }}</a>
</td>

Related

Using v-for in a table

I have a table is populated with some info and I would like to format the table like the picture
Unfortunately the excel sheet which I have no control over is formatted so:
I want any row that has only a Equipment type to span whole row. All other rows should appear as normal table row.
I am using following vue template:
<table>
<caption>
SHS Scrap Table
</caption>
<thead>
<tr>
<th>Make</th>
<th>Model #</th>
<th>Bar Code</th>
<th>Serial #</th>
<th>Location</th>
<th>Condition</th>
</tr>
</thead>
<tbody v-for="item in scrapDataEmptyRowsRemoved" :key="item">
<tr v-if="item['Equipment Type']">
<td class="equipt-type" colspan="6">
Equipment Type - {{ item["Equipment Type"] }}
</td>
</tr>
<tr v-else>
<td>{{ item["Make"] }}</td>
<td>{{ item["Model #"] }}</td>
<td>{{ item["Bar Code"] }}</td>
<td>{{ item["Serial #"] }}</td>
<td>{{ item["Location"] }}</td>
<td>{{ item["Condition"] }}</td>
</tr>
</tbody>
</table>
The only problem is that looking in Devtools I see that every row has a Tbody which is not semantically correct. Any idea's on how to correct this. If I use a container around the v-if v-else all formatting breaks down.Thanks...
Update the only problem is Vite is objecting to moving :key attribute to the v-else:
I dont what other unique key they want.
Update II - Ok apparently if I use different object keys Vite is ok with that ie :key="item['Equipment Type'] and on v-else :key="item['Make']. Does that seem correct?
You can move the v-for in a template tag, that won't be rendered in the DOM.
<tbody>
<template v-for="item in scrapDataEmptyRowsRemoved" :key="item">
<tr v-if="item['Equipment Type']">
<td class="equipt-type" colspan="6">
Equipment Type - {{ item["Equipment Type"] }}
</td>
</tr>
<tr v-else>
<td>{{ item["Make"] }}</td>
<td>{{ item["Model #"] }}</td>
<td>{{ item["Bar Code"] }}</td>
<td>{{ item["Serial #"] }}</td>
<td>{{ item["Location"] }}</td>
<td>{{ item["Condition"] }}</td>
</tr>
</template>
</tbody>

How can I add a click event to the v-data-table?

I want to call the editItem function when the table row is clicked. Current what happens is I click on the table row and it doesn't display the details page. Yet when I put this click event on a particular table data the editItem function gets called. How can I make this same function to be called on the table row itself?
Here in my code I have tried using the the v-data-table template and slot and included the click event on the row but it is not working either
<template slot="items" slot-scope="props">
<tr #click="editItem(item), selected = item.id">
<td>{{ props.item.member }}</td>
<td>{{ props.item[1] }}</td>
<td>{{ props.item[2] }}</td>
<td>{{ props.item[3] }}</td>
<td>{{ props.item[4] }}</td>
<td>{{ props.item[5] }}</td>
<td>{{ props.item[6] }}</td>
<td>{{ props.item[7] }}</td>
<td>{{ props.item[8] }}</td>
<td>{{ props.item[9] }}</td>
<td>{{ props.item[10] }}</td>
<td>{{ props.item[11] }}</td>
<td>{{ props.item[12] }}</td>
<td>{{ props.item[13] }}</td>
</tr>
</template>
I expect that when the row is clicked, the editItem function is called
I found a way around it using #click:row
<v-data-table :headers="headers" :items="desserts" :items-per-page="5"
class="elevation-1" #click:row="handleClick">
</v-data-table>
The handleClick function returns a value of the clicked item so I call the method I want to act upon the value within the handleClick method. I also manually highlighted the clicked row since I didn't find a Vuetify way of doing so.
An example of the handleClick method is here:
handleClick(value) {
this.highlightClickedRow(value);
this.viewDetails(value);
},
You can also access the clicked row using event.target. Example is here
highlightClickedRow(value) {
const tr = value.target.parentNode;
tr.classList.add('highlight');
},
I got another solution with highlighting.
Because Anjayluh's idea was not working for me.
in Vuetify 2.0.0
template
<v-data-table
:headers="headers"
:items="desserts"
:class="[item.selected && 'selected']"
#click:row="handleClick"
/>
...
</v-data-table>
and the script method
handleClick(row) {
// set active row and deselect others
this.desserts.map((item, index) => {
item.selected = item === row
this.$set(this.desserts, index, item)
})
// or just do something with your current clicked row item data
console.log(row.sugar)
},
and a style
.selected {
background-color: red
}
This solutions is the best for, maybe help you, it's work with vuetify 2.x.
{
// inside Vue Component
methods: {
openLink(link) {
console.log(`opened link ${link}`)
}
}
}
<v-data-table
:options="{ openLink }"
>
<template v-slot:body="{ items, options }">
<tbody>
<tr
v-for="item in items"
:key="item.id"
>
<td>
<button #click="() => options.openLink(item)" />
</td>
</tr>
</tbody>
</template>
</v-data-table>
Look: Data Table Api - slots.body it is for me, the best approachable to solve this problem.

Unable to get index of array

I am trying to get the current index of an array when using v-for like so:
<tr v-for="(item,index) in timetable">
Index: #{{index}}
<td>#{{ item.subject }}</td>
<div v-if="index == timetable.length - 1">
<td>#{{ item.lesson_end }}</td>
</div>
<div v-else>
<td>#{{ item.lesson_start }}</td>
</div>
</tr>
But I only get the error message:
[Vue warn]: Property or method "index" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.
Why does it claim that index is not defined, according the docs this should be valid?
The problem is solely due to your invalid HTML structure. Vue's render function is not able to interpolate the result correctly and thus, you get that error.
Try something like
<tr v-for="(item,index) in timetable">
<td>Index: #{{ index }}</td>
<td>#{{ item.subject }}</td>
<td v-if="index == timetable.length - 1">#{{ item.lesson_end }}</td>
<td v-else>#{{ item.lesson_start }}</td>
</tr>
http://jsfiddle.net/Lrvdjxpq/

How to add class name using Vue.js to a table column which is part of a Vue.js Template? [duplicate]

This question already has answers here:
Difference between v-bind and {{}}?
(3 answers)
How can I solve "Interpolation inside attributes has been removed. Use v-bind or the colon shorthand"? Vue.js 2
(6 answers)
Closed 5 years ago.
I need to assign class name from my visitor object (visitor.iso_code) to a table column. However Vue.js will not allow me to do it this way. I've tried v-bind:class and :class and neither of them work. Any help would be appreciated. Thank you in advance.
<template lang="html">
<div>
<table id="vue_generated_visitors_table" class="table">
</table>
<tbody>
<tr v-for="visitor in visitors_table">
<th scope="row">{{ visitor.id }}</th>
<td>{{ visitor.created_at }}</td>
<td><img src="images/blank.png" class="{{visitor.iso_code}}" /> {{ visitor.country }}</td>
<td>{{ visitor.city }}</td>
<td>{{ visitor.state_name }}</td>
<td>{{ visitor.postal_code }}</td>
<td>{{ visitor.lat }}</td>
<td>{{ visitor.lon }}</td>
<td>{{ visitor.timezone }}</td>
<td>{{ visitor.currency }}</td>
<td>{{ visitor.userAgent }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script type="text/javascript">
export default {
props: ['visitors_table','method'],
data () {
return {
}
},
methods: {}
}

vue.js: Variables in attributes [duplicate]

I have a route in Laravel that requires an id as a parameter.
Route::get('/example/{id}', ExampleController#index)
If I had passed the data from the Laravel controller to the view value I would pass it like this:
Click
But my id is a vue value:
<tr v-for="item in items">
<td>#{{ item.id }}</td>
<td>#{{ item.name }}</td>
<td>#{{ item.number }}</td>
<td>#{{ item.address}}</td>
<td v-if="item.status==0">Click</td>
</tr>
Which is the correct way to do this?
You can just use v-bind for this, like following:
<a :href="'/example/' + item.id" class="button success">Click</a>