-
Notifications
You must be signed in to change notification settings - Fork 156
Batman View Filters
I'm finding that there are lots of questions regarding view filters on the Google groups board (Batman Google Groups) so I figured I'd write an article to do a little bit of knowledge sharing.
The out of the box functionality covers the majority of the scenarios you'll run into, but you're going to reach a point where you want some customization, and it's important you lock down these concepts.
I should mention, batman.js is oriented around rails, but you do need to make sure that you leverage the javascript side of it as well . For example, not having to go to the controller to do a sort and instead leveraging the 2 way binding of batman.
So really quickly, you can use views as 2 different things. The first is as a plain ole view (just like in rails), populate some values, and display them on the screen. The second is a "re-usable" view that allows you to use it in multiple areas (these views would contain properties and the logic that controls it).
There's a great read on views here if you'd like more details: Batman Views
Whether you're using the basic views, or the reusable view, you're going to need to know how to use view filters.
A view filter is (in basic terms) a method that can be chained, against an object, within a view. Let's take a look at a couple basic ones:
<span data-bind="template.Name | prepend 'Template: '"</span>
The order executes from left to right. template.Name will be interpreted, and then 'Template: ' will be prepended. So if template.Name was 'Ruby' it would end up as: Template: Ruby
<a data-bind-href="ad.images[0].urls.medium | default '#!/404'"></a>
If there isn't a value in ad.images[0].urls.medium it will default the href to #!/404.
<p data-bind="ad.description | truncate 140 | raw"></p>
You can combo the view filters to your hearts content! This would take the ad's description, truncate it to 140 chars, and strip out all of the html tags!
<div class="ranking">
<div data-foreach-word="wordList">
<span data-bind="word.name | prepend 'Word: '"></span>
</div>
</div>
This would take each of the words from wordList and prepend them with 'Word: ' like so:
Word: waffle
Word: batman
Word: ninja
Word: rock`
That covers the out of the box functionality, but what if you wanted to create your own view filter? Don't worry! It can easily be done. You'll notice that batman-classifieds uses quite a few view helpers.
<p class="price"><span data-bind="ad | displayPrice"/></p>
This would take the ad's created_at date, and run it through the prettyDate view filter. You'll notice that the displayPrice view filter doesn't exist in the default view filter list.
The displayPrice view filter actually resides within the helpers folder under the file ads_helper.js.coffee as a mixin and looks like this (there are other helpers in the file, but I've excluded them):
Batman.mixin Batman.Filters,
displayPrice: (ad) ->
return undefined if typeof ad is 'undefined'
switch ad.get('sale_type')
when 'fixed'
"$#{(ad.get('price') || 0).toFixed(2)}"
when 'free'
'free'
when 'trade'
'trade/swap'
Here you can see that we're mixin' in the display price into our Batman Filters via Batman.mixin Batman.Filters
. And you can also see that displayPrice takes an ad, and displays a string based on the type of ad that it is.
When it comes down to it, these view helpers are similar to what you'd do in rails, just used a bit differently.