Skip to content

Instantly share code, notes, and snippets.

@F-3r
Last active January 2, 2016 07:49
Show Gist options
  • Save F-3r/8272362 to your computer and use it in GitHub Desktop.
Save F-3r/8272362 to your computer and use it in GitHub Desktop.
Client side functionality for Rack::MethodOverride using plain Vanilla Javascript.

This attempt is fairly easy, creates a form which takes href of the link as action, method is always POST and adds the _method param. The link onclick's, prevents the default event functionality and submits such form instead.

//method_override.js

methodOverride = function(){
  handler = function(event){
    event.preventDefault();

    form = document.createElement('form');
    form.action = this.href;
    form.method = 'post';
    form.innerHTML = '<input name="_method" value="'+ this.dataset.method + '">';

    form.submit();
  };
  
  linkSelector = 'a[data-confirm]';
    
  document.querySelectorAll(linkSelector).forEach(function(link){
    link.addEventListener('click', handler);
   });
}();

A simple core extension to allow a NodeList to have same forEach iterator as Arrays (lazynessss...)

//core_ext.js

NodeList.prototype.forEach = function(iterator) {
  for(i = 0; i < this.length; i++){
    iterator(this.item(i));
  }
}

In order to add a user confirmation before submitting, another script may be added. The only caveat is the confirmation handling script must be required and used before the method override. (This was tested on fiefox and chrome and works, IE? who knows...)

//confirmation.js
      
confirmation = function(){
  handler = function(event){
    if(!confirm(this.dataset.confirm)){
      event.cancel = true;
      event.cancelBubble = true;
      event.preventDefault();
      event.stopImmediatePropagation();
    }
  };
  
  linkSelector = 'a[data-confirm]';
  
  document.querySelectorAll(linkSelector).forEach(function(link){
    link.addEventListener('click', handler);
  });
}();

So a simple example usage could be:

<html>
  <body>
    <ul>
      <li><a href="#confirm-method" data-method="get" data-confirm=""> GET Google</a></li>
      <li><a href="#method" data-method="post"> POST Google </a></li>
      <li><a href="http://www.google.com" data-method="put"> PUT Google </a></li>
      <li><a href="http://www.google.com" data-method="delete"> DELETE Google </a></li>
      <li><a href="#">no data-method, no data-confirm</a></li>
      <li><a href="#">no data-method, no data-confirm</a></li>
      <li><a href="#">no data-method, no data-confirm</a></li>
    </ul>
    
    <script src="core_ext.js"></script>
    <script src="confirmation.js"></script>
    <script src="method_override.js"></script>
  </body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment