{"id":92,"date":"2012-05-18T10:22:00","date_gmt":"2012-05-18T14:22:00","guid":{"rendered":"http:\/\/blogs.law.harvard.edu\/acts\/?p=92"},"modified":"2012-05-18T10:31:33","modified_gmt":"2012-05-18T14:31:33","slug":"bootstrap-alerts-with-backbone-views","status":"publish","type":"post","link":"https:\/\/archive.blogs.harvard.edu\/acts\/2012\/05\/18\/bootstrap-alerts-with-backbone-views\/","title":{"rendered":"Bootstrap Alerts with Backbone Views"},"content":{"rendered":"<p>One of the nice things about <a href=\"http:\/\/twitter.github.com\/bootstrap\/\">Bootstrap<\/a> is that it provides reusable HTML\/CSS components for common tasks such as displaying buttons, tabs, forms, and alerts (among other things). The markup for an alert is very simple:<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;div class=&quot;alert alert-error&quot;&gt;\r\n&lt;a href=&quot;#&quot; class=&quot;close&quot;&gt;&amp;times;&lt;\/a&gt;\r\n&lt;strong&gt;Oops!&lt;\/strong&gt; Something went terribly wrong.\r\n&lt;\/div&gt;\r\n<\/pre>\n<p>A jQuery plugin that comes with Bootstrap is used for the close button. I found myself duplicating this markup in a <a href=\"http:\/\/documentcloud.github.com\/backbone\/\">Backbone.js<\/a> project with various <a href=\"http:\/\/documentcloud.github.com\/underscore\/\">Underscore<\/a> templates scattered around the view classes, so for the sake of DRYness, I decided to whip up a simple view to encapsulate the markup and behavior. Here&#8217;s the result:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar AlertView = Backbone.View.extend({\r\n\tclassName: &#039;alert fade in&#039;,\r\n\talerts: &#x5B;&#039;success&#039;, &#039;error&#039;, &#039;info&#039;],\r\n\ttemplate: _.template(&#x5B;\r\n\t\t&#039;&lt;a href=&quot;#&quot; class=&quot;close&quot;&gt;&amp;times;&lt;\/a&gt;&#039;,\r\n\t\t&#039;&lt;%= message %&gt;&#039;\r\n\t].join(&#039;&#039;)),\r\n\tinitialize: function(options) {\r\n\t\tvar message = options.msg || &#039;&#039;;\r\n\t\tvar alert = options.hasOwnProperty(&#039;alert&#039;) ? options.alert : &#039;info&#039;;\r\n\r\n\t\tif(_.indexOf(this.alerts, alert) === -1) {\r\n\t\t\tthrow new Error(&#039;Invalid alert: &#x5B;&#039; + alert + &#039;] Must be one of: &#039; + this.alerts.join(&#039;, &#039;));\r\n\t\t}\r\n\r\n\t\tthis.alert = alert;\r\n\t\tthis.message = message;\r\n\t},\r\n\trender: function() {\r\n\t\tvar output = this.template({ message: this.message });\r\n\t\tthis.$el.addClass(&#039;alert-&#039;+this.alert).\r\n\t\t\thtml(output).\r\n\t\t\talert(); \/\/ jquery plugin\r\n\t\treturn this;\r\n\t}\r\n});\r\n\r\nAlertView.msg = function($el, options) {\r\n\tvar alert = new AlertView(options);\r\n\t$el.html(alert.render().el);\r\n\treturn alert;\r\n};\r\n<\/pre>\n<p>Now I can use it from my other views for simple alert messages like this:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nAlertView.msg(this.$el, { \r\n     alert: &#039;error&#039;, \r\n     msg: &#039;Something went terribly wrong.&#039; \r\n});\r\n<\/pre>\n<p>Of course, it can still be improved with shortcut methods and general cleanup, but the goal is not to make it work for every possible alert, just the most common ones. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the nice things about Bootstrap is that it provides reusable HTML\/CSS components for common tasks such as displaying buttons, tabs, forms, and alerts (among other things). The markup for an alert is very simple: &lt;div class=&quot;alert alert-error&quot;&gt; &lt;a href=&quot;#&quot; class=&quot;close&quot;&gt;&amp;times;&lt;\/a&gt; &lt;strong&gt;Oops!&lt;\/strong&gt; Something went terribly wrong. &lt;\/div&gt; A jQuery plugin that comes with Bootstrap [&hellip;]<\/p>\n","protected":false},"author":4572,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[63924,63966,63967,17295],"tags":[111295,111296,111293],"class_list":["post-92","post","type-post","status-publish","format-standard","hentry","category-atg","category-backbone","category-bootstrap","category-javascript","tag-backbone","tag-bootstrap","tag-javascript"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/posts\/92","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/users\/4572"}],"replies":[{"embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/comments?post=92"}],"version-history":[{"count":41,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/posts\/92\/revisions"}],"predecessor-version":[{"id":118,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/posts\/92\/revisions\/118"}],"wp:attachment":[{"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/media?parent=92"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/categories?post=92"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/tags?post=92"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}