0

I run this code in the console in Chrome and it works, when I push the code up to staging, it doesn't work. All other functions in the file work fine. Scoping issue? I'm learning JavaScript. Any insight appreciated!

  $('#excheck').change(function() {
    console.log('checked!');
    exEnableContinue();
  });

  function exEnableContinue() {

      var button = $('.ex-button');

      if ($('#excheck').prop('checked') === true) {

        button.removeAttr('disabled');
        button.addClass('available');
      } else {
        button.removeClass('available');
      }


      button.on('click', function (e) {
        console.log('button clicked');
        processLineItem();
      });

  }

For more context, here's all the contents of the file cartbench.js:

/**
 * The drawer page containing any functionality related to adding a license to
 * the cart object. This differs from mm.DrawerCartPage.
 * @public
 * @extends {mm.DrawerPage}
 * @return {Object} mm.DrawerCartbenchPage
 */
mm.DrawerCartbenchPage = function () {
  'use strict';

  var self = mm.DrawerPage($('.mm-drawer-wrap #cartbench')),
      form,
      $buckets,
      $licenses,
      _licenseID,
      _pendingTrackID,
      _remove = false,
      _pendingTrack;

  /**
   * Fetch the parsed template from the server showing the proper grouping of 
   * licenses and options.
   * @private
   */
  function fetchTemplate(callback) {
    mm.drawer.spin(true);
    $.get('/tracks/licenses/'+_pendingTrackID)
      .done(function (data) {
        self.$el.html(data);
        self.rebuild();
        mm.drawer.spin(false);
        if (typeof callback === 'function') callback();
      });
  }

  /**
   * With both the license_id and track_id set, submit a POST request to the
   * server and hydrate the mm.cart object with the response.
   * @private
   */
  function processLineItem() {
    var item = {
      line_item: {
        track_id: _pendingTrackID,
        license_id: _licenseID
      }
    };
    mm.drawer.spin(true);
    if (_remove) {
      mm.drawer.trigger('cart:remove', function () {
        process(item);
      });
    } 
    else {
      process(item);
    }
  }

  function process(item) {
    $.post('/add-to-cart', item)
      .done(function () {
        mm.user.cart.hydrate(function () {
          mm.drawer.spin(false);
          mm.drawer.delay = false;
          mm.drawerProxy.trigger('cart');
        });
      })
      .fail(function (data) {
        console.error(data);
      });
  }


  $('#excheck').change(function() {
    console.log('checked!');
    exEnableContinue();
  });

  function exEnableContinue() {

      var button = $('.ex-button');

      if ($('#excheck').prop('checked') === true) {

        button.removeAttr('disabled');
        button.addClass('available');
      } else {
        button.removeClass('available');
      }


      button.on('click', function (e) {
        console.log('button clicked');
        processLineItem();
      });

  }


  /**
   * Extends base self.hide method to reset our track and license id's
   * @public
   * @return {Object} mm.drawerCartbenchPage
   */
  var superHide = self.hide;
  self.hide = function () {
    _pendingTrackID = null;
    _licenseID = null;
    _remove = false;
    superHide();
    if(!_.isUndefined(form)){ form.reset(); }
    return self;
  };

  /**
   * Extends base self.rebuild method, sets and rebinds drawer specific
   * elements.
   * @public
   * @return {Object} mm.drawerCartbenchPage
   */
  var superRebuild = self.rebuild;
  self.rebuild = function () {
    superRebuild();
    $buckets = $('[data-bucket-targ]', self.$el); 
    $licenses = $('.license', $buckets);

    var trackExStatus = _pendingTrack.exclusive;
    var localNestLinks = $('.local-nest', self.$el);

    self.$nestLinks.on('click', function (e) {
      e.preventDefault();
      console.log(trackExStatus);
      var targ;
          if (trackExStatus === true) {
            targ = 'exclusive';
            console.log("made it here.....");
          } else {
            targ = $(this).attr('data-bucket') 
          }
          console.log(targ);
      var bucket = $('[data-bucket-targ="'+targ+'"]', self.$el);
      $buckets.not(bucket).removeClass('active');
      bucket.addClass('active');


    });

    localNestLinks.on('click', function (e) {
      e.preventDefault();
      var targ = $(this).attr('href').replace(/^#/, '');
      mm.drawer.delay = false;
      mm.drawer.setState(targ);
    });


    $licenses.on('click', function (e) {
      e.preventDefault();
      _licenseID = $(this).attr('data-license-id');
      $licenses.off('click');


      processLineItem();


      // "When a track is licensed & what type"
      var license_name = $(this).data("license-name");
      var track_name = _pendingTrack && _.has(_pendingTrack, "display_name") ? _pendingTrack.display_name : "";
      var trackObject = _pendingTrack;
      console.log(license_name, track_name);
      console.log(trackObject);
      _gaq.push(['_trackEvent', 'Track', 'License', track_name, license_name]);
    });

    return self;
  };

  /**
   * Extends base self.show method, checks for payload (track_id) and fetches
   * the template if it exists.
   * @public
   * @return {Object} mm.drawerCartbenchPage
   */
  var superShow = self.show;
  self.show = function (payload, remove) {
    _remove = remove;
    if (payload && _.has(payload, "id")) {
      _pendingTrack = payload;
      _pendingTrackID = payload.id;
      console.log(_pendingTrack);
      fetchTemplate(function () {
        form = mm.DrawerForm($('.mm-drawer-form', self.$el), {
          url: '/tracks/'+_pendingTrackID+'/customize_license',
          type: 'POST',
          empty: true
        });
        form.reset();
        form.$inputs.on('focus', function (e) {
          var that = this;
          $(that).on('keydown keyup', function (evt) {
            if (that.value.length > 0) {
              form.$submit.addClass('available').removeAttr('disabled');
            } else {
              form.$submit.removeClass('available').attr('disabled', true);
            }
          });
        });
      });
    }
    superShow();
    return self;
  };

  return self;

};

HTML.ERB file

<section class="root">
  <hgroup>
    <h1>License Track</h1>
    <h2>Select the appropriate license and add it to your cart. Once you've gathered all of your licenses, continue to checkout.</h2>
  </hgroup>
  <ul>
    <% @buckets.each do |bucket| %>
      <li>
        <a data-prevent-default class="bucket nest button-box" data-bucket="<%= bucket[:name] %>">
          <span class="name"><%= bucket[:name] %></span>
          <span class="price"><%= bucket[:price] %></span>
          <span class="icon"></span>
        </a>
      </li>
    <% end %>
  </ul>
  <p>Need some help? Or maybe you're not seeing all of the usual options? Tell us exactly what you need and we'll craft a license and terms to fit your project.</p>
  <a data-prevent-default class="nest button-box" data-bucket="custom">
    <span class="name">Custom License</span>
    <span class="icon"></span>
  </a>
</section>

<section id="options" class="nested">
  <% @buckets.each do |bucket| %>
    <% licenses = @track.licenses.where(name: bucket[:name]) %>
    <div data-bucket-targ="<%= bucket[:name] %>">
      <hgroup>
        <h1><%= bucket[:name] %></h1>
        <% if licenses.first.description.present? %>
          <h2><%= licenses.first.description.gsub(/[\n]/, "<br/>").html_safe %></h2>
        <% end %>
      </hgroup>
      <ul>
        <% licenses.each do |license| %>
          <li>
            <a data-prevent-default class="button-box license" data-license-name="<%= license.name %>" data-license-id="<%= license.id %>">
              <span class="range"><%= license.range.present? ? license.range : license.name %></span>
              <span class="price"><%= number_to_currency license.price %></span>
              <span class="icon"></span>
            </a>
          </li>
        <% end %>
      </ul>
      <p>Not finding the right license option? Tell us exactly what you need and we'll craft a license and terms to fit your project.</p>
      <a data-prevent-default class="nest button-box" data-bucket="custom">
        <span class="name">Custom License</span>
        <span class="icon"></span>
      </a>
    </div>
  <% end %>

  <div data-bucket-targ="custom">
    <hgroup>
      <h1>Custom License</h1>
      <h2>We can craft you a license for any use you can imagine. Share with us your specific project details such as client, film content, media use and lifespan and lets get the ball rolling.</h2>
    </hgroup>
    <div class="mm-drawer-form">
      <div class="errors">
        <div>Please fill out the form below.</div>
      </div>
      <div class="success">
        <p>Thanks! A Marmoset representative will contact you shortly with more information about your request.</p>
      </div> 
      <form data-scope="none">
        <input type="text" placeholder="Your Name" name="sender_name">
        <input type="email" placeholder="Your Email" name="sender_email"> 
        <textarea placeholder="Tell us about your custom license needs and we'll be in touch within 24 hours to continue the dialog." id="notes" name="notes"></textarea>
        <div class="spin-targ">
          <button type="submit" class="box-button-black" disabled="true">Submit</button>
        </div>
      </form>
    </div>
  </div>

  <div data-bucket-targ="exclusive">
    <hgroup>
      <h1>Exclusivity</h1>
      <h2>It looks like this track has some exclusivty to the <strong><%= @track.exclusive_industry %> </strong>industry. This means someone decided they wanted this track to be completely special and unique to their project. If you are hoping to license this track and are in the same industry, we may have to find you another track that enhances your project. If you are not in the same industry, carry on, and enjoy!</h2>
    </hgroup>
    <div class="checkbox-exclusive">
      <input type="checkbox" name="agreement" id="excheck">
      <label for="agreement"></label>
      <p id="excheck-text">My project is not in conflict with this track's exclusivity</p><br><br>
    </div>
    <div class="spin-targ">
      <button type="submit" class="ex-button box-button-black" disabled="true">Continue</button>
    </div>
  </div>

</section>

EDIT:

As soon as I go to the page, or refresh the browser, and run this in the console:

if(document.getElementsById("excheck")){
    alert("Element exists");
} else {
    alert("Element does not exist");
}

it alerts "Element exists", so I know it's there in the DOM. I still don't understand why I can't select it from my JS file.

Ryan Rebo
  • 1,168
  • 1
  • 10
  • 22

1 Answers1

0

The key was event delegation. The HTML was being dynamically added after the JS had already loaded. Thanks for the help guys, getting me pointed in the right direction.

  $(document).on('change', '#excheck', function(e) {
      console.log('checkbox clicked!');
      exEnableContinue();
  });

    function exEnableContinue() {

        var button = $('.ex-button');

        if ($('#excheck').prop('checked') === true) {
          console.log('checked!');
          button.removeAttr('disabled');
          button.addClass('available');
        } else {
          console.log('not checked!');
          button.removeClass('available');
        }


        button.on('click', function (e) {
          e.preventDefault();
          console.log('button clicked');
          processLineItem();
        });

    }
Ryan Rebo
  • 1,168
  • 1
  • 10
  • 22