Generating pure html using AngularJS - javascript

I'm trying to extract a raw HTML table of data from a table which I currently generate on a web page using AngularJS.
To give a simple example:
Angular code:
<table>
<tr ng-repeat="customer in customers">
<td>{{customer.firstname}}</td>
<td>{{customer.lastname}}</td>
</tr>
</table>
I don't want to code two different solutions and so would like to use AngularJS.
Is it possible to extract the raw html code using AngularJS? i.e. the following :
<table>
<tr>
<td>John</td>
<td>Smith</td>
</tr>
<tr>
<td>Fred</td>
<td>Bloggs</td>
</tr>
...etc
</table>

you can use
var element = angular.element(element)
element[0] //show give raw dom element
refer jqlite and below link in angularJS , probably will get idea https://docs.angularjs.org/api/ng/function/angular.element
Fiddle: https://jsfiddle.net/shushanthp/Lho8myw2/

Related

Using JavaScript variables in a Thymeleaf th:each

I am trying to build a table using th:each and have the whole row of the table clickable as a link through JavaScript.
<table>
<th:block th:each='user : ${list}'>
<script th:inline="javascript">
var userid = [[${user.id}]];
</script>
<tr onclick="location.href='user?id='+userid">
<td th:text="${user.firstName}"></td>
<td th:text="${user.lastName}"></td>
</tr>
</th:block>
</table>
However, the variable always refers to the latest value and not the one it was when the row was created. Is there a way to do that? Or maybe a different solution to what I'm trying to do?
No need for the th:block, you can simply put the th:each on the tr.
To accomplish the click, I recommend putting the id in a data attribute, and retrieving it in JavaScript. This should work for you:
<table>
<tr th:each="user : ${list}"
th:data-id="${user.id}"
onclick="location.href = 'user?id='+this.getAttribute('data-id')">
<td th:text="${user.firstName}"></td>
<td th:text="${user.lastName}"></td>
</tr>
</table>
You can avoid using JavaScript by adding an <a> element to each table cell (Inspired by https://stackoverflow.com/a/17147909/40064):
<table>
<th:block th:each='user : ${list}'>
<tr>
<td><a th:href="#{/user(id=${userid})}" th:text="${user.firstName}"></a></td>
<td><a th:href="#{/user(id=${userid})}" th:text="${user.lastName}"></a></td>
</tr>
</th:block>
</table>

Regarding AngularJS and datatable combination

First and foremost, hello! I'm new here.
I've been recently learning AngularJS and web development as I'm working so I apologize for my newbieness. I had stumbled upon a wall of sorts regarding datatable integration with AngularJS. Here's the structure of it:
<table class="datatable table table-hover">
<thead>
<tr>
<th ng-repeat="column in columns">
{{column.name}}
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="form in forms | filter : {userName : activeFilter['user name']|rangeDate:activeFilter['range begin']:activeFilter['range end']:'birthDate'">
<td class="row-md-1">
<span ng-model="approvedForm.userName">
{{approvedForm.userName}}
</span>
</td>
<td class="row-md-1">
<span ng-model="approvedForm.birthDate">
{{approvedForm.birthDate}}
</span>
</td>
</tr>
</tbody>
</table>
I've to mention I make use of the filters on the client side, so they can choose the correct rows. The problem was that upon filtering some users and row-sorting with datatable, the data would get misteriously duplicated on the view, and I couldn't delete it or whatsoever. To solve it I had to take out the ng-repeat filters and filter with datatable filter support. Does anybody know what might have caused this behaviour?
Btw I'm using angularJS 1.x and datatable 1.10
Thanks!
Your data is duplicating because you bind it twice as the attribute of the HTML element and with handlebars. Remove either ng-model="..." attribute or {{...}} in your code so it would look like this:
<span>
{{approvedForm.userName}}
</span>
as #Shaishab Roy mentioned ng-model is not supposed to work with <span> so try ng-bind instead:
<span ng-bind="approvedForm.userName"></span>

Vue.js block repeat table rows doesn't work in IE

I would like to repeat adding table rows using a template tag with vue.js, but it doesn't work in IE11. Here is the code.
<table border="1">
<tr>
<td rowspan="2">ID</td>
<td colspan="2">Name</td>
</tr>
<tr>
<td>Height</td>
<td>Weight</td>
</tr>
<template v-repeat="items">
<tr>
<td rowspan="2">{{id}}</td>
<td colspan="2">{{name}}</td>
</tr>
<tr>
<td>{{height}}</td>
<td>{{weight}}</td>
</tr>
</template>
</table>
Any help?
See http://vuejs.org/guide/components.html#Using_Components and the warning at the end of that section:
The table element has restrictions on what elements can appear inside
it, so custom elements will be hoisted out and not render properly. In
those cases you can use the component directive syntax:
<tr v-component="my-component"></tr>.
I found a solution that changed the <template> tag to a <tbody> tag. However there would be multiple <tbody> tags in a table, I hope this is the best solution in this case.
Make a long story short, This is HTML restrictions in IE, if you want compatibility, you will have to change your HTML structure.
I found an issue with similar question like yours here: https://github.com/vuejs/vue/issues/2404
Vue renders the template into real html before compiling it, so the same html restrictions apply for Vue templates, no matter how you define it.
IE does not support inside elements like , ..

jQuery With Mustache js Issue

I'm using jQuery and Mustache Js in a project.
I have the template in a script tag. The template requires some dynamic/variable html based on some data. Hence I load the template using jQuery, manipulate it, and then write it back into the script tag.
However, loading the template into a div(for manipulation), using jquery seems to alter the structure of the template (it moves things around), which invalidates the template.
How do i update the template dynamically and avoid this issue? (Any help / Pointers / etc)
Original Template
<table>
<thead>
<tr>
<td>FN</td>
<td>SN</td>
<td>OT</td>
</tr>
</thead>
<tbody>{{#Users}}
<tr class="tr-border" data-row-id="{{DCSID}}">
<td class="td-border">{{FN}}</td>
<td class="td-border">{{SN}}</td>
<td class="td-border">{{OT}}</td>
</tr>{{/Users}}</tbody>
</table>
Loading with jquery into another div causes this below(moves {{#Users}} {{/Users}} out of place)
{{#Users}} {{/Users}}
<table>
<thead>
<tr>
<td>FN</td>
<td>SN</td>
<td>OT</td>
</tr>
</thead>
<tbody><tr class="tr-border" data-row-id="{{DCSID}}">
<td class="td-border">{{FN}}</td>
<td class="td-border">{{SN}}</td>
<td class="td-border">{{OT}}</td>
</tr></tbody>
</table
The code below is how I'm going about it. Also this is a js fiddle link here
var $newDcsTemplate = $('<div/>').html($('#dcs-template').html()); // for manipulation
var original1 = $('#dcs-template').html()
var original2 = document.getElementById('dcs-template').innerHTML;
// manipulate the template here and replace content of script tag with it.
console.log(original1); // works fine
console.log(original2) // works fine
console.log($newDcsTemplate.html()) // messed up the template
Do it like this, with .html() and without </script>:
<table>
<thead>
<tr>
<td>FN</td>
<td>SN</td>
<td>OT</td>
</tr>
</thead>
<tbody>
<!-- {{#Users}} -->
<tr class="tr-border" data-row-id="{{DCSID}}">
<td class="td-border">{{FN}}</td>
<td class="td-border">{{SN}}</td>
<td class="td-border">{{OT}}</td>
</tr>
<!-- {{/Users}} -->
</tbody>
</table>
Your template is being modified by the DOM because you're inserting it into a <div> as "HTML", which it isn't. It's doing exactly what a browser would do if you gave it that markup. It's putting the {{# Users }} in the nearest available valid place to put it.
This is the same reason your template is originally stored in a <script> tag. You should always use <script> tags to hold your templates, and you should always use .text() to read and write them:
var $newDcsTemplate = $('<script/>').text($('#dcs-template').text());
console.log($newDcsTemplate.text())

dynamically close and open table rows

I have a table on my site that contains the options for different products. I didn't put it there, the ecommerce platform did. It lists the options in a row in the table. The table looks like this:
<div class="attributes">
<table>
<tbody>
<tr>
<td>Size:</td>
<td> </td>
<td><select><option>Sizes here</option></select></td>
</tr>
</tbody>
</table>
</div>
Then if there were another option it would be in an additional row with the same markup.
This renders with the label (size in this case) out in front of the <select> box. I want the label above the <select> box and I figured the easiest way to accomplish this would be to close the <tr> and open a new one. Any ideas on how to do this?
EDIT: I should mention that the ecommerce platform generates the html and I do not have access to the source code
Assuming that it follows that exact structure, try this:
$(".attributes select").each(function(){
$label = $(this).parent().prev().prev();
$label.parent().before("<tr></tr>");
$label.parent().prev().append($label.clone());
$label.remove();
$(this).parent().prev().remove();
});
Here's an example: Demo
Like so?
<div class="attributes">
<table>
<tbody>
<tr>
<td>Size:</td>
</tr>
<tr>
<td><select><option>Sizes here</option></select></td>
</tr>
</tbody>
</table>
</div>
I think you have to do it in two steps:
remove the elements:
$('.attributes').find('tr:first-child').remove();
$('.attributes').find('tr:first-child').remove();
2.append them back in the same place
$('.attributes').find('tr:first-child').before('<tr><td>Sizes here</td></tr>');

Categories