Text angular doesnt load the cell borders in angularjs - javascript

I would like to be able to display a table with cell borders in a text angular div.
The content renders but the cell border doesnt
markup
<div ng-app="test">
<div ng-controller="testController">
<div text-angular name="testEditor" ng-model="htmlContent"></div>
</div>
</div>
controller code
angular.module('test', ['textAngular'])
.controller('testController',
function($scope, $timeout, textAngularManager) {
$scope.htmlContent = undefined;
//$scope.htmlContent = '<p>Hello There!</p>';
$timeout(function () {
$scope.htmlContent = "<table><tr><td style ='border: 1px solid black'>aaaa</td><td style ='border: 1px solid black'>dddddd</td></tr><tr><td style ='border: 1px solid black'>fffff</td><td style ='border: 1px solid black'>ffffffff</td></tr></table>";
//textAngularManager.refreshEditor('testEditor');
}, 1000);
});
This is demonstrated at ->
http://jsfiddle.net/x20mfq44/
However if i render the html in a separate jsfiddle without text angular, the cell borders show up fine.
<table>
<tr>
<td style ='border: 1px solid black'>aaaa</td>
<td style ='border: 1px solid black'>dddddd</td>
</tr>
<tr>
<td style ='border: 1px solid black'>fffff</td>
<td style ='border: 1px solid black'>ffffffff</td>
</tr>
</table>
https://jsfiddle.net/1xhfLpmq/

Are you using angular-sanitize? That can mess with HTML attrs through ng-model.

A rule of thumb - don't use inline styling in your html. It's messy and outdated.
A simple css rule can solve your problem, something like
table td {border: 1px solid black}
I updated your fiddle, here : http://jsfiddle.net/x20mfq44/1/
Hope this helps!

Related

Dynamically add table rows in html email template

My task is to add table rows dynamically in the email template.
This is how I created email template
<html>
<head>
<style type=3D"text/css">
</style>
</head>
<body><div>
<p>
{{userName}} modified the order. Here are the latest order details...
<br/>
<br/>
<table style="font-family: arial, sans-serif; border-collapse: collapse; width: 100%;">
<tr>
<th style="border: 1px solid #dddddd; text-align: left; padding: 8px;">Product</th>
<th style="border: 1px solid #dddddd; text-align: left; padding: 8px;">Quantity </th>
<th style="border: 1px solid #dddddd; text-align: left; padding: 8px;">Price</th>
</tr>
{{data}}
</table>
<br/>
<br/>
<p>- - - - -</p>
<p>Please do not reply to this email. You have received this email because you have opted in to these notifications. If you wish to no longer receive these notifications, you can turn them off in your user profile.</p>
</div></body>
</html>
And from the backend, I am passing an object with the required data as below
val tableData = '<tbody>
<tr><td>ABC</td> <td>5</td> <td>100</td></tr>
<tr><td>PQR</td> <td>2</td> <td>200</td></tr>
<tr><td>XYZ</td> <td>1</td> <td>75</td></tr>
</tbody>';
const processData = {
data: table,
userName: "XYZ"
}
But in mail, I'm getting below content
Can someone please help me to pass table rows dynamically.
Apart from the above solution here is another one.
From the backend, you can pass an array of objects. And in hbs template, built-in-helpers functions of handlebars.
Built-in-helpers Doc link
Here is the link where I tried creating dynamic rows by passing an array of objects from the backend using handlebars built-in functions
Link
In your email template, you are passing the variable "data" to the table, which contains the HTML string for the table body, but it is not being rendered as HTML in the email.
To render the table body as HTML, you can use triple curly braces {{{data}}} instead of double curly braces {{data}} in your Handlebars template. This will tell Handlebars to render the HTML string as-is, without escaping the HTML tags.
So the final result should look like:
<html>
<head>
<style type=3D"text/css"></style>
</head>
<body>
<div>
<p>
{{userName}} modified the order. Here are the latest order details...
<br/>
<br/>
<table style="font-family: arial, sans-serif; border-collapse: collapse; width: 100%;">
<tr>
<th style="border: 1px solid #dddddd; text-align: left; padding: 8px;">Product</th>
<th style="border: 1px solid #dddddd; text-align: left; padding: 8px;">Quantity </th>
<th style="border: 1px solid #dddddd; text-align: left; padding: 8px;">Price</th>
</tr>
{{{data}}}
</table>
<br/>
<br/>
<p>- - - - -</p>
<p>Please do not reply to this email. You have received this email because you have opted in to these notifications. If you wish to no longer receive these notifications, you can turn them off in your user profile.</p>
</div>
</body>
</html>
You can check HTML-escaping part in the docs for more details.

HTML Table: border-collapse and visibility collapse of tr

I have a table with multiple lines, e.g.:
<table>
<tr id="line1"><td>Line</td><td>1</td></tr>
<tr id="line2"><td>Line</td><td>2</td></tr>
<tr id="line3"><td>Line</td><td>3</td></tr>
</table>
Now, in javascript (based on a radio input field) I want to remove (e.g.) #line3 by adding a visibility:collapse, something like:
document.getElementById("line3").style = "visibility:collapse";
The special thing about #line3 is that it has a border-top:
<style>
table {
border-collapse: collapse;
}
#line3 {
border-top:1px solid black;
}
</style>
The problem I have with that: When I "collapse" #line3 the border persists, eventhough the element "does not exist". I guess this should be due to the border-collapse in the table style "inheriting" a border element on the previous tr element? How can I fix that issue?
EDIT: I'd like to keep the javascript like that. Of course I could remove/readd the style element but there should be a different way to solve this?!
Of course I could remove/readd the style element
I think this means you don't want to mess with the border-top property when changing the row's visibility, correct?
In that case, it looks like your only option is to use display:none instead of visibility:collapse[1], which is unfortunate because then your table might have the wobbly effect that visibility:collapse was designed to prevent.
[1] https://drafts.csswg.org/css-tables-3/#visibility-collapse-track-rendering is not crystal clear, but looks like the spec prescribes the behavior you don't want. And chrome and firefox act a bit differently in the visibility:collapse case. https://jsfiddle.net/dgrogan/gLqo9s4w/2
let visible = 1;
toggle.onclick = function() {
line3.style.visibility = visible ? "collapse" : "visible";
//line3.style.display = visible ? "none" : "table-row";
visible = !visible;
}
table {
border-collapse: collapse;
}
td {
border: 1px solid lime;
}
#line3 {
border-top: 2px solid black;
}
<table>
<tr id="line1">
<td>Line</td>
<td>1</td>
</tr>
<tr id="line2">
<td>Line</td>
<td>2</td>
</tr>
<tr id="line3">
<td>Line</td>
<td>3</td>
</tr>
</table>
<br><br>
<button id=toggle>toggle</button>
<P>
https://drafts.csswg.org/css-tables-3/#visibility-collapse-track-rendering
</P>
Have you tried "display: none"?
document.getElementById("line3").style = "display: none";
Or maybe you could try setting the border-top to 0 which should hide it.
document.getElementById("line3").style = "visibility:collapse; border-top: 0";
.cssText
You can edit the whole inline [style] attribute by using .cssText:
document.getElementById("line3").style.cssText = "visibility:collapse; border-top:0px";
This allows you to set visibility and border properties (and more if you want) in one line.
Demo
document.getElementById("line3").style.cssText = "visibility:collapse; border-top:0px";
table {
border-collapse: collapse;
}
#line3 {
border-top: 1px solid black;
}
<table>
<tr id="line1">
<td>Line</td>
<td>1</td>
</tr>
<tr id="line2">
<td>Line</td>
<td>2</td>
</tr>
<tr id="line3">
<td>Line</td>
<td>3</td>
</tr>
</table>
You have several solutions to do this, with Jquery:
$('#line1').hide();
//OR
$('#line1').css('visibility','collapse');
//OR
$('#line1').css('display','none');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr id="line1"><td>Line</td><td>1</td></tr>
<tr id="line2"><td>Line</td><td>2</td></tr>
<tr id="line3"><td>Line</td><td>3</td></tr>
</table>
You can also use Javascript directly with the getElementById property:
document.getElementById("line1").style.display = "none";
Or
document.getElementById("line1").style.visibility = "collapse";

Embed Angular Within HTML created by Javascript

I have a table declared statically with html and the quantity of table rows is dependent on information stored on a database. The cells are created using Javascripts insertRow function and I can access the TD element by using table.row[x].cells[y]. My goal is to insert Angular's md-button in place of the HTML button attribute I created using .innerHTML.
If you are using angular - then you should use the ng-repeat (or *ngFor in Angular 2+) directives to add the content to the page instead of using javascript. The following will give a table with two rows and 3 tds per tr.
So its really more a case of getting your data, adding it to $scope and formatting it in a way that you can iterate over in the ng-repeat.
If you really want to keep it the way yuo have it - then simple create a button and styling it with the stylnig to make it look like the button you like.
var angularTest = angular.module('angularDiv',[]);
angularTest.controller('tableController', ['$scope', function($scope) {
$scope.items= [
{ contents: ['content 1.1', 'content 1.2','content 1.3']},
{ contents: ['content 2.1', 'content 2.2','content 2.3']},
];
}])
table {border-collapse: collapse}
th {
border: solid 1px #d4d4d4;
padding: 5px 10px;
background: #ededed;
border-bottom-width: 2px
}
td {
border: solid 1px #d4d4d4;
padding: 5px 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="angularDiv">
<table ng-controller="tableController">
<thead>
<tr>
<th ng-repeat="heading in items[0].contents">
Heading {{$index + 1}}
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in items">
<td ng-repeat ="content in item.contents">{{content}}</td>
</tbody>
</table>
</div>

Changing border left color based on value

I have a table where I want each row's border-left to differ based on priority level.
My HTML:
<tr id= "rows">
<td data-title="Link"><img src="form_blank.png" title="Agreement" width="40"/> ${gr1.short_description.getDisplayValue()}</td>
<td data-title="State"> ${gr1.state.getDisplayValue()} </td>
<td data-title="Due" input="date" data-date-format="MM/DD/YYYY">${gr1.due_date.getDisplayValue().substring(0,10)} </td>
</tr>
My Javascript:
<script>
function bordercolor() {
var leftborder = document.getElementById("rows");
if (${gr1.priority.getDisplayValue()} = 1){
leftborder.style.borderLeft = "solid 10px #b30000";}
else if (${gr1.priority.getDisplayValue()} = 2){
leftborder.style.borderLeft = "solid 10px #ffa500";}
else if (${gr1.priority.getDisplayValue()} = 3){
leftborder.style.borderLeft = "solid 10px #ffff00";}
else if (${gr1.priority.getDisplayValue()} = 4){
leftborder.style.borderLeft = "solid 10px #7fbf7f";}
else {leftborder.style.borderLeft = "solid 10px #006600";}
}
</script>
Any suggestions on what I'm doing wrong?
I'm not sure what ${...} means inside your code, hopefully I'm not missing something obvious but it's nothing I could recognize as valid. It smells to some preprocessing replacement logic but without confirmation is hard to say for sure.
Something else that is wrong at first sight is the fact that you're using assign operator (=) on the if statement instead of the equal operator (==)
Another problem is that tr can't take a border. Below you'll find how I would implement this. Notice the use of css classes instead of manipulating directly the element border. I'm also asigning an id to the table and using this control to apply styles instead of rows
HTML
<table id="table">
<tr>
<td data-title="Link"><img src="form_blank.png" title="Agreement" width="40"/> ${gr1.short_description.getDisplayValue()}</td>
<td data-title="State"> ${gr1.state.getDisplayValue()} </td>
<td data-title="Due" input="date" data-date-format="MM/DD/YYYY">${gr1.due_date.getDisplayValue().substring(0,10)} </td>
</tr>
</table>
CSS
.priority-1 td:first-child {
border-left: solid 10px #b30000;
}
.priority-2 td:first-child {
border-left: solid 10px #ffa500;
}
.priority-3 td:first-child {
border-left: solid 10px #ffff00;
}
.priority-4 td:first-child {
border-left: solid 10px #7fbf7f;
}
.priority-other td:first-child {
border-left: solid 10px #006600;
}
JAVASCRIPT
function bordercolor() {
var priority = ${gr1.priority.getDisplayValue()};
var table = document.getElementById("table");
if (priority <= 4)
table.className = "priority-" + priority;
else
table.className = "priority-other";
}
DEMO
You should be styling the leftmost td, you can't have a different left border on a row
The id attribute should be unique, rows would be better as a class
Leverage the variables you have when possible. Would this work?
<tr class= "rows" data-priority="${gr1.priority.getDisplayValue()}">
<td data-title="Link"><img src="form_blank.png" title="Agreement" width="40"/> ${gr1.short_description.getDisplayValue()}</td>
<td data-title="State"> ${gr1.state.getDisplayValue()} </td>
<td data-title="Due" input="date" data-date-format="MM/DD/YYYY">${gr1.due_date.getDisplayValue().substring(0,10)} </td>
</tr>
And css like this, targeting the data-priority attribute
.rows[data-priority="1"] td:first-child{ border-left: 2px solid #234324;}
.rows[data-priority="2"] td:first-child{ /* your css for this one */}
.rows[data-priority="3"] td:first-child{ /* your css for this one */}
/* and so on */

Editable datas on button click

How do i make all td rows from text appear a textbox on button click to edit data in db. Example:
Before edit is clicked
After edit is clicked
Add a class to your table. When you click on a row, iterate through each cell in that row.
If there is no input elemenet, then get the content of the cell, clear the content and add an input element with the text.
Here is a working jsFiddle.
Warning: you should handle the name of the input values, and you should care about html tags in the value of the cells, if there are not only pure texts.
HTML
<table class="editable" style="border: 1px solid #000; border-collapse: collapse">
<tr>
<td style="border: 1px solid #000; padding: 10px;">This is a text</td>
<td style="border: 1px solid #000; padding: 10px;">Another text</td>
</tr>
</table>
jQuery
$('table.editable').on('click', 'tr', function () {
$(this).find('td').each(function () {
if ($(this).find('input').length < 1) {
let html = $(this).html();
$(this).empty();
$(this).append('<input name="value[]" value="' + html + '" />');
}
});
});

Categories

Resources