Nunjucks string embed at render rather than compile time - nunjucks

We have a template that's taking up to 40 seconds to render which has been attributed to a JavaScript inline insertion being performed at what appears to be compile and not render time. We found this by turning cache on.
The workflow 'dump' is about 2Mb.
<script type="text/javascript">
window.addEventListener('DOMContentLoaded', function () {
var form = document.getElementById('workflow');
window.app.caseSection(form, '{{ workflow | dump }}');
});
</script>
One option is to abort the approach entirely and load the data later via ajax. Is there another way to solve it inline?

Related

Loading iframe.src runs all javascript in the JSP

My app runs inside an iframe in a wrapper page. When the wrapper page loads, the source for the iframe is set like this
<script type="text/javascript">
var frameSrc = 'myApp.jsp';
$(document).ready(function() {
loadFrame(frameSrc);
$("#iFrm").height($(window).height() - 175);
$(window).bind('resize', function(){
$("#iFrm").height($(window).height() - 175);
return false;
});
$("#adminLink").click(function(){
frameSrc = 'myAdmin.jsp';
loadFrame(frameSrc);
});
return false;
});
function loadFrame(src){
$("#iFrm").attr('src', src);
}
</script>
And this loads and runs just fine, but then I've got the admin link on the page that is intended to load a different page into the iframe and it has an event handler inside the document.ready function.
The issue that I'm encountering is that the myAdmin.jsp is loading and then the original document.ready script, in the wrapper page, is running again - completely with the original frameSrc value. It seems as though by changing the iframe source, it's triggering a reload of the entire wrapper page and the original iframe source. Has anyone seen this? Am I missing something obvious?
I got an answer to this question while working through various possible solutions. The problem turned out to have to do with adminLink. The href value was empty, which appears to have directed the browser to reload the current page (the wrapper). When I put javascript: return false; in the href my issue resolved.
<a id="adminLink" href="">Administration</a>
vs
<a id="adminLink" href="javascript:return false;">Administration</a>

Chosen not working on elements from AJAX call

I have a form which populates div elements based on selections from a select box using an AJAX call.
The content of the populated div is a multiselect box that I want Chosen to apply to. Unfortunately it seems that the 'chzn-select' is not firing, no doubt due to this being pulled in dynamically.
I have added this:
<script type="text/javascript">
$(".chzn-select").chosen();
</script>
To the bottom of the code that is pulled in by AJAX, but it is still not firing. Any ideas on how to make this work as desired?
Solved myself. Will post for future reference. I put the Chosen calls in their own function on my original page that calls the AJAX:
<script type="text/javascript">
function doChosen() {
$(".chzn-select").chosen();
$(".chzn-select-deselect").chosen({allow_single_deselect:true});
}
</script>
And in the AJAX script itself, I added a call to the function after the responseText part:
document.getElementById(div).innerHTML=oXmlHttp.responseText
doChosen();
instead of using chosen(), try change() method. It works on change event.
try:
$(".chzn-select").change(function () {
var str = "";
$("select option:selected").each(function () {
// do your coding here
});
})
.trigger('change');

Load zebra strip in ajax loaded table

I tried to apply a zebra strip with an ajax loaded table but it's not work. I tried googling some suggestion over the net but no luck. Here's my code:
CSS:
<style>
.odd{background:#eeeeee}
</style>
Javascript:
<script src="../jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("tr:even").addClass("even");
$("tr:odd").addClass("odd");
});
//supplier ajax viewer
$(document).ready(function(stripTable) {
$("#supplier_viewer").load("inc/stock_view.php");
$('tr:odd',this).addClass("odd");
var refreshId = setInterval(function() {
$("#supplier_viewer").load('inc/stock_view.php?randval='+ Math.random());
}, 10000);
$('tr:odd',this).addClass("odd");
$.ajaxSetup({ cache: false });
});
</script>
And this is where the table is loaded.
HTML:
<div id="supplier_view"></div>
I've tried to add
$('tr:even',this).addClass("even");
to the load stage but not work. Please suggest.
You are applying the classes to the element before they are actually loaded.
Try applying these classes when the loaded event is fired.
I would also recommend to use FireBug to view the generated html and see if the classes are really applied to the dynamically loaded data. (which I highly suspect not)
Once the data is loaded, you need to execute these two lines
$("tr:even").addClass("even");
$("tr:odd").addClass("odd");
But only after the data has been loaded to the div

Conflict when loading a page multiple times with jQuery ajax load

I designed a ASP.NET page named kk-container.aspx to be used as a control which will be loaded in Default.aspx with jQuery load function. The page kk-container.aspx has many HTML controls and javascript events bound as in the example.
<!--Sample code from kk-container.aspx-->
<div id="kk-container">
Action
<!--Many HTML controls here-->
</div>
<script type="text/javascript">
$(document).ready(function () {
$("#kk-action").click(function () {
return false;
});
});
//Many javascript here.
</script>
I load this kk-container.aspx into Default.aspx with such code in the Default.aspx.
<div id="mycontainer"></div>
<script type="text/javascript">
$("#mycontainer").load("kk-container.aspx");
</script>
Everything works fine up to here. However, I have to load this kk-container.aspx in a few more divs in the Default.aspx. This causes conflict in the id's of HTML controls. $("#kk-action").click() doesn't work for all. How can I solve this problem and load kk-container.aspx multiple times in one Default.aspx page.
More to say: I considered giving random id's for HTML controls for each load of kk-container.aspx. However I had already designed my stylesheet mostly with id selector. And I use a packet javascript, valums uploader, working in kk-container.aspx. It will also require edit. If there is a simpler way, I don't want to code all over.
I expected too much from jQuery and asked this question desperately. I should have decided first whether I will use "kk-container" thing once or multiple times in a page. For loading "kk-container" thing multiple times, I had to consider these:
Designing CSS using class selectors instead of id selectors.
Producing random id for my HTML elements like in this question.
Writing my javascript functions so that they work compatible with those random id's.
Therefore loadind "kk-container.aspx" in a page with jQuery load wouldn't cause any id conflicts.
Anyway, I did a mistake and didn't want to rewrite my code. I found a solution to load content of "kk-container.aspx" in my Default.aspx page without a problem. Instead of jQuery load function I used iframes.
Since there is already an item with id "kk-action",
Action (like this one)
loading a content having an item with id "kk-action" will cause trouble.
$("#mycontainer").load("kk-container.aspx?id=" + recordID); //troublesome method.
Instead create an iframe without border and load that content into iframe.
function btnEdit_Click(recordID) {
$('#mycontainer').html("");
var kayitKutusuFrame = document.createElement("iframe");
kk-Frame.setAttribute("id", "kk-iframe");
kk-Frame.setAttribute("src", "kk-container.aspx?id=" + recordID);
kk-Frame.setAttribute("class", "kk-iframe"); //For border: none;
kk-Frame.setAttribute("frameBorder", "0");
kk-Frame.setAttribute("hspace", "0");
kk-Frame.setAttribute("onload", "heightAdapter();"); //For non-IE
document.getElementById("Mycontainer").appendChild(kk-Frame);
if (isIE = /*#cc_on!#*/false) { //For IE
setTimeout(function () { heightAdapter() }, 500);
}
}
I didn't gave random id to "kk-iframe" because I will not use it mulitple times. It now resides in FaceBox. To make the iframe flawless, it needs to be auto-resized. My heightAdapter() function will do it. Not only when a content is loaded into iframe but also content changes dynamically because of my clicks.
Here is the actual code for resizing iframe to fit content by Guy Malachi.
function calcHeight(content) {
//find the height of the internal page
var the_height = content.scrollHeight;
//change the height of the iframe
document.getElementById("kk-iframe").height = the_height;
}
Here is my heightAdapter() function which will work both when content is loaded and when I clicked something causing content to expand.
function boyutAyarlayici() {
var content=document.getElementById("kk-Frame").contentWindow.document.body;
calcHeight(content);
if (content.addEventListener) { //Forn non-IE
content.addEventListener('click', function () {
calcHeight(content);
}, false);
}
else if (content.attachEvent) { //For IE
content.attachEvent('onclick', function () {
calcHeight(content);
});
}
}
And the following is a link in a repeater. Since the link will be replicated, it should have unique id by asp server.
<a href="#mycontainer" rel="facebox" id='btnEdit-<%# Eval("ID") %>'
onclick='btnEdit_Click(<%# Eval("ID") %>); return false;'>Düzenle</a>
Now, whenever I click one of the replica links, the content having an item with id "kk-action" can be loaded into the my flawless iframe which will be created in "mycontainer".
<div id="mycontainer" class="kk-iframe" style="display:none"></div>
And the content will be shown in my fancy FaceBox.
You're going to have to use classes to style the elements. There can only be one unique ID per page, so you are going to have to generate different IDs or use class selectors in your JavaScript such as:
$('.kk-action').click()
The above is probably the best way to go as it will give every element with that class the binding

What would the be reason JQuery has access to DOM but not ExtJS?

I have a Kohana framework which is building ExtJS objects in one view, which in turn loads (via JQuery AJAX) other views inside of it with a this function:
function replaceContentOnClick(id, route) {
$('body').delegate(('#' + id), 'click', function(){
$.get(route, function(data) {
$('#region_center .x-panel-body').html(data);
});
});
}
This is working fine but only when these child views are merely HTML/Javascript/JQuery, but in the child views I cannot get any ExtJS objects to display, even if I render them to DOM elements that exist and to which I can successfully append JQuery elements. It is as if the DOM doesn't exist for ExtJS at that moment.
The main problem is: the JQuery code successfully fills the element:
<script type="text/javascript">
$('#region_center .x-panel-body').html('this is from jquery...');
</script>
but the ExtJS code fails to fill the same element (an there is no error reported in Firebug/Net panel):
<script type="text/javascript">
var region_center = new Ext.Panel({
id: 'region_center',
region: 'center',
renderTo: '#region_center .x-panel-body',
margins:'10 10 10 10',
padding:'10 10 10 10',
autoScroll:true,
html: 'this is from ExtJS...'
});
</script>
What do I have to do so that ExtJS can access the DOM element as JQuery can?
These two bits of code are doing different things. This code:
<script type="text/javascript">
$('#region_center .x-panel-body').html('this is from jquery...');
</script>
...is accessing the DOM node at '#region_center .x-panel-body' and injecting a new innerHTML value. This code:
<script type="text/javascript">
var region_center = new Ext.Panel({
id: 'region_center',
region: 'center',
renderTo: '#region_center .x-panel-body',
margins:'10 10 10 10',
padding:'10 10 10 10',
autoScroll:true,
html: 'this is from ExtJS...'
});
</script>
...is attempting to render a complete Panel component into itself (i.e., the renderTo config is pointing at the panel with id 'region_center', which is the panel itself). This makes no sense and will not work. You can only render components to an existing DOM node -- in this example, there is no existing DOM node with id 'region_center' because the panel is not yet (and cannot be) rendered.
The equivalent code to do exactly what you're doing in jQuery would be this:
<script type="text/javascript">
Ext.get('#region_center').child('.x-panel-body').update('this is from Ext...');
</script>
Assuming all things are equal in the DOM when this is run, it should execute exactly like your jQuery code.
Now, assuming that your BorderLayout is properly rendered, and it in fact has a center region with id 'region_center', you should be able to add a new panel into it dynamically (make sure the new panel's id is unique). Note that it would be preferable to go through the Component API (instead of the DOM API) to do this as layout will be managed for you in that case. E.g., you'd want to do something like:
// assuming myCenterPanel is a valid *component* ref (NOT a DOM element):
myCenterPanel.add(new Ext.Panel(...));
myCenterPanel.doLayout();
You'd also want to ensure that the center panel has an appropriate layout assigned (via the layout config). If you simply render the new panel directly to the underlying DOM node instead (as you're trying to do above), it may work, but in the long term will probably cause you other issues (again, since you are bypassing Ext's layout manager in that case).

Resources