{"id":976,"date":"2014-02-23T14:56:12","date_gmt":"2014-02-23T14:56:12","guid":{"rendered":"http:\/\/blog.rajarshidas.com\/?p=976"},"modified":"2014-02-23T15:05:00","modified_gmt":"2014-02-23T15:05:00","slug":"creating-my-project-euler-solution-website","status":"publish","type":"post","link":"http:\/\/blog.rajarshidas.com\/?p=976","title":{"rendered":"Creating my Project Euler Solution Website"},"content":{"rendered":"<p>I&#8217;ve recently started going through the <a href=\"https:\/\/projecteuler.net\/\" target=\"_blank\">Project Euler<\/a> problems. It&#8217;s an awesome site that basically has a list of math problems that usually need computing power to solve. There are close to 500 problems on there right now, but my OCD means I gotta do them in order! I started working on them a bit and realized I was forgetting why I did things a certain way. Many of their problems can be brute forced, but also have elegant solutions available. I wanted to keep a record of what I was doing so I decided to <a href=\"http:\/\/rajarshidas.com\/projects\/ProjectEuler\/\" target=\"_blank\">make a page for it<\/a>. I&#8217;m still working on the site, but it&#8217;s almost done. This post is actually not about Project Euler, but about what I learned making the site, especially when I moved from jQuery to AngularJS.<br \/>\n<!--more--><\/p>\n<p>I&#8217;ve created a kind of workflow for myself whenever I make any website:<\/p>\n<ol>\n<li>Create a mockup in HTML\/CSS.<\/li>\n<li>Fill the mockup with some actual content for the main pages.<\/li>\n<li>Redesign the site&#8217;s looks.<\/li>\n<li>Add any functionality features using JavaScript and JavaScript libraries.<\/li>\n<li>Tweak! I don&#8217;t get too crazy on perfecting it in one go &#8211; I&#8217;ve found revisiting it after a few weeks helps me look at design more objectively.<\/li>\n<li>Remember that I completely forgot to make it mobile friendly and redesign&#8230; (My goal is to move this step up to #1 &#8211; but it never happens)<\/li>\n<\/ol>\n<h4>1. Create a Mockup<\/h4>\n<p>This is always hand waving because I know it&#8217;ll eventually look radically different from what I first envisioned. In this case, I looked at what I needed: header, left navigation with a grid to select problems, right content area for the main text. Simple enough. I usually make a colorful mockup to make sure I set up all the divs correctly. I like to do it by hand to understand it, but I&#8217;d be open to hear what other tools people use. In this case, I came up with something that looks like this:<br \/>\n<img decoding=\"async\" alt=\"\" src=\"http:\/\/blog.rajarshidas.com\/wp-content\/uploads\/2014\/02\/mockup.png\" \/><br \/>\nGorgeous.<\/p>\n<h4>2. Fill the Mockup with Content<\/h4>\n<p>This is more to make sure I&#8217;m not looking over anything obvious, such as titles that are too long or information that needs a separate section. I ensure I can get all the information in the mockup with no big issues.<\/p>\n<h4>3. Redesign the Site<\/h4>\n<p>In this step, I go hard on the CSS. I usually pick a color scheme (here I went with the same colors as my personal page), font, spacing, etc. Really just trying to make it pleasing to look at. Here&#8217;s what I have after this step:<br \/>\n<img decoding=\"async\" alt=\"\" src=\"http:\/\/blog.rajarshidas.com\/wp-content\/uploads\/2014\/02\/mockup2.png\" \/><br \/>\nYou can still see the similarities in layout, but now it&#8217;s not a bunch of bright jarring colors. The left navigation now has a grid of numbers for each Project Euler problem.<\/p>\n<h4>4. Functionality<\/h4>\n<p>This is the fun step! I created a brief checklist of things I wanted in the site:<\/p>\n<ol>\n<li> Tooltip on problem hover<\/li>\n<li> Template with partials for each problem<\/li>\n<li> Syntax highlighting (the image above already has it included &#8211; but that&#8217;s actually an external library)<\/li>\n<li> Charts for runtimes<\/li>\n<\/ol>\n<p>The tooltip is easy &#8211; I used <a href=\"http:\/\/onehackoranother.com\/projects\/jquery\/tipsy\/\" target=\"_blank\">Tipsy<\/a>. For the syntax highlighting I started with the most popular one: <a href=\"http:\/\/alexgorbatchev.com\/SyntaxHighlighter\/\" target=\"_blank\">Alex Gorbatchev&#8217;s SyntaxHighlighter<\/a>, but I had to switch later to <a href=\"http:\/\/highlightjs.org\/\" target=\"_blank\">highlight.js<\/a>. For charts my answer is always <a href=\"http:\/\/d3js.org\/\" target=\"_blank\">D3<\/a>. It&#8217;s not the easiest to start with, but the customization is amazing. Every time I use it, I have to spend a good chunk of time relearning the basics, but then I&#8217;m set to rock!<\/p>\n<p>This leaves the template. I wanted to use jQuery since it&#8217;s&#8230; well&#8230; magical. Fortunately, it has a load() function (basically a GET request) that serves my purpose. Using jQuery is awesome because after designing the page, I can easily go though and manipulate the DOM to create all those pieces above. It&#8217;s really easy to follow and understand so I was able to code up the site to do what I wanted in very little time. Of course, there&#8217;s a but&#8230;<\/p>\n<p>I started to run into issues when I was linking within my app. Let&#8217;s take a look at the code to create a link for each problem:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n$(document).ready(function() {\r\n\t$(&quot;#p&quot; + i).click({id: i}, function(e) {\r\n\t\t$(&quot;#text-area&quot;).load(&quot;problems\/&quot; + e.data.id + &quot;.html&quot;, function() {\r\n\t\t\tSyntaxHighlighter.highlight();\r\n\t\t\t$(&quot;.selected&quot;).removeClass(&quot;selected&quot;);\r\n\t\t\t$(&quot;#p&quot; + e.data.id).addClass(&quot;selected&quot;);\t\r\n\t\t});\r\n\t});\r\n});\r\n<\/pre>\n<p>When the page is ready (and we access the DOM), I add a link to each problem number in the left grid (see image above). In the code above, the &#8220;i&#8221; is actually a variable being set elsewhere so let&#8217;s just assume here that &#8220;i&#8221; is 3. So for problem 3, the div has id &#8220;p3&#8221;. When &#8220;p3&#8221; is clicked, &#8220;text-area&#8221; is loaded with &#8220;problems\/3.html&#8221; and then we have a &#8220;completed&#8221; callback function. After the html is loaded, the code runs the SyntaxHighlighter and selects the right item in the grid using the class &#8220;selected&#8221; (turning it dark green).<\/p>\n<p>Great, that works so what&#8217;s the deal? Well, this code has to be done for every link now, instead of the &lt;a href&gt; we normally use. Furthermore, the navigation links I have on top of the content area to go forward or back 1 problem, now needs to be set up this same way on page load. The code is starting to get really messy&#8230;<\/p>\n<p>Furthermore, the url isn&#8217;t synchronized with the page being loaded. I could never send a direct link to problem 3 such as &#8220;www.example.com\/problem\/3&#8221;, instead I could only send a link to the home page. For the same reason, this didn&#8217;t create any browser history so you couldn&#8217;t go back and forward.<\/p>\n<p>This is when I decided to use AngularJS. I&#8217;ve used it before but never got deep into it for 2 main reasons: it&#8217;s easy to do magic with it quickly, but getting to the more complicated stuff is exponentially more difficult and, I honestly wasn&#8217;t a fan of their docs\/tutorials. AngularJS is not made to be an add-on to jQuery. In fact, it&#8217;s a completely different style of thinking, so I got rid of (almost) all the code I had. In jQuery, it&#8217;s all about manipulating the DOM, while AngularJS is about data binding (synchronizing the model and the view). In Angular, the view is king. When I look at the HTML, I should be able to spot Angular directives that control the functionality.<\/p>\n<p>So let&#8217;s revisit the jQuery code above. I no longer need to create a click function. Now, I just use a controller to serve the right files depending on the URL route. So in my controller, I just need one line of code:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n$scope.templateUrl = 'pages\/' + $routeParams.problemID + '.html'\r\n<\/pre>\n<p>This essentially takes care of all the routing. Now if I go to <a href=\"http:\/\/rajarshidas.com\/projects\/ProjectEuler\/#\/problem\/3\/\" target=\"_blank\">http:\/\/rajarshidas.com\/projects\/ProjectEuler\/#\/problem\/3\/<\/a> &#8211; it works!<\/p>\n<p>Cool, what about the callbacks? For the &#8220;selected&#8221; functionality that highlights the link in dark green for the current page we&#8217;re on, we can use built-in directives:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n&lt;a ng-href=&quot;#\/problem\/{{col}}&quot; ng-class=&quot;{ selected:activeProblem(col) }&quot; ng-attr-title=&quot;{{problems&#x5B;col]}}&quot; tipsy=&quot;s&quot;&gt;{{col}}&lt;\/a&gt;\r\n<\/pre>\n<p>Here col, is the problem number, so let&#8217;s say 3. The ng-href is creating a link to &#8220;#\/problem\/3&#8221;. The ng-class is essentially setting the class of this &lt;a&gt; tag to be &#8220;selected&#8221; if it&#8217;s tied to problem 3. The tipsy is a custom directive I explain below.<\/p>\n<p>Ok and how about the Syntax highlighting? Well this is where Angular gets a little trickier. Basically, we need to create custom directives that allow us to attach behavior to the element. This needs to be done for each external library. For syntax highlighting, I found <a href=\"https:\/\/www.jiwhiz.com\/#\/blogs\/522cee9fe4b006e1e10cb71a\" target=\"_blank\">this post<\/a> which used highlight.js. I tried to translate for SyntaxHiglighter but couldn&#8217;t get it to work so switched to highlight.js instead.<\/p>\n<p>I had to do the same for the Tipsy, the tooltip library as well.<br \/>\nIn the original jQuery:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n$(&quot;#p&quot; + i).tipsy({gravity: 's', fade: true});\r\n<\/pre>\n<p>As an AngularJS directive:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nmyApp.directive('tipsy', function() {\r\n\treturn {\r\n\t\trestrict: 'A',\r\n\t\tlink: function(scope, element, attrs) {\r\n\t\t\telement.tipsy({ \r\n\t\t\t\tgravity: attrs.tipsy, \r\n\t\t\t\tfade: true\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n});\r\n<\/pre>\n<p>And the corresponding view:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n&lt;a ng-href=&quot;#\/problem\/{{col}}&quot; ng-class=&quot;{ selected:activeProblem(col) }&quot; ng-attr-title=&quot;{{problems&#x5B;col]}}&quot; tipsy=&quot;s&quot;&gt;{{col}}&lt;\/a&gt;\r\n<\/pre>\n<p>Here the tipsy tag creates the Tooltip. Notice how Angular&#8217;s style makes it apparent in the view that we have a tooltip compared to jQuery where that is somewhere in the script.<\/p>\n<p>So that&#8217;s where I&#8217;m at right now. I still have to figure out how to incorporate D3.js with this. I temporarily hacked it to work using jQuery on top of AngularJS. But hope to change that soon!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve recently started going through the Project Euler problems. It&#8217;s an awesome site that basically has a list of math problems that usually need computing power to solve. There are close to 500 problems on there right now, but my OCD means I gotta do them in order! I started working on them a bit [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,33],"tags":[35,20,34,36],"class_list":["post-976","post","type-post","status-publish","format-standard","hentry","category-programming","category-web-development","tag-angularjs","tag-javascript","tag-jquery","tag-project-euler"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"http:\/\/blog.rajarshidas.com\/index.php?rest_route=\/wp\/v2\/posts\/976","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.rajarshidas.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.rajarshidas.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.rajarshidas.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.rajarshidas.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=976"}],"version-history":[{"count":10,"href":"http:\/\/blog.rajarshidas.com\/index.php?rest_route=\/wp\/v2\/posts\/976\/revisions"}],"predecessor-version":[{"id":1001,"href":"http:\/\/blog.rajarshidas.com\/index.php?rest_route=\/wp\/v2\/posts\/976\/revisions\/1001"}],"wp:attachment":[{"href":"http:\/\/blog.rajarshidas.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=976"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.rajarshidas.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=976"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.rajarshidas.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=976"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}