BorisMoore / jquery-tmpl

The original official jQuery Templates plugin. This project was maintained by the jQuery team as an official jQuery plugin. It is no longer in active development, and has been superseded by JsRender.
3.23k stars 1.01k forks source link

Unbound variables evaluated in template rendering context might be bound to DOM elements #155

Open lincolnq opened 13 years ago

lincolnq commented 13 years ago

The below example demonstrates clearly what is going on. As far as I can tell, the evaluation of {{= errr}} in the template language searches the template data, and then searches the DOM for an element with id matching the name of the variable. I expected the variable to be undefined at this point (and therefore also fail the '{{if errr}}').

Unfortunately, after trying to debug, I have no idea why it is doing this.

I will work around it with $data.err, but this was surprising behavior that seems like a bug to me.

<!doctype html>
<html>
<div id="errr" style="display:none;">The presence of this div in the page affects template rendering</div>

<hr>
<p>The test template which refers to 'errr' will be rendered in the below div, with the context {'ok': 'ok'}
</p>

<div id="contents-ok">
</div>

<p>The test template which refers to 'errr' will be rendered in the below div, with the context {'errr': 'you failed'}
</p>

<div id="contents-err">
</div>

<hr>
<p>The test template which refers to 'errr2' will be rendered in the below div, with the context {'ok': 'ok'}
</p>

<div id="contents2-ok">
</div>

<p>The test template which refers to 'errr2' will be rendered in the below div, with the context {'errr2': 'you failed'}
</p>

<div id="contents2-err">
</div>

<hr>
<p>The test template which refers to '$data.errr' will be rendered in the below div, with the context {'ok': 'ok'}
</p>

<div id="contents3-ok">
</div>

<p>The test template which refers to '$data.errr' will be rendered in the below div, with the context {'errr': 'you failed'}
</p>

<div id="contents3-err">
</div>

<script id="test-with-errr-ref" type="text/x-jquery-tmpl"> 
<p>Template rendering... {{if errr}}there was some errr: {{= errr }}
{{else}}there was no errr
{{/if}}</p>
</script>

<script id="test-with-errr2-ref" type="text/x-jquery-tmpl"> 
<p>Template rendering... {{if errr2}}there was some errr2: {{= errr2 }}
{{else}}there was no errr2
{{/if}}</p>
</script>

<script id="test-with-data-errr-ref" type="text/x-jquery-tmpl"> 
<p>Template rendering... {{if $data.errr}}there was some $data.errr: {{= $data.errr }}
{{else}}there was no $data.errr
{{/if}}</p>
</script>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.js" type="text/javascript"></script>
<script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.js" type="text/javascript"></script>
<script type="text/javascript">
jQuery(function($) {
    $.tmpl($("#test-with-errr-ref"),      {'ok': 'ok'}           ).appendTo("#contents-ok");
    $.tmpl($("#test-with-errr-ref"),      {'errr' :'you failed'} ).appendTo("#contents-err");
    $.tmpl($("#test-with-errr2-ref"),     {'ok': 'ok'}           ).appendTo("#contents2-ok");
    $.tmpl($("#test-with-errr2-ref"),     {'errr2':'you failed'} ).appendTo("#contents2-err");
    $.tmpl($("#test-with-data-errr-ref"), {'ok': 'ok'}           ).appendTo("#contents3-ok");
    $.tmpl($("#test-with-data-errr-ref"), {'errr':'you failed'}  ).appendTo("#contents3-err");
});
</script>

</html>
BorisMoore commented 13 years ago

IE will create global vars for ID'd elements. If this is in IE, this will be the reason... Not a bug in tmpl. But you have to avoid have ids with the same name as data variables you are testing for. This can also break regular javascript if you test for undefined on something which has the same name as an ID for an element.

lincolnq commented 13 years ago

Ah, sorry - I didn't realize it was browser specific. Firefox doesn't reproduce, but Chrome does. Don't have an IE to test with.

rdworth commented 13 years ago

Thanks for taking the time to submit this issue. Just wanted to let you know this plugin is no longer being actively developed or maintained by the jQuery team. See README for more info.