problem with vue draggable width in table? - javascript

I'm using vuedraggable inside a Bulma table, but it creates a styling problem:
It's not a problem of the Bulma table. I used this in my own table, and the same issue occurs.
Here is my code:
<table class="table is-fullwidth is-bordered">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>brand</th>
<th>Date Created</th>
<th colspan="2">Actions</th>
</tr>
</thead>
<tfoot>
<tr>
<th></th>
<th>Name</th>
<th>brand</th>
<th>Date Created</th>
<th colspan="2">Actions</th>
</tr>
</tfoot>
<tbody>
<tr>
<td colspan="5" v-if="featureds.length == 0">0 Models Found</td>
</tr>
<draggable v-model="furds" :options="{group:'furds'}" #start="drag=true" #end="drag=false" #change="onChnage">
<tr class="dragndrop" v-for="featured in furds">
<td class="drag-icon"><i class="fa fa-arrows"></i></td>
<td>{{ featured.name }}</td>
<td>{{ featured.brand.name }}</td>
<td>{{ featured.created_at | moment("MMMM Do, YYYY") }}</td>
<td><a :href="`/manage/featured/${featured.id}`">View</a></td>
<td><a :href="`/manage/featured/${featured.id}/edit`">Edit</a></td>
</tr>
</draggable>
</tbody>
</table>

Instead of wrapping tr with draggable,pass tbody as draggable element.
<draggable element="tbody" v-model="furds">
See the link for better understanding:
https://jsfiddle.net/dede89/L54yu3L9/ (Example with table) (found in vue draggable official doc)
[[Update: full code(based on question)]]
<table class="table is-fullwidth is-bordered">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>brand</th>
<th>Date Created</th>
<th colspan="2">Actions</th>
</tr>
</thead>
<tfoot>
<tr>
<th></th>
<th>Name</th>
<th>brand</th>
<th>Date Created</th>
<th colspan="2">Actions</th>
</tr>
</tfoot>
<draggable element="tbody" v-model="furds"> <!-- change here -->
<tr>
<td colspan="5" v-if="featureds.length == 0">0 Models Found</td>
</tr>
<tr class="dragndrop" v-for="featured in furds">
<td class="drag-icon"><i class="fa fa-arrows"></i></td>
<td>{{ featured.name }}</td>
<td>{{ featured.brand.name }}</td>
<td>{{ featured.created_at | moment("MMMM Do, YYYY") }}</td>
<td><a :href="`/manage/featured/${featured.id}`">View</a></td>
<td><a :href="`/manage/featured/${featured.id}/edit`">Edit</a></td>
</tr>
</draggable>
</table>
<script>
import draggable from "vuedraggable";
export default {
components: {
draggable
},
...
}
</script>

The styling issue occurs because vuedraggable uses a <div> as its root element by default, and that <div> (along with its contents) is stuffed into the first column of the table.
Solution: vuedraggable allows changing its root element with the tag property, so you could set it to tbody, replacing the existing <tbody> in the <table>:
<table>
<!-- FROM THIS: -->
<!--
<tbody> 👈
<draggable> 👈
<tr v-for="featured in furds">
...
</tr>
</draggable>
</tbody>
-->
<!-- TO THIS: -->
<draggable tag="tbody">
<tr v-for="featured in furds">
...
</tr>
</draggable>
<table>

Related

Calculation in multiple Html tables on a single page

I want to perform calculations at the end of every table (on a footer) in a single page.
Suppose I have two tables and I want to perform calculations on a Total Amount column.
How can I do that using Jquery and Javascript?
There might be more than two tables so please be sure it works on multiple tables on a single page.
These values in HTML table are gained using for loop in Django.
This image contains 2 HTML tables and I want calculations on both table on a total amount column.
<div class="row">
<div class="table-responsive col-md-6">
<table id="example" class="table table-striped table-bordered table-responsive-xl">
<caption style="caption-side:top; text-align: center;"><h3>Income</h3></caption>
<thead class="thead-dark">
<tr>
{# <th>S No.</th>#}
<th>Particulars</th>
<th>Description</th>
<th>Total Amount</th>
</tr>
</thead>
<tbody>
{% for item in all_profit %}
{% if item.category.under == "Income" %}
<tr>
{# <td>{{ }} </td>#}
<td>{{item.category}}</td>
<td>{{item.category.desc}}</td>
<td>{{ item.balance }} </td>
</tr>
{% endif %}
{% endfor %}
</tbody>
<tfoot>
<tr class="totalColumn">
<td style="visibility:hidden;"></td>
<td>Total:</td>
</tr>
</tfoot>
</table>
</div>
I set same class for each income item's total amount then get them with Jquery and convert them to Int and calculate total.
$(document).ready(function() {
var total = 0;
$('.income-amount').each(function(i, obj) {
total += parseInt($(obj).text());
});
$('#income-total').text(total.toFixed(1));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<div class="row">
<div class="table-responsive col-md-6">
<table id="example" class="table table-striped table-bordered table-responsive-xl">
<caption style="caption-side:top; text-align: center;">
<h3>Income</h3>
</caption>
<thead class="thead-dark">
<tr>
<th>S No.</th>
<th>Particulars</th>
<th>Description</th>
<th>Total Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td>1 </td>
<td>A</td>
<td> </td>
<td class='income-amount'>2000.0 </td>
</tr>
<tr>
<td>1 </td>
<td>B</td>
<td> </td>
<td class='income-amount'>1400.0 </td>
</tr>
</tbody>
<tfoot>
<tr class="totalColumn">
<td style="visibility:hidden;"></td>
<td id='income-total'>Total:</td>
</tr>
</tfoot>
</table>
</div>

Is there a way to make v-if work in v-for to render a template dynamically to create sub-table?

I am trying to create a dynamic table which will have sub table to display values belong to main item.
Table should be like this:
http://prntscr.com/q2slsw
Also the code I am trying is like this:
<div v-for="item in detailList" class="item--detailed">
<table>
<thead>
<tr>
<th>
Date
</th>
<th>
{{item.creationDate}}
</th>
</tr>
<tr>
<th></th>
<th>
Payment Methods
</th>
<th>
Count
</th>
</tr>
</thead>
<tbody>
<template v-for="jsonItem in item.jsonData.paymentMethods">
<tr>
<td></td>
<td>
{{jsonItem.ID}}
</td>
<td>
{{jsonItem.orderCount}}
</td>
</tr>
<tr v-if="jsonItem.orderCount > 0">
<table>
<thead>
<th>Order ID</th>
<th>Creation Date</th>
<th>Status</th>
</thead>
<tbody>
<tr v-for="orderItem in jsonItem.orders">
<td>{{orderItem.orderId}}</td>
<td>{{orderItem.creationDate}}</td>
<td>{{orderItem.status}}</td>
</tr>
</tbody>
</table>
</tr>
<tr v-else>
There is no order created.
</tr>
</template>
</tbody>
</table>
</div>
The condition for v-if="jsonItem.orderCount > 0" and v-else block are not working in v-for. I have also tried v-show.
Thanks.
If possible try this code.
<div v-for="item in detailList" class="item--detailed">
<table>
<thead>
<tr>
<th>
Date
</th>
<th>
{{item.creationDate}}
</th>
</tr>
<tr>
<th></th>
<th>
Payment Methods
</th>
<th>
Count
</th>
</tr>
</thead>
<tbody>
<tr v-for="jsonItem in item.jsonData.paymentMethods">
<td></td>
<td>
{{jsonItem.ID}}
</td>
<td>
{{jsonItem.orderCount}}
</td>
<td>
<template v-if="jsonItem.orderCount > 0">
<table>
<thead>
<th>Order ID</th>
<th>Creation Date</th>
<th>Status</th>
</thead>
<tbody>
<tr v-for="orderItem in jsonItem.orders">
<td>{{orderItem.orderId}}</td>
<td>{{orderItem.creationDate}}</td>
<td>{{orderItem.status}}</td>
</tr>
</tbody>
</table>
</template>
<template v-else>
There is no order created.
</template>
</td>
</tr>
</tbody>
</table>

JS get HTML `<template>` innerHTML with table content fails

In an HTML file, I have the following content:
<template id="notWorking">
<table class="table table-xs table-hover">
<thead>
<tr>
<th>Conteneur</th>
</tr>
</thead>
<tbody>
{{ each(options.dossier.conteneurs) }}
<tr>
<td>{{ #this.numConteneur }}</td>
</tr>
{{ /each }}
</tbody>
</table>
</template>
But when I call console.log(document.getElementById("notWorking").innerHTML), I get the following:
{{ each(options.dossier.conteneurs) }}
{{ /each }}
<table class="table table-xs table-hover">
<thead>
<tr>
<th>Conteneur</th>
</tr>
</thead>
<tbody><tr>
<td>{{ #this.numConteneur }}</td>
</tr></tbody>
</table>
It seems that the element is not being parsed properly...? Am I doing something incorrectly?
See: https://codepen.io/nebrelbug/pen/OJJEvmW
<tbody> can only have <tr> as children. Text content is not allowed.

AngularJS - ng-repeat show header just once

I have 2 lists (persons and animals) that I'm displaying with ng-repeat. I want to show these two lists in one table with a heading.
Here is an example how I want to show the data.
I already tried it with ng-show="$first", but that is not the result I want to achieve.
<thead>
<tr>
<th>ID</th>
<th>BIRTHDAY</th>
<th>NAME</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="ps in $ctrl.persons" ng-if="$ctrl.valuePersons == true">
<th ng-show="$first">PERSONS</th>
<td>{{ ps.id }}</td>
<td>{{ ps.birthday | date: 'dd.MM.yyyy'}}</td>
<td>{{ ps.name }}</td>
</tr>
<tr ng-repeat="an in $ctrl.animals" ng-if="$ctrl.valueAnimals == true">
<th ng-show="$first">ANIMALS</th>
<td>{{ an.id }}</td>
<td>{{ an.birthday | date: 'dd.MM.yyyy'}}</td>
<td>{{ an.name }}</td>
</tr>
<tbody>
This will work, as per the documentation for ng-repeat.
...
<tr ng-repeat-start="ps in $ctrl.persons" ng-if="$ctrl.valuePersons == true && $first">
<th>PERSONS</th>
<td></td>
<td></td>
</tr>
<tr ng-repeat-end ng-if="$ctrl.valuePersons == true && !$first">
<td>{{ ps.id }}</td>
<td>{{ ps.birthday | date: 'dd.MM.yyyy'}}</td>
<td>{{ ps.name }}</td>
</tr>
...
This is long but can help you...
<table>
<tr>
<th>ID</th>
<th>BirthDay</th>
<th>NAME</th>
</tr>
<tr>
<td>Persons</td>
<td></td>
<td></td>
</tr>
<tr ng-repeat="ps in $ctrl.persons">
<td>{{ps.id}}<td/>
<td>{{ps.bday}}<td/>
<td>{{ps.name}}<td/>
</tr>
<tr>
<td>Animals</td>
<td></td>
<td></td>
</tr>
<tr ng-repeat="ps in $ctrl.animals">
<td>{{ps.id}}<td/>
<td>{{ps.bday}}<td/>
<td>{{ps.name}}<td/>
</tr>
</table>
var app = angular.module("Profile", [] );
app.controller("ProfileCtrl", function($scope) {
$scope.items = [{'title':'PERSON','data':[{'birth_day':'1/1/2011','name':'a1'},{'birth_day':'1/1/2011','name':'a2'},{'birth_day':'1/1/2011','name':'a3'}]},{'title':'ANIMALS','data':[{'birth_day':'1/1/2011','name':'a1'},{'birth_day':'1/1/2011','name':'a2'},{'birth_day':'1/1/2011','name':'a3'}]}]
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="Profile" ng-controller="ProfileCtrl">
<table class="table" border="1">
<thead>
<tr>
<th>ID</th>
<th>BIRTHDAY</th>
<th>Name</thu>
</tr>
</thead>
<tbody>
<tr ng-repeat-start="item in items" ng-init="main_ind= $index">
<td colspan="3">{{item['title']}}</td>
</tr>
<tr ng-repeat-end ng-repeat="val in item['data']">
<td>{{$index+1}}</td>
<td>{{val['birth_day']}}</td>
<td>{{val['name']}}</td>
</tr>
</tbody>
</table>
</body>

Add multi-row items to a table with a directive

This is my model:
$scope.orders = [
{
id: 234324,
created: '2015-05-01T13:53:25.366Z',
orderedBy: 'John Smith',
items: [
{
itemNumber: '225-3',
count: 3,
state: 'Sent'
},
{
itemNumber: '3423-1',
count: 1,
state: 'Waiting from supplier'
}
]
},
{
id: 423423,
created: '2015-06-01T13:53:25.366Z',
orderedBy: 'Eva Andersson',
items: [
{
itemNumber: '423-3',
count: 1,
state: 'Sent'
},
{
itemNumber: '234-3',
count: 3,
state: 'Sent'
}
]
}
]
Its a list with orders where each order has an array with items.
I want to show this in table.
I tried do nest ng-repeats but it proved to be difficult with the static html syntax of a table. I think I manually have to add the subelements somehow. I'm not really sure how.
JsFiddle: http://jsfiddle.net/hadey1cf/4/
Any ideas?
You can have multiple tbody so it's easy to do:
JSFiddle
<tbody ng-repeat="order in orders">
<tr class="active">
<td><b>{{order.id}}</b></td>
<td><b>{{order.orderedBy}}</b></td>
<td>{{order.created | date:'yyyy-MM-dd'}}</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr ng-repeat="item in order.items">
<td></td>
<td></td>
<td></td>
<td>{{item.itemNumber}}</td>
<td>{{item.count}}</td>
<td><span class="label label-success label">{{item.state}}</span></td>
</tr>
</tbody>
Why don't you use nested repeats? Do your first repeat on the tbody and inside it repeat over the rows for the items:
http://jsfiddle.net/mcgraphix/kfnvLts0/1/
<table class="table">
<thead>
<tr>
<th>Order Id</th>
<th>Orderd By</th>
<th>Created</th>
<th>Item id</th>
<th>Count</th>
<th>State</th>
</tr>
</thead>
<tbody ng-repeat="order in orders">
<tr class="active">
<td><b>{{order.id}}</b></td>
<td><b>{{order.orderedBy}}</b></td>
<td>{{order.date | date:'yyyy-MM-dd'}}</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr ng-repeat="item in order.items">
<td></td>
<td></td>
<td></td>
<td>{{item.itemNumber}}</td>
<td>{{item.count}}</td>
<td><span class="label label-success label">{{item.state}}</span></td>
</tr>
</tbody>
</table>
An alternative approach if you for some reason don't want more than one tbody in your table is to use the ng-repeat-start and ng-repeat-end directives as shown here:
<table class="table">
<thead>
<tr>
<th>Order Id</th>
<th>Orderd By</th>
<th>Created</th>
<th>Item id</th>
<th>Count</th>
<th>State</th>
</tr>
</thead>
<tbody>
<!-- repeat will start with this but won't end with the closing tr tag
Instead it will end at the ng-repeat-end directives closing tag. see below-->
<tr class="active" ng-repeat-start="order in orders">
<td><b>{{order.id}}</b></td>
<td><b>{{order.orderedBy}}</b></td>
<td>{{order.date | date:'yyyy-MM-dd'}}</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr ng-repeat="item in order.items">
<td></td>
<td></td>
<td></td>
<td>{{item.itemNumber}}</td>
<td>{{item.count}}</td>
<td><span class="label label-success label">{{item.state}}</span></td>
</tr>
<!-- the outer repeat will end when this tag is closed. I'm seeting "display:none" so that it doesn't show a gap in your table -->
<tr ng-repeat-end><td colspan="6" style="display:none"></td></tr>
</tbody>
</table>
I think my first answer is a better way to go though since logically you have groups of content in your table which is what tbody is for. It is valid html to have more than one as the HTML DTD states:
<!ELEMENT table
(caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))>
However, it is good to understand how the ng-repeat-start and ng-repeat-end works as there are many cases where this is useful.
You can use the ng-repeat-start and ng-repeat-end directive.
You can find more information about it here
Please see working example
<script type="text/ng-template" id="orders.tmpl.html">
<h2 class="page-header">Orders-directive</h2>
<table class="table">
<thead>
<tr>
<th>Order Id</th>
<th>Orderd By</th>
<th>Created</th>
<th>Item id</th>
<th>Count</th>
<th>State</th>
</tr>
</thead>
<tbody>
<tr class="active" ng-repeat-start="order in orders">
<td><b>{{order.id}}</b></td>
<td><b>{{order.orderedBy}}</b></td>
<td>{{order.date | date:'yyyy-MM-dd'}}</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr ng-repeat-end="" ng-repeat="item in order.items">
<td></td>
<td></td>
<td></td>
<td>{{ item.itemNumber }}</td>
<td>{{ item.count }}</td>
<td><span class="label" data-ng-class="{'label-success':item.state=='Sent', 'label-primary':item.state=='Waiting from supplier'}">{{ item.state }}</span></td>
</tr>
</tbody>
{{content}}
</script>

Categories