Search code examples
javascriptjqueryractivejs

Ractive JS and jquery plugins - accessing / manipulating data


Following on from this discussion: RactiveJS and jQuery plugins I was able to wrap a jquery plugin into a ractive decorator. You'll see I hardwire / manipulate the data array with the line data.resources.splice(newIndex, 0, data.resources.splice(oldIndex, 1)[0] );

This is brute force. Ideally, I'd like to be able to retrieve the keypath from the node.

I'm having difficulty trying to figure out how I can get the keypath used by the selected node... It is populated by data.resources. I've tried ractive.get() - but that returns everything from the root ('data').

Is there a method that will return ('data.resources')

var sorttable = function (node) {

  var oldIndex;
  var newIndex;
  $(node).sortable({
  containerSelector: 'table',
  itemPath: '> tbody',
  itemSelector: 'tr',
  placeholder: '<tr class="placeholder"/>',
  onDragStart: function ($item) {
    oldIndex = $item.index();
      console.log(oldIndex , newIndex);
  },
  onDrop: function  ($item) {
    newIndex = $item.index();
    if(newIndex != oldIndex) {
      console.log(oldIndex , newIndex);
      data.resources.splice(newIndex, 0, data.resources.splice(oldIndex, 1)[0] );
    }

  }
});
  return {
    teardown: function () {
      $(node).sorttable('destroy');
    }
  };
};

Ractive.decorators.sortable = sorttable;

***** EDIT *****

    var sorttable = function (node) {

  var oldIndex;
  var newIndex;
  $(node).sortable({
  containerSelector: 'table',
  itemPath: '> tbody',
  itemSelector: 'tr',
  placeholder: '<tr class="placeholder"/>',
  onDragStart: function ($item) {


    oldIndex = $item.index();
      console.log(oldIndex , newIndex);
  },
  onDrop: function  ($item) {
    newIndex = $item.index();

    var info = $item.context.parentNode;
    info = Ractive.getNodeInfo(info);
    var sourceKeypath = info.keypath;


    var lastDotIndex = sourceKeypath.lastIndexOf( '.' );
    var sourceArray = sourceKeypath.substr( 0, lastDotIndex );


    if(newIndex != oldIndex) {
      console.log(oldIndex , newIndex);
      data[sourceArray].splice(newIndex, 0, data[sourceArray].splice(oldIndex, 1)[0] );
    } 

  }
});
  return {
    teardown: function () {
      $(node).sortable('destroy');
    }
  };
};

I had to do some weird traversal due to how I set things up... I had to find the TR, and from that I was able to get the keypath. However, I still have to put in 'data.' before... so just got to figure that bit out now.

***** EDIT 2 - this works! *****

    var sortTable = function (node) {

  var oldIndex;
  var newIndex;
  $(node).sortable({
  containerSelector: 'table',
  itemPath: '> tbody',
  itemSelector: 'tr',
  placeholder: '<tr class="placeholder"/>',
  onDragStart: function ($item) {
  // Get index of our 'grabbed' item
    oldIndex = $item.index();
      console.log(oldIndex , newIndex);
  },
  onDrop: function  ($item) {
    // Get index of our 'dropped' item
    newIndex = $item.index();
    // Get the parentNode (this would be the tr)
    var info = $item.context.parentNode;
    // Then get all the Ractive info about this TR (gives us the keypath etc)
    info = Ractive.getNodeInfo(info);
    // Put the keypath into its own variable
    var sourceKeypath = info.keypath;

    // The keypath returns the array, plus the index of the item.
    // We don't need the index - only the name of the array
    var lastDotIndex = sourceKeypath.lastIndexOf( '.' );
    var sourceArray = sourceKeypath.substr( 0, lastDotIndex );
    // We need the parentObj so we can do parentObj[sourceArray]
    // nb: data[resources]
    // So grab the parent, and stick it into its own var
    var parentObj = ractive.get( sourceKeypath.parent );

    // Then update the array with the new order here
    if(newIndex != oldIndex) {
      console.log(oldIndex , newIndex);
      parentObj[sourceArray].splice(newIndex, 0, parentObj[sourceArray].splice(oldIndex, 1)[0] );
    } 

  }
});
  return {
    teardown: function () {
      $(node).sortable('destroy');
    }
  };
};    

Solution

  • var info = Ractive.getNodeInfo(node);
    

    (See: http://docs.ractivejs.org/latest/ractive-getnodeinfo)

    gives you { ractive: instance, keypath: keypath, index: indices } where keypath is the context of the node which if it were in an {{#each}} would be something like resources.0.

    You could then do something like:

        lastDotIndex = sourceKeypath.lastIndexOf( '.' );
        sourceArray = sourceKeypath.substr( 0, lastDotIndex );
        sourceIndex = +( sourceKeypath.substring( lastDotIndex + 1 ) );
    

    to get the array (above is from ractive-decorators-sortable)