SortableSidebar : a custom input tv to manage sidebars for Evolution 1.05

 

Easily manage the sidebar of your website via drag and drop.

Watch the screencast.  Tip Watch it fullscreen so that you can easily view the code.

1.1.12-The download has been updated (with the generous help of Stefan the developer of the categorized_tv_tabs plugin so that they play nicely together.

Inside the zip is another version of the same plugin which Stefan created that uses mootools instead of jQuery ui to accomplish the same thing.  His version is a big improvement because it allows you to use more more than one of these custom sortable tvs per page whereas mine only allows you to use it once.  His version pulls the chunk category from the tv's decription field wheras mine is hardcoded in the customtvSort.php file.  Take your pick.  They are both cool.

If you use his plugin categorized_tv_tabs, you also need to change the ondocformrender.phtml file which is included in the zip file, which is located in assets/plugins/tv_categorized_tabs  directory

Download the zip file → customSort.zip 59 downloads

 

I have always wanted an easier way to maintain sidebar content for my clients. I had this idea where clients would be able to see the names of all the available sidebar chunks to choose from and then be able to select some to output and then be able to drag and drop sort them in the desired order. It seemed totally intuitive. Only problem was that it was difficult for the non developer.

Years have passed.

MODX implemented the custom TV input type for evolution 1.05. I heard about it, but never had the time to devote to it until now.

I watched ChuckTrucks amazing Youtube screencast and had also read Splitting Red's tutorial on the old modx wiki. I had also played with and implemented Temus' plugins to add multiphotos to a document. His tutorial had been translated into English by Sharkbait at www.kunane.com. I have sinced played around with a lot of permutations and have something to share with you.

It is rough.

It works.

I hope that you use it, improve it and then share your improvements with the community.

You will have to create one tv, one snippet with attached code and you will be good to go.

Here is how to implement it:

1. Create new tv named ourCustomTv

2. Give it the following values:
caption : sidebar
Input Type: Custom Input
Input Option Values: @INCLUDE manager/tvs/customtvSort.php
Widget: Delimited List, delimiter is comma
If you are using Stefan's version, put "category: sidebar" minus the quotes in the tv's description field.

3. Link this new tv to template you'd like to have sidebar chunks output to.

4. Create a new chunk category called "sidebar".

5. Create a snippet named chunkParser and paste in the following code which is attached in the zip file:

$ar_chunks = explode(',',$chunks);
$ar_chunks = array_unique($ar_chunks);

$output = '';

foreach ($ar_chunks as $chunk) {
if ($chunk != '') {
$c = $modx->getChunk($chunk);
if ($c) $output .= $c;
}
}

if ($output != '' && isset($wrapperdiv)) {
$output = '<div id="'.$wrapperdiv.'">'.$output.'</div>';
}

return $output;


6. call it like this:

[!chunkParser?chunks=`[*ourCustomTv*]` &wrapperdiv=`sidebarChunks`!]

where [*ourCustomTv*] is the name of the custom TV and wrapperdiv is the name of the div that you want the output to be wrapped in.

You could also modify the snippet code below to change:

if ($output != '' && isset($wrapperdiv)) { $output = '<div id="'.$wrapperdiv.'">'.$output.'</div>';

To:

if ($output != '') { $output = $output;

And the chunks would be output in the place where the snippet is called without being wrapped in a div. In this case you would call the snippet like:

[!chunkParser?chunks=`[*ourCustomTv*]`!]

7. Download the zip file → customSort.zip 59 downloads

and extract it in the root level of your site. I have included the files needed to get this to work.

8. If you don't want to download zip, paste code below into file named 'customtvSort.php' and save it in manager/tvs:

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script>
<script>
$.noConflict();
jQuery(function() {
    jQuery('#sortable').sortable({placeholder: 'ui-state-highlight',axis:'y'});
    jQuery('#sortable').disableSelection();
    jQuery('#sortable li').filter(':has(:checkbox:checked)').addClass('selected').end().click(function(event) {
        if (event.target.type !== 'checkbox') {
            jQuery(':checkbox', this).trigger('click');
        }
    }).find(':checkbox').click(function(event) {
        jQuery(this).parents('li:first').toggleClass('selected');
    });
    jQuery('input[type=checkbox]').click(function(){
        jQuery(this).parent('li').toggleClass('checked');
    })
});

</script>
<style type="text/css" media="all">
li.checked, li.selected {background: #CFEFC6;}
ul#sortable li {cursor: move;padding: 0.5em 0;width: 250px;margin: 0.5em 0;list-style:none!important; border: 1px solid #cccccc;}
.ui-state-highlight { height: 2.5em; line-height: 1.2em; background-color: yellow; }
ul#sortable {list-style: none;}
ul#sortable li:hover {background: #9DE288}
</style>

<?php
$category = 'sidebar'; // I used sidebar for configurable name of chunk category to pull chunks from.
echo'<p><strong>click on list Item to select / deselect.  Drag and drop to sort.  Click Save.</strong></p>';
echo '<ul id="sortable">';
$selected_values = explode('||', $row['value']);
$selected        = array();
$not_selected    = array();
if ($selected_values[0] == '') {
} else {
    foreach ($selected_values as $set) {
        echo '<li class="checked"><input value="' . $set . '" name="tv' . $field_id . '[]" style="" onchange="documentDirty=true;" type="checkbox"';
        echo 'checked="checked"';
        echo '>';
        echo '<label>' . $set . '</label></li>';
    }
}
$q_chunks  = $modx->db->query('SELECT chunk.* FROM ' . $modx->getFullTableName('site_htmlsnippets') . ' AS chunk INNER JOIN ' . $modx->getFullTableName('categories') . ' AS category ON chunk.category = category.id WHERE category.category IN ("' . $category . '") ORDER BY name');
$ar_chunks = array();
while ($row = $modx->db->getRow($q_chunks)) {
    $ar_chunks[] = $row['name'];
}
foreach ($ar_chunks as $set) {
    if (in_array($set, $selected_values)) {
    } else {
        echo '<li class="unchecked"><input value="' . $set . '" name="tv' . $field_id . '[]" onchange="documentDirty=true;" type="checkbox"';
        
        echo '>';
        echo '<label>' . $set . '</label></li>';  
    }
}
echo '</ul>';
?>

9. Set up category name in variable name above.
Remember it must appear exactly like the name of the chunk category you created in step 4;
Any chunk that you want the dynamic menu to pull from needs to be put in this category.

10. You can select one to activate and drag and drop sort them and click save. The selected options should be saved in the order you saved them in.
11. Hit preview the page and you will see the chunks output on the page.
12. Boat drinks all around!!

Known Limitations

This code can only be used once per document.  If you want to be able to use it more than once per document you need to use Stefan's version and you need to use multiple chunk parser snippet calls (from step 6) in the template code with each one pointing to a separate custom TV.  This too looks like a part of the code that can be refactored.

The code could be improved and I'm sure you will.

I only ask you share your improvements with the rest of us!

Download zip now → customSort.zip 59 downloads


Comments (6)

  1. Default Admin User:
    Dec 28, 2011 at 04:20 AM

    I hope you all found this to be useful. I would love your feedback!

  2. Peter:
    Jan 02, 2012 at 03:53 AM

    Sounds really useful. Would love to see a video of it in action.

  3. Default Admin User:
    Jan 03, 2012 at 06:40 PM

    Hi Peter, I added a screencast. You can see it at:
    http://www.youtube.com/watch?v=PVVtxS1r7II&feature=youtube_gdata_player

  4. J:
    Jan 04, 2012 at 02:24 AM

    Hi Noah,

    good job! thanks a lot

    cheers, j

  5. Noah:
    Jan 04, 2012 at 09:53 AM

    Hey Sharkbait,
    Thanks for that. It means a lot to me. Let me know if you implement it it and if it works out for you!

    -Noah

  6. Christian Hanvey:
    Jan 18, 2012 at 12:50 AM

    Nice work Noah - this is something that has been on my 'things to get around to' list for quite a while. Now, I can scrub it off my list - you have denied me the challenge... I'd better be quicker next time!
    (ps the quip preview comment styles dont read so great - light text on white)


Add a Comment





Allowed tags: <b><i><br>Add a new comment:


LEARNER DESIGN   |  9 Lewis Court  |  Nantucket, MA 02554  |  508-325-6626  |   © Learner Design 2012