How do i drag multiple rows using vue.draggable? - html

I wanted to drag multiple table data in a row instead of just a single td tag. In other words, when i drag either columns, i want to drag both the "Random" and "name" column together.
<table id="app">
<tr>
<th>Random</th>
<th>name</th>
</tr>
<tr>
<td>
<draggable v-model="items">
<transition-group name="list-complete">
<div v-for="item in items"
v-bind:key="item.message"
class="list-complete-item">
{{ item.message }}
</div>
</transition-group>
</draggable>
</td>
<td>
<div v-for="item in items" class="list-complete-item">
{{ item.name }}
</div>
</td>
</tr>
</table>
I have tried shifting and playing around with the draggable tag and the transition-group tag but nothing seems to work.
Please help. :(
Here is my jsfiddle code ->
https://jsfiddle.net/wusprtnL/63/

This is not supported by Sortable nor by Vue.draggable. So there are no combination of options that will make irt work. Reference: https://github.com/SortableJS/Sortable/issues/1049

Right now this is supported as a plugin by sortable, but the plugin has not been integrated in vue.draggable.
https://github.com/SortableJS/Vue.Draggable/issues/649

Related

Vertical table header in vuetify

I need to display a table with a vertical header instead of the traditional horizontal header. Since the table has to be under another table that is using Vuetify, I want to make the vertical table using the same layout using Vuetify as well.
In plain html/css I know that you can optain this using TH as rows:
<table>
<tbody>
<tr>
<th scope="row">A</th>
<td>b</td>
</tr>
<tr>
<th scope="row">C</th>
<td>d</td>
</tr>
</tbody>
</table>
However, Vuetify doesn't allow that much of modification of its framework and I can't find any other way using their documentation: https://vuetifyjs.com/en/components/data-tables/
Is there any other way to make a vertical table with Vuetify?
You can specify body inside v-data-table with slots.
<v-data-table
:items="desserts">
<template v-slot:body="{ items }">
<tbody>
<tr v-for="header in headers">
<td>
{{ header.text }}
</td>
<td v-for="item in items">
{{ item[header.value] }}
</td>
</tr>
</tbody>
</template>
</v-data-table>

VueJs v-for renders divs but not table rows?

I'm having trouble understanding why this is happening! So, this block of code:
<div class="container">
<div class="row" v-for="rows in data.Rows"> {{ rows }} </div>
</div>
Will render all the rows in the object.
But, when I use the same syntax in a table instead like this:
<table>
<tr v-for="rows in data.Rows"> {{ rows }} </tr>
</table>
I get the error:
[Vue warn]: Property or method "rows" 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.
How come there are issues in using the v-for like this in a table? I want a table to display the data as it better suits the purpose in this case. Othewise I would have chosen divs instead of table rows, but I would love for this to works. Any ideas as to why this is happening?
If you use that template directly within an HTML file (as opposed to a template string or SFC) it will be parsed by the browser before it gets to Vue. Browsers are fussy about tables and what elements are allowed inside which other elements.
The example below shows how the browser will parse your template into DOM nodes. Notice how the {{ rows }} gets moved:
let html = document.getElementById('app').innerHTML
html = html.replace(/</g, '<').replace(/>/g, '>')
document.getElementById('output').innerHTML = html
#app {
display: none;
}
<div id="app">
<table>
<tr v-for="rows in data.Rows"> {{ rows }} </tr>
</table>
</div>
<pre id="output">
</pre>
It is this mangled version of the template that Vue is trying to run and as you can see {{ rows }} has been moved outside the v-for, causing the error.
The official documentation covers this here:
https://v2.vuejs.org/v2/guide/components.html#DOM-Template-Parsing-Caveats
The solution would just be to include a <td> in your template:
<table>
<tr v-for="rows in data.Rows">
<td>{{ rows }}</td>
</tr>
</table>
You cannot directly use "rows" property inside tr tag, you need td tag
like this
<table>
<tr class="row" v-for="rows in data.Rows"> <td>{{ rows }} </td></tr>
</table>
working codepen here: https://codepen.io/chansv/pen/dyyVybK

Angular 2 Make entire row clickable

I want to make each row of a table clickable in Angular 2. However, only the parts of the cell that contain data are clickable. i.e. if one cell contains more data than another, and so has a greater height, the empty bit of the smaller cell is not clickable.
For example, in the page below the first cell is only clickable on the line containing the name, whereas the entirety of the second cell is clickable
<table>
<thead></thead>
<tbody>
<tr *ngFor="let item of items" routerLink="/otherpage/{{item.Id}}">
<td>{{item.name}}</td>
<td>
<ul>
<li *ngFor="let detail of item.details">
{{detail}}
</li>
</ul>
</td>
</tr>
</tbody>
</table>
I've fixed the routerLink code for you.
<table>
<thead></thead>
<tbody>
<tr class="clickable" *ngFor="let item of items" [routerLink]="['/otherpage/', item.Id]">
<td>{{item.name}}</td>
<td>
<ul>
<li *ngFor="let detail of item.details">
{{detail}}
</li>
</ul>
</td>
</tr>
</tbody>
</table>
You need to add CSS for the animation.
clickable {
cursor: pointer;
}
This will make the entire <tr></tr> clickable with the cursor animation
set the padding for the <tr> to 0. this way the <td> elements would fill the rows, hence making the whole cell clickable.
note that depending on your css file this might be a bit more difficult. but the solution is basically to make your data cover your rows.

ngIf for closing/opening tag

I have a table and I'm iterating in a over an array. In some scenarios, I'll want to add an extra <tr>. I'm looking for something like this:
<table>
<tr *ngFor="let element in array">
<td>
some content
</td>
//Starting block that will only be activated if some variable is true
</tr>
<tr>
<td>
some extra content
</td>
//End of the block that will only be activated if some variable is true
</tr>
</table>
Is there a way to create a boulder html that can wrap it like this?
The options I've tried so far are changing the data structure (array) so it include the element I'm looking for but I'm not pleased with having extra data there just for displaying purpose.
This should do what you want
<table>
<ng-container *ngFor="let element in array"
<tr>
<td>
some content
</td>
</tr>
<tr *ngIf="someVar">
<td>
some extra content
</td>
</tr>
</ng-container>
</table>
Perhaps the best option is to work with ng-repeat.
Example with ng-repeat:
<table ng-controller="myCtrl">
<tr ng-repeat="x in records">
<td>{{x.Name}}</td>
<td>{{x.Country}}</td>
</tr>
</table>
Ng-repeat makes a for in your object or array.
See if this can help you.

Pre-render angular's template to re-use them

I have an HTML structure with a list of tables like this
<div ng-repeat="row in rows">
<table>
<td ng-repeat="row2 in rows2">
<tr ng-repeat="col in cols">
{{blablabla}}
</tr>
</td>
</table>
</div>
The table is always quite the same, but Angular just redraw it every times (for each elements in 'rows'), which leads to some performance issues.
Is there a way to tell angular to pre render the table in the middle, and then display the list ?