diff --git a/content/using-input-fields/README.md b/content/using-input-fields/README.md new file mode 100644 index 0000000..282cfd6 --- /dev/null +++ b/content/using-input-fields/README.md @@ -0,0 +1,383 @@ +# Using input fields with choo +🌐 Made by [@louiscenter](https://twitter.com/louiscenter) 🌐 + +✨ This guide will help demonstrate the use of input fields within a simple interactive `choo` application + +## choo handbook +This guide has been published at [https://handbook.choo.io/using-input-fields](https://handbook.choo.io/using-input-fields). + +## Who is guide this for? +To follow along, you should be comfortable with the basics of JavaScript, HTML & CSS. + +You should also feel comfortable with the basics of `choo`. If you haven't already, complete the [your-first-choo-app](https://handbook.choo.io/your-first-choo-app) guide before starting this one. It's a good introduction to what `choo` is, and how it works. + +## What will we build? +For this guide, we're going to build a variation of the animal simulator we built in the [your-first-choo-app](https://handbook.choo.io/your-first-choo-app) tutorial, that will allow our animals to talk to one another. I call it `choo-talking-animals`. + +This is what it looks like: + +[![screenshot](images/choo-talking-animals.gif)](https://choo-talking-animals.glitch.me) + +Using the provided input fields, a user can change what each animal is saying to the other. The lion's input field will work slightly differently to the crocodile's input field, and this should help demonstrate the basic ways in which input fields can update our application's state. + +You can try the finished version of this app here: [https://choo-talking-animals.glitch.me](https://choo-talking-animals.glitch.me) + +## Let's get started! +For this guide, we will be using the [Glitch](https://glitch.com/) code editor. + +If you're not familiar with how Glitch works, you should refer to the `Let's get started` section in our [your-first-choo-app](https://handbook.choo.io/your-first-choo-app) tutorial. + +If you're already familiar with Glitch, open the following starter project URL, remix/fork the project and let's begin: [https://glitch.com/edit/#!/project/choo-talking-animals-starter](https://glitch.com/edit/#!/project/choo-talking-animals-starter) + +## Creating input fields +With our starter project loaded, let's have a look at what code is provided for us. Click the `index.js` file in Glitch's left sidebar, and make sure that you see the following: + +```js +// import choo +var choo = require('choo') + +// import template +var main = require('./templates/main') + +// initialize choo +var app = choo() + +// declare routes +app.route('/', main) + +// start app +app.mount('div') +``` + +First, we are importing the `choo` framework, as well as a pre-made HTML template into our codebase. We then initialize an instance of `choo` (stored in the `app` variable), and then create a new `/` route which points to the template we imported above. Finally, we mount the app to our webpage using the `mount()` function, which simultaneously starts the application when everything has finished loading. + +Let's take a look at the template which we imported, and stored in the `main` variable. Click on the `templates/main.js` file in Glitch's left sidebar, and make sure that you see the following: + +```js +// import html helper +var html = require('choo/html') + +// export function +module.exports = function (state, emit) { + return html` +
+
+
+ +
+
+ +
+ +
+
+
+
+ ` +} +``` + +At the top of this file, we've imported the `html` function that comes with `choo`, which allows us to create HTML templates that `choo` can understand and render on the page. Below, we're exporting a function that returns a template which will render a square of grass, a lion, a crocodile and some speech bubbles (the assets and CSS styles for these HTML elements are included with the starter project). + +We can see what our app currently looks like, by clicking the "Show" button near the top left hand corner of the window: + +![starter1](images/starter1.gif "Screenshot of starter project") + +Let's add some input fields to our application. Modify the HTML template inside `template/main.js` to read the following: + +```html +
+
+
+ +
+
+ +
+ +
+
+
+ +
+
+
The Lion says
+ +
+ +
+
The Crocodile says
+ + +
+
+
+``` + +Let's see what our app looks like now: + +![inputs1](images/inputs1.gif "Screenshot of new input fields") + +Below our grass square (`
`), we've a added new container (`
`) which includes two input fields (``), and a ` +
+
+ + ` + + // update what lion says + function updateLion (e) { + emit('updateAnimal', { + type: 'lion', + value: e.target.value + }) + } +} + +``` + +Before we dissect all the changes we just made, let's try our application again: + +![inputs4](images/inputs4.gif "Our first input now works!") + +It's working! Our animals can now talk, and we can make the Lion say whatever is on our mind. + +Let's run through a list of what just changed: + +- At the top of our template function, we created two new variables, `lion` and `crocodile`, which point to `state.animals.lion` and `state.animals.crocodile` respectively. + +- Next, inside of each animal's speech bubble, we render those variables (eg. `
${lion}
`), so that we can see what each animal is saying. + +- Finally, we added a `value` property to our first input field. We set this property to be equal to the `lion` variable, the same variable used inside of the Lion's speech bubble. + +Prior to these changes, when we entered text into our first input field, nothing on the screen was updated, not even the input field itself. + +The important change here is the new `value` property we added to the `` element. When this element detects new input from the keyboard, it runs the `updateLion()` function. This then emits the `updateAnimal` event, which first updates our `state.animals` object, and then triggers `emitter.emit('render')`, re-rendering our application. + +If `choo` re-renders, but an `` element's `value` property isn't set to anything, `choo` will re-render that element *without* any value. Thus we end up with the effect that nothing is being updated at all. + +## Minimizing re-renders +This application is starting to work a lot better now, but depending on what kind of behaviour you'd like your input fields and forms to exhibit, re-rendering the application after each keystroke might not be ideal. + +There's another way in which we can transfer information from an input field, to our application state, without all of the extra re-rendering. + +Let's make a change to the Crocodile's input field, and the ` + +``` + +Like before, we've added a `value` property to this input field, and set its value to the `crocodile` variable. However, you may have noticed that we didn't add an `oninput` property. Instead, we've added an `onclick` property to the `