Sortable table

164 views
Skip to first unread message

Mike

unread,
Jan 31, 2021, 7:51:02 AM1/31/21
to Joomla! General Development
Hi!

I'd like to use a sortable table in the backend of my component. This site seems to be a good place to start:


Before I get going - I'd like to 1) drag and drop the table-rows, and then 2) renumber them according to the new order. In other words, the UI should allow me to shuffle around the rows, and my backend code should be able to read the new arrangement in order to make the corresponding changes into the database.

Is this possible with the solution provided in the link,  or do I need to look further?

cheers,

  Mike 

Roger Creagh

unread,
Jan 31, 2021, 8:10:21 AM1/31/21
to joomla-de...@googlegroups.com
So you want to sort by a column (lets say the "Title" column) which will sort according to whatever criteria you set in your model getListQuery() where yoou build the query that generates the list/table

You then want to drag'n'drop rows to generate a new order and save this new order to the database - typically in a column/field named "ordering" which can then be used by the Joomla front end to order the display (and also by the backend if you sort by ordering)

So you'll have the ordering column visible in the backend list view, which enables the drag'n'drop re-ordering.

Part of your problem is going to be that when you click on the column header for the ordering column to allow you to re-order it starts by reordering the list into the previously existing order and away from the Title (eg) column that you used as the basis for your order.

So what you need is an extra custom button in the toolbar which saves the current order to the ordering field. Then you'd be able to click on the ordering column header and work from there.

However there is a further gotcha - the way the ordering column works is that it normally does a two level sort - first sorting by category, and then by ordering value within the category. So you will have to work around this either by ensuring that all the items in the view you want to sort are in the same category (eg by applying a filter), or by adjusting the ordering code in your getListQuery() on both front-end and backend and probably in the core drag'n'drop code as well..

To see how the ordering works by default try creating some test articles in two different categories and then re-orting them using the ordering column - you'll find you can only drop an item next to an item in the same category.

Hope this helps
Roger
--
You received this message because you are subscribed to the Google Groups "Joomla! General Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to joomla-dev-gene...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/joomla-dev-general/f18b586d-0230-4e1d-9557-c43883f08f5dn%40googlegroups.com.

Mike

unread,
Jan 31, 2021, 8:16:35 AM1/31/21
to Joomla! General Development
Thx, Roger, you're very helpful. This certainly did throw some light on the challenge, and on how I should proceed! Let's see how I manage...!

bw,

   Mike



Roger Creagh

unread,
Jan 31, 2021, 8:20:53 AM1/31/21
to joomla-de...@googlegroups.com
By the way that link is a bit out of date (although the code will still work). You no longer need to have the hidden fields on your view to store the sort order. The newer way is to use `searchtools.sort` in place of `grid.sort` and have these two lines in the php at the top of the page:

$listOrder = $this->escape($this->state->get('list.ordering'));
$listDirn      = $this->escape($this->state->get('list.direction'));

and use those variables in the table column headers like this

<th>
<?php echo JHtml::_('searchtools.sort', 'Title', 'title', $listDirn, $listOrder); ?>
</th>

Roger

On Sun, 2021-01-31 at 04:51 -0800, Mike wrote:

Mike

unread,
Jan 31, 2021, 11:13:09 AM1/31/21
to Joomla! General Development
Thx again - I'll see what I can do with that!

I might as well at the same time ask if I'll have to unlearn a lot of this when Joomla 4 premiers?

cheers,

  Mike

Roger Creagh

unread,
Feb 1, 2021, 4:12:10 PM2/1/21
to joomla-de...@googlegroups.com
From the little I've seen so far starting a component from scratch in J4 is _very_ different - totally changed file structure for starters. Unfortunately the J4 component tutorial is very far from complete - I guess no-one really knows how to do it yet.

But as I understand it (which may be completely wrong) J3 components will work on J4 with some minor adjustments for specific changes - there is a page here https://docs.joomla.org/Potential_backward_compatibility_issues_in_Joomla_4 which gives some clues. I had thought that if a component ran ok on j3.10 then it should run on J4 but that doesn't seem to be the case.

For myself I will ignore J4 for some years yet; some of my sites have a fair amount of customisation and I reckon I'll continue with J3 on those for at least 5 years (by which time the internet may well be on its last legs anyway). If starting a new site in the next couple of years I would stick with J3 - there really doesn't seem much point to J4 - just because its new doesn't mean its better. But then I do not do sites that are used for ecommerce or aim to generate mass traffic - I couldn't care less if they are visible to search engines or not - in some cases I actively discourage search engines; those who need to know know where to find it.

Back on the main thread your question caused me to find that in one of my components re-ordering has stopped working and I've just spent a day trying to work out why.
It seems that everything follows the pattern of the HelloWorld J3 MVC tutorial and is pretty much the same as the banners and articles components, plus it used to work some time ago.

But now, although drag'n'drop reordering of the table works and generates appropriate changed values in the rows they never get saved to the database and I can't for the life of me see what's wrong.

Inspecting the ordering column element for a row that has just moved shows

<input type="text" style="display:none" name="order[]" size="5" value="4" class="width-20 text-area-order ">

where the value has correctly been changed to reflect the new order position, but nothing has saved to the database ordering column for the item...

any guesses anyone?

Roger

Hannes Papenberg

unread,
Feb 1, 2021, 6:45:38 PM2/1/21
to Joomla! General Development
1. The basic structure of a component is still the same in Joomla 4. Files have largely just been moved in the src folder. The changes are smaller than you think.

2. Joomla 3 will only get support for 2 more years, so waiting for 5 years to upgrade will be very risky. 

3. Regarding the sorting: check the Ajax response after the sorting. Set error reporting to maximum and maybe enable debugging and see what it says then.

--
You received this message because you are subscribed to the Google Groups "Joomla! General Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to joomla-dev-gene...@googlegroups.com.

Roger Creagh

unread,
Feb 2, 2021, 6:57:07 AM2/2/21
to joomla-de...@googlegroups.com
Thanks for the reassurance Hannes, I expect one day I'll grapple with J4 but not for a while. For a low traffic unimportant site, or one that is purely on an internal network the risks of using a 3 year out of date J3 are pretty minimal.

On my sorting problem I get this error on the console:

jquery.js?e0dd0c178b7899759869fe045b754616:10271 POST http://joomla.localhost/administrator/index.php?option=com_xbfilms&task=films.saveOrderAjax&tmpl=component 500 (Internal Server Error)

Whereas on the same site with reordering of Articles or Banners items I get no errors.

The drag and drop works, but the ajax call seems to be failing.

Here is the code from my component near the top of default.php in the view tmpl:

if ($saveOrder) {
$saveOrderingUrl = 'index.php?option=com_xbfilms&task=films.saveOrderAjax&tmpl=component';
JHtml::_('sortablelist.sortable', 'xbfilmsList', 'adminForm', strtolower($listDirn), $saveOrderingUrl);
}

and here is the corresponding lines from com_banners

if ($saveOrder)
{
$saveOrderingUrl = 'index.php?option=com_banners&task=banners.saveOrderAjax&tmpl=component';
JHtml::_('sortablelist.sortable', 'articleList', 'adminForm', strtolower($listDirn), $saveOrderingUrl);
}

xbfilmsList is the id of the table element and adminForm is the name and id of the form.

I can see that each row has the attribute sortable-group-id set to the category id, I can see that the value on the hidden input (display:none) on the sortable column element which has name=order[] has value= changed to a new value by the drag and drop action, but this is not getting saved.

Clearly something is missing...

Roger

Polyna-Maude R.-Summerside

unread,
Feb 2, 2021, 8:10:10 AM2/2/21
to 'Roger Creagh' via Joomla! General Development

Hi !

If you get a error 500 then you should post the log of your web server (or look into them).

As it says, the error 500 is caused by a internal problem of your server, so the answer won't come from the usual Joomla log.

--
You received this message because you are subscribed to the Google Groups "Joomla! General Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to joomla-dev-gene...@googlegroups.com.

Roger Creagh

unread,
Feb 2, 2021, 1:15:25 PM2/2/21
to joomla-de...@googlegroups.com
Thanks, but there is nothing relevant in the apache2 error.log No server error is logged at the time.

I should also say that  this doesn't just happen on this (localhost) server, it happens on any server.

Also to stress that the problem doesn't arise with other components, so it _must_ be to do with the way I have set this particular component (mustn't it?)

The error message I quoted came from the browser console (ie javascript).

So I have just tried entering the saveOrderingUrl directly into the browser (obviously with administrator/  at the start since we are in the admin side)

$saveOrderingUrl = 'index.php?option=com_banners&task=banners.saveOrderAjax&tmpl=component';

This works and prints 1  on a blank screen.
The same for articles and the helloworld tutorial component.

However when I enter 
 /administrator/index.php?option=com_xbfilms&task=films.saveOrderAjax&tmpl=component 
I get an error which doesn't show in normal operation (presumably it is trapped somewhere in the Joomla code and unhelpfully ignored)

0 Call to undefined method XbfilmsModelFilms::saveorder()
/var/www/joomla/public_html/libraries/src/MVC/Controller/AdminController.php:378
and looking at line 378 in the referenced file I see that is is indeed a line in the function 

public function saveOrderAjax()

and is a call to a function saveorder() in the model

$model = $this->getModel();

$return = $model->saveorder($pks, $order);
if ($return)
{
echo '1';
}

which is where the '1' on the screen comes from if you call the url directly.

However neither com_component, nor com_banners, nor com_helloworld from 


has a saveorder() function anywhere in their models or controllers.

So how do they manage it?. 

Roger

::1 - - [02/Feb/2021:17:34:03 +0000] "POST /administrator/index.php?option=com_xbfilms&task=films.saveOrderAjax&tmpl=component HTTP/1.1" 500 25014 "http://joomla.localhost/administrator/index.php?option=com_xbfilms&view=films" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36"

Polyna-Maude R.-Summerside

unread,
Feb 2, 2021, 1:28:57 PM2/2/21
to 'Roger Creagh' via Joomla! General Development

Hi !

Have you enabled a tracing debugger (xdebug for example) ?

If you get a error 500 from your web server then either you haven't turned on logging or you missed something because it will leave information about what caused the error.

Is it caused by PHP ? Is it some pre-processing / validation on the server side that failed (example mod_security that modified a request in a wrong way or just threw a error)...

Now regarding your question on how do com_helloword / com_banners / com_xxxx work.

They simply inherit function from the parent object.

What model do you inherit from ? (extend)

--
You received this message because you are subscribed to the Google Groups "Joomla! General Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to joomla-dev-gene...@googlegroups.com.

Roger Creagh

unread,
Feb 2, 2021, 2:53:21 PM2/2/21
to joomla-de...@googlegroups.com
That's what I thought.
I have

class XbfilmsModelFilms extends JModelList {

which seems right

saveorder() however is not found in ListModel.php, it is found in AdminModel.php (both in /libraries/src/MVC/Model/)

so I wonder if the saveOrderAjax() function is supposed to be getting the item model, not the list model.

The error message when calling the saveOrderAjax function directly by entering the url


as per previous message refers to undefined method XbfilmsModelFilms::saveorder()
shouldn't this actually be calling XbfilmsModelFilm::saveorder() for each item it is saving the ordering of?

The list view, model and controller are "films" and the individual item view, model and controller are "film" (as with banners, articles etc)

I really appreciate your help and suggestions - each sparks off several more lines of investigation, none of which have yielded a result.

Its going to turn out to be either a really silly little typo, or just possibly something I deleted several iterations ago and didn't notice the consequence until I re-tested the drag and drop re-order (which I doubt I've used since in this application as I don't really need it.)
Reply all
Reply to author
Forward
0 new messages