1

Just starting to look at Handlebars.js today and wanted a clear approach. Assume the following: We don't have control over how the JSON was created (So no server side solutions). JSON will have 1 or more records in it. In each record, there will be a Message_Type name/value pair the value of which would be useful in some function which css class(es) are used in the presentation.

ex: message_type: basic, ad, notification, warning, critical. Each message_type will have a css class(es). So critical message type might get classes .msg_box .critical_msg.

How should I do this (remember, we can't change the original source).? Option 1: process json data before handlebars and add name/value pair for each that contains the appropriate classes. Option 2: some way in handle bars that is unclear to me.

FreddyNoNose
  • 478
  • 1
  • 7
  • 13

2 Answers2

1

I believe the handlebars convention would be to parse your JSON and add the appropriate class name to the resulting object prior to passing it to the Handlebars template. Handlebars can be hacked to include the necessary logical operators, but I think it's generally frowned upon.

var messageMapping = {
  basic: 'msg_box', 
  ad: 'msg_box', 
  notification: 'msg_box', 
  warning: 'critical_msg', 
  critical: 'critical_msg'
};

//Your data from the server
var yourJSON = '[{"message_type":"basic", "value":"test"},{"message_type":"warning", "value":"test"}]';

var data = JSON.parse(yourJSON),
    i = 0,
    l = data.length; 

//Update the class names
for(; i < l; i++){
  data[i].msgClass = messageMapping[data[i].message_type];  
}

//Add to the DOM
var source   = $('#template').html();
var template = Handlebars.compile(source);

$('body').append(template({messages:data})); 
.critical_msg{
  background-color:red;  
}

.msg_box{
  background-color:green;  
}
<script src="//cdnjs.cloudflare.com/ajax/libs/handlebars.js/2.0.0/handlebars.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script id='template' type='template/text'>
{{#each messages}}
  <div class="{{msgClass}}">{{value}}</div>
{{/each}}
</script>
Community
  • 1
  • 1
Brandon Boone
  • 16,281
  • 4
  • 73
  • 100
  • This works very nicely. I thought that parsing json before passing to handlebars would be one approach but it sounds like it is the standard approach. Thank you very much! – FreddyNoNose Sep 25 '14 at 03:44
1

Handlebars is designed to be fairly "logic-less" which means it doesn't come with built in capabilities to make decisions based on the data passed in other than a simple if based on whether something exists or not in the data. Deciding what class to put in the HTML based on what the value is of some data structure element is not a built-in capability.

As such your options are:

  1. Assuming the templates are being used client-side, you can pre-process the JSON on the client side to put it into a no-logic needed form before it is sent to the template.

  2. Create helper methods that you can pass data to and they can make decisions based on it that are communicated back to the template.

  3. Add helper methods that can add logic capabilities to your template (you can find some pre-built ones).

  4. Switch to a template engine that has more logic capabilities built in.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • As in my reply to the other answer, my original thought of parsing json first is the way to go. – FreddyNoNose Sep 25 '14 at 07:13
  • @FreddyNoNose - you can select one of the answers as your choice for "best answer" by selecting the green checkmark to the left of that answer. – jfriend00 Oct 10 '14 at 19:24