SASS / HandlebarsJS conflicts? - css

Background: For a project, I am trying to use SASS and Handlebars to create a vote counter that displays a stored value from my database and updates when a user presses the up or down vote buttons.
Are there any known interactions/conflicts that would causes SASS styling to not be applied when used with Handlebars or vice-versa?
For reference, here is the code I have in my HTML that I am working with.
<div id='voteWrapper'>
<script id='voteTile' type="text/x-handlebars-template">
{{#each proTipVote}}
<div class="vote circle">
<div class="increment up" data-id={{_id}}></div>
<div class="increment down" data-id={{_id}}></div>
<div class="count" data-id={{_id}}>{{tipScore}}</div>
</div>
{{/each}}
</script>
</div>

Related

Use a helper to set a css class

I need to make reactive a class inside a const (exported from a module).
export const messageControls = '
<div id="controls"">
<i id="idcont" class="{{starred}}"></i>
</div>
'
This class belongs to an HTML block who's inserted as innerHTML of a createElement.
var newElement = document.createElement('div');
newElement.id = i._id;
newElement.className = "single_message";
newElement.innerHTML = messageControls;
document.getElementById('conversation_details').appendChild(newElement);
The {{helper}} below is not rendering anything :
starred: function () {
return 'bob';
},
<i id="idcont" class="{{starred}}"></i> gives {{starred}} in plain text
<i id="idcont" class=" ' + {{starred}} + ' "></i> breaks all
Any idea?
Update - full Blaze template as requested
<template name="inbox">
<div class="searchmessages">
<input type="text" name="searchmessages" id="searchmessages" placeholder="  any word / any date">
</div>
<div class="row">
<div class="col-xs-4 l-O list_messages">
<div id="gridreceived" class="gridmessages">
{{#each incoming_all}}
<div id="{{_id}}" class="item {{readornot}}">
<div class="item-content">
<div class="task_inlist">
<div class="task_from">
{{{from}}}
</div>
<div class="task_date">
{{initialdate}}
</div>
<div class="task_subject">
{{{subject}}}
</div>
<div class="task_content">
{{{htmlbody}}}
</div>
</div>
</div>
</div>
{{/each}}
</div>
<div class="grid_nomatch">{{grid_noresult}}</div>
</div>
<div id="conversation_details" class="col-xs-8" media="print">
<!--
here are each selected message details
-->
</div>
</div>
</template>
You're trying to inject spacebars template markup directly into the DOM but meteor-blaze wants to use spacebars to build the DOM. It doesn't watch the DOM for arbitrary changes and then make template substitutions inside of it!
You can instead use Meteor's reactivity to automatically insert new items into the DOM for you based on changes to the underlying data. In your case it looks like you're trying to show the details of a message that's been clicked on. You probably have a template event handler already to catch the click. In that template handler you can set a Session variable which indicates which message is currently selected and then use that Session variable inside the helper that renders the message details.
For example:
<template name="inbox">
<div class="searchmessages">
<input type="text" name="searchmessages" id="searchmessages" placeholder="  any word / any date">
</div>
<div class="row">
<div class="col-xs-4 l-O list_messages">
<div id="gridreceived" class="gridmessages">
{{#each incoming_all}}
<div id="{{_id}}" class="item {{readornot}}">
// render summary of each message
</div>
{{/each}}
</div>
<div class="grid_nomatch">{{grid_noresult}}</div>
{{#with selectedMessage}}
<div id="conversation_details" class="col-xs-8" media="print">
// render selected message details
</div>
{{/with}}
</div>
</template>
Your js:
Template.inbox.events({
'click .item'(ev) {
Session.set('selectedMessageId',this._id);
}
});
Template.inbox.helpers({
selectedMessage() {
return Messages.findOne(Session.get('selectedMessageId'));
}
});
Now to your follow-up question about how to reactively style an element. Let's say your message* object has aisStarredboolean key. In the message detail section we've set the data context using{{#with currentMessage}}` so any key of the current message can be used directly in our spacebars template. Where you are displaying the message details you can do:
<div id="controls"">
<i id="idcont" class="{{#if isStarred}}starred{{/if}}"></i>
</div>
Depending on whether or not the message is starred this will render as class="" or class="starred".

Inject data into scope without <template>

I would like to get rid of two lines in the html used in a vue 2.x application. The lines with <template scope="props"> and the corresponding </template> should not be necessary.
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<p>{{ message }}</p>
<my-component>
<template scope="props">
<p>{{props.test}}</p>
</template>
</my-component>
</div>
I would rather define my own component attribute to define the scope name
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<p>{{ message }}</p>
<my-component with="props">
<p>{{props.test}}</p>
</my-component>
</div>
So instead of exposing the writer of the HTML to the concepts of templates and scopes we would do that inside my-component.
Does anybody know whether the vue templating mechanism is open for extension inside components like this ?
The benefit of having component is that it can be re-used at multiple places. so idea is to define template at one place and you can use it at multiple places.
the example you have written, you will be able to re-use it at again. template of component is generally not defined inside component, it will be separate and than that component can be used at multiple places.
See one sample below:
<div id="app">
<template id="item-edit">
<li>
<span v-show="!inEdit">{{item.name}}</span>
<input v-show="inEdit" type="text" v-model="item.name" />
{{inEdit ? 'save' : 'edit'}}
</li>
</template>
<ul>
<item-edit v-for="item in items" :item="item"></item-edit>
</ul>
</div>
Complete fiddle: http://jsfiddle.net/corh2tqo/

how to render several templates in the same place several times?

I have several templates:
<template name='mamals'>
<div id={{id}} class="mamals-container">
{{> UI.contentBlock}}
</div>
</template>
<template name='dog'>
{{#mamals}}
<div class="dog">
<p>I'm a dog</p>
</div>
{{#mamals}}
</template>
<template name='cat'>
{{#mamals}}
<div class="cat">
<p>I'm a cat</p>
</div>
{{#mamals}}
</template>
<template name='pig'>
{{#mamals}}
<div class="pig">
<p>I'm a pig</p>
</div>
{{#mamals}}
</template>
so in the main page I have a where user can drag and drop as many animal as they want into the farm. What I need to accomplish is every time a user drag an animal I would like to render that template and add it to farm (NO replacing, just add it). How may I implement this???
thanks in advance!
with Blaze you can render any template dynamically using JS http://docs.meteor.com/#/full/blaze_render

Meteor js not responding

I have been working with meteor.js and have been practicing using examples from getting started with meteor.js Javascript framework. The book is 2 years old and I have been running across some snags. For instance the book tells you to use var to define a variable, but after searching on stack I read that you didn't have to use it and now it works. I'm new so I write programs, run them, debug them and start from scratch to help me learn. For some reason this program that I have done 4 times before today is not running and I cant figure out why.
I keep getting this message :
While building the application:
LendLib.html:37: Expected "template" end tag
...  </div>
after inputting the following code:
<head>
<title>LendLib</title>
</head>
<body>
{{> hello}}
<div id="categories-container">
{{> categories}}
</div>
</body>
<template name="hello">
<h1>Lending Library</h1>{{greeting}}
<input type="button" value="Click" />
<template name="categories">
<div class="title">my stuff</div>
<div id="categories">{{#each lists}}
<div class="category">{{Category}}</div>{{/each}} </div>
</template>
</template>
any advice will be appreciated
dont define templates inside another template.
try like this.
<template name="hello">
<h1>Lending Library</h1>
{{greeting}}
<input type="button" value="Click" />
</template>
<template name="categories">
<div class="title">my stuff</div>
<div id="categories">
{{#each lists}}
<div class="category">
{{Category}}
</div>
{{/each}} 
</div>
</template>
Like pahan said, you cannot define a template within another template. They each have to be separate and un-nested. You CAN, however, call a template from within another template.
<template name="myOtherTemplate">
<h1> Lalalala </h1>
</template>
<template name="myTemplate">
{{> myOtherTemplate}} //injects the contents of myOtherTemplate
</template>
On another note, you also cannot nest Template instances within other Template instances.
Say that you want to register a helper function only after a certain template has been rendered.
Template.myTemplate.rendered = function({
Template.myTemplate.helpers({
key: "value",
anotherKey: "anotherValue"
});
});
^^ This also won't work.

Rendering a template when value in Mongo equals certain value

So I want to render a template that will hold an image when the value of the score in my Players collection equals 500, it right now doesn't render at all even when a player score equals 500, do I need an if statement in my handlebars or something else?
Relevant code I made so far
client
foo.html
<body>
<div class="container">
{{> header}}
<div class="row-fluid">
<div class="span8">
{{> leaderboard}}
</div>
<div class="span4">
{{> champion}}
</div>
</div>
</div>
</body>
<template name="champion">
{{#each winners}}
{{> winner}}
{{/each}}
</template>
<template name="winner">
<img src="gold.jpg" alt="winner">
</template>
foo.js
Template.champion.winners = function () {
return Players.find({score: 500});
};
You marked the Template code as being on the server in your question, but the code with Template.winner.winners should be on the client, not the server. This is most likely the problem. Also, you have two templates named winner, although Meteor should throw an error on the command line if you have duplicate template names.
Finally, this isn't what you asked, but it may come handy for debugging too. You can detect whether the cursor is empty in your templates using Handlebars {{else}}:
{{#each winners}}
{{> winner}}
{{else}}
no winners!
{{/each}}

Resources