RF Word Counter
Tags: javascript, webdev, beginners, frontend
Published: 2024-07-07 02:45:02

## RF Word Counter
Simple word counter web app for beginners. I will share how I developed this project step by step.

When the user types or pastes any text, the app counts the number of words and characters in the textarea. Words exclude spaces and line breaks, while characters include everything.

**Tech**: html, css and javascript

![RF Word Counter](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gfcjw8jj026sex03gv05.png)

- live link: [rf-word-counter.netlify.app](https://rf-word-counter.netlify.app/)
- github repo: https://github.com/rahatfaruk/rf-word-counter


### html
In html, I have created a container `textarea-and-result` that contains textarea (for user's text) and results (how many words and characters - initially 0).  
```html
  <div class="textarea-and-result">
    <!-- results -->
    <div class="result-container">
      <p><span id="words">0</span> Words</p>
      <p><span id="chars">0</span> Characters</p>
    </div>
    <!-- textarea -->
    <textarea name="textarea"></textarea>
  </div>
```

Rest codes inside html is for styling and page structure purpose.


### css
I have tried to keep the design as simple as possible. I have tried to explain styles through comment. Paste the following code inside style.css file.

```css
  /* ## resets and base styles */
  * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: sans-serif;
  }

  body { padding: 1rem; }

  h1 {
    margin: 1rem 0 1.5rem;
    text-align: center;
  }

  textarea {
    display: block;
    height: 100px;
    width: 100%;
    padding: 1rem;
    border: none;
    border-radius: .5rem;
    background: #dfdfdf;
    font-size: 1rem;
    resize: vertical;
  }

  /* ## app styles */
  .app {
    max-width: 600px;
    margin: 0 auto;
  }

  .textarea-and-result {
    padding: 2rem 1rem;
    border: 2px solid #ccc;
    box-shadow: 3px 3px 8px #ccc;
    border-radius: .25rem;
  }

  .result-container {
    display: flex;
    gap: 1rem;
    margin-bottom: 1.5rem;
    justify-content: center;
  }
  .result-container p {
    padding: 1rem;
    border-radius: .5rem;
    background: #dfdfdf;
    text-align: center;
  }
  .result-container p span {
    display: block;
    font-weight: bold;
    font-size: 2.5rem;
    margin-bottom: .5rem;
  }

  .attribution {
    margin-top: 1.5rem;
    color: #999;
    font-size: .9rem;
    text-align: center;
  }
```


### Javascript (Steps):

```js
  // 1.
  const textarea = document.querySelector('textarea')
  const wordsEl = document.getElementById('words')
  const charsEl = document.getElementById('chars')
  const spacesEl = document.getElementById('spaces')

  // 2.  
  textarea.addEventListener('input', e => { 
    // 3.
    const text = e.target.value

    // 4. & 5.
    const words = text.match( /\S+/gm )
    const spaces = text.match( /\s/gm )

    // 6. & 7.
    wordsEl.textContent = words ? words.length : 0
    charsEl.textContent = text ? text.length : 0
    spacesEl.textContent = spaces ? spaces.length : 0
  })
```

Expanation: 
1. Get all important elements.
2. Add the `input` event to the textarea to count words immediately after typing or pasting text.
3. Get the text inside the textarea.
4. Get an array of all words (excluding spaces and line breaks) and store it in the `words` variable. Use `text.match( /\S+/gm )`. Explanation of the regex:
  - `g` flag means global match.
  - `m` flag means multi-line.
  - `\S` matches any non-whitespace character.
  - `+` matches the previous token one or more times.
5. Get an array of all spaces. Use `text.match( /\s/gm )`. Spaces includes line breaks.
6. Calculate the results. If the textarea is empty, `words` is `null`; otherwise, it's an array. Return `0` for `null`, otherwise count the words.
  - Use `words.length` to count words.
  - Use `text.length` to get the total number of characters.
7. Update the UI with the results.