font styles not working in meteor when retrieved from db - meteor

I am collecting the values from text area of a form and inserted them into a collection. But when i tried to display them in another template from the db, the styles are not getting applied.
Suppose if i have inserted Android Programmer in the database it is displaying 'Android Programmer' with the bold tags when i retrieved.
I am using bootstrap3-wysihtml5 richtext editor in my form.
What is the solution to avoid this problem.?My sample code here...
Jobs = new Meteor.Collection('jobs');
Template.postSubmit.events({
'click .formsubmit': function(event){
if(Meteor.user())
{
jobdescription = $('#jobDescription').val();
Jobs.insert({
J_Description:jobdescription;
});
}
});
<template name="jobPage">
<div class="jobDetailBody">
<p class="desc">{{J_Description}}</p>
</div>
</template>

When displaying the text from db i made use of handlebars. So the solution in this case is
<template name="jobPage">
<div class="jobDetailBody">
<p class="desc">{{{J_Description}}}</p>
</div>
</template>
Just add three curly braces to the handle bars for which you want to escape html.

Related

Meteor: single post view, via id and flow router is not parsing any data from the collection

Im trying to open a single record from my #each loop of items into its own view by clicking a link that says 'see more', which will take me to the single article. I set up my Flow router and its working but i cannot see the data that's supposed to come in.
the template helper for the single article looks like this
Template.collectionSingle.helpers({
articles: function () {
var id = FlowRouter.getParam('_id')
return theCollection.findOne({_id: id});
}
});
}
my route looks like this
FlowRouter.route('/collection/:_id', {
name: 'collection',
action() {
BlazeLayout.render("AppLayout", {main: "collectionSingle"});
}
});
and the template "collectionSingle" looks like this
<template name="collectionSingle">
<h1>{{title}}</h1>
<h1>This is a test</h1>
<img src="{{thumbnail}}" alt="" />
</template>
when i navigate to http://localhost:3000/collection/thePublication-0
all i see is the test message 'This is a test', but i don't see the {{title}} nor the thumbnail.
furthermore, when i change:
return theCollection.findOne({_id: id});
to another one of my collections :
return OtherCollection.findOne({_id: id});
http://localhost:3000/collection/thePublication-0
remains the same.
how can i successfully have a single articles page for each of my articles and have them linked properly with flow router?
You need to actually use your template helper that is returning the data context:
<template name="collectionSingle">
<h1>{{title}}</h1>
<h1>This is a test</h1>
{{#with articles}}
<img src="{{thumbnail}}" alt="" />
{{/with}}
</template>
Since your articles helper returns a single document you use {{#with articles}}. If it returned a cursor or array you would loop over that with {{#each articles}}. The normal convention is to use the singular form for the former, the plural for the latter.

FullpageJs and Meteor : Capture event from template

I'm struggling with fullpage.js in Meteor.
When I add a button inside a template, the Template.templatename.events function does not fire on event.
For example:
Template HTML (messages.html)
<template name="messages">
<ul>
{{#each mess}}
<li>{{ messContent}}</li>
{{/each}}
<button class="addMessage">Add Message!</button>
</ul>
</template>
Template JavaScript (messages.js)
Template.messages.helpers({
mess: function(){
return Messages.find();
}
});
Template.messages.events({
'click .addMessage' : function(event){
console.log("clicked")
}
})
Main HTML
<head>
<title>fulltest</title>
</head>
<body>
{{> full}}
</body>
<template name="full">
<div id="fullpage">
<div class="section active">
<h1>First slide</h1>
{{> messages}}
</div>
<div class="section">
<h1>Second slide</h1>
</div>
</div>
</template>
My fullpage initialisation:
Template.full.rendered = function(){
$('#fullpage').fullpage();
}
If I remove the fullpage initialisation then the click event gets logged. Still new at Meteor, I didn't manage to grasp what's going wrong here.
All help much appreciated,
Joris
Use delegation or use verticalCentered:false and scrollOverflow:false.
From the fullPage.js FAQs:
My javascript/jQuery events don't work anymore when using fullPage.js
Short answer: if you are using options such as verticalCentered:true or overflowScroll:true in fullPage.js initialization, then you will have to treat your selectors as dynamic elements and use delegation. (by using things such as on from jQuery). Another option is to add your code in the afterRender callback of fullpage.js
Explanation: if you are using options such as verticalCentered:true or overflowScroll:true of fullPage.js, your content will be wrapped inside other elements changing its position in the DOM structure of the site. This way, your content would be consider as "dynamically added content" and most plugins need the content to be originally on the site to perform their tasks. Using the afterRender callback to initialize your plugins, fullPage.js makes sure to initialize them only when fullPage.js has stopped changing the DOM structure of the site.

how to insert a string containing a link with a helper in meteor blaze

I would like to insert a string that contains a link with a helper (or is there any better option to achieve this?) in meteor blaze.
So far blaze just gives back the link as normal text with the '' tags.
Does anyone have a good solution or workaround for this?
Here is a simple example to get you started :
<template name="parent">
{{> linkTemplate linkData}}
{{#each links}}
{{> linkTemplate}}
{{/each}}
</template>
<template name="linkTemplate">
{{title}}
</template>
Links=new Meteor.Collection(null);
Links.insert({
url:"https://www.google.com",
title:"Google"
});
Template.parent.helpers({
linkData:function(){
return {
url:"https://www.google.com",
title:"Google"
};
},
links:function(){
return Links.find();
}
});
If you want to render a string in a template that happens to contain a link, you would have to provide the HTML string as in
var string="A link to Google.";
Then you can use the triple bracket syntax {{{helperReturningHTMLString}}} and it will work as expected, but I don't think it's good practice unless you're working with something like a WYSIWYG editor.

How do i get an onload function on the body for a specific template using meteor.js?

I'm trying to get the following behavior for a certain template:
<body onload="someInitFunction();">
Let's say i have the following markup (i'm using mrt router, not iron-router, for {{renderPage}}):
// Main Template
<head>
<title>meteorite-knowviz</title>
</head>
<body>
{{> header}}
<div class="container-fluid">
<div class="row">
{{renderPage}}
</div>
</div>
{{> footer}}
</body>
That renderPage is the secondTemplate:
<template name="secondTemplate">
{{#if currentUser}}
<div class="col-md-2">
<div class="list-group">
<a class="list-group-item" href="{{render thirdTemplate please...}}">Third Template</a>
<a class="list-group-item" href="{{render fourthTemplate please...}}">Fourth Template</a>
</div>
</div>
// In this case let's say thirdTemplate gets rendered
{{render the choice taken above please...}}
{{/if}}
</template>
And within this template, depending on which link was clicked on, (in this case the third) there will finally be a thirdTemplate, which will show a data visualization with some help by a javascript framework, which will be in need of a <body onload="initFunction();">in order to display the data:
<template name="thirdTemplate">
<div class="col-md-5">
<h2>THIS!! section needs a "<body onload="initFunction();"> in order to work" ></h2>
</div>
<div class="col-sm-5">
<h2>Some other related content here</h2>
</div>
</template>
To sum up i have three questions:
1a. How could i get the third template to get a <body onload="initFunction();">
2a. In which way can i render different templates within the secondTemplate?
2b. Can i use a {{renderPage}} within this template even though this template is the renderedPage in the main template or should i do it in some other way?
In order to get the <body onload="initFunction();"> i had to do the following:
First add the following function to a .js file in the client folder:
Template.thirdTemplate.rendered = function() { // Template.thirdTemplate.created - also worked.
$('body').attr({
onload: 'init();'
});
}
This however got me an error saying that initFunction is not defined. In an standard html page my could work just fine, but in meteor i had to change my function from:
function initFunction(){
//what ever i wished to do
}
To:
init = function() {
//what ever i wished to do
}
Regarding the rendering of pages, iron-routing is the way to go since the router add on is not under development any more.
1a. How could i get the third template to get a <body
onload="initFunction();">
You probably want to call initFunction when the third template has been rendered, so just put your call to it in the rendered callback.
Template['thirsTemplate'].rendered = function(){
initFunction()
}
2a. In which way can i render different templates within the
secondTemplate?
2b. Can i use a {{renderPage}} within this template even though this
template is the renderedPage in the main template or should i do it in
some other way?
Listen for clicks on the links, and when one happen you manually render the desired template (possible with Meteor.render, if you need reactivity) and add it to the right node in the document. See this question.
It may be possibly to achieve with router (I don't know that package).
I think that what you want to use is the created callback, that will be called each time your template is created, and not the rendered callback, that would be called each time a change has caused the template to re-render.
Template.thirdTemplate.created = function(){
initFunction()
}
See the documentation for templates for other types of callbacks: http://docs.meteor.com/#templates_api

Meteor js - how to hook into the 'rendered' event of a recursive template?

I've got a situation where I'm rendering a Handlebars partial recursively based on a Mongodb tree structure, something like this :
<template name='menu'>
<ul class='menu'>
{{#each topLevelChildren}}
{{>menu-item}}
{{/each}}
</ul>
</template>
<template name='menu-item'>
<li>{{name}}
{{#if listChildren.count}}
<ul>
{{#each listChildren}}
{{>menu-item}}
{{/each}}
</ul>
{{/if}}
</li>
</template>
where the mongodb docs look like this :
{ _id : ObjectId("525eb7245359090f41b65106"),
name : 'Foo',
children : [ ObjectId("525eb60c5359090f41b65104"), ObjectId("525eb6ca5359090f41b65105") ]
}
and listChildren just returns a cursor containing the full docs for each element in the children array of the parent.
I want to do a bit of jquery makeup on the rendered tree, but I can't seem to hook into the 'rendered' event for the entire tree, something like
Template.menu-completed.rendered = function(){
// console.log('done!');
}
Trying this
Template.menu.rendered = function(){
console.log($('menu li'));
}
Not only doesn't this return the right results (brackets filled with commas), it also freezes web inspector (but not the app...).
Any help would be much appreciated !
This is an interesting problem :)
In the current version of Meteor (0.7.x) the rendered callback is called once when the template is first rendered, and then again once any partial inside the template is re-rendered. (This behavior will change when Meteor 0.8 - the shark branch or "Meteor UI" - lands.)
I've never tried doing things recursively, but it's going to be very hard to tell which callback you get is actually for the parent. One thing you might want to try is to start the recursive rendering in a template called menu-parent or something. That way, when the rendered callback is called for the first time (and as long as your data is loaded), you know the whole tree is rendered.
However, I suspect there might be a better way to do this. Generally, you should not be using jQuery to modify classes and attributes on DOM elements, as you'll confuse yourself as to what Meteor is doing and what jQuery is doing. Can you elaborate on what you are trying to achieve with the following, and I'll update my answer?
I need to find a specific anchor tag within the fully rendered template and add a class to it... and then add a class to each of its parents
Petrov, your code actually works for me, with just some minor modification to the jquery part. But perhaps I'm misunderstanding. Here is what I did:
Created a brand new project.
Added your template in the .html with minor change: <li><span class="name">{{name}}</span>
Created a new collection List.
Template.menu.topLevelChildren = function() { return List.find(); };
Then I added this handler:
Template.menu.rendered = function(e){
$('.name').each(function(i, e) {
console.log(e);
});
}
Now, upon render, for instance when new data is inserted into the List collection, I get a printout on the console like this:
<span class=​"name">​second​</span>​
<span class=​"name">​second2​</span>​
<span class=​"name">​second21​</span>​
<span class=​"name">​second22​</span>​
<span class=​"name">​third​</span>​
<span class=​"name">​third2​</span>​
<span class=​"name">​third21​</span>​
<span class=​"name">​third22​</span>​
<span class=​"name">​third​</span>​
<span class=​"name">​third2​</span>​
<span class=​"name">​third21​</span>​
<span class=​"name">​third22​</span>​
This is just a flat list of the tree elements I had added (where second2 is nested in second, and second2x is nested in second2, etc.). So from what I understand you could just take the selection coming back from jquery and find the tag you are looking for and change its class, as you wanted. Please let me know if I misunderstood something.
Complete code below.
test.html:
<head>
<title>test</title>
</head>
<body>
{{> menu }}
</body>
<template name='menu'>
<ul class='menu'>
{{#each topLevelChildren}}
{{>menu-item}}
{{/each}}
</ul>
</template>
<template name='menu-item'>
<li><span class="name">{{name}}</span>
<ul>
{{#each children}}
{{>menu-item}}
{{/each}}
</ul>
</li>
</template>
test.js:
List = new Meteor.Collection("List");
if (Meteor.isClient) {
Template.menu.topLevelChildren = function() {
return List.find();
};
Template.menu.rendered = function(e){
$('.name').each(function(i, e) {
console.log(e);
});
}
}
if (Meteor.isServer) {
Meteor.startup(function () {
// code to run on server at startup
});
}

Resources