In Meteor how can I create a generic event handler?

Viewed 5854

I want to create a generic event handler that I can reuse on dom elements so I don't have to write boiler plate over and over again. I thought I had it figured out but I am getting errors.

The problem I am having is that I think the event handlers are bound at a different time than I need. Maybe at document.ready? Where I think I need to attach them with the .live() method? Though I may have no idea what I am talking about here.

Here is what I am trying to do:

Multi page application.

Multiple collections where data needs to be inserted.

Button code to show the insert form.

<button id="btnShowInsert" class="btn btn-success" rel="tooltip" title="add group">
    <i id="btnIcon" class="icon-plus-sign icon-white"></i>
</button>

Template that shows the form based on the page (controller)

{{> groups_insert}}

Here is the form.

<template name="groups_insert">
    {{#if acl_check}}
    {{> alert}}
    < p>
      < form class="form-horizontal well hide" id="insert">
        <fieldset>
          < div class="control-group">
            < label class="control-label" for="name">Name</label>
            < div class="controls">
              < input type="text" class="input-xlarge" id="name" name="name">
            < /div>
          < /div>
          < div class="form-actions well">
            < button id="btnReset" type="reset" class="btn btn-large">Reset</button>
            < button id="btnSubmit" type="button" class="btn btn-primary btn-large">Submit</button>
          < /div>
        < /fieldset>
      < /form>
    < /p>
  {{/if}}
< /template>

Here is the client code to implement the button that shows the form on the page.

Template.groups.events[ Meteor.eventhandler.btn_events('#btnShowInsert') ] =  Meteor.eventhandler.make_btn_show_insert_form_click_handler();

Here is my generic event handler:

var EventHandler = Base.extend({
  btn_events: function(selector) {
    return 'click ' + selector; //, keydown '+selector+', focusout '+selector;
  },

  make_btn_show_insert_form_click_handler: function(){
    //var click = options.click || function () {};
    return function (event) {
      if (event.type === "click") {
        event.stopPropagation();
        event.preventDefault;
        try{
          if ($('#btnIcon').hasClass('icon-plus-sign') ) {
            $('#btnIcon').removeClass('icon-plus-sign');
            $('#btnIcon').addClass('icon-minus-sign');
          } else {
            $('#btnIcon').removeClass('icon-minus-sign');
            $('#btnIcon').addClass('icon-plus-sign');
          }

          $('#insert').slideToggle('slow', 'swing');

        } catch(error) {
          Alert.setAlert('Error', 'Critical Error: ' + error, 'alert-error');
        }
      }
    }
  },

});

Meteor.eventhandler = new EventHandler;

THE ERROR

Uncaught TypeError: Cannot call method 'btn_events' of undefined

BUT, if I define the event handler this way and call it this way it works.

Template.groups.events[ btn_events('#btnShowInsert') ] =  make_btn_show_insert_form_click_handler();

var btn_events = function (selector) {
  return 'click ' + selector; //, keydown '+selector+', focusout '+selector;
};


var make_btn_show_insert_form_click_handler = 
function () {
  //var click = options.click || function () {};
  console.log( Meteor.request.controller );

  return function (event) {
    if (event.type === "click") {
      event.stopPropagation();
      event.preventDefault;
      try{
        if ($('#btnIcon').hasClass('icon-plus-sign') ) {
          $('#btnIcon').removeClass('icon-plus-sign');
          $('#btnIcon').addClass('icon-minus-sign');
        } else {
          $('#btnIcon').removeClass('icon-minus-sign');
          $('#btnIcon').addClass('icon-plus-sign');
        }

        $('#insert').slideToggle('slow', 'swing');

      } catch(error) {
        Alert.setAlert('Error', 'Critical Error: ' + error, 'alert-error');
      }
    }
  }
};

The Problem
I don't want to have to replicate code all over my site in order to implement a nice button that can slideToggle and form on any page. If I could get it abstracted then I should be able to have a Show Form type of button on all pages for any collection that I am rendering that allows data entry. As well, this leads into being able to create one form handler for all forms as well and then tying them to the controller through an action to the model.

Any ideas?

4 Answers
Related