Templating Bootstrap Carousel with underscore.js and Backbone.marionette - javascript

I am the last step of a multi-level, nested sturcture of views - a collection of composite views.
However, based on array of image information, I am trying to render the bootstrap carousel, where the image with the highest priority_order is given the default "item active" class.
<%=_.each(images, function(x){
if (x.priority_order = 1)
{return
"<div class='item active'>
<img class='responsive-image' src=" + x.image + " alt=''>
<div class='container'>
<div class='carousel-caption'>
<h1>" + x.title + "</h1>
</div>
</div>
</div>"
}
else
{return
"<div class='item'>
<img class='responsive-image' src" + x.image + " alt=''>
<div class='container'>
<div class='carousel-caption'>
<h1>" + x.title + "</h1>
</div>
</div>
</div>"}
})%>
NOTE: The Above is simply manually pretty-printed for this post. In the real code, the line breaks are removed, otherwise you'll get:
Uncaught SyntaxError: Unexpected token ILLEGAL
When all is said and done, this still doesn't render properly. Am I missing something, or can underscore perform do this?

The way you've got it written there is syntax-error bait. (Plus, using a string literal largely defeats the purpose of using a template, no?)
I'd use code blocks <% %> for the logic parts, <%= %> for the rendering parts, and have the HTML as markup, not as a string literal:
<% _.each(images, function(x){ %>
<% if (x.priority_order == 1){ %>
<div class='item active'>
<img class='responsive-image' src=" + x.image + " alt=''>
<div class='container'>
<div class='carousel-caption'>
<h1> <%= x.title %></h1>
</div>
</div>
</div>
<% } %>
<%  } %>
Also, this is a typo -- if (x.priority_order = 1) -- should be the equality operator ==.
JSFiddle
Just as a note -- if you absolutely have to putt the markup in a string literal for some reason, then you can't have new lines within the string. It has to be either inline like this:
print "<div class='item active'><img class='responsive-image' src='" + x.image + "' alt=''><div class='container'><div class='carousel-caption'><h1>" + x.title + "</h1></div></div></div>";
Or appending the strings with the + like:
print "<div class='item active'>" +
"<img class='responsive-image' src='" + x.image + "' alt=''>" +
"<div class='container'>" +
"<div class='carousel-caption'>" +
"<h1>" + x.title + "</h1></div></div></div>";

Related

Cleaner way to add large block of HTML in javascript in rails

I have a rails app along with angular, and I need to populate a large block of HTML so that it can fill in default text for textarea tag. Currently what I did was add the text like this
"<div class='navbar navbar-default letter-header hidden-sm hidden-xs'>\n" +
" <div class='container'>\n" +
" <div class='letter-navbar-header navbar-header'>\n" +
" <a href='/'><img src='/assets/logo.png' class='letters-logo navbar-brand'></a>\n" +
" </div>\n" +
" <div class='navbar-header header-text'>\n" +
" <div class='navbar-text'>\n" +
" "text" + "\n" +
" </div>\n" +
" </div>\n" +
" <div class='letter-navbar-header navbar-header'>\n" +
" <a href='/'>\n" +
" <img src='' class='second-logo'>\n" +
" </a>\n" +
" </div>\n" +
" <div class='navbar-header navbar-right'>\n" +
" {{ user_login }}" + "\n" +
" </div>\n" +
" </div>\n" +
"</div>\n"
I would like to know if there is a cleaner way to do it. I have tried using js.erb file with the render function like this
<%= j render('navbar') %>
but placed it in the asset folder so the render function is not working https://stackoverflow.com/a/8370847/1087841. I would like to know if there is a better way to do it.
[EDIT]
The js.erb file is actually an angular factory which has default HTML for the navbar, which then can be used by the angular controller to render default data. The factory file is then also gets added to application.js as a require.
this is the textarea that needs default html
<textarea name="t[navigation]" id="input-navigation-bar" ng-model="t.navigation_bar" class="form-control" rows="10"></textarea>
I could have placed the value tag with the default html but it has ng-model so nothing gets displayed. So I created a factory for the default data. Now the factory lives in /assets and has a //= require 'default_html_factory' in application.js.
I finally found a way to do it. In the erb page I added
<script>
<%= render 'style_factory.js.erb' %>
</script>
and in the factory I added this
this.ngapp.factory('TenantStyle', function() {
return {
header: "<%= j render 'navbar' %>"
}
});
and in the _navbar.html.erb file I added this
<div class="navbar navbar-default letter-header hidden-sm hidden-xs">
<div class="container">
<div class="letter-navbar-header navbar-header">
</div>
<div class="navbar-header header-text">
<div class="navbar-text">
</div>
</div>
<div class='letter-navbar-header navbar-header'>
<a href='/'>
<img src='' class='second-logo'>
</a>
</div>
<div class="navbar-header navbar-right">
</div>
</div>
</div>
and now I can call the factory in angular and get the header value.

How to take a script from an HTML file and move it to it's own .JS file?

I am trying to simplify my HTML file, and I have very long scripts that consist of just HTML (templates) that I'd like to move to their own external files. This is easy for me to do when the <script> tags involve functions, but in my case it's just straight HTML. In the new external file, how do I properly type up those HTML tags? See below.
<script type="text/template7" id="myStuffTemplate">
{{#each results}}
<div class="list-block media-list">
<ul>
<li>
<a href="#" class="item-link item-content">
<div class="item-media"><img src={{this.pictures['1']}} width="80" height="80px"></div>
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">{{this.name}}</div>
</div>
<div class="item-text">{{this.description}}</div>
</div>
</a>
</li>
</ul>
</div>
{{else}}
<div style="text-align:center">
<h1>Nothing yet!</h1>
<h2>Upload things you're willing to trade so you can start trading!</h2>
</div>
{{/each}}
</script>
That's the script within the HTML File. I'd like that moved into its own external file. How can one go about doing this? And do I reference it just like every other file when I link it? eg.:
<script type="text/template7" src="js/views/mystuff.js" id="myStuffTemplate"></script>
Thanks in advance.
This is not a script, it's a template made with either handlebars or moustache templates.
You can't "source" them with <script src="..."> like you can with Javascript, but they can be stored externally, then loaded and processed at runtime. This needs to be done asynchronously through an AJAX call. For example, assuming you were using jQuery, you could achieve it with the following:
// request the template
$.get('templates/products.hbs', function(rawTemplate) {
// once received, convert the raw template to a handlebars template
var template = Handlebars.compile(rawTemplate);
// compile the template with your context 'data' and set it on an element with an id
$('#someTargetId').html(template(data));
}, 'html'); // <-- tell jquery to load the file as html
Just be warned, even small templates will take some time to load, so there will be a delay between your page loading and the template loading then being displayed.
First of all, consider using a framework like Angular.js or React.js however this should work for you:
Let's suppose that you want to put that inside a div with id=items:
<div id="items"> Your code... </div>
In the html file add this, just before the <body> closing tag:
<script type="text/javascript" src="code.js"></script>
to include your code and this
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
to include jQuery.
Create a code.js file and put the following code inside:
$(document).ready( function() {
var myCode = "{{#each results}}" +
"<div class="list-block media-list">" +
"<ul>" +
"<li>" +
"<a href="#" class="item-link item-content">" +
"<div class="item-media"><img src={{this.pictures['1']}} width="80" height="80px"></div>" +
"<div class="item-inner">" +
"<div class="item-title-row">" +
"<div class="item-title">{{this.name}}</div>" +
"</div>" +
"<div class="item-text">{{this.description}}</div>" +
"</div>" +
"</a>" +
"</li>" +
"</ul>" +
"</div>" +
"{{else}} " +
"<div style="text-align:center">" +
"<h1>Nothing yet!</h1>" +
"<h2>Upload things you're willing to trade so you can start trading!</h2>" +
"</div>" +
"{{/each}}";
$( "#items" ).html( myCode );
} );

Issue adding a unique ID to an HTML attribute using jQuery

I am having an issue changing the ID of HTML attributes using JQuery.
This is what I have been using:
$(document).ready(function () {
$('.hiddenDiv').each(function (i) {
$(this).attr("id", "title" + (i + 1));
});
This the HTML:
<div id="Foo">
<div class="title"></div>
<hr></hr>
<div class="hiddenDiv" style="display:none;"></div>
<hr></hr>
<div class="title"></div>
<hr></hr>
<div class="hiddenDiv" style="display:none;"></div>
</div>
I am producing the HTML using another JQuery script that creates it, iterating through an object creating a title and hiddenDiv divs for each element that exists in the object.
jQuery Script that produces the HTML:
$('#Foo').append('<div class="hiddenDiv" style="display:none;">' + foo[0].Content + '<br>' + 'Address: ' + foo[0].Address + '</div><br><hr>');
Both scripts execute when the document is ready.
Looks like elements are not created on DOM ready. You need to add the ids to them just after appending the content. like this:
$('#Foo').append('<div class="hiddenDiv" style="display:none;">' + foo[0].Content + '<br>' + 'Address: ' + foo[0].Address + '</div><br><hr>');
$('.hiddenDiv').each(function (i) {
$(this).attr("id", "title" + (i + 1));
});
Demo

nth-child. Create a div and populate it

I have this function that appends a div (Base-Shirt) to a div (Button)
<div class="Button"><div class="Base-Shirt"></div></div>
I then want the images to populate the (Base-Shirt) div. When I run the script the images are placed after the "Base-Shirt" div. Do you know how I would get them into the "Base-Shirt" and not after them?
This is what is happening:
<div class="Button">
<div class="Base-Shirt"></div>
<img class="2016" src="img/swatch/2016.jpg" title="Ruby_Red" alt="Main, Pique">
<img class="2017" src="img/swatch/2017.jpg" title="Khaki_Tan" alt="Main, Pique">
This is what I want to happen:
<div class="Button">
<div class="Base-Shirt">
<img class="2016" src="img/swatch/2016.jpg" title="Ruby_Red" alt="Main, Pique">
<img class="2017" src="img/swatch/2017.jpg" title="Khaki_Tan" alt="Main, Pique">
</div>
Function
function parse(document){
//Product
$(document).find("Item").each(function(){
$(".Button").append('<div class="' + $(this).attr('name') +'"></div>');
});
//Swatch
$(document).find("Swatch").each(function(){
$(".Button:nth-child(1)").append(
'<img class="' + $(this).attr('name') + '" alt="' + $(this).attr('alt') + '" title="' + $(this).attr('title') + '" src="img/swatch/' + $(this).attr('name') + '.jpg">'
);
});
}//function parse End
Thank you.
You could try $(".Button").children(":first") which will land you on the div-shirt element
use children and eq
$(".Button").children(":eq(0)"); //<-- this will get you the first children(start form 0)
$(".Button").children(":eq(1)"); //<-- this will get you the second children

How to ouput multi-line html with variable into div using javascript?

I want to output this multi line html with variable into div from inside jquery but it never ouput the block of code inside div! I am using only variable inside it which is"itemName". could any one tell me why my code doesn't out to div ?
var siteContents2 ="<li> +
" <iframe src='<iframe src='http://bsite.com/itemshow.php?"+itemName+"&title=ok&bgcolor=white' height=200 width=200 style='border: none;></iframe><br>+
" <div class="details">+
" <div class="title">+
" +itemName+
" </div>+
" </div>+
" </li> ";
document.getElementById("myDiv").innerHTML += siteContents2;
</script>
</head>
<body>
<div id="myDiv"></div>
Since ES6, you can store multi-line variables as template literals by surrounding them with backticks (`s):
var siteContents2 =`<li>
<iframe src='<iframe src='http://bsite.com/itemshow.php?`+itemName+`&title=ok&bgcolor=white' height=200 width=200 style='border: none;></iframe><br>
<div class='details'>
<div class='title'>
<a href='`+itemName+`'>`+itemName+`</a>
</div>
</div>
</li> `;
document.getElementById("myDiv").innerHTML += siteContents2;
More on template literals here.
Your quotes and concats are not correct. try this:
var siteContents2 ="<li>" +
" <iframe src='<iframe src='http://bsite.com/itemshow.php?"+itemName+"&title=ok&bgcolor=white' height=200 width=200 style='border: none;></iframe><br> "+
" <div class='details'>"+
" <div class='title'>"+
" <a href='/"+itemName+"/'>"+itemName+"</a>"+
" </div>"+
" </div>"+
" </li> ";
You're missing some quotes from the end of some of the lines and you can use either single quotes (') or an escaped double quote (\") within the html.
var siteContents2 ="<li> "+
" <iframe src='<iframe src='http://bsite.com/itemshow.php?"+itemName+"&title=ok&bgcolor=white' height=200 width=200 style='border: none;></iframe><br>"+
" <div class='details'>"+
" <div class='title'>"+
" <a href='"+itemName+"'>"+itemName+"</a>"+
" </div>"+
" </div>"+
" </li> ";
document.getElementById("myDiv").innerHTML += siteContents2;
Your code had erroneous quotes throughout it so it was technically an invalid string and most likely being rejected. In addition, you can do multiline strings by ending each line with a \ so you don't have to worry about so many quotes.
Your code, rewritten and working, could look like this:
var itemName = "blahblah";
var siteContents2 = "<li>\
<iframe src='http://bsite.com/itemshow.php?" + itemName + "&title=ok&bgcolor=white' height=200 width=200 style='border: none;'></iframe>\
<br>\
<div class='details'>\
<div class='title'>\
<a href='" + itemName + "'>" + itemName + "</a>\
</div>\
</div>\
</li>";
document.getElementById("myDiv").innerHTML += siteContents2;
Here's a jsFiddle of the code:
http://jsfiddle.net/vkaC8/

Categories