from underscore template to mustache.js - javascript

I would like to change from underscore template to mustache.js.
Since in mustache.js there are no if statements how can I change this piece of code in order to use mustache.js ?
<% if (done) { %>
<span class="todo-clear">
<a href="#">
Clear <span class="number-done"><%= done %></span>
completed <span class="word-done"><%= done === 1 ? 'item' : 'items' %></span>
</a>
</span>
<% } %>
My solution is:
{{#total}}
<span class="todo-count">{{ total }}
<span class="number">{{ remaining }}</span>
<span class="word"><%= remaining == 1 ? 'item' : 'items' %></span> left.-->
</span>
<span class="hint">
Drag tasks from one list into another and vice versa.
</span>
{{/total}}
It works for total variable, because it could be 0 or more, but I have no idea what is the best way to fix it on remaining variable, which could be 1 or more.
<span class="word"><%= remaining == 1 ? 'item' : 'items' %></span> left.</span>
It should be something like that:
<span class="word">
{{#remaining}} 'items' {{/remaining}}
{{^remaining}} 'item' {{/remaining}}
</span>
It does not work because remaining could be 1 or more.

In your view you could make something like this:
Mustache.render(yourTemplate, {
remaining: items.length > 1 ? true : false
}

If your just moving to a new templating framework, I would recommend using handlebars.js. This has support for if statements as follows:
{{#if total}}
<span>something</span>
{{else}}
<span>something else</span>
{{/if}}

Related

jiren/filter.js with express and ejs files - conflicts

I'm creating an app with express/sequelize and ejs files.
And now i want to use this fantastic solution of filters by Jiren but this solution is using the same syntax as ejs variables.
When i'm including my template with these variables in the script tag type="text/html" its trigger me an error (which is not defined but appears at the lines of my include). When i change the template to "john do" the page is displaying but my console brings me the "error JSONquery is not defined" (it's maybe two differents errors i'm not sure but JSONquery is a part of the filter.js plugin). I can show you my template here
<script id="artists-template" type="text/html">
<li
class="main__product-list-item"
data-height="<%= height %>"
data-width="<%= width %>"
data-low="<%= yearBegin %>"
data-high="<%= yearEnd %>"
data-name='<%= artist %>'
data-longueur='<%= height %>'
data-largeur='<%= width%>'
>
<figure class="main__product">
<a class="main__product-image-link" href="/name/<%= id %>">
<% if(Images.length !== 0) { %>
<img alt="illustration" src="./img/_thumb<%= Images[0]['adress'] %>.jpg"/>
<% } else { %>
<img alt="illustration" src="./img/icon-no-image.svg"/>
<% } %>
</a>
<figcaption class="main__product-description">
<h3>
<a href="/name/<%= id %>">
<span class="product__title">"<%= title %>" - <%= artist %></span>
<span class="product__date">, <span class="product__period"><%= period %></span></span>
</a>
</h3>
<p>
Créé probablement entre <span class="product__low-date"><%= yearBegin %></span> et <span class="product__high-date"><%= yearEnd %></span>
<br/>Hauteur : <span class="product__height"><%= height %></span> cm / Largeur : <span class="product__width"><%= width %></span> cm
<span class="main__product-description-story"><%= description %></span></p>
</figcaption>
</figure>
</li>
</script>
It's the same problem when i inject just one variable like <%= artist %>. Here is how i bind my data:
<% var datas = JSON.stringify(creations) %>
<script>
var data = <%- datas %>;
console.log(data);
</script>
I hope it's just a simple issue and i have to change just a simple character to make it work. At this time I think that the biggest issue is about this "JsonQUERY is not defined" because even if i don't bind my template with datas, the zone which must be filled with the template is actually not bound.
I tried to google the error but i found nothing. If someone have any ideas...thanks.
Here is the website of the filters solution : https://github.com/jiren/filter.js
Hourrayyy !!! I've found the solution, i googled ejs conflicts and found that the point is to change the plug-in syntax: if you encounter the same problem try to change those lines :
var templateSettings = {
evaluate : /<%([\s\S]+?)%>/g,
interpolate : /<%=([\s\S]+?)%>/g,
escape : /<%-([\s\S]+?)%>/g
};
to these
var templateSettings = {
interpolate: /\{\{(.+?)\}\}/g,
escape: /\{\{\-(.+?)\}\}/g,
evaluate: /\{\%(.+?)\%\}/g
};
now i just have to use this syntax : {{ variable }} and its working properly !

Rails jquery select by dynamic value

I'm using Ruby on Rails and I'm trying to hide/show an individual div from a collection of dynamically generated items by using the dynamically generated id which I then insert in a data attribute. This is what I've come up with so far, I think I'm on the right track but can't figure out what I'm missing. Without the if statement it works but shows the hidden div of every item instead of that specific one, and with the if statement, nothing happens.
Link and hidden div
<span class="options" data-ovly=<%= activity.targetable.id %>>
<i class="fa fa-ellipsis-h"></i>
</span>
<div class="ed_ovly none" data-ovly=<%= activity.targetable.id %>>
<span class="shu_e">
<%= link_to "Edit", edit_medium_path(activity.targetable), :title => "Edit", :alt => "Edit", class: '' %>
</span>
<span class="shu_d">
<%= render :partial => "activities/delete", :locals => {:activity => activity} %>
</span>
</div>
jquery
$('.options').click(function(){
var $ovly = $(this).attr("data-ovly");
if ($('.ed_ovly').data("ovly") === $ovly) {
$('.ed_ovly').toggleClass("none");
}
});
TL;DR
Use id attributes instead of data-ovly in your div tags and avoid the if statement in your script:
html
<span class="options" data-ovly=<%= activity.targetable.id %>>
<i class="fa fa-ellipsis-h"></i>
</span>
<div class="ed_ovly none" id="<%= activity.targetable.id %>">
<span class="shu_e">
<%= link_to "Edit", edit_medium_path(activity.targetable), :title => "Edit", :alt => "Edit", class: '' %>
</span>
<span class="shu_d">
<%= render :partial => "activities/delete", :locals => {:activity => activity} %>
</span>
</div>
script
$('.options').click(function() {
var $ovly = $(this).data("ovly");
$('#' + $ovly).toggleClass("none");
});
Check this snippet:
$(document).ready(function() {
$('.options').click(function() {
var $ovly = $(this).data("ovly");
$('#' + $ovly).toggleClass("none");
});
});
.none {
display: none;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="options" data-ovly="1">
ovly#1 <i class="fa fa-ellipsis-h"></i>
</span>
<br><br>
<span class="options" data-ovly="2">
ovly#2 <i class="fa fa-ellipsis-h"></i>
</span>
<div class="ed_ovly none" id="1">
<span class="shu_e">
<a title="Edit ovly # 1" alt="Edit" href="#">Edit</a>
</span>
<span class="shu_d">
"Your rendered partial for ovly # 1"
</span>
</div>
<div class="ed_ovly none" id="2">
<span class="shu_e">
<a title="Edit ovly # 2" alt="Edit" href="#">Edit</a>
</span>
<span class="shu_d">
"Your rendered partial for ovly # 2"
</span>
</div>
Explanation
The first problem is in your if statement: You are using === to compare your values, but, since you are getting those values with different methods (attr and data), you are getting different data types.
Look closely at your code (i added a couple of comments):
$('.options').click(function(){
var $ovly = $(this).attr("data-ovly"); // Returns a string: "1"
if ($('.ed_ovly').data("ovly") === $ovly) // Returns a number: 1
{
$('.ed_ovly').toggleClass("none");
}
});
So your if returns false every time (since you are comparing string with number). To fix this, just use the same method1 to get data in both lines, like this:
$('.options').click(function(){
var $ovly = $(this).data("ovly"); // Returns a number: 1
if ($('.ed_ovly').data("ovly") === $ovly) // Returns a number: 1
{
$('.ed_ovly').toggleClass("none");
}
});
Now that you are getting same data types, your if statement will work as expected. But you are not out of the woods yet, there is another issue with your code, look how you are identifying each unique <div>:
if ($('.ed_ovly').data("ovly") === $ovly)
{
$('.ed_ovly').toggleClass("none");
}
You are using $('.ed_ovly'), that is, you are using the class, and all divs have that class, so with
$('.ed_ovly').data("ovly")
you will always get the value of the first div with class ed_ovly; and in
$('.ed_ovly').toggleClass("none")
you apply toggleClasss("none") to all divs with ed_ovly class (and, as a result, you will hide/show all divs every time).
So, you want to target only one div at a time, and the best way to do it is assigning an id to each div (also dynamically), something like this:
<div class="ed_ovly none" data-ovly="<%= activity.targetable.id %>" id="<%= activity.targetable.id %">
<!-- Your div code... -->
</div>
And on your script, refer only to the div you want to show/hide using its id, and that can be done by changing $('.ed_ovly') to $('#' + $ovly). Now your script should look like this:
if ($('#' + $ovly).data("ovly") === $ovly) {
$('#' + $ovly).toggleClass("none");
}
Your script now should be working fine, but something is off: with the changes we made, now the if is not necessary at all! Since we now get a unique id for each div, its safe to delete it:
$('.options').click(function() {
var $ovly = $(this).data("ovly");
$('#' + $ovly).toggleClass("none");
});
And, while we are at it, lets get rid also of that unnecessary data tag in your div (i assume you don't need it for anything else):
<div class="ed_ovly none" id="<%= activity.targetable.id %">
<!-- Your div code... -->
</div>
Note
1 You could still get away using both methods by comparing them with ==, but i prefer sticking with ===. Check this question for more information.

knockout dynamic expression value for class - css binding

I have a knockout expression below:
<span class='icon' data-bind='css: step_type() '></span>
if my step_type() return register :
<!-- in case of step_type() return a register -->
<span class='icon 0 1 2 3 4 5 6 7' data-bind='css: step_type() '></span>
<!-- in case of step_type() return a date -->
<span class='icon 0 1 2 3' data-bind='css: step_type() '></span>
What I noticed from the output knockout does not take expression value correctly instead it takes indices of each character in the string value. below is what I expected to see
<!-- in case of step_type() return: date -->
<span class='icon date' data-bind='css: step_type() '></span>
<!-- in case of step_type() return: register -->
<span class='icon register' data-bind='css: step_type() '></span>
Do I miss something ? Please help how to get this done.
From what i understood from your question
You need to add a css to a element conditionally . so, we need to do something like this .
Input :
<span class='icon' data-bind='css:{"abc":true}'></span>
OutPut :
<span class='icon abc' data-bind='css:{"abc":true}'></span>
If you need a if check on top of element here we go
<!-- ko if : step_type()== 'your value' -->
<span class='icon' data-bind='css:{"abc":true}'></span>
<!--/ko-->
Edit :
Then you need to have computed of step_type like below
vm.step_type= ko.Computed(function() {
return (check condition here) ? "register" : "date";
}, vm);
later on in you binding do like
<span class='icon' data-bind='css:step_type'></span> **(i/p)**
<span class='icon register' data-bind='css:step_type'></span> **(o/p)**
You can refer the Docs here neatly mentioned how to deal
Working fiddle here

Count specific characters within a class (and apply text truncate logics to each instance of that class)

I have HTML like
<a href="/blabla" class="matchupLink">
<span class="teams"> USA</span>
<strong> -0 </strong>
<span class="teams">Netherlands</span>
<span class="pull-right dateOrScore"><strong>15 Jul</strong> : 3:00pm CST</span>
</a>
<a href="/blabla2" class="matchupLink">
<span class="teams"> USA</span>
<strong> -0 </strong>
<span class="teams">Netherlands</span>
<span class="pull-right dateOrScore"><strong>15 Jul</strong> : 3:00pm CST</span>
</a>
<a href="/blabla3" class="matchupLink">
<span class="teams"> USA</span>
<strong> -0 </strong>
<span class="teams">Netherlands</span>
<span class="pull-right dateOrScore"><strong>15 Jul</strong> : 3:00pm CST</span>
</a>
I want to count the number of characters that's inside each "matchupLink" class, but without counting the characters inside the "dateOrScore" class.
My goal is to then cut the text and put ellipses after char 20 if char count is over 20 characters, while keeping the date (dateOrScore) element there.
I tried something like
$('.matchupLink .teams').each(function () {
console.log($(this).html())
});
But that returns every teams element individually, can't really use the ellipses logics that way.
Any ideas?
Thanks
Ps: I also tried taking all text, and excluding 'dateOrScore' (using not()) but that also failed.
Is this what you want?
var ellipses = 20;
$('.matchupLink').children().not('.dateOrScore').each(function() {
var text = $(this).text();
if(text.length > ellipses)
$(this).text(text.substr(0, ellipses) + '...');
});

row selected row using javascript

In my MVC Razor project I am showing data in rows (list format).
These values are shown using javascript Knockout.
I want to higlight the selected row using javascript KnockoutJs.
Is there a better way of doing this.
Here is my code
<ul class="navlist" data-bind="foreach:selectOptions" >
<li><a href="#" data-bind="click:selectOption">
<span data-bind="text:name"></span>
<span data-bind="text:option"></span>
<span data-bind="text:optiondate"></span></a>
</li>
</ul>
I made a fiddle, it's pretty simple.
As you can see i store the the selected option in an observable.
And the databind applies the 'highlight' class if the selected option is the current option.
<ul class="navlist" data-bind="foreach:selectOptions" >
<li>
<div data-bind="click:$parent.selectOption, css: {'highlight' : $parent.selectedOption() == $data }" style="cursor: pointer">
<span data-bind="text:name"></span>
<span data-bind="text:option"></span>
<span data-bind="text:optiondate"></span>
</div>
</li>
</ul>
View model :
vm = {
selectOptions : [{name:'name1',option : 'option1', optiondate:'optiondate1'},
{name:'name1',option : 'option2', optiondate:'optiondate2'},
{name:'name3',option : 'option3', optiondate:'optiondate3'}],
selectOption : function(opt){
vm.selectedOption(opt);
},
selectedOption: ko.observable()
}
ko.applyBindings(vm);
I hope it helps.
I have posted something useful here:
Storing selected row in array in JavaScriptenter image description hereavascript/61581214#61581214

Categories