A TO-DO app that fits in a single tweet

Sunday morning while I was scrolling through my Twitter feed one tweet caught my eye,

The challenge was to make a todo app that fits in a single tweet, just like any other todo app, you should be able to add or remove tasks and clear the task list. I thought how hard this can get, I thought to myself this is doable just by using plain JavaScript.

So since I don’t have a laptop, what resulted was a whole day of torture having to code though my iPad on codepen.

Plain JavaScript

Soon after I started using plain JavaScript it became obvious that I was not able to make it within one tweet, the DOM manipulation was taking too much characters, document.createElements, document.getElements.

It was obvious that was not the right approach.

Using vue

Vue framework won’t require any build tools, so I don’t have to go through setting up Webpack,

Also I can easily create the DOM within the script tag using simple HTML. So that will save some characters for me in DOM manipulation.

The first version I made use the method option in Vue app to handle button clicks, the button click event will call the function in methods to add new tasks and clear the task list.

However, I was unable to reduce it to one tweet. Then I went back to in-line functions, the same methods were added to button click events inline and not within the methods section.

Also I had to change buttons to anchor tags, in order to save some characters, and I had to use emojis instead of button text to save some more characters.

I also had to drop few buttons like a button to add a task, and instead I had to go with pressing enter key to add a task instead.

So I made the final version, the JavaScript code looked like this,

See the Pen qBaXmpE by Rukshan Ranatunge (@rukshn) on CodePen.

Then I ran the code through an online JavaScript minifier and then the whole HTML though an HTML minifier, and ended up with this piece of code,

<body><script src=https://unpkg.com/vue@next></script><script>var x={data:()=>({t:[],k:""}),template:'<input @keyup.enter="t.push(k)" v-model="k"><a @click="t=[]">❎</a><p v-for="(v,i) in t"><a @click="t.splice(i,1)">?️</a>{{v}}</p>'};Vue.createApp(x).mount("body")</script>

With my fingers crossed, I copied the code on to Twitter, and guess what it fits perfectly inside a single Tweet.

And here is the code in action, link

See the Pen qBaXmpE by Rukshan Ranatunge (@rukshn) on CodePen.

What I failed to achieve

The original Tweet says, that the completed tasks should have a strike through.

But because css was costing me too much characters I had to fall back to remove completed tasks instead, but I’m sure someone will figure a solution for that as well.

At the same time, I think you can save even more characters by using mithril, because you have short-codes for DOM elements as well, but I haven’t tried mithril in awhile.

One last thing

No I didn’t waste my whole Sunday on this problem, but I had to spend few hours, thinking and trying different versions.

I would have cut back some more time if I had a laptop. Somerimes I feel like buying an old laptop and refurbishing it and installing Ubuntu on it.

Sunday well spent? Absolutely yes.

Best answer?

One thing I love about HN is the fact that there are lot of bright minds out there. Since I posted this on HN I knew it was just a matter of time since someone figures this out.

I guess this is the best answer and also ticks all the boxes, well done.

 <script>document.write(`<style>:checked+*{text-decoration:line-through}#t{display:none}</style><p id="t"><input type="checkbox"><input><div id="f"></div><p><button onclick="f.appendChild(t.cloneNode(true)).id=''">+</button><button onclick="f.innerHTML=''">×</button>`)</script>

HN link to this answer: https://news.ycombinator.com/item?id=25493533

Original thread on HN: https://news.ycombinator.com/item?id=25492302

12 responses

  1. Konstantin Avatar
    Konstantin

    Have thought of using tag instead of css for strike-through?

    1. Yes I thought about it as well but since most websites say that tag is redundant I thought about not using it 🙂

      But yes true that is a possibility

  2. document.write(`:checked+*{text-decoration:line-through}#t{display:none}+×`)

  3. […] post was an awesome one, I learned a lot in JavaScript and and I was happy to see people doing what I […]

  4. […] previous day’s post was as soon as an incredible one, I learned loads in JavaScript and and I was as soon as happy to […]

  5. Hi!
    I posted a 155 chars solution. The strkethrough is done using innerHTML.strike()

    https://twitter.com/MaximeEuziere/status/1341656188207964160

    1. Hi yes, I just saw this solution, that’s pretty awesome.

      But I still don’t understand the dollar sign notations you have used in that post, can you r plain it a bit more?

      1. Hey 🙂
        As said on Twitter, I use ES6 template literals.
        Feel free to contact me if you wish to update your blog post and need more explanations!

        1. Yes, thanks for sharing your blog post on Twitter. I’ll update my post and link it to your blog 🙂

          1. Thanks!
            I didn’t really use the tricks from my blog post for this, what I did is replace recurring parts of my code (“innerHTML” and ” onclick=”) with single char variables. The strikethrough is achieved using a deprecated String method .strike(). I could also use the deprecated HTML tag, but escaping it would have taken more chars.
            Congrats for the blog btw, very interesting!

          2. We removed 5 extra bytes from my 155 chars solution btw 🙂
            https://github.com/xem/minitodo

Leave a Reply to Rukshan Cancel reply

Your email address will not be published. Required fields are marked *