Mustache.js splits HTML attibuts between whitespaces - javascript

Mustache.js splits an HTML attribut between many HTML attributs between whitespaces. How can I keep the attribut as it is ?
The Object to render (width contains whitespaces)
cardpool = {
width:"col-md-offset-3 col-md-6 col-sm-4"
}
The template to use
<div class={{width}}>
</div>
The wrong result (Mustache.js splits the attributs between the whitespaces) :
<div class="col-md-offset-3" col-md-6="" col-sm-4="">
</div>
The expected result (I want to keep the whitespaces in the attribut)
<div class="col-md-offset-3 col-md-6 col-sm-4">
</div>
Do you have a solution to get the expected result ?
Thank you for your help.

This isn't Mustache's fault. Your template is rendered to this:
<div class=col-md-offset-3 col-md-6 col-sm-4>
</div>
Notice the lack of any quotation marks around your class names. A browser can internally convert this to what you're seeing (I'm guessing that you are inspecting the generated data inside your browser's dev tools).
Your template should include the quotation marks around the variable if you want to group the class names into a single class attribute value:
<div class="{{width}}">
</div>
Mustache is (mostly) agnostic about the context in which it's used, so it doesn't know that attributes in HTML should be surrounded by quotation marks if the values contain whitespace. Hence, you need to add those yourself.

Try with the triple mustache: {{{width}}}. This prevents HTML escaping, which it does if used as {{width}}.

Not familiar Mustache.js, but ejs for example works like this :
<div class="<%= preRendData.class %>"></div>
So try your code with quotes :
<div class="{{width}}">

Related

Angularjs: render raw html inside double curly braces - possible?

I'd like to render raw html snippet inside angular's double curly braces, but couldn't find a way to do it.
I know there's ng-bind-html directive for binding raw html text, but this only works inside a tag (I mean it replaces the contents of a tag), but I want to insert a html snippet without enclosing it in any tag.
Example:
<div class="row">
<div>....</div>
<div>....</div>
.....
<div>...</div>
{{</div><div class="row">}} <- here's what i'd like to insert - close a row and start a next one
<div>....</div>
<div>....</div>
.....
<div>...</div>
</div>
So, if you look at the html structure above, I want to insert a closing tag and immediately open a new one. This has to be done dynamically, because all the content is dynamic and I would like to divide it into rows depending on the data model.
Any ideas?
I'm not sure about what you wanna do, and I'm very sure, that it's not the best way or even smart, but you can try this:
{{'</div><div class="row">'}}
Define one variable in your scope:
$scope.rowHtml = "<strong>Your text here</strong>"
Assign it to ng-model of your <DIV>
<div class="row" ng-model="rowHtml ">

How to set the id attribute of a HTML element dynamically with angularjs (1.x)?

Provided an HTML element of type div, how to set the value of its id attribute, which is the concatenation of a scope variable and a string ?
ngAttr directive can totally be of help here, as introduced in the official documentation
https://docs.angularjs.org/guide/interpolation#-ngattr-for-binding-to-arbitrary-attributes
For instance, to set the id attribute value of a div element, so that it contains an index, a view fragment might contain
<div ng-attr-id="{{ 'object-' + myScopeObject.index }}"></div>
which would get interpolated to
<div id="object-1"></div>
This thing worked for me pretty well:
<div id="{{ 'object-' + $index }}"></div>
In case you came to this question but related to newer Angular version >= 2.0.
<div [id]="element.id"></div>
A more elegant way I found to achieve this behaviour is simply:
<div id="{{ 'object-' + myScopeObject.index }}"></div>
For my implementation I wanted each input element in a ng-repeat to each have a unique id to associate the label with. So for an array of objects contained inside myScopeObjects one could do this:
<div ng-repeat="object in myScopeObject">
<input id="{{object.name + 'Checkbox'}}" type="checkbox">
<label for="{{object.name + 'Checkbox'}}">{{object.name}}</label>
</div>
Being able to generate unique ids on the fly can be pretty useful when dynamically adding content like this.
You could just simply do the following
In your js
$scope.id = 0;
In your template
<div id="number-{{$scope.id}}"></div>
which will render
<div id="number-0"></div>
It is not necessary to concatenate inside double curly brackets.
Just <input id="field_name_{{$index}}" />
If you use this syntax:
<div ng-attr-id="{{ 'object-' + myScopeObject.index }}"></div>
Angular will render something like:
<div ng-id="object-1"></div>
However this syntax:
<div id="{{ 'object-' + $index }}"></div>
will generate something like:
<div id="object-1"></div>

Unable to specify multiple attributes in handlebar

I am having problem specifying multiple attributes in any class at all.
if I have a key:value like
{"class":"javascript handlebar-js"}
and use it like this
<div class={{class}}><div>
it only spits out
<div class="javascript"><div>
when I want
<div class="javascript handlebar-js"><div>
Sometimes I have one class sometimes I have multiple classes
Is there any other way to do this besides putting all classes inside an array and using a with + each statement to move through each class and cramping up my object with unnecessary arrays? Not that I am sure if using said method would work.
any help would be appreciated
As said by Pointy, enclosed class definition into simple or doubles quotes.
Based upon this data ({"className":"javascript handlebar-js"}),
<div class="{{className}}"> </div> will produce <div class="javascript handlebar-js"></div>
<div class={{className}}> </div> will produce <div class="javascript" handlebar-js></div>
The two results will not be interpreted in the same way in the browser.

Appending large block of html with append()

Im trying to append a large block of text using jquery's append().
$('#add_contact_btn').click(function(event) {
event.preventDefault();
var large = '<div class="accordian_container"><h4>Co-Borrower Information</h4><hr/><div class="accordian_item" id="accord_item_2"><label> First Name</label><br/><input type="text"/><br/><label>Middle Name</label><br/>
<input type="text"/><br/>
<label>Last Name</label><br/>
<input type="text" /><br/>
<label>Home Number</label><br/>
<input type="text"/><br>
<label>Work Number</label><br/>
<input type="text"/><br>
<label>Cell Number</label><br/>
<input type="text"/><br>
</div>
</div>';
$('#accordion_container').append(large);
});
It doesn't seem to be working and after looking at the documentation for append(), I can't figure out why - any ideas? Is it the large amount of HTML that I am trying to append?
Modern Answer
As ES6 (and beyond) becomes more common, and as more and more people transpile from ES6, we are more and more able to use template literals, which can be used as multiline strings:
var myString = `<p>Line One</p>
<p>Line Two</p>
<p>Line Three</p>`;
Original 2012 Answer (ES5)
Javascript does not have multiline strings in the way you are writing them, you can't just open a string on one line, go down a few lines and then close it. (there are some ways of doing multi-line strings in JS, but they are kind of backwards).
How most people do it is something like this:
var myString = '<p>Line One</p>' +
'<p>Line Two</p>' +
'<p>Line Three</p>';
You could create a template in HTML that is hidden, then append its content HTML. For example:
<div class="hide" id="template">
<b>Some HTML</b>
</div>
jQuery:
$("#container").append($("#template").html());
Putting HTML in a JavaScript string is harder to read and search for, is error prone and your IDE will struggle to format it properly.
Update 2019
Check out the template tag, which was created for this purpose: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template
The template tag is even allowed to contain what would be invalid HTML elsewhere, e.g. a td tag outside a table.
Remove the line breaks.
http://jsfiddle.net/DmERt/
var large = '<div class="accordian_container"><h4>Co-Borrower Information</h4><hr/><div class="accordian_item" id="accord_item_2"><label> First Name</label><br/><input type="text"/><br/><label>Middle Name</label><br/><input type="text"/><br/><label>Last Name</label><br/><input type="text" /><br/><label>Home Number</label><br/><input type="text"/><br><label>Work Number</label><br/><input type="text"/><br><label>Cell Number</label><br/><input type="text"/><br></div></div>';
$('#accordion_container').append(large);​
It's my understanding that if you want to put your long string on multiple lines that it's more efficient to use an array of strings and join them.
var bigString = [
'some long text here',
'more long text here',
'...'
];
$('#accordion_container').append(bigString.join(''));
You can use a backslash at the end of each line.
http://davidwalsh.name/multiline-javascript-strings
var multiStr = "This is the first line \
This is the second line \
This is more...";
Another alternative is Template literals with back-ticks:
var large = `some long text here
some long text here
some long text here`;
It's a fairly new syntax and not supported in IE though.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
Use Template literals Template literals are literals delimited with backticks (`), allowing embedded expressions called substitution
var test = `<div class="question-content"> <p> ${mydata.commented.comment}</p></div> <div class="about-info">
<div class="count-section">
<button id="clike-button" value={{comment.id}}><i class="fas fa-arrow-up"></i></button>
<h3 id="clike_count">{{ question.clike_count }}</h3>
<button id="cdislike-button" value={{comment.id}}><i class="fas fa-arrow-down"></i></button>
</div>
<div class="user-profile">
<img src="{% static 'img/profile-pic.png' %}" alt="">
<div class="user-info">
<p> ${mydata.user}</p>
<p class="user-badge">
<p class="user-badge"> <span style="padding-left: 2px;">13.1k</span><i
class="fas fa-circle gold"></i> <span> 2</span> <i class="fas fa-circle silver"></i>
<span>
7</span> <i class="fas fa-circle bronze"></i> <span>56</span>
</p>
</div>
</div></div> `;
$("#commentlist").append(test)
https://i.stack.imgur.com/5BZHB.png
Javascript have the option to extend multiple lines/HTML section into a single line, for each line of HTML row add backslash() to identify that its continue line.
Note :-The only thing to consider while append lines are the single quote and double quote. If you start with the single quote, then use double quote in the internal string or vice-versa, otherwise, line is break and do not get the proper result.
$(element).append('<div class="content"><div class="left"></div><div class="right"></div></div>');
Javascript syntax
var str = ' <div class="content"> \
<div class="left"> \
</div> \
<div class="right"> \
</div> \
</div> ';
document.getElementsByName(str).html(str);
//or
document.getElementsById(str).html(str);
Jquery syntax
$(element).append(' \
<div class="content"> \
<div class="left"> \
</div> \
<div class="right"> \
</div> \
</div> \
');
Or
you can use a html template for this as mention in 3rd link via jquery
$("#div").load("/html_template.html");
http://www.no-margin-for-errors.com/blog/2010/06/17/javascript-tip-of-the-day-extending-a-string-across-multiple-lines/
Appending multiple html elements using Jquery
spread html in multiple lines javascript
By default, the HTML code containing wraps cannot be used with append/prependdirectly use 'or". However currently there are following methods to do that:
Use "+" to join HTML code pieces.
Use "\" to escape.
Use "`" (back-tick, grave accent), do not need any extra operations.
This method is supported from ES2015/ES6 (Template literals).
Add a hidden tag containing the same HTML code you need, e.g. <p id="foo" style="display:none;">, then use.append($('#foo').html());.
Now post some use scenarios to the first three methods metioned above (just run them in the console of Chrome browser.):
We can see their differences clearly.
You can also clone the div with jQuery and then append the clone--way less messy.
var accordionClone = $('.accordion_container').clone();
$('#accordion_container').append(accordionClone);
just add like this $(#element).append(large_html),large_html in special character(``) and thank me later.
If line-breaks are an issue just use innerHTML, works in every browser since IE5:
$('#accordion_container')[0].innerHTML += large;​
Or, for collections:
$('.accordion_container').forEach(function () {
this.innerHTML += large;​
});

How to concatenate strings in JavaScript with tabs and carriage returns in Geany?

I'm making an app with dynamic content loader, it's load the content via ajax then change the DOM. I have a structure/schema, my question is how can I to concatenate the strings, I want to keep my code "indentated" for make it easly readable...
Example:
How can I achieve that? I need some special scape character or sort of?
You can escape the newline character at the end of each line with a \, though it's generally considered bad practice (because it's very easy to miss an escape in maintaining the code.)
var page = '\
<div class="row well">\
<div class="row info-block">\
<div class="col-xs-4 logo-container">\
' + logo + '\
</div>\
</div>\
</div>';
What you really want is ES6 template strings, though:
var page = `
<div class="row well">
<div class="row info-block">
<div class="col-xs-4 logo-container">
${logo}
</div>
</div>
</div>`;
Template strings allow multiline strings by default and support interpolation (the ${logo} above.)
Note: there is a difference between the two resulting strings. In the newline-escaped string, the newlines are actually not a part of the resulting string; whereas, they are in the template string example.

Categories

Resources