Adding jinja template dynamically - javascript

I have a jinja template that is the only content inside a set of div tags.
<div id="section0">
{% include 'temppage.html' %}
</div>
When I press a button, I want to replace everything between the tags with something else. I was hoping to replace it with another jinja template, "{% include 'realpage.html' %}", but first I am unsure of how to replace the entire section, instead of just replacing a single word. Second, can I even add a jinja template dynamically, or do I need replace it with a string with the contents of the file directly.

As glls said, replacing the content can be used with,
document.getElementById("section0").innerHTML = "something";
As for adding a jinja template dynamically, you need to replace the innerHTML with a multi-line string of the wanted jinja template, with is used with backticks, "`". So it would look like,
document.getElementById("section0").innerHTML = `{% include 'realpage.html' %}`;
The template is executed when the page loads (which is unavoidable as far as I'm aware), so when inspecting the html of the live page, the multi-line string will contain whatever is in the file you are including.

You could use a JS framework (such as Angular, React...) in order to achieve this...I am assuming you are trying to build a single page app?
Otherwise, you will have to rely more on Javascript in order to change the HTML under you div depending on what you click. For example, if you have button 1, 2, 3. Each rendering a different HTML template upon clicking.
Example (using jQuery):
$(document).on('click', '.some-class', function() {
document.getElementById("section0").innerHTML = "something";
});
fyi: "something" can be an html structure.

Related

Js Handlebars - use and apply CSS inside a template

I use handlebars like this somewhere inside the body of the HTML
{{template.header}}
Everything works as expected till I want to add css styles/or HTML tags as the "header" content (styling is not as part of the parent item, because I dynamically get the styling from outside) .
Eg: "header" -> <p style="font-size:14px"> My header </p>
If I try to use that I get them in the outputted result, probably as expected because I don't specify somehow that the template owner wants control over the styling inside the passed template data
Is there a way for the user to specify styling from outside and handlebars just to output the passed input styling ?
You can use triple brackets to render html. Just be careful because this opens you up to XSS attacks if its user input viewable by other users.
{{{template.header}}}
https://handlebarsjs.com/guide/expressions.html#html-escaping

why handlebars compile the script template as CDATA

I write a function which compile a handlebars template and append to the html.
I use thousands times of handlebars template in my project and all things go well.
I have to mention it'll be rendered properly in localhost, but in the server it returns me with CDATA.
but in this case handlebars outputs like this and causes lots of problems.below is template html which is inside template.php file
<script id="w-l-template" type="text/x-handlebars-template">
<div data-name="name{{ID}}"></div>
.....
</script>
here is function inside a js file called my.js
var num = 2;
function add_name(){
var out = $('#w-l-template').html();
var template = Handlebars.compile(out);
var data={
ID:num
}
var res=template(data);
$('[data-main-content="main"]').append(res);
num = num+1;
}
$(document).on('click', '#add', function(){
add_name();
});
but after being rendered by handlebars, I'll get CDATA at the first line like this
<!--[CDATA[*/<div class="col-lg-12 "data-name="2"-->
I know this answer is kind of late, but I had a similar issue today. I found out that Handlebars isn't adding the CDATA into my HTML, it's actually Drupal. We sometimes create pages with Drupal's inline editor, and so I'll drop in HTML via the Full HTML editor.
Unfortunately, if you don't configure the HTML editor in Drupal to NOT rewrite broken HTML -- it considers Handlebar script syntax as broken, then Drupal will attempt to fix the tag and add in CDATA which makes your tag get commented out. Handlebars will then try to template that new commented tag and also output a commented out tag. Frustrating! But hope my answer somewhat helps you with yours (or if you run into this situation again in the future).
Basically TL:DR, it's not Handlebars -- it's probably some setting in your PHP (or CMS that uses PHP) that is probably trying to "fix" the Handlebars template because it thinks the HTML is broken.

Using PrototypeJs, how to load a jsp page asynchronously

We're using Spring and PrototypeJs in our app. Basically I want to have a template page and then fill the template page with some values. I found a JQuery.load method but we're not using JQuery.
Closest thing I found was prototype Template object which is just a string. I can make a template in Javascript like the following:
var template1 = new Template("user id: #id name is <span class name='userName'>#name</span>");
and then once I have all the data as json fill in the blanks but this is not enough. I want to display tags etc and be more complex and ideally just load this template file once and just fill in the values later. Is that even possible without using backbone.js or angularjs?
I guess my question is, how do I construct a page better? Currently I'm creating my entire page in javascript (e.g. new Element("div").addClassName("something")) so I was hoping to create my page 'template' in a jsp or some other form and then just fill in the blanks.
I have all the data to display on the page as json.
The Template class is quite flexible about how you create its members. What I would do, for readability, is code your template as an actual page element in the HTML, and then remove it on page load before using it to fill in your JSON.
<div id="template-1" class="#{classname}">
<h1>#{headline}</h1>
<p>#{description}</p>
</div>
<div id="articles"></div>
<script type="text/javascript">
var tmp = $('template-1').remove();
tmp.writeAttribute('id',false);
var template = new Template(tmp.outerHTML);
// do whatever with it
$('articles').insert(template.evaluate(myJSON));
</script>
That should get you started. The major benefit of working this way is that you don't have to keep backslashing quotes and writing everything in one line, or bashing it together with + signs.

How to reload javascript for jinja template?

I'm relatively new to jinja2 (and by no means a web dev expert), and I'm having trouble getting the javascript associated with a jinja template to reload (and update its variables) based on changes in the state of the program.
Essentially, I have one template iterating through a list of items:
{% for item in items %}
<p> {{item['property a']}}</p>
blah blah blah`
and then I call another template I've imported within that for loop:
{% import 'secondTemplate.html' as s %} //not sure whether this matters if it goes inside or outside the for loop
<p> {{s.doSecondStuff(item)}}</p>
That all works. The second template executes each time with each item, which is want I want.
But, I have some secondTemplate.js associated with secondTemplate.html that operates on the variables passed to secondTemplate.html. My problem is that secondTemplate.js only ever operates on the first item's values.
It seemed like the top answer from Loading external script with jinja2 template directive would work, so I've been trying to put the following in the for loop:
{% block javascript %}
<script type="text/javascript">
{% include "secondTemplate.js" %}
</script>
{% endblock %}
But the js is still only reflecting the values of the first item in the list.
Any ideas? Thanks!
If you open your Flask app with a browser, Flask looks through the routes you defined and selects the one that it finds the most appropriate, for example:
#app.route('/<name>')
def index(name):
return render_template('index.htm', var1=name)
It executes the inside of the function like a normal function in any programming language. And here is the point: The function only returns a string of HTML. It doesn't do any "magic" to pass any information about variable names to the browser. To be concrete, if index.htm looked like this:
<h1>Hello {{ name }}!</h1>
Then render_template('index.htm', name="world") returns a string with the content "<h1>hello world!</h1>", which is what your view returns, which is what Flask gives the browser.
So the browser, and therefore your Javascript code, have absolutely no idea which part of the HTML was a variable and which not. By the time you are executing Javascript in the browser, your Flask app already has forgotten about the client and the value of name it was given.
It's really unclear what you are asking, but i hope i made it clear to you how the thing you are trying to achieve will not be possible in that way.
I am not familiar with jinja, but there is a trick like below, if you want to reload js file (if I understand you right). Let's make all tags with id's, so:
<script src="be/happy.js" id ="be/happy.js"></script>
<script src="be/very/happy.js" id ="be/very/happy.js"></script>
and so on. Now is the clue. We can force browser to load file again, using this method:
var s = document.getElementById('be/happy.js'); //get access to node
d.parentNode.removeChild(s); //remove it from document
delete d; //destroy element
d = document.createElement('script'); //create new script tag
d.src = d.id = 'be/happy.js'; //add the same value to id and src attribute
document.getElementsByTagName('head')[0].appendChild(d); //append child again, what force browser to script reload

jQuery .append() not rendering html entity

I have a variable with html in it like this:
var html = '<div>Hello, you're awesome!</div>';
I want to append it to an element $("body").append(html) for some reason it's not decoding the HTML Entity. I tried $("body").append($(html)); and that didn't work. My text is stuck inside the element and I can't individually put it together.
Is there any way to append html with a text-based entity inside it into another element, and have the html entity render on the page?
I've read a bunch of posts on stackoverflow reguarding html entities and it seems that none of them include the html & text within a variable like this.
Try this:
var html = $('<div>Hello, you're awesome!</div>');
$("body").append(html)
Demo here
It could be possible that your page did not finish loading while the jQuery code was trying to append the content. Try:
$(document).ready(function (){
var html = '<div>Hello, you're awesome!</div>';
$('body').append(html)
});
And I would suggest using single quotations only unless you need to use escaped characters.

Categories

Resources