Swizec Teller - a geek with a hatswizec.com

    Using Backbone to improve multiselects

    Sometimes you need to ask a users for multiple answers to a single question. But what's the best way to go about it?

    Checkbox-field

    A multiselect input field is kind of strange for the user, sticks out and doesn't really behave like everything else on the web.

    A bunch of checkboxes is better for the user ... but have you ever tried handling a form with dynamically created checkboxes? Let alone creating useful tests and consolidating everything into a single list of values. No decent forms framework will let you do that easily.

    I had to solve this similar problem for a time and attendance software I worked on, so I made a Javascript thing to convert a select field into a checkbox-field. Then I made it into a simple jquery plugin thing for everyone to use :)

    Check out the demo!

    The idea is pretty simple:

    • take a select, turn it into a list of options
    • every option becomes a Checkbox model in a collection
    • render each Checkbox as a CheckboxView
    • connect everything with some events

    What I really love about the Backbone approach is that all of this works almost magically. Instead of bending over backwards to get checkboxes and the hidden multiselect synced up, all I had to do was create some models, some views and tell them how they are connected.

    This is how the field itself is created

    $multiselect.find("option").each(function (i, el) {
    var $el = $(el);
    // hidden behind the scenes here is that:
    // 1. creating a Checkbox, correctly binds together all needed events
    // 2. adding it to checkboxes, takes care of rendering and adding to the DOM
    checkboxes.add(
    new Checkbox({
    value: $el.val(),
    label: $el.html(),
    selected: $el.attr("selected"),
    })
    );
    });

    And to make sure data is synced up between its three representations (multiselect, visual checkboxes, the data structure itself), all it takes is this:

    var Checkbox = Backbone.Model.extend({
    initialize: function () {
    this.bind("change:selected", this.toggled);
    this.attributes.id = this.cid;
    },
    toggled: function () {
    var $opt = $multiselect.find("option[value=" + this.get("value") + "]");
    if (this.get("selected")) {
    $opt.attr("selected", "1");
    } else {
    $opt.removeAttr("selected");
    }
    },
    });

    Yep, that's the whole model and that's all it takes to sync everything up. Pretty cool huh? I remember trying to do this with just jQuery once ... I nearly stabbed my eyes out to end the misery.

    All in all the whole thing is just 123 sloc, which can only mean one thing: Backbone is cool.

    If you use my checkbox-field library, it's only going to be a single sloc for you:

    $("#my_selector").checkboxField();

    That's it :)

    Let me know what you think.

    Enhanced by Zemanta

    Did you enjoy this article?

    Published on April 13th, 2012 in Checkbox, HTML, JavaScript, jQuery, Languages, Programming, Scripts, Uncategorized, User interface,

    Learned something new?
    Read more Software Engineering Lessons from Production

    I write articles with real insight into the career and skills of a modern software engineer. "Raw and honest from the heart!" as one reader described them. Fueled by lessons learned over 20 years of building production code for side-projects, small businesses, and hyper growth startups. Both successful and not.

    Subscribe below 👇

    Software Engineering Lessons from Production

    Join Swizec's Newsletter and get insightful emails 💌 on mindsets, tactics, and technical skills for your career. Real lessons from building production software. No bullshit.

    "Man, love your simple writing! Yours is the only newsletter I open and only blog that I give a fuck to read & scroll till the end. And wow always take away lessons with me. Inspiring! And very relatable. 👌"

    ~ Ashish Kumar

    Join 15,883+ engineers learning lessons from my "raw and honest from the heart" emails.

    ⭐️⭐️⭐️⭐️✨
    4.5 stars average rating

    Have a burning question that you think I can answer? Hit me up on twitter and I'll do my best.

    Who am I and who do I help? I'm Swizec Teller and I turn coders into engineers with "Raw and honest from the heart!" writing. No bullshit. Real insights into the career and skills of a modern software engineer.

    Want to become a true senior engineer? Take ownership, have autonomy, and be a force multiplier on your team. The Senior Engineer Mindset ebook can help 👉 swizec.com/senior-mindset. These are the shifts in mindset that unlocked my career.

    Curious about Serverless and the modern backend? Check out Serverless Handbook, for frontend engineers 👉 ServerlessHandbook.dev

    Want to Stop copy pasting D3 examples and create data visualizations of your own? Learn how to build scalable dataviz React components your whole team can understand with React for Data Visualization

    Want to get my best emails on JavaScript, React, Serverless, Fullstack Web, or Indie Hacking? Check out swizec.com/collections

    Want to brush up on modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com

    Did someone amazing share this letter with you? Wonderful! You can sign up for my weekly letters for software engineers on their path to greatness, here: swizec.com/blog

    Want to brush up on your modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com

    By the way, just in case no one has told you it yet today: I love and appreciate you for who you are ❤️

    Created by Swizec with ❤️