SVG sprites in helper function - meteor

I use svg sprites like this:
<svg><use href="combined.svg#filter_sent"></use></svg>
In a Meteor/Blaze template helper, svg sprites are not rendered:
<div class="colorset">
{{{color}}}
</div>
color: function () {
if (this.color && !this.validate) {
return '<svg><use href="combined.svg#green"></use></svg>';
}
if (this.color && this.certain) {
return '<svg><use href="combined.svg#orange"></use></svg>';
} else {
return '<svg><use href="combined.svg#red"></use></svg>';
}
}
=> Inside the use > shadow-root, nothing is inserted.

There are a number of error possibilities, best if you post all your code.
One possibility: Not matching template name to helper function declaration. e.g.
In html file:
<template name="foo">
...
In js file:
Template.bar.helpers({ ....
(this bites me more often than I care to admit)
I do not know what you mean by
=> Inside the use > shadow-root, nothing is inserted.
Using the chrome inspector you can choose the element you want to examine and see if it is has been rendered in the page really easily.

Related

What CSS should I write in html template to generate a pdf of a particular height & width

I am generating a PDF using nodejs with pdf-creator-node and I got success.
My requirement is I need to generate a PDF with Height X Width = 926px X 1296px.
I don' know what css I should write to generate this dimension pdf.
right now if I set div or body height and widht with above mentioned dimension I am getting 3 pages
this is what I tried
#page {
width: 1296px;
height: 926px;
}
<div
class="parent-div"
style="
width: 1296px;
height: 926px;
background-color: #faf0e6;
border: 1px solid red;
"
></div>
jsPDF is able to use plugins. In order to enable it to print HTML, you have to include certain plugins and therefore have to do the following:
Go to https://github.com/MrRio/jsPDF and download the latest
Version.
Include the following Scripts in your project:
jspdf.js
jspdf.plugin.from_html.js
jspdf.plugin.split_text_to_size.js
jspdf.plugin.standard_fonts_metrics.js
If you want to ignore certain elements, you have to mark them with an ID, which you can then ignore in a special element handler of jsPDF. Therefore your HTML should look like this:
<!DOCTYPE html>
<html>
<body>
<p id="ignorePDF">don't print this to pdf</p>
<div>
<p><font size="3" color="red">print this to pdf</font></p>
</div>
</body>
</html>
Then you use the following JavaScript code to open the created PDF in a PopUp:
var doc = new jsPDF();
var elementHandler = {
#ignorePDF': function (element, renderer) {
return true;
}
};
var source = window.document.getElementsByTagName("body")[0];
doc.fromHTML(
source,
15,
15,
{
'width': 180,'elementHandlers': elementHandler
});
doc.output("dataurlnewwindow");
**For me this created a nice and tidy PDF that only included the line 'print this to pdf'.
Please note that the special element handlers only deal with IDs in the current version, which is also stated in a GitHub Issue. It states:**
Because the matching is done against every element in the node tree, my desire was to make it as fast as possible. In that case, it meant "Only element IDs are matched" The element IDs are still done in jQuery style "#id", but it does not mean that all jQuery selectors are supported.
Therefore replacing '#ignorePDF' with class selectors like '.ignorePDF' did not work for me. Instead you will have to add the same handler for each and every element, which you want to ignore like:
var elementHandler = {
#ignoreElement': function (element, renderer) {
return true;
},
#anotherIdToBeIgnored': function (element, renderer) {
return true;
}
};
From the examples it is also stated that it is possible to select tags like 'a' or 'li'. That might be a little bit too unrestrictive for the most use cases though:
We support special element handlers. Register them with a jQuery-style ID selector for either ID or node name. ("#iAmID", "div", "span" etc.) There is no support for any other type of selectors (class, of the compound) at this time.
One very important thing to add is that you lose all your style information (CSS). Luckily jsPDF is able to nicely format h1, h2, h3, etc., which was enough for my purposes. Additionally, it will only print text within text nodes, which means that it will not print the values of textareas and the like. Example:
<body>
<ul>
<!-- This is printed as the element contains a textnode -->
<li>Print me!</li>
</ul>
<div>
<!-- This is not printed because jsPDF doesn't deal with the value attribute -->
<input type="textarea" value="Please print me, too!">
</div>
</body>

Hide a whole div with CSS with part of it is empty

Is there a way to hide a whole div if part of it is empty? For example if "dd" is empty as shown below can I hide the whole class "test" so the keyword Restrictions does not show either. I tried .test dd:empty { display: none; } but this does not work. thanks!
<div class="test"><dt>Restrictions:</dt>
<dd></dd></div>
I don't think there's any easy way to do what you're talking about with just CSS. Better to test it server-side if you can. But if you can't here's some JS that will do the job.
<script type="text/javascript">
// handles multiple dt/dd pairs per div and hides them each conditionally
function hideIfEmpty() {
// get all the elements with class test
var els = document.getElementsByTagName('dl');
// for every 'test' div we find, go through and hide the appropriate elements
Array.prototype.map.call(els, function(el) {
var children = el.childNodes;
var ddEmpty = false;
for(var i = children.length - 1; i >= 0; i--) {
if(children[i].tagName === 'DD' && !children[i].innerHTML.trim()) {
ddEmpty = true;
} else if(children[i].tagName === 'DT') {
if(ddEmpty) {
children[i].style.display = 'none';
}
// reset the flag
ddEmpty = false;
}
}
});
}
window.addEventListener('load', hideIfEmpty);
</script>
<div class="test">
<div style="clear: both;"></div>
<dl>
<dt>Restrictions:</dt>
<dd></dd>
<dt>Other Restrictions:</dt>
<dd>Since I have content, I won't be hidden.</dd>
</dl>
</div>
Just a fair warning: the code uses some functions that may not exist in older IE, such as Array.prototype.map, String.prototype.trim, and addEventListener. There are polyfills available for these and you could also write your own pretty easily (or just do it with a for loop instead).
CSS alone can't do that. Either, you need a javascript to retrieve empty elements and hide their parents, or your CMS applies special CSS classes if there's no content.
Put as an answer as requested by #Barett.
You could update your CSS to be
.test{
display: none;
color: transparent;
}
This would make the text transparent too, but display:none should hide it anyway.
To make the div with the id test ONLY show when the dd tag is EMPTY, and you can use jQuery, try the following JavaScript along with the CSS:
if($("dd").html().length ==0)
{show();
}
Note: this solution requires jQuery, which is a JavaScript library.

dynamic stylesheet with angularjs

I have and angularjs application that fetches data via api, and builds a webpage with it.
Usually I use ng-style to create dynamic styling, but now I have to use the nth-of-type attribute that can only be used in a css stylesheet (I cannot use individual styling since the number and order of elements always change).
I have tried this naive code (in the html page):
<style ng-if="styles.sc && styles.sc.length==3">
a.mosection:nth-of-type(3n) > div {
background-color: {{styles.sc[0]}} !important;
}
a.mosection:nth-of-type(3n+1) > div {
background-color: {{styles.sc[1]}} !important;
}
a.mosection:nth-of-type(3n+2) > div {
background-color: {{styles.sc[2]}} !important;
}
</style>
But it didn't work... Apparently angular doesn't bind the data inside the style tag (the ng-if attribute does get digested properly)
Does anyone have any idea how this can be done?
Thanks!
You should checkout those three ng-*
https://docs.angularjs.org/api/ng/directive/ngClass
https://docs.angularjs.org/api/ng/directive/ngClassOdd
https://docs.angularjs.org/api/ng/directive/ngClassEven
all of them can accept functions as attributes, you can also checkout
https://docs.angularjs.org/api/ng/directive/ngStyle
which might be actually the best in your case
Thanks!
I indeed solved it by using ng-style with a function
The HTML
<div class="widget widget-people" ng-style="{backgroundColor: staggerBgColors('widget', 'widget-people', '#333333')}"></div>
<div class="widget widget-property" ng-style="{backgroundColor: staggerBgColors('widget', 'widget-property', '#24d10f')}"></div>
The scope function
$scope.staggerBgColors = function(elesClass, eleClass, defaultColor){
if (!$scope.styles || !$scope.styles.sc || $scope.styles.sc.length!=3){
return defaultColor;
}else{
var listItem = $('.'+eleClass);
var n = $('.'+elesClass).index( listItem ) % 3;
return '#' + $scope.preview.moment.sc[n];
}
}
I had to implement the same functionality of the css property "nth-of-type" using jQuery, but it works prefectly!

How to get multi css rule for ng-style by function?

I need for apply multi css rule to html tag in angular form template.
<div class="form-control" id="data.objectStyle"
ng-model="data.type"
ng-style="getStyle(data.objectStyle)">
{{data.objectStyle.title}}
</div>
getStyle function in controller :
$scope.getStyle = function (taskType) {
return {
background-color:taskType.backColor,
color: taskType.color,
font-size:taskType.fontSize,
font-family:taskType.font
}
)};
taskType object:
{
backColor:'#006',
color:'#56DA',
fontSize:12,
font:'New Times Roman'
}
The getStyle function does not return a style! What to do?
EDIT
The docs specify that you need to wrap your keys in quotation marks so they aren't invalid JSON object keys:
return {
"background-color": taskType.backColor,
"color": taskType.color,
"font-size":taskType.fontSize,
"font-family":taskType.font
}
Old Answer (not using ng-style)
While I never used ng-style, it doesn't seem to take objects. Rather it is an equivalent of ng-class but for single styles.
Try changing your function to:
$scope.getStyle = function (taskType) {
return {
"background-color:"+taskType.backColor+
";color:"+ taskType.color+
";font-size:"+taskType.fontSize+
";font-family:"+taskType.font+";";
}
)};
and the html to use the regular style tag with a bind:
<div class="form-control" id="data.objectStyle"
ng-model="data.type" style="{{getStyle(data.objectStyle)}}">

What is the convention in Rails (with asset pipeline) for internationalization inside CSS?

I know CSS isn't supposed to have content, but it does, like this nice box (below) extracted from the Twitter Bootstrap documentation CSS:
/* Echo out a label for the example */
.bs-docs-example:after {
content: "Example";
}
I don't care for "Example", I use something like that as a mixin:
.box (#legend) {
/* Echo out a label for the example */
&:after {
content: #legend;
}
}
Then I don't need really dynamic CSS, I can easily include the mixin in a class, but instead of passing "Observation" I need to pass t 'box.observation':
.observation {
.box("<%= t 'box.observation' =>");
}
Rails is supposed to follow Conventions over Configuration, it is very easy to just add a static CSS/LESS/SCSS and it is already included in all pages in a single minified CSS. What is the convention for internationalized CSS? For example, where I am supposed to put declarations like that of .observation?
You don't need to generate a new CSS file for each locale - that borders on madness. Why does your CSS care about the text content of your website?
I think your best bet would be to use a data-attribute to grab the value...
<div class='bs-docs-example' data-before-content='<%= t.css_example %>'>
<!-- html here -->
</div>
And then in your css:
.bs-docs-example:after {
content: attr(data-before-content);
}
You could probably find a way to extract this into a partial (or helper), so that your erb file ends up like this:
<%= docs_example do %>
<!-- html here -->
<% end %>
And a helper method:
def docs_example
content_tag(:div, class: "bs-docs-example", "data-before-content" => t.css_example) do
yield
end
end
I could generate one CSS per locale as suggested in this answer, but since the CSS is the same except by the I18n bits, I would have either of:
A folder with a multitude of static CSS/LESS with the locale inlined, e.g.:
/* en */
.observation {
.box("Observation");
}
Lots of exactly identical dynamic CSS's, e.g.
/* en */
html[lang=en] {
.observation {
.box("Observation")
}
}
Instead I choose to create a CSS and ERB view and deliver using using page caching with the locale code in the URL, this way there is no duplication. See code below.
config/routes.rb
X::Application.routes.draw do
get 'index.:locale.:format' => 'css#index',
constraints: { locale: /[a-z]{2}(-[A-Z]{2})?/,
format: 'css' }
end
app/controllers/css_controller.rb
class CssController < ActionController::Base
caches_page :index
def index
#locale = params[:locale]
end
end
app/views/css/index.css.less.erb
#import "mixins";
.observation {
.box("<%= t 'box.observation', locale: #locale %>");
}
app/assets/stylesheets/mixins.less
.box (#legend) {
/* Echo out a label for the example */
&:after {
content: #legend;
}
}
This example would work as is if it was a simple ERB view, but since it is using Less, I have to parse the ERB and LESS manually as of rails 4:
class CssController < ActionController::Base
caches_page :index
def index
#locale = params[:locale]
erb_source = find_template.source
less_source = Tilt::ERBTemplate.new { erb_source }.render(self)
css_source = Less::Parser.new(paths: Rails.application.config.less.paths).parse(less_source).to_css
render text: css_source
end
private
def find_template(_action_name = action_name)
lookup_context.disable_cache { lookup_context.find_template(_action_name, lookup_context.prefixes) }
end
end

Resources