Angular Datatable Responsive Extention not working with *ngFor directive - datatables

I am working on jhipster 5.7.2 project with angular 7 and I am using angular datatables and it's responsive extension is working fine when I have static data, but when I use *ngFor directive in tag it doesn't collapse the column on resizing, just hides the column header but the column is still there.
After I resize to small window size and size back to normal the orientation of the first table row gets distorted and doesn't get fixed until I reload the page.
P.S - Struggled a lot on finding a fix, and tried giving width=100% to the table but the issue still persists.
user-management-component.html
<div>
<table datatable [dtOptions]="dtOptions" class="row-border hover" width="100%">
<thead>
<tr class="tr-bg">
<th>ID</th>
<th>Login</th>
<!-- <th>Last name</th> -->
</tr>
</thead>
<tbody>
<tr *ngFor="let user of users; trackBy: trackIdentity">
<td><span>{{user.id}}</span></td>
<td><span>{{user.login}}</span></td>
<!-- <td><span>Bar</span></td> -->
</tr>
</tbody>
</table>
</div>
Here is the ngOnInit() function where dtOptions are declared.
user-management-component.ts
ngOnInit() {
this.dtOptions = {
responsive: true
};
this.accountService.identity().then(account => {
this.currentAccount = account;
this.loadAll();
this.registerChangeInUsers();
});
}
Full size page table
Table After resizing the window
Thanks in advance for the help!

I have a half answer to your question, the code below adjusts the table, im using it to readjust my tables on sidemenu open/close. Its a half answer because I dont know when should you call it. I hope It helps
datatableElement.dtInstance.then((dtInstance: DataTables.Api) => {
dtInstance.columns.adjust().draw();
})

Related

How to init DataTable in Vue3 application after table render

I have a Vue3 component which make an ajax request to server which sends array with articles back. Then I need to render the html table according the filled model via v-for and then init DataTable via DataTable() call on this rendered table. But it seems the problem is that DataTable() call runs before html table is rendered so the table is empty.
The ajax code looks like:
getArticles()
{
axios.get( apiRoutes.ARTICLES_URL )
.then((response) => {
let data = response.data.articles;
// Fill the model
this.articles = data;
// Init DataTable
$('#dataTable').DataTable({ ... });
//setTimeout(this.setDataTable, 3000); // This works but want to avoid it.
})
},
The template code
<template>
<div class="table-responsive">
<table :id="id" class="table table-bordered nowrap" width="100%;">
<thead>
<tr>
<th>id</th>
<th>Title</th>
<th>Created</th>
<th>Visible</th>
<th>User</th>
<th></th>
</tr>
</thead>
<tbody>
<tr v-for="article in articles" :key="article.id">
<td>{{article.id}}</td>
<td>{{article.title}}</td>
<td data-order='{{article.created_at}}'>{{getCreatedAt(article.created_at)}}</td>
<td>{{article.visible}}</td>
<td>{{article.user.name}}</td>
<td>
{{article.visible === 1 ? 'hide' : 'show'}}
delete
</td>
</tr>
</tbody>
</table>
</div>
The question is how to properly wait for the render is done? Thanks for any help.
So if I understand it I need to use $nextTick() which will wait while the DOM render is done.

vue.js 2 nested components with inline templating results in error (component must have one child element only)

I'm trying to make components that would handle some table data for me. I figured the best approach is to create a component for each part of the table.
So, I have
Vue.component('my-table', { ... });
Vue.component('my-table-header', { ... });
Vue.component('my-table-header-column', { ... });
As I was writing the code, my HTML looked like this first:
<my-table inline-template>
<table>
<thead>
....
</thead>
<tbody>
....
</tbody>
</table>
</my-table>
This worked just fine.
Now I wrote the second component (my-table-header) and changed the HTML like so:
<my-table inline-template>
<table>
<my-table-header inline-template>
<thead>
....
</thead>
</my-table-header>
<tbody>
....
</tbody>
</table>
</my-table>
This however results in vue complaining that "Inline-template components must have exactly one child element."
I can't seem to find a good explanation on what I'm doing wrong here. It seems just by using a nested component, I create this issue.
The problem was indeed with table element being finicky ands stuff getting thrown out.
I finally managed to get this working with is="component-name" construct, like so:
<my-table inline-template>
<table>
<thead is="my-table-header" inline-template>
<thead>....</thead>
</thead>
<tbody>
....
</tbody>
</table>
</my-table>
Ask me not why I had to repeat the thead tag. It wouldn't render without it.

vue.js: Highlighting a newly inserted row

We are using vue.js to render logs from live stream as follows:
<tr v-else v-for="log in logs" v-cloak>
<td>{{log.id}}</td>
<td>...</td>
</tr>
We unshift the array with elements from EventSource like this:
this.eventSource.onmessage = function(log) {
if (log.data) {
vue.logs.unshift(JSON.parse(log.data));
}
};
This is all nice and working. What I would like to do is to highlight the newly inserted elements for 10 seconds with certain colour so that users can see there is something new.
This would be a good place to use a List Transition effect. Here's a sample of how to apply a highlight effect to new rows in a table:
Template
<table>
<tbody is="transition-group" name="list">
<tr v-for="log in logs" :key="log.id">
<td>{{ log.id }}</td>
<td>...</td>
</tr>
</tbody>
</table>
CSS
.list-enter-active {
transition: all 5s;
}
.list-enter {
background: yellow;
}
This will give a 5 second yellow background highlight to newly added log entries.

Editing subrow - jquery easyui edatagrid

OK- I have been beating my head against this since last Friday, I figure it is finally time to post for help. I think I have my code fairly settled, and I think things should work.
I have a grid where I edit the row, add rows, and then I expand the rows loading a subgrid (editable edatagrid). I want to simply edit and cancel the editable subgrid. However also want to take the ID column that I pass to the server page for updating from the parent row (api).
Editing and adding new rows is working, opening the fields I want as editable in an editable grid in the sub row is working. However getting the sub grid to cancel edit, save, and use iconCls will not work (iconCls code removed at the moment for the subgrid). I have not included all the code, just what is relevant to the question here so there are some other calls with missing javascript. If anybody would like that code just holler, and I will include it.
master grid
<section class="grid">
<table id="wells" class="easyui-datagrid" title=" " style="width:100%;height:500px"
pagination="true" idField="api" fitColumns="true" url="getinfo.php"
collapsible="true" singleSelect="true" toolbar="#tb" resizeHandle="both"
autoRowHeight="true" nowrap="false" rownumbers="true" pageList="[10,25,50,100,5000]">
<thead>
<tr>
<th data-options="field:'well_name', width:48" sortable="true">Name</th>
<th data-options="field:'well_num',width:18" sortable="true">Num</th>
<th data-options="field:'field',width:48" sortable="true">Field</th>
<th data-options="field:'pad',width:36" sortable="true">Pad</th>
<th data-options="field:'api',width:32" sortable="true">API</th>
<th data-options="field:'legal_description',width:46" sortable="true">Legal</th>
<th data-options="field:'county_state',width:40" sortable="true">County, State</th>
<th data-options="field:'lease',width:33" sortable="true">Lease</th>
<th data-options="field:'unit_ca_pa',width:57" sortable="true">Unit CA PA</th>
<th data-options="field:'status',width:27">Status</th>
<th data-options="field:'status_date',width:22">Updated</th>
<th data-options="field:'wildlife_stips',width:75">Wildlife Stips</th>
<th data-options="field:'notes',width:75">Notes</th>
</tr>
</thead>
</table>
master grid toolbar
<div id="tb" style="padding:3px"><span>Field:</span>
<input id="field" style="line-height:22px;border:1px solid #ccc">
<span>Pad:</span>
<input id="pad" style="line-height:22px;border:1px solid #ccc">
<span>API:</span>
<input id="api" style="line-height:22px;border:1px solid #ccc">
Search
Reset
New Well
Edit Well
</div>
expandable, edatagrid section
<script type="text/javascript">
$('#wells').datagrid(
{
view: detailview,
detailFormatter:function(index,row)
{ return '<div style="padding:2px"><table class="ddv"></table></div>'; },
onExpandRow: function(index,row)
{
var ddv = $(this).datagrid('getRowDetail',index).find('table.ddv');
ddv.edatagrid(
{
url:'geteditexpand.php?api='+row.api,
saveUrl:'updateeditwell.php?api='+row.api,
fitColumns:true,
singleSelect:true,
rownumbers:true,
loadMsg:'',
height:'auto',
columns:[[
{field:'location',title:'Location'},
{field:'NorthSouth',title:'N+S-',editor:'text'},
{field:'EastWest',title:'E+W-',editor:'text'},
{field:'latitude',title:'Latitude',editor:'text'},
{field:'longitude',title:'Longitude',editor:'text'},
{field:'lot',title:'Lot',editor:'text'},
{field:'tract',title:'Tract',editor:'text'},
{field: 'action', title: 'Action',
formatter:function(value,row,index)
{
var s = 'Save ';
var c = 'Cancel';
return s+c;
}
}
]],
onResize:function()
{ $('#wells').edatagrid('fixDetailRowHeight',index); },
onLoadSuccess:function()
{
setTimeout(function(){
$('#wells').edatagrid('fixDetailRowHeight',index);
},0);
}
});
$('#wells').datagrid('fixDetailRowHeight',index);
}
});
</script>
you dont have updateURL, im not sure
url(source)
saveUrl(NewRecord)
missing
updateUrl:'updatefile.php'

Dynamically added rows to table does not the get the Dojo style

I am working in ASP.Net MVC4 with Dojo. I have a strange problem when I am adding new rows to html table. I need to have a table which supports adding and removing rows and textboxes inside should have dojo style. I referred the post http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/ ad tried to create the same thing. Let me explain my code. Below is my view
#section scripts {
<script type="text/javascript">
require(["dojo/parser", "dijit/form/TextBox", "dijit/form/Button"]);
</script>
}
<table id="servicesTable">
<tr>
<th>
<label id="lblSelectService">
Select</label>
</th>
<th>
<label id="lblServiceName">
Name</label>
</th>
<th>
<label id="lblTitle">
AE Title</label>
</th>
</tr>
#for (int i = 0; i < Model.Services.Count; i++)
{
#Html.Partial("_ServiceRow", Model.Services[i])
}
</table>
My partial view for rendering each row is like below
#model WebUI.Models.RemDevServiceViewModel
<tr>
<td>
#Html.CheckBoxFor(x => x.IsMarked,
new { id = #String.Format("Service[{0}]IsMarked", #Model.ID) })
</td>
<td>
<input style="width: 100px; id="Service[#Model.ID]Name"
name="Service[#Model.ID].Name" type="text"
data-dojo-type="dijit/form/TextBox" value="#Model.Name"/>
</td>
<td>
<input style="width: 100px;" id="Service[#Model.ID]Title"
data-dojo-type="dijit/form/TextBox"
name="Service[#Model.ID].Title" type="text"
value="#Model.Title" />
</td>
</tr>
I have an add button which will add new row to the table. The problem that I am facing is, new row does not get the dojo style and they are rendered as normal textboxes. Initially loaded rows are rendered as dojo style text boxes, but the newly added are not like that. My jquery function to add new rows is like below
function addNewService() {
$.ajax({
url: rootPath + "MyController/AddNewService",
type: "get",
cache: false,
success: function (html) {
$("#servicesTable tbody").append(html);
},
error: function (ts) {
alert("Error while adding services");
}
});
}
Can any one tell me how to solve this? Please note that I am aware about the existence of Dojo grid. I want to take the advantage of model binding and hence following this style
Try running the parser over the added nodes. Are you seriously loading jquery on the page as well? Anyway, with the code you've got, it's kind of tricky to select the just added nodes, but if you put the following inside the success method it might work.
var newNodes = $(html).appendTo("#servicesTable tbody");
require(["dojo/parser"], function(parser){
newNodes.forEach(function(node){
parser.parse(node);
});
});
If you parse over nodes that were already parsed, the parser will throw an error. Also, if you need to support older browsers you'll want to replace the forEach with a standard for loop.
Thanks a lot David for your reply. Your code did not work exactly, but I got the idea and below code is working for me. Please dont feel that I am answering my own question. I want to format the code properly and hence using this view. Once again thanks a lot
success: function (html) {
var newNodes = $(html).appendTo("#servicesTable tbody");
require(["dojo/_base/array", "dojo/parser"], function (array, parser) {
array.forEach(newNodes, function (node, i) {
parser.parse(node);
});
});