Sorting Listings: Difference between revisions

From Littledamien Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(11 intermediate revisions by the same user not shown)
Line 8: Line 8:
Currently the library works with the Littledamien and Damien Jay sites. It works with different content types, but is hard-coded to expect certain behaviors from the AJAX script that commits the changes.  
Currently the library works with the Littledamien and Damien Jay sites. It works with different content types, but is hard-coded to expect certain behaviors from the AJAX script that commits the changes.  


The goal is to make a new version of the `resort.js` plugin that will be more generic and customizable.
The goal is to refactor the `resort.js` plugin to be more generic and customizable.


The goal on the AJAX handler side is to create a reusable Symfony bundle.
The goal on the AJAX handler side is to create a reusable Symfony bundle.
Line 41: Line 41:
** `record_id`: Name of the key storing the id of the record(s) being repositioned. (default: `'id'`)   
** `record_id`: Name of the key storing the id of the record(s) being repositioned. (default: `'id'`)   
** `position_offset`: Name of the key that stores the position of the first record currently being displayed relative to the first record in the entire set of matching listings. (default: `'po'`)
** `position_offset`: Name of the key that stores the position of the first record currently being displayed relative to the first record in the entire set of matching listings. (default: `'po'`)
** `content_type`: Name of the entity represented in the listings. (default: `'type'`)
** `filter`: (Optional) name of the key use to pass filters to apply to the entities, e.g. if they belong to a group. (default: `'filter'`) ''(Note that it's singular.)''
** `filters`: (Optional) list of keys holding filter values applied to the list of sortable items. These keys correspond to `data-` attributes of the sortable container element. (default: `[]`) ''(Note that it's plural.)''
=== CSRF ===
Passing a CSRF token isn't handled by the plugin directly.
See [[CSRF_Validation_in_AJAX_With_Symfony#JavaScript.2FjQuery|CSRF Validation in AJAX With Symfony]]


== Markup ==
== Markup ==
Line 67: Line 76:
=== Example of alternate markup ===
=== Example of alternate markup ===


<syntaxhighlight lang="text">
<syntaxhighlight lang="text" enclose="div">
|
|
+-- <ul class="list-group" data-po="n" data-type="Foo">
+-- <ul class="list-group" data-po="n" data-type="Foo" data-gid="filter_value">
|    |
|    |
|    +-- <li class="list-group-item" data-id="n">
|    +-- <li class="list-group-item" data-id="n">
Line 78: Line 87:
|    |
|    |
|    (...)
|    (...)
|
+-- (...)
|
+-- <div id="csrf-token" data-token="token_string"></div>
|
|
(...)
(...)
</syntaxhighlight>
Configure sorting for the example above with:
<syntaxhighlight lang="javascript">
$(document).ready(function() {
return this.resort({
uris: { resort: '/resort' },
dom: {
listings_container: '.tutorial-group',
sortable_selector: 'li'
},
keys: {
filters: ['gid']
}
});
});
</syntaxhighlight>
</syntaxhighlight>


Line 96: Line 126:
* `status` Simple string containing a plain English result to be displayed in the browser as confirmation of the operation.
* `status` Simple string containing a plain English result to be displayed in the browser as confirmation of the operation.
* `error` String containing error message if any errors were encountered.
* `error` String containing error message if any errors were encountered.
=== CSRF ===
See [[CSRF_Validation_in_AJAX_With_Symfony#Symfony_controller|CSRF Validation in AJAX With Symfony]] for a method for checking a CSRF token passed to the AJAX script in the request headers.


=== Littledamien configuration ===
=== Littledamien configuration ===
Line 131: Line 165:
== MySQL ==
== MySQL ==


Tables with sortable records must contain
Required resortable entity properties (table columns):


* An `id` column containing a unique id for the record.
* `id` column containing a unique id for the record.
* A `slot` column holding the value of the record’s position in the listings relative to all other records.
* `slot` column holding the value of the record’s position in the listings relative to all other records.

Latest revision as of 13:37, 2 March 2015

Overview[edit]

A jQuery plugin that enables drag-n-drop resorting of listings displayed in the browser.

Future development[edit]

Currently the library works with the Littledamien and Damien Jay sites. It works with different content types, but is hard-coded to expect certain behaviors from the AJAX script that commits the changes.

The goal is to refactor the resort.js plugin to be more generic and customizable.

The goal on the AJAX handler side is to create a reusable Symfony bundle.

Content Properties CMS[edit]

CMS > Content Properties

  • Is Sortable: checked
  • Sorting URI: /hostmgr/_ajax/utils/resort.php (default shared AJAX handler script)

JavaScript[edit]

Sorting logic is defined in littled/resort.js which is wrapped up in littled.js.

Example:

$(document).ready(function() {
	/* options can be passed as first argument to resort() */
	$('.listings table:first').resort();
});

Settings[edit]

  • uris
    • resort: URL of the AJAX script that will commit the resorted listings. (default: /_ajax/utils/resort.php)
  • dom
    • listings_container: The listings container selector. (default: '.listings')
    • sortable_selector: Selector used to define sortable elements. (default: tr.rec_row)
  • keys
    • record_id: Name of the key storing the id of the record(s) being repositioned. (default: 'id')
    • position_offset: Name of the key that stores the position of the first record currently being displayed relative to the first record in the entire set of matching listings. (default: 'po')
    • content_type: Name of the entity represented in the listings. (default: 'type')
    • filter: (Optional) name of the key use to pass filters to apply to the entities, e.g. if they belong to a group. (default: 'filter') (Note that it's singular.)
    • filters: (Optional) list of keys holding filter values applied to the list of sortable items. These keys correspond to data- attributes of the sortable container element. (default: []) (Note that it's plural.)

CSRF[edit]

Passing a CSRF token isn't handled by the plugin directly.

See CSRF Validation in AJAX With Symfony

Markup[edit]

When loading modal dialogs and refreshing listings content, the library looks to the data-po attribute of .listings table:first by default.

Default markup[edit]

|
+-- <div class="listings">
     |
     +-- <table data-po="n">
          |
          +-- <tr>
          |    |
          |    +-- <th>
          |    |
          |    (...)
          |
          +-- <tr class="rec-row">
          |
          (...)

Example of alternate markup[edit]

|
+-- <ul class="list-group" data-po="n" data-type="Foo" data-gid="filter_value">
|    |
|    +-- <li class="list-group-item" data-id="n">
|    |    |
|    |    +-- <div>
|    |    |
|    |    (...)
|    |
|    (...)
|
+-- (...)
|
+-- <div id="csrf-token" data-token="token_string"></div>
|
(...)

Configure sorting for the example above with:

$(document).ready(function() {
	return this.resort({
		uris: { resort: '/resort' },
		dom: {
			listings_container: '.tutorial-group',
			sortable_selector: 'li'
		},
		keys: {
			filters: ['gid']
		}
	});
});

PHP[edit]

Input (proposed)[edit]

  • po Position offset of the first record in the listings from the first record in the entire unfiltered collection.
  • id Array of record ids resorted to the desired arrangement.
  • type Name of the entity represented in the listings.
  • filters Associative array of filters to apply, for example if resorting only those items in a certain group.

Output[edit]

  • Output as JSON by default.
  • status Simple string containing a plain English result to be displayed in the browser as confirmation of the operation.
  • error String containing error message if any errors were encountered.

CSRF[edit]

See CSRF Validation in AJAX With Symfony for a method for checking a CSRF token passed to the AJAX script in the request headers.

Littledamien configuration[edit]

/_classes/site_content/cache_class.php

Add include directives for both the parent page’s content and content filter classes:

require_once (APP_CLASS_DIR."site_content/press_class.php");
require_once (APP_CLASS_DIR."site_filters/press_filters_class.php");

Update the set_filters() routine to include the filter class representing the page’s content type.

/_classes/site_content/cache_class.php

Potentially no changes need to be made to this class on a content-type-by-content-type basis as long as the default action for all content types is

if ($this->filters instanceof filters_collection_class) {
    $this->filters->parse_filters();
    $this->filters->page_len->value = null; /* get all available records */
}

If some other action needs to be taken for a specific content type then a new case would need to be created in the retrieve_section_properties() routine.

Paging is handled with

include (COMMON_TEMPLATE_DIR."framework/navigation/listings_page_links.php");

MySQL[edit]

Required resortable entity properties (table columns):

  • id column containing a unique id for the record.
  • slot column holding the value of the record’s position in the listings relative to all other records.