4

I am using one meta box for each image in a custom post type, and I would like to use the drag and drop functionality to allow the client to easily reorder them, the problem is when one custom post is reordered, the others are reordered as well... Is there any way that each post has it's own order?

Where is the order of the meta boxes saved?

Are there any filters I could use to modify the behavior for a particular post type?

Thanks a lot in advance! Gioia

  • I think WordPress architecture is in a manner that is not possible to change the order of metaboxes for each post(default or custom post type). But it is possible with PHP,HTML & CSS. – sri Jun 17 '14 at 12:16
  • 2
    Answering my own question, the order is saved in the user meta table. I have come to the conclusion that although it might be possible to change this behaviour, it would be too much trouble, and probably even would not be such a good idea to change something that is expected behaviour. At the end I solved it making sortable field groups, which in the long run is a more flexible solution. – Gioia Fueter Jun 18 '14 at 13:58
  • You could answer your own question. Explain what you did in your scenario if you can! You get some reputation too :) – sri Jun 18 '14 at 14:47
5

As suggested by sri, I will answer my own question :)

The drag and drop of the meta boxes is for remembering the order of the meta boxes for each user, so if user A like to have meta box 5 on top because he uses that feature more, he doesn't have to do move the meta box every time. I decided that changing that behaviour was not a good idea, as users who know of that behaviour could get confused. Also would mean messing around with the database.

So I instead used the already built in jquery ui sortable to make my custom fields sortable. I created a container div for the sortable fields area, with an id "sortable", then added a table for each field group (I wanted a group of fields to be sortable, not individual fields). Then a tr for each field. One of the custom fields in each table I used to save the order as a post meta.

<div id="sortable">
    <table>
        <tr><th class="title">My title</td></tr>
        <tr><td>Code postfield 1 - 1</td></tr>
        <tr><td>Code postfield 1 - 2</td></tr>
        <tr><td><input name="ordering_1" type="hidden" class="ordering" value="$meta"></td></tr>
    </table>
    <table>
        <tr><th class="title">My title</td></tr>
        <tr><td>Code postfield 2 -1 </td></tr>
        <tr><td>Code postfield 2 -2</td></tr>
        <tr><td><input name="ordering_2" type="hidden" class="ordering" value="$meta"></td></tr>
    </table>
</div>

Of course this is a over-simplification, as I use arrays to generate the postfields codes, but just to show the structure.

Then I added the javascript:

To add a value to the order custom fields based on their position:

$("#sortable > table").each(function(index) {
    console.log(index+1);
    var count = index+1;
    $(this).find(".ordering").val(count);
}) 

To make the tables sortable. I had to add the handle to the title, otherwise, trying to upload a file started the dragging mode:

$("#sortable").sortable({ 
    cursor: "move", 
    containment: "parent",
    cursorAt: { left: -5,top:-5 },
    distance: 10,
    handle:"th.title"
});

Then to update the order as I drag and dropped:

$('#sortable').on("sortstop", function( event, ui ) {
    $("#sortable > table").each(function(index) {
        console.log(index+1);
        var count = index+1;
        $(this).find(".ordering").val(count);
    }) 
} );

The final thing was to order the tables based on my custom order. I modified the code:

<div id="sortable" style="float:left">
    <? $field_groups = array();
    if (get_post_meta($post->ID,"order_eng_1_1",true)) {
        for ($i = 1; $i <= 20; $i++){
            $field_groups[get_post_meta($post->ID,"order_eng_".$i."_1",true)] = $i;
        }
        ksort($field_groups);
        foreach ($field_groups as $field_order => $field_id) {?>
            <table class="form-table dropable">
                <tr>
                    <th class="title">My Title <?= $field_order?></th>
                </tr>
                <tr><td>Code postfield 1 - 1</td></tr>
                <tr><td>Code postfield 1 - 2</td></tr>
                <tr><td><input name="ordering_1" type="hidden" class="ordering" value="$meta"></td></tr>
            </table>
         <? }
    } else {
        for ($i = 1; $i <= 20; $i++) {?>
            <table class="form-table dropable">
                <tr><th class="title">My title <?=$i?></th></tr>
                <tr><td>Code postfield 1 - 1</td></tr>
                <tr><td>Code postfield 1 - 2</td></tr>
                <tr><td><input name="ordering_2" type="hidden" class="ordering" value="$meta"></td></tr>
            </table>
         <? }
     }?>
</div>

This is my first time trying to explain my code, it's probably not comprehensive at all, so anything I can do to make it more clear, suggestions are very welcome ;)

|improve this answer|||||
  • 3
    Good on you for answering your own question, unanswered questions provide no real value to the community, so whether you are answering someone else' question or your own - it's all valuable. – Adam Jun 19 '14 at 6:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.