volosoft / jtable

A JQuery plugin to create AJAX based CRUD tables.
http://www.jtable.org
1.1k stars 506 forks source link

Support for legacy REST Services #772

Open alperkose opened 11 years ago

alperkose commented 11 years ago

Currently, I am working on a legacy system with REST services that are being used. I want to use JTable for displaying the results from the REST service. Since the system is being used for some time, there is no possibility to change the format of the REST service responses. Is there a way to handle this situation and convert the responses to the JTable compliant format?

usoniajoe commented 10 years ago

I just started working with jTable today and have succeeded in consuming an existing RESTful API by virtue of jTable's ajaxSettings option. jTable passes this value to jQuery's ajax method whole, which means you can specify a "beforeSend" and/or a "dataFilter" handler as needed. The beforeSend handler provides an opportunity to set the request method, which I've made a prefix of each of the jTable action URLs. The dataFilter handler is passed (and expected to return) raw data, so I instead choose to wrap the success handler in my beforeSend to avoid having to unnecessarily parse and then (re)stringify the response.

Although you'll undoubtedly need to make changes for it to work with whatever API you're using, this excerpt should serve as a decent example:

$('#tableDiv').jtable(
{
  title: 'List of Resources',
  ajaxSettings:
  {
    dataType:'json',
    beforeSend:function(xhr, options)
    {
      if (options.url.match(/^(GET|POST|PUT|DELETE)>(.*)$/i))
      {
        options.type = RegExp.$1;
        options.url  = RegExp.$2;
      }

      if (options.data)
      {
        var data = unescapeQueryString(options.data);

        if (data.id) options.url += data.id;

        options.data = JSON.stringify(data);
      }

      var callback = options.success;

      options.success = function(input)
      {
        var output = { Result:input.status_code == 200 ? 'OK' : 'ERROR' }

        output[input.data instanceof Array ? 'Records' : 'Record'] = input.data;

        if (callback) callback(output);
      }
    }
  },
  actions:
  {
    listAction:     'GET>/api/v1/resources/',
    createAction:  'POST>/api/v1/resources/',
    updateAction:   'PUT>/api/v1/resources/',
    deleteAction:'DELETE>/api/v1/resources/',
  },
  fields:
  {
    /* ... */
  }
});

function unescapeQueryString(s)
{
  var i, obj = {};

  if (s.length)
  {
    var pairs = s.replace(/[+]/g, '%20').split('&');

    for (i = 0; i < pairs.length; i++)
    {
      var pair = pairs[i].split('=');

      if (pair[0])
      {
        obj[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
      }
    }
  }

  return obj;
}

Note that the ajaxSettings are tuned to a particular REST API, not necessarily a particular resource within. So, provided the API is consistent in its structure, you should be able to declare the settings once and pass a reference to them to multiple jTable instances that operate on various resources of the same API.

So far I am quite pleased with jTable and hope it continues!