Comments (20)
Yes, thanks, I was aware of this issue, and will fix it soon...
from jsrender.
I have same problem any luck with this issue?
Right now I can only use the code like: {{=$itemNumber-1 undef 0}}
from jsrender.
I'm planning to include a fix for this, but it may have to wait until some bigger changes that are in the pipeline, since it relates to other issues like #7 - and to make both that issue and this one satisfied has to be compatible with maintaining current perf optimization. If you have a workaround, then best to stay with that in the meantime...
from jsrender.
+1, but workaround does work
from jsrender.
+1 but couldn't get workaround to work with an encoder (new workaround using a function below).
Pre-workaround, I started with {{=shopping.change.amount!currency}}
where "currency" is a custom formatter (encoder) registered with...
$.views.encoders["currency"] = function currency(number) {
//alert("typeof "+ number +": "+ typeof number);
try {
return number.toFixed(2);
} catch(e) {
// supplied something other than a number
return number +"(NaN)";
}
}
... so my unformatted workaround became {{=shopping.change.amount undef 0}}
which works but has no formatting.
I then tried adding the encoder as {{=shopping.change.amount undef 0!currency}}
but it gave same results as no workaround (value if non-zero; else blank).
I then went and read the source but can't adequately-grok-in-sensible-time how to use a formatter with the workaround (thattmpl
+ compile
code is kind'a heavy! :-O ). Guessing didn't work either ;-)
In case it's relevant, I'm using this with JQuery loaded.
Alternative workaround (that allows formatting)
Instead, I switched to using a function...
$.views.registerHelpers({
currency: function(number) {
// alert("typeof "+ number +": "+ typeof number);
try {
return number.toFixed(2);
} catch(e) {
// supplied something other than a number
return number +"(NaN)";
}
}
});
... and my template obviously now has {{=$ctx.currency(shopping.change.amount)}}
.
Zero and all other values render correctly. HTH other zero formatters!
from jsrender.
Doing
$.template("Quantity: {{=quantity}}")
generates ... result = "" + "Quantity: " + html($data.quantity || "");
where it should be ... result = "" + "Quantity: " + html($data.quantity);
and $.views.encoders.html
should become:
function (text) {
if (null == text) return ""; // skip null and undefined elements.
return String(text).replace(htmlSpecialChar, replacerForHtml);
}
PS:
(null == text) is true for undefined and null elements, but false for 0 and false,
whereas (text || "") will evaluate to "" for null, undefined, false, and 0.
Another inline optimization possibility is (null == text ? "" : text) instead of (text || "")
which should have good performance and certainly shorter than
("undefined" === typeof text || null === text ? "" : text).
from jsrender.
Looks like this problem comes from the paramsOrEmptyString
optimization.
I have branch (https://github.com/josher19/jsviews/blob/master/jsrender.js) with a commit (josher19/jsviews@338755b) which gets rid of the optimization and puts a similar one in the html encoder. HTML encoded text using {{= item }} will return blank ('') for undefined or null values but not for 0 or false, but using the ! will show 'undefined' and 'null' values:
{{= item !}}
Example usage:
$.template("HTML", "Qty: {{=Qty}}, null:{{=nil}}, notset:{{=blank}}, bool:{{=bool}}")(falsy={"Qty":0,"nil":null,"bool":false})
// Expected output: Qty: 0, null:, notset:, bool:false
// Old output: Qty:, null:, undefined:, bool:
$.template("NONE", "Qty: {{=Qty!}}, null:{{=nil!}}, notset:{{=blank!}}, bool:{{=bool!}}")(falsy={"Qty":0,"nil":null,"bool":false})
// Expected output: Qty: 0, null:null, notset:undefined, bool:false
// Old output: Qty:, null:, notset:, bool:
from jsrender.
Seeing this open for a year doesn't give me hope I could offer a fix myself, so I hate to simply post a breaking example in both the current jsrender and @josher19's version. I'm still going to take a look at the jsrender source when I get the chance, but there is definitely still an issue when $data
is 0
. Here's the gist of the example:
<ul id="results"></ul>
<script id="x" type="text/x-jquery-tmpl">
<li>{{=$data!}}</li>
</script>
<script type='text/javascript'>
$("#results").html($("#x").render([0, 1, 0, 2, 0]));
</script>
Results in: "<ul id="results"><li>1</li><li>2</li></ul>"
It doesn't even appear to attempt to step into the template to render the zero-value elements of that array. This seems to make workarounds like the custom tag, custom encoder, and helper function ideas fail too.
from jsrender.
! do have a fix for this already, but it is part of a major update which I have not committed because it involves some breaking changes. I don't want to do breaking changes piecemeal - but rather in one significant upgrade which will require some porting to the new syntax. After that I hope to keep things pretty stable. The JsRender update is ready, but it also ripples to some changes in JsViews, and I am working hard now to integrate JsViews changess with this update too.
So apologies that this is taking some time, but I think/hope the update will be worth the wait! It should be committed in a couple weeks time... I am targetting Beta for JsRender end of February...
from jsrender.
@patridge : fixed in my fork of the code so now your results render correctly with 0's included in the output.
Technical details: changed render to do
content = null != dataItem ? tmpl( dataItem, new View( context, path, arrayView, dataItem, tmpl, this )) : "";
instead of
content = dataItem ? tmpl( dataItem, new View( context, path, arrayView, dataItem, tmpl, this )) : "";
so now it will render the template for each line unless that line is null or undefined
(before it would skip rendering if the dataItem was falsy, meaning 0, false, "", null, or undefined).
Thanks for posting the example. It indirectly makes a strong argument for TDD.
@BorisMoore: feel free to pull these small changes and merge them with your changes to see if it fixes or breaks anything. Also let me know if you would like help setting up a test suite for new JsRender beta.
PS: Now 0 and false will show up whether or not you use ! when rendering:
$.template('qq', 'Quantity: {{=quantity!}}, Boolean: {{=bool!}}')({quantity:0, bool:false})
// "Quantity: 0, Boolean: false"
$.template('qq', 'Quantity: {{=quantity}}, Boolean: {{=bool}}')({quantity:0, bool:false})
// "Quantity: 0, Boolean: false"
from jsrender.
I forked your " breaking example" JsFiddle and added a couple more tests.
Red (failing):
http://jsfiddle.net/yUfyH/1/
Green (passing):
http://jsfiddle.net/mW7Fs/
from jsrender.
Hi Boris,
Updated the original example to use your new code:
<ul id="results"></ul>
<script id="x" type="text/x-jquery-tmpl">
<li>{{: #data }}</li>
</script>
/*global $ */
$(function() {
"use strict";
$("#results").html($("#x").render([-1, 0, 1, 2, 3, 4,
'-- booleans --',
false, true,
'-- null & undefined --',
null, undefined,
'-- strings --',
"", "string"]));
});
Now get '[object Object]' for the "falsy" values of 0, "", null, undefined, and false.
Cheers,
->> Josh <<-
from jsrender.
Ah, I see. Yes that is a slightly different case than the one I was looking at. I was thinking of the case where you have a data object with a property whose value is 0, or undefined. (e.g. { quantity: 0 } as above) - but this additional scenario is valid too. I have a fix for it, which I'll upload soon...
from jsrender.
Fixed in 5d284cb.
Closing, but please reopen if the fix does not work for you... Thanks...
from jsrender.
Yes, that seems to work pretty well:
Now undefined
is replaced with ""
(a blank string) and null
is replaced with the String "null"
, while 0
and false
remain unchanged.
from jsrender.
Yes, that's the intention. Actually, undefined, 0, null, true and false are rendered by the strings "", "0", "null", "true", "false". Would you expect anything different from this design?
JsRender always renders a string, of course. The return value from render() can never be other than a string.
from jsrender.
No, I think "" for undefined and "null" for null works well -- issue closed!
You might include in the documentation how to change that back to the old way (delete "falsy" values) or how to change "null" to "" using a helper function.
from jsrender.
There has been a new issue submitted suggesting null should render as "".
#87
I think it does make more sense. Any disagreement?
from jsrender.
I agree. Might include in the docs how to customize what is displayed using helper functions, because displaying "null" can be useful for debugging, but not so useful for displaying in final HTML produced by render
.
from jsrender.
This definitely fixed that sample jsFiddle (once I updated the syntax: original). I would think an empty string for null
/undefined
ought to be just fine. I have only had one use-case where I wanted to display "null" for null
values and that was an oddball usage. I put together the start of a simple demo using a helper function to display such values for anyone else that runs into a need to do so; it's not elegant, but it should be easily tweaked for someone's debugging needs.
from jsrender.
Related Issues (20)
- template content in external files HOT 2
- renderFile to accept a file as input HOT 2
- Nested props loop is not picking up properties of a function HOT 4
- any breaking changes between 0.9.82 and current 1.0.5 ? HOT 2
- JSRender strips multiple white spaces from input HOT 3
- Node + jsRender: allow absolute paths, (and also passing context to renderFile) HOT 8
- space is not html-encoded HOT 6
- regex not working HOT 2
- Difference between Browser and Node app - Null Propagation Operator HOT 2
- Conditional check if equal to string HOT 5
- Incomplete jsrender.min.map file HOT 2
- Provide support for passing an ID selector to $.templates() even when using JsRender without jQuery HOT 6
- Please provide a good documentation on how to use this in Angular 8+ or React 9+ versions HOT 2
- {{if}} tag doesn't work on keys with array or object with properties HOT 1
- swig.renderFile gives callback function required error HOT 3
- Chrome Extension Manifest V3 HOT 3
- $(...).render is not a function HOT 1
- How can I load data from jsrender template and update it HOT 2
- Using a tmpl selector that begins with a # but is not an ID selector does not work HOT 1
- Get an error t is not a function when adding if block HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from jsrender.