Convert a horizontal table to a vertical one in Ractivejs - html

I have a template like this, and I want ro make the table vertical(using partials is not an option in my environment, and I don't want to do it with inverted condition or duplicating html elements)
<table>
<tr>
<td>row1</td>
<td>row1</td>
<td>row1</td>
<tr>
</table>
The result should be:
<table>
<tr>
<td>row1</td>
</tr>
<tr>
<td>row1</td>
</tr>
<tr>
<td>row1</td>
<tr>
</table>
I already tried
var data = {
foo:true
}
<table>
<tr>
<td>row1</td>
{{#foo}}</tr><tr> {{/foo}}
<td>row1</td>
{{#foo}}</tr><tr> {{/foo}}
<td>row1</td>
<tr>
</table>
and
var data = {
foo:'</tr><tr>'
}
<table>
<tr>
<td>row1</td>
{{{foo}}}
<td>row1</td>
{{{foo}}}
<td>row1</td>
<tr>
</table>

A common misconception about Ractive is that because it uses the Mustache syntax, people think it acts like Mustache.
Mustache does string interpolation, where it replaces {{ }} to values that correspond in an object, and you get HTML. Ractive, on the otherhand, compiles the template into an AST. Then it uses that tree to create the DOM. It is similar to how Babel converts JSX into its object representation before feeding it to React, or how an HTML parser parses HTML, then constructing the DOM.
So for your scenario to work, you'll have to think in terms of properly-formed HTML:
Ractive.DEBUG = false;
const VerticalTableComponent = Ractive.extend({
template: `
<table border="1">
{{#tableItems}}
<tr>
<td>{{.}}</td>
</tr>
{{/}}
</table>
`
});
const app = VerticalTableComponent ({
el: '#app',
data: {
tableItems: ['foo', 'bar', 'baz', 'quz']
}
});
<script src="https://unpkg.com/ractive#0.8.12/ractive.min.js"></script>
<div id="app"></div>

Related

Using this text method with html symbols in jQuery to find td with symbol inside

I am trying to highlight a table row if it has a tick (check mark) in one of the td’s. I am using the jQuery code below, but it will not find a td with a html symbol such as a tick (check mark). It makes no difference if I use .text() or .html(). The code works as expected if I use any other criteria such as text or numbers, but not with html symbols. Is there away round this?
$('#farm td').filter(
function(t) {
if ($(this).text() == "✓") {
$(this).closest('tr').css('background-color', 'Yellow');
return;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="farm" border="1">
<tr>
<th>One</th>
<th>Two</th>
</tr>
<tr>
<td>Cat</td>
<td>Duck</td>
</tr>
<tr>
<td>Pig</td>
<td>✕</td>
</tr>
<tr>
<td>✓</td>
<td>Bull</td>
</tr>
<tr>
<td>8</td>
<td>10</td>
</tr>
</table>
You just need to check for the actual character (✓). jQuery acts on rendered HTML, not markup. I determined this by setting a breakpoint on the line with text() in it and looking at the values that came through.
Also:
.each() makes more sense to me here
no need to return anything in the function
no need to pass in anything (t)
console logs are far nicer than alerts for debugging
$('#farm td').each(function() {
if ($(this).text() == "✓") {
$(this).closest('tr').css('background-color', 'Yellow');
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="farm" border="1">
<tr>
<th>One</th>
<th>Two</th>
</tr>
<tr>
<td>Cat</td>
<td>Duck</td>
</tr>
<tr>
<td>Pig</td>
<td>✕</td>
</tr>
<tr>
<td>✓</td>
<td>Bull</td>
</tr>
<tr>
<td>8</td>
<td>10</td>
</tr>
</table>
Mohamed-Yousef suggested a great refinement using an internal selector:
$('#farm td:contains("✓")').closest('tr').css('background-color', 'Yellow');
It's a slightly different selector as it would also match ✓ blah, for example, but maybe it's useful in your case.
https://api.jquery.com/contains-selector/

Using Handlebars {{each}} in a Table

I have looked on other questions on stack overflow on how to use the each helper in Handlebars in a HTML table but when I am doing it it is not properly reading the each function unless I put it inside the tag. I have seen online this is how it is done but it for some reason is not working for me. The data I am calling using is loading fine on the page because if I put the helper in the it works.
<div class="container" id="content">
<template id="stemplate">
<table>
<tr>
<th>Date</th>
<th>Open</th>
</tr>
<tr class="tData">
{{#each values}}
<td>{{date}}</td>
<td>{{open}}</td>
{{/each}}
</tr>
</table>
</template>
</div>
</div>
Example
Html
<table id="stemplate">
<thead>
<tr>
<th>Date</th>
<th>Open</th>
</tr>
</thead>
<tbody></tbody>
</table>
<script id="table-template" type="text/x-handlebars-template">
{{#each this}}
<tr>
<td>{{date}}</td>
<td>{{open}}</td>
</tr>
{{/each}}
</script>
Js
$(function() {
var template = Handlebars.compile($("#table-template").html());
var data = [{
date: "01.01.2017",
open: true
}, {
date: "01.01.2018",
open: false
}];
$('#stemplate tbody').html(template(data));
});
Example Link

How To Transclude Table Row Into AngularJs Component

Iv been trying to create an angularJS component for constructing a dynamic html table from a provided array.
The components template includes some ng-transclude directives as 'placeholders'/slots for templates provided by the component consumer.
Is it possible to transclude a <tr> template (with nested <th>), to be used inside the table <thead>?
I have tried using all variations for transclution:
transclude: true, transclude: 'element'
and transclude: { header: 'header'}
(the third option seems as the most suitable, as I will eventually required multiple elements to be transcluded).
Component:
app.component("virtualTable", {
bindings: {
someArray: "<"
},
transclude: {
header: "header"
},
templateUrl: () => {
return "/app/components/virtual-table.component.html";
});
Component Template:
<div>
<table>
<thead>
<tr ng-transclude="header"></tr>
</thead>
<tbody>
<tr ng-repeat="item in vt.someArray">
...another place for transclution...
</tr>
</tbody>
</table>
</div>
Consuming HTML (component declaration):
<virtual-table some-array="vm.personList">
<header>
<th>First Column</th>
<th>Second Column<th>
</header>
</virtual-table>
I excpect the compiled DOM to look like this:
<table>
<thead>
<tr>
<th>First Column</th>
<th>Second Column</th>
</tr>
</thead>
...
But instead I get the innerHTML of the transcluded element (header) as Text:
<table>
<thead>
<tr ng-transclude="header">
<header class="ng-scope">
First Column
Second Column
</tr>
</header>
...
I Suspect the browser (chrome 76) to somehow strip the <tr> tags from the transcluded element before it is being provided to the component (as it illegal us to use <tr> outside of a <table>).
I would like to maintain an html table structure.
Is The Any Way to Solve This?

how to vertically populate data cells in angularjs

I need to vertically populate data cells with array.
This is a simple html table
<table>
<th>Name</th>
<th>Value</th>
</table>
Existing table:
Name Value
X
Y
Expected output:
Name Value
X 54
Y 48
I need to fill the data cells for value. I have calculated values for it and stored in array. How to populate the values using angularjs?
You want to use ngRepeat to add a new row for each element in your list. See the docs here for examples of how to use this directive.
<tr ng-repeat="row in data">
<td>{{row.name}}</td>
<td>{{row.value}}</td>
</tr>
Use directive for this. Look
var app = angular.module("App", []);
app.controller("AppController", function($scope) {
$scope.data = [1, 2, 3, 4, 5];
}).directive('indexItemTable', function($timeout) {
return {
link: function(scope, element, attrs) {
var data = scope.data;
angular.element(element).find("td").each(function(index, item){
console.log(item)
angular.element(this).parent().append('<td>' + data[index] + '</td>');
});
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<div ng-app="App" ng-controller="AppController">
<table index-item-table>
<thead>
<th>Name</th>
<th>Value</th>
</thead>
<tbody>
<tr>
<td>A</td>
</tr>
<tr>
<td>B</td>
</tr>
<tr>
<td>C</td>
</tr>
<tr>
<td>D</td>
</tr>
<tr>
<td>E</td>
</tr>
</tbody>
</table>
</div>

Get the width of parent <td> from angularjs directive template

Im trying to figure out if its possible to get the width of the parent my directive is going to be placed in.
Keeping it simple I have some directive my-directive which Im placing inside of a table:
<table>
<tr>
<td><my-directive ..../></td>
<td><my-directive ..../></td>
<td><my-directive ..../></td>
<td><my-directive ..../></td>
</tr>
</table>
And inside my-directive Iwant to know the width of my parent <td> so I could display my content properly - with more or less data according to the width
Can it be done?
Update:
My HTML code:
<table class="table">
<thead>
<tr>
<td width="5%"></td>
<td width="5%"></td>
<td width="85%"></td>
</tr>
<tr>
<th>Col 5</th>
<th>Col 5</th>
<th>Col C 85</th>
</tr>
</thead>
<tbody>
<tr>
<td><trim value="Some value a"></trim></td>
<td>Some value b</td>
<td>Some value c</td>
</tr>
</tbody>
</table>
My directive:
angular.module('ui.directives', []).directive('trim', function() {
return {
restrict: 'E',
scope: {
value: '#'
},
template: "{{value | limitTo:6}}"
};
}
);
From within the template I can limit by a constant I define (or pass by, from outside. But I want to change that, to know myself, from within that directive if I should trim the text or not
Yes you can get the parent element using angular's jqlite, a subset of jquery in the link function. The link function is to provide the behavior to your directive, in this function you can get the directive element and modify it at run time according to your need.
angular.directive('myDirective', [function($document) {
return {
restrict:'E',
link: function(scope, element, attribute) {
var parent = element.parent();// will give an array
var parentWidth = parent[0].offsetWidth;
//modify/truncate your attribute.value depending upon the parentWidth.
}
}
}]);