Vue Component - Rendering in wrong location - javascript

I am seeing strange behavior between a vue component and inline template.
Example #1: Inline Template
This is working as expected. The vue component is unchanged as per example #2 below, the only difference is i've copied the template content into the tag as an inline template.
See: https://jsfiddle.net/pobffmnv/
<div class="panel panel-primary">
<div class="panel-heading">Current Clients</div>
<table class="table table-hover">
<thead>
<tr>
<th>Client Name</th>
<th style="text-align: center;">No. Projects</th>
<th style="text-align: center;">Time (7 days)</th>
<th style="text-align: center;">Edit</th>
</tr>
</thead>
<tbody>
<clientlistitem inline-template>
<tr>
<td>Test</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">
<div class="btn-group btn-group-xs" role="group">
<button type="button" class="btn small btn-primary">Edit</button>
</div>
</td>
</tr>
</clientlistitem>
</tbody>
</table>
</div>
This correctly shows the following:
Example #2: Not inline
The following is my Vue template. Below is the change to the code to remove the inline template.
See: https://jsfiddle.net/Ld47hoy2/
<template>
<tr>
<td>Test</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">
<div class="btn-group btn-group-xs" role="group">
<button type="button" class="btn small btn-primary">
Edit
</button>
</div>
</td>
</tr>
</template>
<script>
export default {
}
</script>
Updated page code:
<div class="panel panel-primary">
<div class="panel-heading">Current Clients</div>
<table class="table table-hover">
<thead>
<tr>
<th>Client Name</th>
<th style="text-align: center;">No. Projects</th>
<th style="text-align: center;">Time (7 days)</th>
<th style="text-align: center;">Edit</th>
</tr>
</thead>
<tbody>
<clientlistitem></clientlistitem>
</tbody>
</table>
</div>
However, with the above, the following is displayed:
Looking at the source code of the output of the page, it appears to have put the rendered code BEFORE my table...? I am expecting this to be between the <tbody></tbody> tags..
Any reason why Vue would output the code to that location instead of the one expected?

The issue here is that with in DOM templates the templates are first rendered by the browser and HTML tables only allow certain kinds of elements inside. That being the case, the component clientlistitem is first rendered outside the table, then Vue compiles the template which results in the component in the wrong place.
To fix that, use the is special attribute.
<tbody>
<tr is="clientlistitem"></tr>
</tbody>
The browser will accept this and render the tr in the correct place, but Vue will interpret it as your component.
Here is your fiddle updated.

Related

How Do I Access Elements in Specific Sections of A Table

how would I access the hair with Javascript (as in Black)? I tried using normal accessing from within other elements gradually through defining variables accessing the table and tr it was in, but it still didn't work. Please respond if you have an answer. Thx
<table id="customers" class="customers">
<tr class="parent" data-toggle="toggle">
<th id="rank" style="text-align: center;">Number</th>
<th id="name" style="text-align: center;">Name</th>
<th id="name" style="text-align: center;"></th>
</tr>
<tbody class="content">
<div class="one">
<tr>
<td>1</td>
<td class="name">Object A</td>
<td class="down">
<button onclick="toggleText()" type="button" class="collapsible" id="1">
+
</button>
</td>
</tr>
</div>
<tr class="panel" id="one-a" colspan="3">
<div class="panel">
<td class="expand">
<div class="hair">
Black
</div>
</td>
</div>
</tr>
</tbody>
</table>
It may have something to do with the table being a table and not being able to fetch certain values like normal code.
Try
var hairColor = document.getElementsByClassName("hair")[0].innerHTML;
it will return an array of elements , your array will be of length 1 (because you only have one tag with the specified class, "hair" in this case) so the value you need is of index 0.
How to use JavaScript to get elements by class name?

Bootstrap 4 html tooltip in bootstrap table angular 8 for loop

I am trying to add the html tooltip in the table.
Included the below CDN:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
Table code:
<table class="table table-bordered">
<thead *ngIf="serchResults">
<tr>
<th scope="col">Description</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of serchResults">
<td data-container="body" data-toggle="tooltip" data-html="true" title="<p>Mapped to: </p> <p>Abcd data </p> <p> Test data </p><p> Test data two </p><p> Test data 3</p>">
{{item.title}}
</td>
<td><input type="checkbox" id="{{item.code}}" name="{{item.code}}" value="{{item.code}}"></td>
</tr>
</tbody>
</table>
Jquery:
<script>
$(function() {
$('[data-toggle="tooltip"]').tooltip({
html: true,
});
});
</script>
Please have a look at the below screenshot. HTML tooltip is not working.
The tooltip HTML is not getting displayed properly in the table and inside for loop. Also applied CSS to "inner-tooltip" is not working inside for loop as well as without for loop.
First thing, avoid using jquery, you can use ngx-bootstrap.
Still, to fix this issue, you might need to run the below script after searchResults has been set. Reason, ngFor creates the DOM only after it has got the object on which it is iterating on. Once the serachResults object is available you need to run.
$(function() {
$('[data-toggle="tooltip"]').tooltip({
html: true,
});
});
Found the solution. It was simple.
<table class="table table-bordered" *ngIf="serchResults; else elseTable">
<thead>
<tr>
<th scope="col">Description</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of serchResults">
<td>
<span data-container="body" data-toggle="tooltip" data-html="true" [tooltip]="tooltipData" placement="bottom">{{item.title}}</span>
<ng-template #tooltipData><p [innerHtml]="createTooltip(item)"></p></ng-template>
</td>
<td><input type="checkbox" id="item.code" name="item.code" value="item.code" (change)="fieldsChange($event, item)"></td>
</tr>
</tbody>
</table>

nested ng-repeat for object within an object within an object

I want to achieve the above image using angular-js ng-repeat. i got a problem for the third column.
<div tasty-table
bind-resource-callback="showTCS.loadAllTCS"
bind-init="showTCS.init"
bind-filters="showTCS.listParams"
bind-reload="showTCS.reloadCallback">
<table class="table table-striped table-condensed table-hover table-bordered table-overflow"
cellpadding="4"
cellspacing="4"
align="center">
<thead tasty-thead bind-not-sort-by="showMainCategory.notSortBy"></thead>
<tbody>
<tr ng-repeat="tcs in rows">
<td>{{tcs.trackName}}</td>
<td>
<table align="left">
<tbody>
<tr ng-repeat="category in tcs.category">
<td>{{category.categoryName}}</td>
<td>
<table> //this one should be on the 3rd <td> of parent table
<tbody>
<tr ng-repeat="skill in category.skill">
<td>{{skill.skillName}}</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
<td align="center">
<a ui-sref="mainCategoryDetails( {mainCatId: mainCategory.mainCat_id} )" class="glyphicon glyphicon-eye-open"></a>
</td>
</tr>
<tr>
<td ng-if="(!rows.length)" colspan="4" class="text-center">No results found.</td>
</tr>
</tbody>
</table>
<div tasty-pagination bind-items-per-page="showTCS.itemsPerPage" bind-list-items-per-page="showTCS.listItemsPerPage"></div>
</div>
This is what i have tried so far and the output is not what i want as shown in the sample image. The problem is how to output the last data which is skills in the third of the parent table.
Found an answer, not quite good since it keeps repeating the tbody but its still ok
<div class="row-fluid" style="padding-top: 2%">
<div tasty-table
bind-resource-callback="showTCS.loadAllTCS"
bind-init="showTCS.init"
bind-filters="showTCS.listParams"
bind-reload="showTCS.reloadCallback">
<table class="table table-striped table-condensed table-hover table-bordered table-overflow"
cellpadding="4"
cellspacing="4"
align="center">
<thead tasty-thead bind-not-sort-by="showTCS.notSortBy"></thead>
<tbody ng-repeat="tcs in rows">
<tr ng-repeat="category in tcs.category">
<td class="text-center" style="vertical-align:middle;">{{tcs.trackName}}</td>
<td class="text-center" style="vertical-align:middle;">{{category.categoryName}}</td>
<td>
<ul class="list-unstyled" >
<li ng-repeat="skill in category.skill">{{skill.skillName}}</li>
</ul>
</td>
<td align="center">
<a ui-sref="mainCategoryDetails( {mainCatId: mainCategory.mainCat_id} )" class="glyphicon glyphicon-eye-open"></a>
<a ui-sref="editMainCategory( {mainCatId: mainCategory.mainCat_id} )" class="glyphicon glyphicon-edit"></a>
<a ui-sref="deleteMainCategory( {mainCatId: mainCategory.mainCat_id} )" class="glyphicon glyphicon-minus-sign"></a>
</td>
</tr>
<tr>
<td ng-if="(!rows.length)" colspan="4" class="text-center">No results found.</td>
</tr>
</tbody>
</table>
<div tasty-pagination bind-items-per-page="showTCS.itemsPerPage" bind-list-items-per-page="showTCS.listItemsPerPage"></div>
</div>

Build HTML from javascript

I have an HTML table which is built in the following way:-
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Party</th> <th>Name</th> <th>Chamber</th> <th>District</th> <th>State</th>
</tr>
</thead>
<tbody>
<tr dir-paginate="user in users|filter:search|itemsPerPage:10">
<td> <img src="{{user.party_name}}" style="max-height: 10%;max-width: 10%;"/> </td>
<td>{{user.fullname}}</td>
<td > <img src="{{user.chamber_type}}" style="max-height: 8%;max-width: 7%;"/>{{user.chamber_name}} </td>
<td>{{user.district_name}}</td>
<td>{{user.state_name}}</td>
<td> <button type="button" class="btn btn-primary">View Details</button></td>
</tr>
</tbody>
</table>
Is it possible to create this table from javascript and in the HTML I just create a div and append the created table from javascript into this div. I tried placing the above content in a javascript variable and do an append but it did not work out. Is there a way to do this?? I think it did not work out may be because of the Angular JS variables. Correct me if I am wrong. I am pretty new to this.
In AngularJS use <div ng-bind-html="html-var"></div> and save the html-code in $scope.html-var.
For that you need to include <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular-sanitize.js"></script>

Bootstrap Table with each row as collapsible

I am working on an application.
The requirement is I have a table and each row is populated via ng-repeat from json data.
While clicking on each row the row has to expand and there would be an nested table and clicking on any row on nested table will expand that row and there would be another nested table.
Till now I am not even able to get the first nested table to open while clicking on row.
Ideally I prefer the each nested view to have a separate html template, but for simplicity I am trying with normal collapsible div.
Here is my code.
<div class="col col-md-12 col-sm-12 col-xs-12">
<table class="table table-responsive table-hover">
<thead>
<tr>
<th>ID</th>
<th>Status</th>
<th>Name</th>
<th>Description</th>
<th>Size</th>
<th>Level</th>
</tr>
</thead>
<tbody>
<tr class="clickable" data-toggle="collapse" data-target="#endpoints" data-ng-repeat="data in datafromservice">
<td>{{data.id}}</td>
<td>{{data.status}}</td>
<td>{{data.name}}</td>
<td>{{data.description}}</td>
<td>{{data.size}}</td>
<td>{{data.level}}</td>
<!-- edit button -->
<td class="edit"><i class="glyphicon glyphicon-pencil"></i>
</td>
<!-- button button -->
<td class="delete"><i class="glyphicon glyphicon-trash"></i>
</td>
</tr>
</tbody>
<div class="collapse" id="endpoints">
<p>Hello world</p>
</div>
</table>
</div>
I must be missing something very obvious, and I am not able to figure out.

Categories

Resources