Backbone Model of Radio Button groups

preparing for WordPress Metaboxes

by helgatheviking

HTML

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>
<div id="sectionContainer" class="widefat fixed sortable">

  <p class="description">Sample Radio Button Groups</p>

  <!-- Template -->
  <script type="text/template" id="sectionTemplate" class="ui-state-default section">

    <label for="sections[<%= index %>][select][alpha]">
      <input id="sections[<%= index %>][select][alpha]" type="radio" name="sections[<%= index %>][select]" data-default="true" value="alpha" />Alpha
    </label>
    <label for="sections[<%= index %>][select][beta]">
      <input id="sections[<%= index %>][select][beta]" type="radio" name="sections[<%= index %>][select]" value="beta" />Beta
    </label>
    <label for="sections[<%= index %>][select][gamma]">
      <input id=for="sections[<%= index %>][select][gamma]" type="radio" name="sections[<%= index %>][select]" value="gamma" />Gamma
    </label>
    <br />

  </script>
  <!-- End template -->

</div>

CSS

.section {
  padding: 1em;
  border: solid 1px #ddd;
  background-color: #fdfdfd;
  margin-bottom: 1em;
}

.section textarea {
  width: 99%;
}

.section label {
  display: block;
}

.section .section-control {
  float: right;
  font-size: .75em;
}

.section input[type="text"] {
  display: block margin-bottom: 1.4em;
}

#sectionContainer .dashicons-before {
  vertical-align: middle;
}

.js .section .handle {
  cursor: move;
}

JavaScript

var Repeating_Meta = Repeating_Meta || {};

(function($, Repeating_Meta) {

  // Model
  Repeating_Meta.Section = Backbone.Model.extend({
    defaults: {
      'input': '',
      'select': 'alpha',
      'textarea': ''
    },
  });

  // Collection
  Repeating_Meta.SectionsCollection = Backbone.Collection.extend({
    model: Repeating_Meta.Section
  });

  // List View
  Repeating_Meta.sectionListView = Backbone.View.extend({

    render: function() {

      this.$el.empty();

      this.collection.each(function(model) {
        var section = new Repeating_Meta.sectionView({
          model: model
        });
        this.$el.append(section.render().$el);
      }, this);

      return this;
    }

  });

  // Singular View
  Repeating_Meta.sectionView = Backbone.View.extend({

    model: Repeating_Meta.Section,
    tagName: 'div',
    className: "ui-state-default section",

    // Get the template from the DOM
    template: _.template($('#sectionTemplate').html()),

    events: {
      'change input[type="radio"]': 'updateRadio',
    },

    initialize: function(e) {

    },

    // Render the single input - include an index.
    render: function() {
      this.model.set('index', this.model.collection.indexOf(this.model) + 1);
      this.$el.html(this.template(this.model.attributes));
      this.setState();
      return this;
    },

    setState: function() {

      var index = Repeating_Meta.sectionCollection.indexOf(this.model) + 1;
      var value = this.model.get('select');

      if (value) {
        $(this.el).find('input[name="sections[' + index + '][select]"]').filter('[value="' + value + '"]').prop("checked", true);
      }

    },

    updateRadio: function(e) {
      this.model.set({
        radio: $(e.currentTarget).val()
      });
    },
  });


  // init
  Repeating_Meta.init = function() {

    var meta1 = new Repeating_Meta.Section({
      input: 'test',
      select: 'alpha',
      textarea: 'some text'
    });
    var meta2 = new...