开发者

Jquery persistent sortable objects in Drupal?

I'm working on a project in drupal that allows me to have visual bookmark screenshots (think zootool.com). I have each screenshot in a grid that is using jQuery to be sortable. This all works correctly and I can sort all the images into whatever order I wish. The only problem is that I can't save the locations/order that I've just changed them to.

I have used the 'weight' module to assign a default value to each screenshot and this is output using Views sorted by this 'weight'. Therefore I need to have a mechanism to update/save the weight order of all the nodes when I move them with jQuery.

Currently I have the jQuery code that outputs an alert box with the new order:

//Draggable boxes
$(function() {
    $( ".sortable-nodes" ).sortable({
        placeholder: "ui-state-highlight",
        opacity: 0.7,
        update: function(event, ui) {
                    var result = $(this).sortable('toArray');
                    alert(result);
                 }
    });
});

My question is this: Does Drupal already have a page I can use to update the nodes through jQuery.post or do I have to make my own one that will save the nodes? Also, is this the right way to go or is there a better 开发者_如何学运维way to update/save the node positions once the sortable box has been moved?

Many Thanks!


Ok, I thought I'd follow up my question with the solution I've found. It may help others. It's based heavily on the answer that googletorp gave to the very similar question posted here: Drupal 6/jQuery Ajax update a field.

Step 1.0 Create a new module. I created a simple updatemynode.info file and updatemynode.module file.

1.1 updatemynode/updatemynode.module contains two functions.

function updatepos_menu() {

    $items = array();
    $items['update_positions'] = array(
        'page callback' => 'update_node_position',
        'type' => MENU_CALLBACK,
        'access callback' => TRUE,
        'access arguments' => array('access content'),
    );
   return $items;
}

This is the first function in the module that creates a URL www.mywebsite.com/update_positions which calls the php function 'update_node_position'. (see below)

1.2 updatemynode/updatemynode.module second function is:

   function update_node_position() {
    // Create an array from the passed string
    $neworder = explode(",", $_POST['theorder']);

    // For each array entry, redo their node weight (which Views sorts on)
    foreach ($neworder as $key => $value){
        $node = node_load($value);
        $node->node_weight = ($key+1);
        node_save($node);
    }
}

For brevity and simplicity I have removed any error checking to it just completes a function and that's it. Basically, it does the following: A. Search for the $_POST['theorder'] variable (which contains a string of NID's in my app), use php 'explode' to convert the string to an array and assign to $neworder. B. For each entry of new array, use the value (NID) to load that Node. C. I'm using the 'Weight' module to create ordering. The $node->node_weight = ($key+1); line assigns the position in the array 1,2,3,4,etc.. to the node wight. (Thus creating an order). D. Save the node and repeat for each entry in array.

2.0 I have a main_javascript.js file that is attached to all of my drupal pages. This javascript file contains the following code:

$(function() {
  $( ".sortable-nodes" ).sortable({
    placeholder: "ui-state-highlight",
    opacity: 0.7,
    update: function(event, ui) {

      // Create result variable that contains array order.
      var result = $(this).sortable('toArray');

      // Run AJAX function with RESULT data to update_positions page

      $.ajax({
        type: "POST",
        url: "/update_positions",
        // Pass the RESULT array
        data: { theorder : [result]},     
      });                   
    }
});

This is the crux of the jQuery and it does a few bits:

2.1 The object (which is a DIV in my case) labelled .sortable-nodes is made sortable using the jQuery 'sortable' method. When I click and drag the DIV it will do this:

2.2 Use the CSS class 'ui-state-highlight' in between each sortable DIV.

2.3 Reduce the opacity to 70%.

2.4 Once the position has been changed then it will run the 'update' event.

2.5 The 'update' event will create a variable called 'result' that contains a string of all the sortable object node id's . (eg. 113,114,115,116,117,etc... )

2.6 The .ajax method is run and is told to send a POST request to the /update_positions URL (created earlier in the updatemynode/updatemynode.module file) and pass the $_POST variable called 'theorder' which contains the string 'result'. Once the string 'result' is passed to the URL then the module function update_node_position() uses this string and does its magic as explained above.

3.0 My results on the page are ordered by the node weight using views. So, when the page is reloaded the order should stay the same as how you ordered it (because the node_weight has been updated) using the AJAX call.

Hope that maybe helps someone. Any questions/comments welcome!


Drupal doesn't already have this sort of functionality, unless you'd count using the Services module over jsonp which would take longer to setup than implementing the functionality yourself would.

In my opinion there isn't any better way to do this, any contributed module you could find to do it would likely be very bloated with lots of functionality you don't need. It's so easy to perform a post to a custom menu item that I'd recommend just doing that. You'll also have full control over the code then and can optimise it as you wish.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜