Complex headers in angular2-data-table - javascript

I'm trying to create a table with a complex header (multi-line header) like this:
using the angular-2-data-table library found here:
https://github.com/swimlane/angular2-data-table
They have something called "Expressive cell templates" in which you can define columns like this:
<datatable
class="material"
[rows]="rows"
[options]="options">
<datatable-column name="Name">
<template let-column="column">
Hi + {{column.name}}
</template>
<template let-value="value">
Hi: <strong>{{value}}</strong>
</template>
</datatable-column>
<datatable-column name="Gender">
<template let-row="row" let-value="value">
My name is: <i [innerHTML]="row['name']"></i> and <i>{{value}}</i>
<div>{{joke}}</div>
</template>
</datatable-column>
</datatable>
plnkr here
But it seems like the column name is always defined as text, and it's unclear how you would have nested column names. Any ideas if complex headers are possible in angular2-data-table? It's possible in regular datatables (https://datatables.net/examples/advanced_init/complex_header.html).
Thanks in advance!

Related

How can I properly format a Vue component?

I would have thought the below would work but it doesn't seem to lay the data out nicely and in a grid like fashion according to this website;
https://bootstrap-vue.org/docs/components/layout
<template>
<div>
<div v-for="i in items">
<b-container class="bv-example-row">
<b-row>
<b-col>Home</b-col>
<b-col>Road</b-col>
<b-col>Home ATS</b-col>
<div class="w-500"></div>
<b-col>{{i.Home_Neutral}}</b-col>
<b-col>{{i.Visitor_Neutral}}</b-col>
<b-col>{{i.ATS}}</b-col>
</b-row>
</b-container>
</div>
</div>
</template>
Can anyone give me some tips on how I can nicely format this data as it doesn't appear to be working for me? I basically just want to get the data spread out more and into a box like this;
example

Vue dynamic components not re rendering inside v-for loop when data changes

I have dynamic table component where I can modify columns (ordering, adding new, removing columns). Table body looks like this:
<tr v-for="row in data" :key="row.id">
<td v-for="column in columns" :key="column.slug">
<component
v-if="column.component"
:is="column.component"
v-bind="{ row: row, countries: row.reach }"
/>
<template v-else>
{{ row[column.slug] }}
</template>
</td>
</tr>
Everything works well except when I edit data (add new column or rearrange the order) then every component inside table body disappears and is not rendered. I tried to attach unique :key to <component> but was not able to make it work. When I inspect table body in Vue devtools I can see that components are inside just not rendered into DOM. When inspecting table body in chrome devtools I can see only <!--function(e,n,r,o){return dn(t,e,n,r,o,!0)}--> in place where component should be rendered. Any ideas what I might be doing wrong here?
You are using duplicated keys. You should provide unique keys for all v-for elements inside the whole component. Try this (see key for every column):
<tr v-for="row in data" :key="row.id">
<td v-for="column in columns" :key="`${row.id}/${column.slug}`">
<component
v-if="column.component"
:is="column.component"
v-bind="{ row: row, countries: row.reach }"
/>
<template v-else>
{{ row[column.slug] }}
</template>
</td>
</tr>
Also when you are in development it is highly recommended to use Vue development mode. It will highlight errors like this.
Turns out I was passing Component object into :is directive instead of string with Component name. That's why it was not rendered properly.

How to add tooltip to datatable header in vuetify?

In older version on vuetify you could access headerCell slot and easily add tooltips - see https://codepen.io/nueko/pen/dZoXeZ
In the latest version you have named slots, so you need to know header name before
<template v-slot:header.givenname="{ header }">
Is there a way to add a tooltip to all headers?
There are 2 ways to achieve this.
Option 1: Customizing whole table row
If you need to customize whole row element inside table heading this might be useful. Even though I would not recommend to follow this way if you don't want to loose sorting functionality which exist by default in v-data-table.
Example:
<template v-slot:header="{ props: { headers } }">
<thead>
<tr>
<th v-for="h in headers">
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<span v-on="on">{{h.text}}</span>
</template>
<span>{{h.text}}</span>
</v-tooltip>
</th>
</tr>
</thead>
</template>
Working pen: https://codepen.io/onelly/pen/QWWmpZN
Option 2: Customizing each heading without losing sorting functionality
I guess this is more like what you are trying to do and the replacement for the old way. You can loop <template v-slot:header> and use Dynamic Slot Names to accomplish this. Syntax for Dynamic slot name looks like this <template v-slot:[dynamicSlotName]>.
Example:
<template v-for="h in headers" v-slot:[`header.${h.value}`]="{ header }">
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<span v-on="on">{{h.text}}</span>
</template>
<span>{{h.text}}</span>
</v-tooltip>
</template>
Working pen: https://codepen.io/onelly/pen/ExxEmWd

Using v-edit-dialog with components?

i had a question about the v-edit-dialog component that vuetify offers. So, the way i am rendering my v-data-table is such that i am importing a component with props into a template slot. According to the documentation link, it seems like the data table has to be rendered directly, like this codepen.
So i am not sure how i can make the v-edit-dialog work using my approach.
Here is what my code looks like:-
<template>
<v-data-table>
<template v-slot:items="props">
<my-component
:protein="props.item.protein"
:carbs="props.item.carbs"
:fats = "props.item.fats"
:iron="props.item.iron"/>
</template>
<v-data-table>
</template>
I am sorry guys, i don't know how i can duplicate this issue but i hope you get some idea. Again, thank you in advance.
You should take a look at the documentation for component props.
What you have done by now is correct and should work, only if you have setup your component my-component correctly:
<!-- my-component example -->
<template>
<v-edit-dialog :return-value.sync="protein">
{{ protein }}
<template v-slot:input>
<v-text-field
v-model="protein"
:rules="[max25chars]"
label="Edit"
single-line
counter
/>
</template>
</v-edit-dialog>
</template>
<script>
export default {
name: 'my-component',
props: {
protein: {
type: String,
default: '',
}, //... the rest of the props you want to access
},
}
</script>
In order to make the protein and other props edit/mutate/update your props.item.protein etc, you have to add a sync modifier to the prop.
<template>
<v-data-table>
<template v-slot:items="props">
<my-component
:protein.sync="props.item.protein"
:carbs.sync="props.item.carbs"
:fats.sync="props.item.fats"
:iron.sync="props.item.iron"/>
</template>
<v-data-table>
</template>
Else, you will get a vue error "you should not mutate an prop directly"
<template v-slot:items="props">.
for this eazy right is
<template v-slot:items="{ item }">
<my-component
{{item. protein}}

Default/Overridable content for Aurelia template (template parts)

I'm trying to dip my toes into the Aurelia framework. I'm trying to create a reusable pager component.
Is there a way to provide some default content, but allow it to be overridden if the user of the component so desires?
For instance, my pager.html looks like this:
<template>
<div class="pager-container">
<content select="pager-beginning"></content>
</div>
</template>
my pager-beginning.html looks like this:
<template>
<content>
<button type="button">|<</button>
</content>
</template>
I was thinking I should be able to do something like this:
<template>
<require from="components/pager/pager"></require>
<pager></pager>
</template>
and have the markup produced look like this:
<div class="pager-container">
<button type="button">|<</button>
</div>
or alternatively I should be able to do something like this:
<template>
<require from="components/pager/pager"></require>
<pager>
<pager-beginning><button type="button"><i class="glyphicon glyphicon-step-backward"></i></button></pager-beginning>
</pager>
</template>
and have the markup produced look like this:
<div class="pager-container">
<button type="button"><i class="glyphicon glyphicon-step-backward"></i></button>
</div>
The idea being that I could provide all of the functionality of a pager, all of the logic specific to a pager in my pager.js file and a default html rendering, but then allow the user of the component to override pieces of the html if they so desired.
What currently seems to be happening is that the markup inside of the pager-beginning.html <content></content> tag is always getting replaced. So I get markup rendered that looks like this:
<div class="pager-container"></div>
I can't figure out how to provide it with that 'default' content functionality.
Use the "template parts" feature. More info here (search for "template parts").
pager.html
<template>
<div class="pager-container">
<button type="button" click.delegate="gotoBeginning()">
<template replaceable part="goto-beginning-button-content">|<</template>
</button>
</div>
</template>
app.html
<template>
<require from="./components/pager/pager"></require>
<pager>
<template replace-part="goto-beginning-button-content">
<i class="glyphicon glyphicon-step-backward"></i>
</template>
</pager>
</template>

Categories

Resources