<?xml-stylesheet href="/pretty-feed-v2.xsl" type="text/xsl"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Trys Mudford's Blog</title>
    <link>https://www.trysmudford.com/categories/training/</link>
    <description>Posts, thoughts, links and photos from Trys</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Mon, 25 Sep 2023 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://www.trysmudford.com/blog/index.xml" rel="self" type="application/rss+xml"/>
    
    <item>
      <title>A quick guide to destructuring</title>
      <link>https://www.trysmudford.com/blog/quick-guide-to-destructuring/</link>
      <pubDate>Mon, 25 Sep 2023 00:00:00 +0000</pubDate>
      
      <guid>https://www.trysmudford.com/blog/quick-guide-to-destructuring/</guid>
      <description><![CDATA[
<p>I was pairing with a junior engineer and we came across a piece of code that confused them. It was around destructuring variables from an object, so rather than send a slack message, I thought I&rsquo;d write a quick blog post on the subject.</p>
<p>Here&rsquo;s an object:</p>
<div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="kr">const</span> <span class="nx">user</span> <span class="o">=</span> <span class="p">{</span>
	<span class="nx">firstName</span><span class="o">:</span> <span class="s1">&#39;Jack&#39;</span><span class="p">,</span>
	<span class="nx">lastName</span><span class="o">:</span> <span class="s1">&#39;Smith&#39;</span><span class="p">,</span>
  	<span class="nx">age</span><span class="o">:</span> <span class="mi">30</span><span class="p">,</span>
<span class="p">};</span>
</code></pre></div><p>If you wanted a variable called <code>firstName</code> with the value of <code>user.firstName</code>, you could do this:</p>
<div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="kr">const</span> <span class="nx">firstName</span> <span class="o">=</span> <span class="nx">user</span><span class="p">.</span><span class="nx">firstName</span><span class="p">;</span>
</code></pre></div><p>But that gets a bit verbose when you also need <code>lastName</code> and <code>age</code>:</p>
<div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="kr">const</span> <span class="nx">firstName</span> <span class="o">=</span> <span class="nx">user</span><span class="p">.</span><span class="nx">firstName</span><span class="p">;</span>
<span class="kr">const</span> <span class="nx">lastName</span> <span class="o">=</span> <span class="nx">user</span><span class="p">.</span><span class="nx">lastName</span><span class="p">;</span>
<span class="kr">const</span> <span class="nx">age</span> <span class="o">=</span> <span class="nx">user</span><span class="p">.</span><span class="nx">age</span><span class="p">;</span>
</code></pre></div><p>To solve this, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">ES6 added destructuring assignment</a>. So, to assign those same variables in a functionally equivalent way, you can do the following:</p>
<div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="kr">const</span> <span class="p">{</span> <span class="nx">firstName</span><span class="p">,</span> <span class="nx">lastName</span><span class="p">,</span> <span class="nx">age</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">user</span><span class="p">;</span>
</code></pre></div><p>Much neater. But if you&rsquo;ve not encountered this syntax before, it&rsquo;s understandably quite confusing to see what looks like an object being used backwards to the &lsquo;normal&rsquo; way.</p>
<h2 id="bonus-tips">Bonus tips</h2>
<p>You can also use destructuring to &lsquo;<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">spread</a>&rsquo; the remaining variables after the initial assignment into a new object:</p>
<div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="kr">const</span> <span class="p">{</span> <span class="nx">age</span><span class="p">,</span> <span class="p">...</span><span class="nx">rest</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">object</span><span class="p">;</span>
<span class="c1">// rest contains { firstName: &#39;Jack&#39;, lastName: &#39;Smith&#39; }
</span></code></pre></div><p>Finally, you can also access nested variables in child objects:</p>
<div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="kr">const</span> <span class="nx">user</span> <span class="o">=</span> <span class="p">{</span>
	<span class="nx">firstName</span><span class="o">:</span> <span class="s1">&#39;Jack&#39;</span><span class="p">,</span>
	<span class="nx">lastName</span><span class="o">:</span> <span class="s1">&#39;Smith&#39;</span><span class="p">,</span>
  	<span class="nx">age</span><span class="o">:</span> <span class="mi">30</span><span class="p">,</span>
	<span class="nx">favouriteMeals</span><span class="o">:</span> <span class="p">{</span>
		<span class="nx">breakfast</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;pancakes&#39;</span><span class="p">,</span> <span class="s1">&#39;yoghurt&#39;</span><span class="p">],</span>
		<span class="nx">lunch</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;sandwiches&#39;</span><span class="p">]</span>
	<span class="p">}</span>
<span class="p">};</span>

<span class="kr">const</span> <span class="p">{</span> <span class="nx">firstName</span><span class="p">,</span> <span class="nx">favouriteMeals</span><span class="o">:</span> <span class="p">{</span> <span class="nx">breakfast</span><span class="p">,</span> <span class="nx">lunch</span> <span class="p">}</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">user</span><span class="p">;</span>
</code></pre></div><p>This assigns the variables: <code>firstName</code>, <code>breakfast</code>, and <code>lunch</code>, but crucially, doesn&rsquo;t assign <code>favouriteMeals</code>.</p>
]]>
      </description>
    </item>
    
    <item>
      <title>Cache busting</title>
      <link>https://www.trysmudford.com/blog/cache-busting/</link>
      <pubDate>Wed, 07 Feb 2018 00:00:00 +0000</pubDate>
      
      <guid>https://www.trysmudford.com/blog/cache-busting/</guid>
      <description><![CDATA[
<h2 id="1-the-classic-query-string">1. The classic query string</h2>
<div class="highlight"><pre class="chroma"><code class="language-html" data-lang="html"><span class="p">&lt;</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">&#34;stylesheet&#34;</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;/style.css?ver=20180207&#34;</span><span class="p">&gt;</span>
</code></pre></div><p>This is the most basic form of cache busting. It works well for manually created assets but it’s a pain to remember, plus it can have <a href="http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/">some issues</a>.</p>
<h2 id="2-the-better-url">2. The better URL</h2>
<div class="highlight"><pre class="chroma"><code class="language-fallback" data-lang="fallback"># .htaccess
# Version control scripts - https://adactio.com/journal/8504
&lt;IfModule mod_rewrite.c&gt;
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)\.([0-9]*)\.(min.js|js|css)$ $1.$3 [L]
&lt;/IfModule&gt;
</code></pre></div><div class="highlight"><pre class="chroma"><code class="language-html" data-lang="html"><span class="p">&lt;</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">&#34;stylesheet&#34;</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;/style.20180207.css&#34;</span><span class="p">&gt;</span>
</code></pre></div><p>You keep your filenames clean but perform a rewrite for requests so: <code>style.20180207.css</code> is served the file <code>style.css</code>. This has the benefit of looking much nicer and not having the querystring problems, but it still requires remembering to update it when you make a change. The other downside is BrowserSync gets a bit upset with it (I haven’t spent much time looking for a fix, it’s probably not a big deal).</p>
<h2 id="25-automating-the-above">2.5 Automating the above</h2>
<p>You can use the last modified time to generate the timestamp. filemtime(assets/style.css) in PHP will return you a timestamp that could be appended to the link/query string:</p>
<div class="highlight"><pre class="chroma"><code class="language-php" data-lang="php"><span class="k">echo</span> <span class="s1">&#39;&lt;link rel=&#34;stylesheet&#34; href=&#34;/style.&#39;</span> <span class="o">.</span> <span class="nx">filemtime</span><span class="p">(</span><span class="s1">&#39;style.css&#39;</span><span class="p">)</span> <span class="o">.</span> <span class="s1">&#39;.css&#34;&gt;&#39;</span>
</code></pre></div><h2 id="3-the-hosting-solution">3. The hosting solution</h2>
<p>As I’m a big fan of Netlify at the moment, I can’t help but recommend their setup. It’s a nice solution because: <strong>You do nothing!</strong></p>
<p>They check the assets when deploying and compare them (or more specifically their ETags) to the current file. If it’s changed, they bust the cache on the file. For the user, it goes something like this:</p>
<p>When you ask for a file, they send the ETag in the request headers. They also set a header to tell the browser not to trust it’s own cache (which sounds a bit mad). Then when you request the page, it opens a persistent HTTP2 connectio (no new connections for subsequent requests). When it requests that earlier asset, the browser sends the ETag back to Netlify and they either return nothing if the ETag matches, or the new file with the new ETag. <code>No style.20180207.css</code> or <code>style.css?v=20180207</code>. Just clean <code>style.css</code> with instant cache invalidation. It’s so so good.</p>
<h2 id="4-the-build-step">4. The build step</h2>
<p>If you’re using a build step, you can perform the hash and add it to the filename on build. Here’s a Webpack example:</p>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">{</span>
  <span class="nx">entry</span><span class="o">:</span> <span class="s1">&#39;./src/app.js&#39;</span><span class="p">,</span>
  <span class="nx">output</span><span class="o">:</span> <span class="p">{</span>
    <span class="nx">filename</span><span class="o">:</span> <span class="s1">&#39;[name].[chunkhash].js&#39;</span><span class="p">,</span>
    <span class="nx">path</span><span class="o">:</span> <span class="nx">path</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="mi">__</span><span class="nx">dirname</span><span class="p">,</span> <span class="s1">&#39;dist&#39;</span><span class="p">)</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div><p>This will create a file like <code>/dist/app.5ec8e954e32d66dee1aa.js</code>. More details <a href="https://webpack.js.org/guides/caching/">here</a>.</p>
<p>The difficult bit is then integrating it into your HTML. With Webpack, you can use the HtmlWebpackPlugin to add the <code>&lt;script src=&quot;app.5ec8e954e32d66dee1aa.js&quot;&gt;&lt;/script&gt;</code> tag to the bottom of your HTML page – this works great if you’re using a fully integrated Webpack setup. This probably means using their dev server for local developement, not storing the compiled production files in the repo and using some form of server deployment build step to generate the production files on the server.</p>
<p>This is the ‘best’ solution if you’re happy to wade in with Webpack and get a full deployment setup working – which in the long term is worthwhile but in the short term sounds scary. It’s also reliant on your hosting setup being good enough too.</p>
]]>
      </description>
    </item>
    
    <item>
      <title>The Recap</title>
      <link>https://www.trysmudford.com/blog/the-recap/</link>
      <pubDate>Sat, 03 Feb 2018 00:00:00 +0000</pubDate>
      
      <guid>https://www.trysmudford.com/blog/the-recap/</guid>
      <description><![CDATA[
<p>Before moving onto a bigger project, I thought it would be worth consolidating the past six sessions. We&rsquo;ve tackled the following subjects:</p>
<h2 id="1-forms">1. Forms</h2>
<ul>
<li>Methods &amp; actions</li>
<li>Input types &amp; attributes</li>
<li>CSS pseudo classes on inputs</li>
</ul>
<p><strong>Task:</strong> Newsletter signup form</p>
<h2 id="2-js---variables">2. JS - Variables</h2>
<ul>
<li>What is a variable</li>
<li>Types of variables</li>
<li>Mutable types</li>
<li>Scope</li>
<li>Global scope</li>
<li>IIFEs</li>
<li>Render function</li>
</ul>
<p><strong>Task:</strong> Milage calculator</p>
<h2 id="3-js---more-javascript">3. JS - More JavaScript</h2>
<ul>
<li>Imperative vs. Declarative</li>
<li>Shorthand operators</li>
<li>Ternary statements</li>
<li>Module/Singleton pattern</li>
<li>You might not need jQuery</li>
<li>Array methods: find, findIndex, filter, map, reduce &amp; sort</li>
</ul>
<p><strong>Task:</strong> Wrangling array data</p>
<h2 id="4-js---dom">4. JS - DOM</h2>
<ul>
<li>What is the DOM</li>
<li>childNodes vs. children</li>
<li>HTMLCollection vs. NodeList</li>
<li>addEventListener</li>
<li>createElement</li>
<li>innerText vs. innerHTML</li>
<li>getAttribute, classlist, dataset &amp; style</li>
<li>Finding elements with querySelector &amp; querySelectorAll</li>
<li>Event delegation and bubbling</li>
</ul>
<p><strong>Task:</strong> TODO List</p>
<h2 id="5-js---ajax">5. JS - AJAX</h2>
<ul>
<li>Polyfill.io</li>
<li>XMLHttpRequest</li>
<li>jQuery</li>
<li>Fetch</li>
<li>Axios</li>
<li>Asynchronous gotchas</li>
<li>Streaming, when to not use AJAX</li>
</ul>
<p><strong>Task:</strong> Load more posts</p>
<h2 id="6-video">6. Video</h2>
<ul>
<li>Resonsive embedding</li>
<li>Video tag attributes</li>
<li>Source tag</li>
<li>.webm &amp; .webp</li>
<li>Object-fit</li>
<li>Fullscreen API</li>
</ul>
<p><strong>Task:</strong> Video player</p>
<h2 id="todays-tasks">Today&rsquo;s task(s)</h2>
<p>I&rsquo;ve created a bunch of small and smallish tasks to run through. Refer back to the previous session notes, there&rsquo;s nothing we haven&rsquo;t covered before. The tasks are in the training repository under: <code>/2018-01-24/index.html</code>. If you load up that file in Sublime/Chrome and check out the script tag.</p>
]]>
      </description>
    </item>
    
    <item>
      <title>DOM</title>
      <link>https://www.trysmudford.com/blog/dom/</link>
      <pubDate>Mon, 27 Nov 2017 00:00:00 +0000</pubDate>
      
      <guid>https://www.trysmudford.com/blog/dom/</guid>
      <description><![CDATA[
<h1 id="dom">DOM</h1>
<p>The DOM (Document Object Model) is the interface between HTML and JS. It represents the page as a tree with the &lsquo;document&rsquo; at the top (the <code>&lt;html&gt;</code> element, and each node as a child, grandchild, great-grandchild etc&hellip;</p>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nb">document</span><span class="p">)</span>
</code></pre></div><div class="highlight"><pre class="chroma"><code class="language-fallback" data-lang="fallback">&lt;html&gt;
    &lt;body&gt;
        &lt;p&gt;Hi there&lt;/p&gt;
    &lt;/body&gt;
&lt;/html&gt;
</code></pre></div><div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nb">document</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">body</span><span class="o">:</span> <span class="p">{</span>
        <span class="nx">children</span><span class="o">:</span> <span class="p">[</span>
            <span class="p">{</span>
                <span class="nx">nodeName</span><span class="o">:</span> <span class="s1">&#39;P&#39;</span><span class="p">,</span>
                <span class="nx">innerText</span><span class="o">:</span> <span class="s1">&#39;Hi there&#39;</span>
            <span class="p">}</span>
        <span class="p">]</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div><p>It acts very much like an object, we can even use dot-notation to access (some) children. Accessing the <code>&lt;body&gt;</code> element is a case of writing <code>document.body</code>.</p>
<h2 id="childnodes">childNodes</h2>
<p>Each item on the tree is a node. There are several different types of node that we need to be aware of:</p>
<ul>
<li>Element</li>
<li>Text</li>
<li>Comment</li>
</ul>
<p>Using the following HTML, we can see how JS interprets markup:</p>
<div class="highlight"><pre class="chroma"><code class="language-fallback" data-lang="fallback">&lt;html&gt;
    &lt;body&gt;
        &lt;!-- A hidden comment --&gt;
        &lt;p&gt;123&lt;/p&gt;
        Hi there!
    &lt;/body&gt;
&lt;/html&gt;
</code></pre></div><div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">childNodes</span><span class="p">)</span>
</code></pre></div><p>How many nodes will be returned in this statement?</p>
<p>The answer is 5:</p>
<ol>
<li>Text: newline character</li>
<li>Comment: our hidden comment</li>
<li>Text: newline character</li>
<li>Element: our paragraph</li>
<li>Text: newline and &lsquo;Hi there! and then newline&rsquo;</li>
</ol>
<p>This shows you can&rsquo;t rely on <code>childNodes</code> returning just the HTML, or just the text. When we indent our code, we&rsquo;re introducing this extra &lsquo;content&rsquo;. It&rsquo;s not a problem for actually displaying the HTML in the page, but it does need to be considered when we&rsquo;re reading from the DOM.</p>
<h2 id="children">Children</h2>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">children</span><span class="p">)</span>
</code></pre></div><p>Let&rsquo;s compare the difference using <code>.children</code> on the same markup. We get a HTMLCollection with one element, the paragraph. This is more useful for only dealing with HTML.</p>
<h2 id="iteration---htmlcollection-vs-nodelist">Iteration - HTMLCollection vs. NodeList</h2>
<p>In our first example, we were returned a NodeList, in the second we got a HTMLCollection. If we console.dir them, we can see the prototyped methods &amp; properties available to us. For HTMLCollection, the only useful property is length. With this, we can use a classic <code>for</code> loop to access the elements.</p>
<p>In a NodeList, we have access to forEach, support is good but it needs a <a href="https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach#Polyfill">polyfill</a> for IE.</p>
<p>A nice loop that works for both is:</p>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="p">[].</span><span class="nx">forEach</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">children</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">el</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">el</span><span class="p">)</span>
<span class="p">})</span>
</code></pre></div><h2 id="addeventlistener">addEventListener</h2>
<p>In jQuery, we can attach events using <code>.on</code>. In vanilla JS, we use <code>.addEventListener</code>. For a single node, we can write:</p>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="nx">element</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s1">&#39;click&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{});</span>
</code></pre></div><p>For a NodeList or HTMLCollection, we need to loop through the elements and attach the event listeners individually:</p>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="p">[].</span><span class="nx">forEach</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">children</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">el</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">el</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s1">&#39;click&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{});</span>
<span class="p">})</span>
</code></pre></div><p><code>.removeEventListener</code> works in the same way as jQuery&rsquo;s <code>.off</code>.</p>
<h2 id="createelement">createElement</h2>
<p><code>document.createElement('p')</code> lets us create new HTML elements. Until they&rsquo;re added to the DOM, they&rsquo;re still virtual.</p>
<h2 id="appendchild">appendChild</h2>
<p>Once we&rsquo;ve created our element, we can append it into another Node with appendChild.</p>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">el</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s1">&#39;p&#39;</span><span class="p">)</span>
<span class="nx">el</span><span class="p">.</span><span class="nx">innerText</span> <span class="o">=</span> <span class="s1">&#39;Abc&#39;</span>
<span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">appendChild</span><span class="p">(</span><span class="nx">el</span><span class="p">)</span>
</code></pre></div><h2 id="removechild">removeChild</h2>
<p>Removing a node is a bit more complicated. You have to call removeChild on the parent node. Fortunately, we can use node.parentNode to find the parent.</p>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="nx">node</span><span class="p">.</span><span class="nx">parentNode</span><span class="p">.</span><span class="nx">removeChild</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span>
</code></pre></div><h2 id="replacechild">replaceChild</h2>
<p><code>.replaceChild</code> has the same parent requirement rules as <code>.removeChild</code>, but we pass in two arguments, the newNode and the oldNode.</p>
<h2 id="innerhtml-vs-innertext">innerHTML vs. innerText</h2>
<p><code>innerText</code> will return the text of the node and it&rsquo;s children. <code>innerHTML</code> returns the text and HTML of the node and it&rsquo;s children.</p>
<div class="highlight"><pre class="chroma"><code class="language-fallback" data-lang="fallback">&lt;html&gt;
    &lt;body&gt;
        &lt;p&gt;123 &lt;b&gt;456&lt;/b&gt;&lt;/p&gt;
    &lt;/body&gt;
&lt;/html&gt;
</code></pre></div><div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">children</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">innerText</span>
<span class="c1">// &#34;123 456&#34;
</span><span class="c1"></span><span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">children</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">innerHTML</span>
<span class="c1">// &#34;123 &lt;b&gt;456&lt;/b&gt;&#34;
</span></code></pre></div><p>Be careful when adding user generated content to the DOM. Always use escape or use <code>innerText</code>! If you use <code>innerHTML</code>, a &lsquo;hacker&rsquo; could add a script tag to their content and it would run on your page. This is called Cross-site scripting or XSS.</p>
<h2 id="getattribute--setattribute">getAttribute / setAttribute</h2>
<p>To read &amp; write attributes to a node, we can use <code>getAttribute</code> and <code>setAttribute</code>. Note that they will always return a string, so remember to cast the type when reading values back if you need to work with anything other than a string.</p>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">setAttribute</span><span class="p">(</span><span class="s1">&#39;a-new-attribute&#39;</span><span class="p">,</span> <span class="mi">123</span><span class="p">)</span>
<span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">getAttribute</span><span class="p">(</span><span class="s1">&#39;a-new-attribute&#39;</span><span class="p">)</span> <span class="c1">// &#39;123&#39;
</span><span class="c1">// &lt;body a-new-attribute=&#34;123&#34;&gt;&lt;/body&gt;
</span></code></pre></div><h2 id="classlist">classList</h2>
<p>Classes can be edited with <code>setAttribute</code>, but it&rsquo;s better to use <code>.classList</code> as it provides much more flexibility.</p>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="nx">el</span><span class="p">.</span><span class="nx">classList</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="s1">&#39;className&#39;</span><span class="p">)</span>
<span class="nx">el</span><span class="p">.</span><span class="nx">classList</span><span class="p">.</span><span class="nx">remove</span><span class="p">(</span><span class="s1">&#39;className&#39;</span><span class="p">)</span>
<span class="nx">el</span><span class="p">.</span><span class="nx">classList</span><span class="p">.</span><span class="nx">toggle</span><span class="p">(</span><span class="s1">&#39;className&#39;</span><span class="p">)</span>
<span class="nx">el</span><span class="p">.</span><span class="nx">classList</span><span class="p">.</span><span class="nx">contains</span><span class="p">(</span><span class="s1">&#39;className&#39;</span><span class="p">)</span>
</code></pre></div><h2 id="dataset">dataset</h2>
<p>Dataset operations lets you read/write to <code>data-</code> attributes on the HTML element.</p>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">dataset</span><span class="p">[</span><span class="s1">&#39;123&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;abc&#39;</span>
<span class="c1">// &lt;body data-123=&#34;abc&#34;&gt;&lt;/body&gt;
</span></code></pre></div><h2 id="style">style</h2>
<p><code>element.style</code> returns all the current CSS applied to an element. It&rsquo;s object-like so you can write <code>element.style.color</code> to be more specific. Hyphenated properties are converted to camelCase: <code>element.style.marginLeft</code>. These a getters and setters.</p>
<h2 id="nodename">nodeName</h2>
<p><code>.nodeName</code> provides an uppercase name of the HTML tag, not used that often, but really helpful on occasion.</p>
<h2 id="element-positioning">Element positioning</h2>
<p><code>.offsetLeft</code> and <code>.offsetTop</code> provide an integer representing the offset to the nearest parent with <code>position: relative</code> (can be found with <code>.offsetParent</code>).</p>
<p><code>.offsetHeight</code> and <code>.offsetWidth</code> give the height of the element including borders and padding.</p>
<p><code>element.getBoundingClientRect()</code> gets you all these things in one go.</p>
<h2 id="finding-elements">Finding elements</h2>
<p>The key methods we need are <code>.querySelector()</code> and <code>.querySelectorAll()</code>. The first takes a CSS selector and returns the first matching element, the second takes a CSS selector and returns a NodeList of all matching elements. These methods are most commonly run on the <code>document</code> but can be run on another node for more specific and performant look ups.</p>
<p>We always want to &lsquo;cache&rsquo; the lookup to minimize DOM read operations:</p>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">ctaButton</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="s1">&#39;.cta-button&#39;</span><span class="p">)</span>
<span class="nx">ctaButton</span><span class="p">.</span><span class="nx">innerText</span> <span class="o">=</span> <span class="s1">&#39;Read more&#39;</span>
<span class="nx">ctaButton</span><span class="p">.</span><span class="nx">style</span><span class="p">.</span><span class="nx">color</span> <span class="o">=</span> <span class="s1">&#39;#123456&#39;</span>
</code></pre></div><h2 id="event-delegation--bubbling">Event delegation &amp; bubbling</h2>
<p>Bubbling is the process of an event working it&rsquo;s way up the DOM tree. For example, when you click on a <code>&lt;button&gt;</code>, you&rsquo;re also clicking on all the parent elements, right up to the document. This can seem like a strange behaviour at first, but it&rsquo;s really helpful. Imagine we want to alert the user every time they click on the text in the following markup:</p>
<div class="highlight"><pre class="chroma"><code class="language-fallback" data-lang="fallback">&lt;p&gt;Abc, easy as &lt;strong&gt;123&lt;/strong&gt;&lt;/p&gt;
</code></pre></div><p>Without event bubbling, we&rsquo;d need to add an event on the <code>p</code> AND <code>strong</code>, as both could be clicked on. This would be a pain to keep track of. So bubbling means we only need to put the event listener on the <code>p</code>, and when the <code>strong</code> is clicked, the <code>p</code> event will be triggered.</p>
<p>We can use this to our advantage to group events and avoid putting eventListeners on multiple elements.</p>
<h2 id="task---todo-list">Task - TODO list</h2>
<p>The classic task. Using the following markup, hook up the JS to make a todo list:</p>
<div class="highlight"><pre class="chroma"><code class="language-fallback" data-lang="fallback">&lt;link href=&#34;https://fonts.googleapis.com/css?family=Barlow+Condensed&#34; rel=&#34;stylesheet&#34;&gt;
&lt;style&gt;.todo,body{padding:40px}body{background:#2962FF;margin:0;font:18px/1.5 &#39;Barlow Condensed&#39;,sans-serif}.todo{width:100%;max-width:400px;margin:0 auto;background:#E3F2FD;border:10px solid #0D47A1}.todo input,.todo li button{background:#FFF;font:inherit}.todo form:after{content:&#39;&#39;;display:table;clear:both}.todo [type=text]{width:calc(100% - 100px);float:left}.todo [type=submit]{width:80px;float:right}.todo input{padding:10px;display:inline-block;border:2px solid #DDD}.todo ul{padding:0}.todo li{padding:5px 0;list-style:none;margin:0}.todo li button{border:1px solid #DDD}.todo li+li{border-top:1px solid rgba(0,0,0,.2)}&lt;/style&gt;


&lt;div class=&#34;todo&#34;&gt;
    &lt;form id=&#34;addTodo&#34;&gt;
        &lt;input name=&#34;todo&#34; type=&#34;text&#34; placeholder=&#34;What would you like to do?&#34; required&gt;
        &lt;input type=&#34;submit&#34; value=&#34;+&#34; /&gt;
    &lt;/form&gt;

    &lt;h2&gt;Still to do&lt;/h2&gt;
    &lt;ul class=&#34;todo__incomplete&#34;&gt;
        &lt;li&gt;&lt;button&gt;&amp;times;&lt;/button&gt; Task 1&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h2&gt;Completed&lt;/h2&gt;
    &lt;ul class=&#34;todo__completed&#34;&gt;
        
    &lt;/ul&gt;
&lt;/div&gt;
</code></pre></div><ol>
<li>When the form submits, add an item to the &lsquo;Still to do&rsquo; list.</li>
<li>When the user click on the button, move the todo between the &lsquo;Still to do&rsquo; and &lsquo;Completed&rsquo; list.</li>
</ol>
]]>
      </description>
    </item>
    
    <item>
      <title>More JS</title>
      <link>https://www.trysmudford.com/blog/more-js/</link>
      <pubDate>Wed, 15 Nov 2017 00:00:00 +0000</pubDate>
      
      <guid>https://www.trysmudford.com/blog/more-js/</guid>
      <description><![CDATA[
<h1 id="more-js">More JS</h1>
<h2 id="imperative-vs-declarative">Imperative vs. Declarative</h2>
<p>In the last session we finished by making a distance calculator in vanilla JavaScript. We found that it was pretty easy to repeat ourselves. For example, when doing the initial render of the list, we wrote code to create a <code>li</code> element, fill it with content and add it to the list. We also wrote code to tot up the distances. The problem came when we added a form to let a user add another trip. All that code was needed again for this feature.</p>
<p>For the <code>li</code> appending feature, we wrote a helper function that added the element to the <code>ul</code>. As each individual route didn&rsquo;t need to know about the previous data, we could do that.</p>
<p>For the total distance feature, we needed all the data to make the calculation so we couldn&rsquo;t use an appending helper function. We needed to re-render the total each time, hence we wrote a &lsquo;render&rsquo; function that destroyed the old data and put in new data.</p>
<p>For page load, we could run the helper function for each of the inital routes and call the render function once. Then for each form submittion, we called the helper function once and the render function once. We moved much of the duplication into functions (which is great), but we still have duplication for the helper function calls.</p>
<p>Duplication is an opportunity for errors to creep in, especially as a program expands. Say another developer came along and added a feature in a few months time that needed to add routes from a real-time database. If they didn&rsquo;t realise they had to call two seperate functions to force a re-render, their could be problems.</p>
<p>This is an imperative programming style. This &lsquo;programming paradigm&rsquo; is pretty common, it&rsquo;s often how we start out developing simple programs. jQuery is regularly used in an imperative fashion: make this <code>button</code> yellow, fade this <code>div</code> out, change this text to say &lsquo;hello&rsquo;. We use statements to change the programs state, and we specify <em>how</em> the program operates.</p>
<p>Constrast this to the declarative paradigm where we describe the logic of the program without specifying <em>how</em> it should run. We can achieve this by de-coupling the inputs and outputs from the state. If the outputs always reflect the current state, we only need to worry about inputting to the state. So when our hypothetical future developer comes along, all they do is add another input to the state and the outputs will react to any changes.</p>
<h2 id="distance-calculator-in-vuejs">Distance calculator in Vue.js</h2>
<p>To make this clearer, I&rsquo;m going to show a rewrite of our distance calculator in Vue.js, a framework that encourages you to be declarative.</p>
<h2 id="js-shorthand-operators">JS shorthand operators</h2>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">a</span> <span class="o">=</span> <span class="mi">1</span>

<span class="nx">a</span><span class="o">++</span> <span class="c1">// Eqivalent to: a = a + 1
</span><span class="c1"></span>
<span class="nx">a</span><span class="o">--</span> <span class="c1">// Eqivalent to: a = a - 1
</span><span class="c1"></span>
<span class="nx">a</span> <span class="o">+=</span> <span class="mi">2</span> <span class="c1">// Eqivalent to: a = a + 2
</span><span class="c1"></span>
<span class="nx">a</span> <span class="o">-=</span> <span class="mi">2</span> <span class="c1">// Eqivalent to: a = a - 2
</span><span class="c1"></span>
<span class="kd">var</span> <span class="nx">b</span> <span class="o">=</span> <span class="s1">&#39;trys&#39;</span>
<span class="o">!!</span><span class="nx">b</span> <span class="c1">// This is the boolean representation of &#39;b&#39;. In this case, !!b === true
</span></code></pre></div><h3 id="heading">||</h3>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">c</span> <span class="o">=</span> <span class="nx">d</span> <span class="o">||</span> <span class="s1">&#39;default&#39;</span>

<span class="c1">// Imagine: 
</span><span class="c1"></span><span class="kd">var</span> <span class="nx">c</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">c</span> <span class="o">=</span> <span class="nx">d</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
  <span class="nx">c</span> <span class="o">=</span> <span class="s1">&#39;default&#39;</span>
<span class="p">}</span>
</code></pre></div><p>&ndash;</p>
<p>This is great for falling back to defaults and is regularly used in functions for default arguments.</p>
<h3 id="heading-1">&amp;&amp;</h3>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">a</span> <span class="o">=</span> <span class="mi">0</span>
<span class="kd">var</span> <span class="nx">b</span> <span class="o">=</span> <span class="mi">1</span>
<span class="kd">var</span> <span class="nx">c</span> <span class="o">=</span> <span class="nx">a</span> <span class="o">&amp;&amp;</span> <span class="nx">b</span> <span class="c1">// 1
</span><span class="c1"></span>
<span class="c1">// Imagine: 
</span><span class="c1"></span><span class="kd">var</span> <span class="nx">c</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">a</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">c</span> <span class="o">=</span> <span class="nx">b</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
  <span class="nx">c</span> <span class="o">=</span> <span class="nx">a</span>
<span class="p">}</span>
</code></pre></div><p><code>&amp;&amp;</code> can be used before function calls to check variable/function existence before making the call:</p>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">map</span> <span class="o">=</span> <span class="kc">false</span>
<span class="nx">map</span> <span class="o">&amp;&amp;</span> <span class="nx">renderMap</span><span class="p">(</span><span class="nx">map</span><span class="p">)</span> <span class="c1">// renderMap doesn&#39;t get called unless &#39;map&#39; is truthy
</span></code></pre></div><h3 id="ternary">Ternary</h3>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">a</span> <span class="o">=</span> <span class="nx">b</span> <span class="o">?</span> <span class="nx">c</span> <span class="o">:</span> <span class="nx">d</span><span class="p">;</span>

<span class="c1">// Imagine:
</span><span class="c1"></span><span class="kd">var</span> <span class="nx">a</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">b</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">a</span> <span class="o">=</span> <span class="nx">c</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
  <span class="nx">a</span> <span class="o">=</span> <span class="nx">d</span>
<span class="p">}</span>
</code></pre></div><h2 id="a-modulesingleton-pattern">A module/singleton pattern</h2>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">Namespace</span> <span class="o">=</span> <span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
  <span class="s2">&#34;use strict&#34;</span><span class="p">;</span>
  <span class="k">return</span> <span class="p">{</span>
    <span class="nx">Initialise</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
      <span class="nx">Namespace</span><span class="p">.</span><span class="nx">Menus</span><span class="p">();</span>
    <span class="p">},</span>

    <span class="nx">Menus</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
      <span class="c1">// Do menu things
</span><span class="c1"></span>    <span class="p">}</span>

  <span class="p">};</span>
<span class="p">}());</span>

<span class="nx">$</span><span class="p">(</span><span class="nx">Namespace</span><span class="p">.</span><span class="nx">Initialise</span><span class="p">);</span>
</code></pre></div><p>Sidenote: <code>$(fn)</code> is equivalent to <code>$(document).ready(fn)</code>.</p>
<p><a href="http://youmightnotneedjquery.com/">You might not need jQuery&hellip;</a></p>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">fn</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">attachEvent</span> <span class="o">?</span> <span class="nb">document</span><span class="p">.</span><span class="nx">readyState</span> <span class="o">===</span> <span class="s2">&#34;complete&#34;</span> <span class="o">:</span> <span class="nb">document</span><span class="p">.</span><span class="nx">readyState</span> <span class="o">!==</span> <span class="s2">&#34;loading&#34;</span><span class="p">){</span>
    <span class="nx">fn</span><span class="p">();</span>
  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="nb">document</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s1">&#39;DOMContentLoaded&#39;</span><span class="p">,</span> <span class="nx">fn</span><span class="p">);</span>
  <span class="p">}</span>
<span class="p">})(</span><span class="nx">Namespace</span><span class="p">.</span><span class="nx">Initialise</span><span class="p">)</span>
</code></pre></div><h2 id="array-methods">Array methods</h2>
<p>Push/pull/unshift/shift</p>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">people</span> <span class="o">=</span> <span class="p">[{</span>
	<span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Jen&#39;</span><span class="p">,</span>
	<span class="nx">age</span><span class="o">:</span> <span class="mi">32</span>
<span class="p">},</span> <span class="p">{</span>
	<span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Keith&#39;</span><span class="p">,</span>
	<span class="nx">age</span><span class="o">:</span> <span class="mi">48</span>
<span class="p">},</span> <span class="p">{</span>
	<span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Sarah&#39;</span><span class="p">,</span>
	<span class="nx">age</span><span class="o">:</span> <span class="mi">22</span>
<span class="p">}]</span>
</code></pre></div><h3 id="find">find</h3>
<p>Find the first item in the array that returns true</p>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="c1">// First person whose name starts with a &#39;K&#39;
</span><span class="c1"></span><span class="kd">var</span> <span class="nx">a</span> <span class="o">=</span> <span class="nx">people</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">person</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">person</span><span class="p">.</span><span class="nx">name</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">&#39;K&#39;</span><span class="p">)</span> <span class="o">===</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="kc">true</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="k">return</span> <span class="kc">false</span>
    <span class="p">}</span>
<span class="p">})</span>

<span class="c1">// This can be refactored down
</span><span class="c1"></span><span class="kd">var</span> <span class="nx">a</span> <span class="o">=</span> <span class="nx">people</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">person</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">person</span><span class="p">.</span><span class="nx">name</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">&#39;K&#39;</span><span class="p">)</span> <span class="o">===</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="kc">true</span>
    <span class="p">}</span>
<span class="p">})</span>

<span class="c1">// And some more
</span><span class="c1"></span><span class="kd">var</span> <span class="nx">a</span> <span class="o">=</span> <span class="nx">people</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">person</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">person</span><span class="p">.</span><span class="nx">name</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">&#39;K&#39;</span><span class="p">)</span> <span class="o">===</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">})</span>

<span class="c1">// In ES2015, we can get even shorter
</span><span class="c1"></span><span class="kd">var</span> <span class="nx">a</span> <span class="o">=</span> <span class="nx">people</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="nx">person</span> <span class="p">=&gt;</span> <span class="nx">person</span><span class="p">.</span><span class="nx">name</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">&#39;K&#39;</span><span class="p">)</span> <span class="o">===</span> <span class="mi">0</span><span class="p">)</span>
</code></pre></div><h3 id="findindex">findIndex</h3>
<p>Same as <code>find</code>, but it returns the index that matches</p>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">b</span> <span class="o">=</span> <span class="nx">people</span><span class="p">.</span><span class="nx">findIndex</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">person</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">person</span><span class="p">.</span><span class="nx">age</span> <span class="o">===</span> <span class="mi">22</span>
<span class="p">})</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">people</span><span class="p">[</span><span class="nx">b</span><span class="p">])</span> <span class="c1">// { name: &#39;Sarah&#39;, age: 22 }
</span></code></pre></div><h3 id="filter">filter</h3>
<p>Create a new array with items that return true</p>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">c</span> <span class="o">=</span> <span class="nx">people</span><span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">person</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">person</span><span class="p">.</span><span class="nx">age</span> <span class="o">&gt;</span> <span class="mi">25</span>
<span class="p">})</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">c</span><span class="p">)</span> <span class="c1">// [{ name: &#39;Jen&#39;, age: 32 }, { name: &#39;Keith&#39;, age: 48 }]
</span></code></pre></div><h3 id="map">map</h3>
<p>Create a new array with a subset of the original array (made from what you return)</p>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">d</span> <span class="o">=</span> <span class="nx">people</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">person</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">person</span><span class="p">.</span><span class="nx">age</span>
<span class="p">})</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="c1">// [32, 48, 22]
</span></code></pre></div><h3 id="reduce">reduce</h3>
<p>Accumulate through an array. The first argument is the reducer function. The second argument is the starting value (in this case: 0). In the reducer function, there are two arguments, the current value of the accumalation, and the current item in the array. You return the new value of the accumalation.</p>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">e</span> <span class="o">=</span> <span class="nx">people</span><span class="p">.</span><span class="nx">reduce</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">current</span><span class="p">,</span> <span class="nx">person</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">current</span> <span class="o">+</span> <span class="nx">person</span><span class="p">.</span><span class="nx">age</span>
<span class="p">},</span> <span class="mi">0</span><span class="p">)</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="c1">// 102
</span></code></pre></div><h3 id="sort">sort</h3>
<p>In the sorting function, you&rsquo;re provided items <code>a</code> and <code>b</code>. If <code>a</code> is less than <code>b</code>, you return -1, if <code>a</code> is greater than <code>b</code>, you return 1, and if they are equal, you return 0. A shorthand can be used:</p>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">f</span> <span class="o">=</span> <span class="nx">people</span><span class="p">.</span><span class="nx">sort</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">a</span><span class="p">.</span><span class="nx">age</span> <span class="o">-</span> <span class="nx">b</span><span class="p">.</span><span class="nx">age</span>
<span class="p">},</span> <span class="mi">0</span><span class="p">)</span>
<span class="c1">// Items in order of Sarah, Jen, Keith
</span></code></pre></div><p>Remember with sorting, it&rsquo;s default is to compare strings, not numbers. The default behavior of &lsquo;sort&rsquo; on a single-dimensional array will gets multiples above 10 in the &lsquo;wrong&rsquo; order.	<code>// [1, 10, 3, 35]</code></p>
<p>Also, don&rsquo;t view this a traditional loop, for longer arrays, it will run items through multiple times.</p>
<h2 id="task-wrangle-some-data">Task: wrangle some data.</h2>
<p>Take <a href="https://raw.githubusercontent.com/trys/training-notes/master/2017-11-15/data.js">this FIFA World Cup data</a> and perform the following operations:</p>
<ol>
<li>Return the item that corresponds to France&rsquo;s first win</li>
<li>Return the array index of the 1970 World Cup final</li>
<li>Return a new array of winner team names</li>
<li>Count up the total number of goals</li>
<li>Return all items where the host has won the World Cup</li>
<li>Sort the items based on the total goals scored</li>
<li>(Stretch goal) Return a new array of teams and their total number of wins, in descending order</li>
</ol>
]]>
      </description>
    </item>
    
    <item>
      <title>Training Notes - JS - Variables</title>
      <link>https://www.trysmudford.com/blog/training-notes-js-variables/</link>
      <pubDate>Fri, 27 Oct 2017 00:00:00 +0000</pubDate>
      
      <guid>https://www.trysmudford.com/blog/training-notes-js-variables/</guid>
      <description><![CDATA[
<h1 id="training---js">Training - JS</h1>
<h2 id="foundations">Foundations</h2>
<p>The engine runs from through your JS from top to bottom. When you call a function, it switches context into the function, runs through it, then returns back to the main context.</p>
<h2 id="variables">Variables</h2>
<p>What is a variable?</p>
<p>A variable is a box you can put things in and retrieve later.</p>
<div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">a</span> <span class="o">=</span> <span class="mi">2</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">a</span><span class="p">)</span> <span class="c1">// 2
</span></code></pre></div><p>Variables can be updated:</p>
<div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="nx">a</span> <span class="o">=</span> <span class="nx">a</span> <span class="o">+</span> <span class="mi">1</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">a</span><span class="p">)</span> <span class="c1">// 3
</span></code></pre></div><p>Variables hold values. There are 7 value &lsquo;types&rsquo;:</p>
<ul>
<li>string</li>
<li>number</li>
<li>boolean</li>
<li>null</li>
<li>undefined</li>
<li>symbol</li>
<li>object</li>
</ul>
<p>The first six are &lsquo;primitive&rsquo; types. Primitive types are immutable (can&rsquo;t be mutated) For a string, this means the once the string is created. It&rsquo;s not possible to modify it!</p>
<div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">b</span> <span class="o">=</span> <span class="s1">&#39;trys&#39;</span>
<span class="nx">b</span><span class="p">.</span><span class="nx">toUpperCase</span><span class="p">()</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">b</span><span class="p">)</span> <span class="c1">// &#39;trys&#39;
</span></code></pre></div><p>You can however reassign <code>b</code> to hold a new string:</p>
<div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">b</span> <span class="o">=</span> <span class="s1">&#39;trys&#39;</span>
<span class="nx">b</span> <span class="o">=</span> <span class="nx">b</span><span class="p">.</span><span class="nx">toUpperCase</span><span class="p">()</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">b</span><span class="p">)</span> <span class="c1">// &#39;TRYS&#39;
</span></code></pre></div><p>Why is this useful? Mutable values are consistent, once they&rsquo;re assigned, you have to be explicit to change them. This becomes more useful when we start passing values around a program.</p>
<h2 id="objects">Objects</h2>
<p>The only non-primitive, mutable data type is an object. It is a collection of data.</p>
<p>Interestingly, arrays and functions are both types of object in JS.</p>
<h2 id="variables-vs-values">Variables vs. Values</h2>
<p>When I said &lsquo;A variable is a box you can put things in and retrieve later&rsquo;, I wasn&rsquo;t being strictly true. A variable points to a value and the value is the box that holds things. This means you can have two variables looking at one value. We&rsquo;ll get to that in a bit.</p>
<h2 id="the-types">The types</h2>
<h3 id="string">String</h3>
<p>Strings represent text data: &lsquo;Trys&rsquo; is a string. &lsquo;1&rsquo; is a string.</p>
<h3 id="number">Number</h3>
<p>Numbers represent numerical data. 0 is a number. Infinity is a number. NaN is a number!</p>
<h3 id="boolean">Boolean</h3>
<p>Booleans are logical values. true or false. Note &lsquo;true&rsquo; is a string, not boolean. More importantly, &lsquo;false&rsquo; is truthy.</p>
<h3 id="null">Null</h3>
<p>Null is the intentionaly absence of a value</p>
<h3 id="undefined">Undefined</h3>
<p>Undefined is when you have a variable that isn&rsquo;t pointing to a value.</p>
<div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">c</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">c</span><span class="p">)</span> <span class="c1">// undefind
</span></code></pre></div><h3 id="symbol">Symbol</h3>
<p>Symbols are a bit beyond our scope. They were added in ES2015 and they represent unique, primitive (immutable) data.</p>
<h2 id="whats-the-big-deal">What&rsquo;s the big deal?</h2>
<p>Variables come into their own when you start passing them around your program. They are a way of linking sections of your program. They help you enforce modularity.</p>
<h2 id="arrays">Arrays</h2>
<p>An array is a zero-based collection of items. They are generally created with square brackets:</p>
<div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">a</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;12&#39;</span><span class="p">,</span> <span class="s1">&#39;34&#39;</span><span class="p">]</span>
<span class="kd">var</span> <span class="nx">b</span> <span class="o">=</span> <span class="p">[]</span>
</code></pre></div><p>You can <code>push</code> items onto the end of it, <code>pop</code> items off the end, <code>shift</code> to remove the first item, <code>unshift</code> to prepend items. <code>.forEach</code> loops them, <code>indexOf</code> returns the index position. You access them via square brackets: <code>arrayName[arrayIndex] = 123</code>. You can remove items with <code>splice</code>. <code>slice</code> makes a shallow copy.</p>
<h2 id="scope">Scope</h2>
<p>When a variable is declared, the compiler notes down what the value is and what scope it was defined in.</p>
<p>Imagine a tree. A leaf is concerned about leafy things. It has access to all it&rsquo;s own information. This is called &lsquo;local scope&rsquo;. When the leaf asks for the variable <code>leafColour</code>, the engine asks the local scope if it has the value <code>leafColour</code>. The scope says yes and returns &lsquo;orange&rsquo;.</p>
<p>Occasionally, a leaf needs to know some twig information, say twig length. So it asks for the variable <code>twigLength</code>. First, the engine asks the local scope for the value <code>twigLength</code>. The scope says nope. So the engine goes up a level to the twig scope and asks for <code>twigLength</code>. It replies yes and returns &lsquo;10cm&rsquo;.</p>
<p>Finally, the leaf may ask for the type of tree. It asks the leaf scope, then the twig scope, then the branch scope, then the trunk scope, then the tree scope. In this tenuous analogy, the tree is the global scope and it returns the type &lsquo;oak&rsquo;.</p>
<p>If the leaf had asked for the variable &lsquo;breakfast&rsquo;, the engine would&rsquo;ve worked up the scopes, to the global scope. If nothing was found, it would return <code>undefined</code>.</p>
<p>So scope works from the children up to the global scope. So sibling leaves don&rsquo;t have access to each other, they only have access to their own local scope and all parent scopes. The other key takeaway is parent scope doesn&rsquo;t have access to child scope.</p>
<p>Scopes are (mostly) created each time you call a function.</p>
<h2 id="scopes-and-primitives">Scopes and primitives</h2>
<div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">a</span> <span class="o">=</span> <span class="mi">1</span>
<span class="kd">function</span> <span class="nx">add</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">a</span> <span class="o">=</span> <span class="nx">a</span> <span class="o">+</span> <span class="mi">1</span>
<span class="p">}</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">a</span><span class="p">)</span> <span class="c1">// 1
</span><span class="c1"></span><span class="nx">add</span><span class="p">()</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">a</span><span class="p">)</span> <span class="c1">// 2
</span></code></pre></div><p>Compare to:</p>
<div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">a</span> <span class="o">=</span> <span class="mi">1</span>
<span class="kd">function</span> <span class="nx">add</span><span class="p">(</span><span class="nx">b</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">b</span> <span class="o">=</span> <span class="nx">b</span> <span class="o">+</span> <span class="mi">1</span>
<span class="p">}</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">a</span><span class="p">)</span> <span class="c1">// 1
</span><span class="c1"></span><span class="nx">add</span><span class="p">(</span><span class="nx">a</span><span class="p">)</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">a</span><span class="p">)</span> <span class="c1">// 1
</span></code></pre></div><p>In the first example, the function <code>add</code> asks for <code>a</code>, the scope doesn&rsquo;t have it in local scope, so it goes up a level to global scope and finds it.  So it is able to modify a variable in the parent.</p>
<p>Contrast it to the second example. We pass <code>a</code> into the function, it comes in to the parameter <code>b</code> (for clarity). As it is immutable, it creates a new variable called <code>b</code> that is no longer linked to <code>a</code>. Calling <code>add(a)</code> only updates the values inside the function. There are two ways around this. One, return the new value of <code>a</code> after each function call. Two, use a mutable data type.</p>
<p>One:</p>
<div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">a</span> <span class="o">=</span> <span class="mi">1</span>
<span class="kd">function</span> <span class="nx">add</span><span class="p">(</span><span class="nx">b</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nx">b</span> <span class="o">=</span> <span class="nx">b</span> <span class="o">+</span> <span class="mi">1</span>
<span class="p">}</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">a</span><span class="p">)</span> <span class="c1">// 1
</span><span class="c1"></span><span class="nx">a</span> <span class="o">=</span> <span class="nx">add</span><span class="p">(</span><span class="nx">a</span><span class="p">)</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">a</span><span class="p">)</span> <span class="c1">// 2
</span></code></pre></div><p>Two:</p>
<div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">a</span> <span class="o">=</span> <span class="p">{</span>
  <span class="nx">count</span><span class="o">:</span> <span class="mi">1</span>
<span class="p">}</span>
<span class="kd">function</span> <span class="nx">add</span><span class="p">(</span><span class="nx">b</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">b</span><span class="p">.</span><span class="nx">count</span> <span class="o">=</span> <span class="nx">b</span><span class="p">.</span><span class="nx">count</span> <span class="o">+</span> <span class="mi">1</span>
<span class="p">}</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">a</span><span class="p">.</span><span class="nx">count</span><span class="p">)</span> <span class="c1">// 1
</span><span class="c1"></span><span class="nx">add</span><span class="p">(</span><span class="nx">a</span><span class="p">)</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">a</span><span class="p">.</span><span class="nx">count</span><span class="p">)</span> <span class="c1">// 2
</span></code></pre></div><h2 id="var-const-let">var, const, let</h2>
<p>In ES2015, <code>const</code> and <code>let</code> were added. Where <code>var</code> declares variables that are limited to function-level scope, <code>let</code> and <code>const</code> declare block-level scope.</p>
<div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="kd">function</span> <span class="nx">varTest</span><span class="p">()</span> <span class="p">{</span>
  <span class="kd">var</span> <span class="nx">x</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
  <span class="k">if</span> <span class="p">(</span><span class="kc">true</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">x</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>  <span class="c1">// same variable!
</span><span class="c1"></span>    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">x</span><span class="p">);</span>  <span class="c1">// 2
</span><span class="c1"></span>  <span class="p">}</span>
  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">x</span><span class="p">);</span>  <span class="c1">// 2
</span><span class="c1"></span><span class="p">}</span>

<span class="kd">function</span> <span class="nx">letTest</span><span class="p">()</span> <span class="p">{</span>
  <span class="kd">let</span> <span class="nx">x</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
  <span class="k">if</span> <span class="p">(</span><span class="kc">true</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">let</span> <span class="nx">x</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>  <span class="c1">// different variable
</span><span class="c1"></span>    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">x</span><span class="p">);</span>  <span class="c1">// 2
</span><span class="c1"></span>  <span class="p">}</span>
  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">x</span><span class="p">);</span>  <span class="c1">// 1
</span><span class="c1"></span><span class="p">}</span>
</code></pre></div><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let">MDN link</a></p>
<p>Furthermore variables declared as <code>const</code>, can&rsquo;t be reassigned.</p>
<div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="kr">const</span> <span class="nx">a</span> <span class="o">=</span> <span class="mi">123</span>
<span class="nx">a</span> <span class="o">=</span> <span class="mi">456</span> <span class="c1">// TypeError: Assignment to constant variable.
</span></code></pre></div><p><code>const</code> can be mutated:</p>
<div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="kr">const</span> <span class="nx">b</span> <span class="o">=</span> <span class="p">[]</span>
<span class="nx">b</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="mi">123</span><span class="p">)</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">b</span><span class="p">)</span> <span class="c1">// [123]
</span></code></pre></div><p>In ES2015, <code>const</code> is now seen as the &lsquo;correct&rsquo; way to declare variables. <code>let</code> should be only used if you have to updated it (ie. a counter). <code>var</code> shouldn&rsquo;t be used at all. However, we&rsquo;re not all in ES2015 land just yet.</p>
<h2 id="global-scope">Global scope</h2>
<p>You may&rsquo;ve heard the phrase &lsquo;polluting the global scope&rsquo;. This happens when we define our programs globally. The problem is collisions. If you write a plugin that requires a global object that holds certain values, calling it <code>settings</code> may well conflict with another plugin that also uses a <code>settings</code> variable. Now whichever program registers the variable last, overwrites all previous settings, and probably breaks your program in the meantime.</p>
<p>You want to reduce global variables as much as possible, ideally to zero or one instances. Then name your global variable to something sensible.</p>
<p>If you don&rsquo;t need to pollute the global scope at all, you can use a IIFE (instantly instantiated function expression). They look like this:</p>
<div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
  <span class="c1">// Your program
</span><span class="c1"></span><span class="p">})()</span>
</code></pre></div><p>An IIFE creates a new functional scope block so your variables don&rsquo;t pollute the global scope. You can even pass in values into an IIFE:</p>
<div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">a</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">a</span><span class="p">)</span> <span class="c1">// 123
</span><span class="c1"></span><span class="p">})(</span><span class="mi">123</span><span class="p">)</span>
</code></pre></div><p>This is a great pattern to utilise as it forces you to break your code into modules.</p>
<h2 id="task---mileage-calculator">Task - mileage calculator</h2>
<p>Take an array of journey objects, each with a start, end and distance.</p>
<ul>
<li>To begin with, output them in the console.</li>
<li>Then calculate the total distance and display it on the page</li>
<li>Display the trips on the page</li>
<li>Stretch goal: Add a form that lets you add new journeys</li>
<li>Stretch stretch goal: store the changes in localstorage for persistent calculations</li>
</ul>
]]>
      </description>
    </item>
    
    <item>
      <title>Training notes: Forms</title>
      <link>https://www.trysmudford.com/blog/training-notes-forms/</link>
      <pubDate>Wed, 11 Oct 2017 00:00:00 +0000</pubDate>
      
      <guid>https://www.trysmudford.com/blog/training-notes-forms/</guid>
      <description><![CDATA[
<p>I recently carried out the inaugural training session for a couple of developers in Tomango and a neighbouring brand agency. The syllabus is going to be based around web fundamentals.</p>
<p>It was a very new experience to conduct such a formal session but it seemed to go down pretty well. I’ve noted down lots of tweaks to make in preparation for the next session in three weeks time. Below are my (pretty rough) notes for the ‘talky’ bit of the session, we followed up with a coding task.</p>
<hr>
<h2 id="why-use-a-form">Why use a form?</h2>
<ul>
<li>Getting user-generated data to and from a server.</li>
<li>It links client and server side.</li>
<li>There are accessibility benefits like keyboard shortcuts, tabindex, outlines</li>
<li>There are user benefits like autocomplete</li>
<li>They are system optimised, datepickers, email fields etc</li>
<li>They are standardised forms of input</li>
</ul>
<p>It’s possible (and arguably too easy) to create psuedo-forms with JS. But they fail accessiblity and they don’t leverage web standards.</p>
<h2 id="actions">Actions</h2>
<p>A standard form attribute is <code>action</code>. It tells the browser where to submit the form, kindof like a href on an <code>&lt;a&gt;</code> tag. If omitted, it submits to the current URL.</p>
<h2 id="methods">Methods</h2>
<p>Methods tell the browser which HTTP method to use. There are two main ones. <code>GET</code> and <code>POST</code>. They both cause a full page reload (by default).</p>
<p>A <code>GET</code> request passes the submitted data into the URL of the next page. Search is a good example of this. If you don’t mind the data being public (or messed with), <code>GET</code> is a good option. All the data will be visible in users history, so you wouldn’t want to expose passwords etc.</p>
<p><code>POST</code> requests are more private. They don’t expose the data to the URL so they’re not shareable in the same way <code>GET</code> requests are. This makes them more useful for login forms.</p>
<p>There are three more HTTP request types but they’re not usable on forms (yet). They are <code>PUT</code>, <code>HEAD</code> and <code>DELETE</code>. They are used in REST APIs. Example</p>
<div class="highlight"><pre class="chroma"><code class="language-fallback" data-lang="fallback">Add a user      - POST /users/             -&gt; POST   /users/
Get the user    - GET  /users/trys/        -&gt; GET    /users/trys
Edit the user   - POST /users/trys/edit/   -&gt; PUT    /users/trys
Delete the user - POST /users/trys/delete/ -&gt; DELETE /users/trys
User existence  - GET  /users/trys/        -&gt; HEAD   /users/trys
</code></pre></div><p>The method describes the indent of the request, a search <code>GET</code>s data from the server, and login <code>POST</code>s data to the server.</p>
<h2 id="input-types">Input types</h2>
<p>The default input type is text. Common others are number, email, password, hidden, checkbox, radio &amp; submit. If you omit the type or put an invalid type, it falls back to text. This is the great ‘progressive enhancement’ feature of forms. There are other form ‘inputs’ such as textarea, button, select.</p>
<p>Run through inputs on MDN: <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input">input</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select">select</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea">textarea</a> &amp; <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button">button</a></p>
<h2 id="form-layout">Form layout</h2>
<h3 id="required-attributes">‘Required’ attributes</h3>
<p>Although there are not strictly mandatory attributes, there are attributes are necessary on each input to provide basic functionality.</p>
<div class="highlight"><pre class="chroma"><code class="language-html" data-lang="html"><span class="p">&lt;</span><span class="nt">input</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;username&#34;</span><span class="p">&gt;</span>
</code></pre></div><p>All inputs arrive on the server as a key/value pair. name is the key. Whatever you type into the input is the value. For a Google search, <code>q</code> is the name attribute, which translates in the URL to <code>?q=123</code>.</p>
<div class="highlight"><pre class="chroma"><code class="language-html" data-lang="html"><span class="p">&lt;</span><span class="nt">label</span> <span class="na">for</span><span class="o">=</span><span class="s">&#34;username&#34;</span><span class="p">&gt;</span>Username<span class="p">&lt;/</span><span class="nt">label</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">input</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;username&#34;</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;username&#34;</span><span class="p">&gt;</span>
</code></pre></div><p><code>id</code> is required to link a label to an input with for. This is crucial for accessibility, even if you have placeholders. If you click on a label linked to an input, it focuses on the input. Label wrapping does this too</p>
<div class="highlight"><pre class="chroma"><code class="language-html" data-lang="html"><span class="p">&lt;</span><span class="nt">input</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;hidden&#34;</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;post-type&#34;</span> <span class="na">value</span><span class="o">=</span><span class="s">&#34;post&#34;</span><span class="p">&gt;</span>
</code></pre></div><p><code>value</code> pre-fills the input. This is useful for defaults, hidden inputs and re-filling after failed validation.</p>
<div class="highlight"><pre class="chroma"><code class="language-html" data-lang="html"><span class="p">&lt;</span><span class="nt">label</span> <span class="na">for</span><span class="o">=</span><span class="s">&#34;username&#34;</span><span class="p">&gt;</span>Username<span class="p">&lt;/</span><span class="nt">label</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">input</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;username&#34;</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;username&#34;</span> <span class="na">placeholder</span><span class="o">=</span><span class="s">&#34;Batman, Robin...&#34;</span><span class="p">&gt;</span>
</code></pre></div><p><code>placeholder</code> is used to provide an example of the expected input. It only shows when the input is empty. It’s often ‘abused’ by designers to replace the need for a label. Never remove the label, hide it using screen-reader safe CSS. <code>display: none</code> is not read by screenreaders so hiding a label like that is useless. Placeholder styling is a bit buggy, some browsers take the colour value straight from the <code>color</code> of the input, others take it and make it a bit lighter to differentiate.</p>
<h3 id="checkboxesradios">Checkboxes/radios</h3>
<p>The input types checkbox/radio are a bit different as you tend to have multiple input tags. Either wrap the input in the label or, write it as:</p>
<div class="highlight"><pre class="chroma"><code class="language-html" data-lang="html"><span class="p">&lt;</span><span class="nt">input</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;contact&#34;</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;radio&#34;</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;contact_2&#34;</span> <span class="na">value</span><span class="o">=</span><span class="s">&#34;Phone&#34;</span><span class="p">&gt;&lt;</span><span class="nt">label</span> <span class="na">for</span><span class="o">=</span><span class="s">&#34;contact_2&#34;</span><span class="p">&gt;</span>Phone<span class="p">&lt;/</span><span class="nt">label</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">input</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;contact&#34;</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;radio&#34;</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;contact_1&#34;</span> <span class="na">value</span><span class="o">=</span><span class="s">&#34;Email&#34;</span><span class="p">&gt;&lt;</span><span class="nt">label</span> <span class="na">for</span><span class="o">=</span><span class="s">&#34;contact_1&#34;</span><span class="p">&gt;</span>Email<span class="p">&lt;/</span><span class="nt">label</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">input</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;contact&#34;</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;radio&#34;</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;contact_3&#34;</span> <span class="na">value</span><span class="o">=</span><span class="s">&#34;Pigeon&#34;</span><span class="p">&gt;&lt;</span><span class="nt">label</span> <span class="na">for</span><span class="o">=</span><span class="s">&#34;contact_3&#34;</span><span class="p">&gt;</span>Pigeon<span class="p">&lt;/</span><span class="nt">label</span><span class="p">&gt;</span>
</code></pre></div><p>Checkboxes have multiple inputs and multiple outputs, so you need to add [] to the name. This’ll arrive on the server as an ‘array’ (of sorts).</p>
<div class="highlight"><pre class="chroma"><code class="language-html" data-lang="html"><span class="p">&lt;</span><span class="nt">input</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;toppings[]&#34;</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;checkbox&#34;</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;toppings_2&#34;</span> <span class="na">value</span><span class="o">=</span><span class="s">&#34;Mozzerella&#34;</span><span class="p">&gt;&lt;</span><span class="nt">label</span> <span class="na">for</span><span class="o">=</span><span class="s">&#34;toppings_2&#34;</span><span class="p">&gt;</span>Mozzerella<span class="p">&lt;/</span><span class="nt">label</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">input</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;toppings[]&#34;</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;checkbox&#34;</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;toppings_1&#34;</span> <span class="na">value</span><span class="o">=</span><span class="s">&#34;Tomato&#34;</span><span class="p">&gt;&lt;</span><span class="nt">label</span> <span class="na">for</span><span class="o">=</span><span class="s">&#34;toppings_1&#34;</span><span class="p">&gt;</span>Tomato<span class="p">&lt;/</span><span class="nt">label</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">input</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;toppings[]&#34;</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;checkbox&#34;</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;toppings_3&#34;</span> <span class="na">value</span><span class="o">=</span><span class="s">&#34;Chicken&#34;</span><span class="p">&gt;&lt;</span><span class="nt">label</span> <span class="na">for</span><span class="o">=</span><span class="s">&#34;toppings_3&#34;</span><span class="p">&gt;</span>Chicken<span class="p">&lt;/</span><span class="nt">label</span><span class="p">&gt;</span>
</code></pre></div><h3 id="accessibility">Accessibility</h3>
<p>tabindex can be used, don’t if you can avoid it. It gets super confusing and difficult to manage. Leave the broweser to do its job.</p>
<p>Provide an <code>&lt;input type=&quot;submit&quot;&gt;</code> or <code>&lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;</code>. Some browsers get grumpy if they’re not present. Plus: accessibility \o/</p>
<h3 id="styling">Styling</h3>
<p>Styling can be a pain. There are a load of incompatibilities between browsers. Some input types aren’t supported at all and fallback to text. But it can be ‘reset’ pretty well, you just have to be a bit creative about styling techniques.</p>
<p><code>:invalid</code>, <code>:focus</code>, <code>:active</code>, <code>:checked</code> can all be used in CSS to target an input with a given state.</p>
<h3 id="task-newsletter-sign-up-form">Task: Newsletter sign up form.</h3>
<p>We’ll make a Mailchimp-esque form with first name, last name, email (required) and a subscribe button. It should POST to itself and catch invalid states. It should be responsive (1 col on mobile, 4 col on desktop).</p>
<h3 id="future-things-for-future-weeks">Future things for future weeks</h3>
<p>Grabbing data in PHP, filtering data safely, catching/inspecting forms in JS. event.PreventDefault() – how not to use it. Event bubbling/delegation. Security. OTK.</p>
]]>
      </description>
    </item>
    
  </channel>
</rss>