Passing array of sorted record ids from List to Form for Prev/Next Form nav.

Duke3D

Member
I'm circling back on this topic as I think the data is available / already rendered and just needs to be accessed. I suspect I didn't ask my question very clearly so I'm trying again.

Starting at a List View, a user-selected sort is active (column headings are clicked), pages have been turned and the Edit button for a specific record is now being clicked.

At that moment, a query has already retrieved an array of records to display, applied joins and sort criteria, broken into page-long ranges, and we can parse the data in the specific record that was clicked. This info remains available for reuse when the Form is closed via Save or Cancel, the List is redisplayed with the same sort in effect, same page selected, and possibly the same offset tagged as active.

How can I access / extract / store / pass both the array of sorted record IDs and the index of the selected record to the Form View so that controls added to that template can jump to the Next or Previous record in the array while remaining in Form View?

$id=$sortedListArray[$currentIndex+1] or $id=$sortedListArray[$currentIndex-1]
(trap index < 0 and > array.length-1)

Is there a fabrik variable that already has this active array for the currently displayed sorted List? It seems the index within that array can be picked up from the button instance that is clicked.

Conceptually this seems vary straight forward. I just don't know how to accomplish it in the Fabrik context without requerying and reapplying all the user sort preferences. It seems it should be simpler than reinventing the wheel and re-executing the active queries all over again. Is there an object or variable I can latch onto that preserves and could pass on the active array of record ID's?

If, in fact, I need to re-run the queries, how to I apply the same sort criteria as the current List View. Is the sort phrase in a fabrik object or variable?

I can't be the first person looking to implement some form of paging / record traversal in Form View. (My PHP-foo is weak so specific code examples or links to tutorials are appreciated.)
/D
 
Last edited:
No, we don't store a list of id's, for a variety of reasons. We store the filter and pagination states in the standard J! session store, and re-run the list query for each list load.

I'm slightly unclear as to what you are trying to achieve. Are you simply wanting to move between details/form views with prev/next buttons, or do you want to be able to "Save and edit next"?

If all you need to do is prev/next (without saving), have you looked at the "pagination" form plugin, which does exactly that?

If you need to "Save and edit next", the pagination plugin doesn't do that, but it at least shows you how we go about working out the first, prev, next and last rowids. If you look in ./plugins/fabrik_form/pagination/pagination.php, around line 124, the getNavIds() method, you'll see how we get the ids we need. As you can see, we don't specifically look at the session data for the state of the filters, that's all handled in the list model methods that build the query. So that code shows you how to get the "next" rowid.

The main question really is where you would actually put that, to build a "save and next" feature. I think it would have to be an option on the existing 'redirect' plugin, so it could simply redirect to the next rowid.

-- hugh
 
So, does getNavIds() return the same sorted list as was displayed in the last List view?

Yes, the goal is Save & Next.

Example:
List view's currently active sort is showing records 9 - 8 - 7 - 6- 5 - 4.
They click to edit 6
Save and Next saves and then displays 5 in edit mode.
Save and Next displays 4 in edit mode.
Save and Next hits the end of the array and returns to List view.

Use Case:
We have 100 program applicant records. They each need to be read and scored by 30 readers. The Scores table is prebuilt with default data for the 3,000 records - a foreign key to the user entering scores, and a foreign key to the application being read (and joined for read-only display).

Coming from a List view where they have set a sort order such as by Name or by Total Score, they click to edit one of their application's scores which opens Form view for that score. Save always returns to the List view. The goal is to add a Save and Next button to the form that takes them to the next record according to the Sort criteria they already have in place.

So - Is the best approach to:
  1. While in list view and when the Edit button is clicked, write/save the IDs of the list records that are currently being displayed to a user-keyed navigation table so the array is available to the Form view's Next button, and for the Form view after that and the Form view after that.
  2. While in form view use the getNavIds() code to retrieve the array from the latest list view (assuming that is what it does), scan the array from the ID of the current record, and trigger the display in Form view of the record following the current record. (And if at the end of the array, act like the normal Save button and return to the List view.)
 
Last edited:
As this involves some fairly serious Fabrik Voodoo (the redirect code gets pretty dense), I went ahead and added a first cut at a Save and Next feature, as it's something I've been meaning to add for a while.

At the moment, if you are on the last row, it'll redirect to a new form. That'd have to be added as an option (new form or back to list), as I can see people wanting to do either of those.

https://github.com/Fabrik/fabrik/commit/9e336c69a1b6ef04905ca628918acd1baee344be

I haven't tested it very extensively, so do a github update, give it a whirl, and let me know.

-- hugh
 
Specifically, I haven't tested with much by the way of filtering / different ordering on the list, or in any kind of AJAX context. Just making sure I've got the basics working first.

-- hugh
 
OMG! You are both awesome and quick! Will DL now and test.

BTW - Tried a couple times this week to setup subscription but Paypal keeps balking - have you experienced before? Can we switch to email to solve this?
 
My email is hugh dot messenger at gmail dot com.

I have to go run some errands now, but I'll be around in a few hours.

-- hugh
 
NP -

For our use case, we would definitely want to return to List view - Add is blocked by ACL - no ballot stuffing!

Will try Paypal again and let you know results - thanks.
 
Test process and results -
Files applied and default front-end behaviors are unchanged - List View to Form view, Save and return to List view continue to work as expected.
Backend - Form Edit options are unchanged on Buttons tab and elsewhere.

I presume the plugin is not loaded and used by default.
In Form Edit view, went to Plugins tab, clicked Add and the only option is "Loading"
The purpose of this Loading plugin was not clear so I deleted it.

Checked wiki - Google searched "Fabrik plugin redirect"
Instructions did not mention where/how to install it.
Guessed that the next place to check was the Joomla Plugins panel to see if it can be managed there / set to published.
Found that Fabrik Form Redirect plugin was already published.
Clicked to Edit. - No settings form found. No instructions found for where to look next.

Checked wiki - Google searched "Fabrik form plugins"
Found Forms - Form Plugins, a nice list but no generic instruction about how to install.

Checked wiki for Forms in general and discovered that the "Loading" plugin's purpose is to load other plugins and that "... Do ..." means Plugin Name.
None of these prompts for Loading have tooltips. (Obviously, the field names should be improved, tooltips added, wiki page for Fors Plugins updated.))

Reinstalled Loading plugin. Set for Redirect, Front end, Edit and left Options at default.

On SAVE got "INVALID FORM" error in popup. - looking at code changes for syntax issues. Guessing - Does the new options field need to be added to the schema?

Deleting the Loading plugin revealed system message "Invalid field . . . Do . . ."
 
Last edited:
It seems the issue is regardless of which plugin is selected. Does it have to do with the validation of ... Do .... (Select plugin) as a required field?
 
Not sure what you mean by a "Loading" plugin, there is no such thing. We just have a "loading" msg in the plugins list when we're loading up the plugin settings via AJAX. And no, no form plugins are set up on a form by default.

Here's a screencast of my setup. As you can see, I've got a number of plugins on my test form, including 'redirect'. When I reload that page I flip Eclipse (my development environment) up and you can see all the AJAX calls hitting the server as it loads up the plugins.

Anyway ... you'll also see where I have "Edit and Save" set to Yes on the redirect plugin. Then I go and edit row 2 on my test list, save it, and it redirects back to row 3.

http://screencast.com/t/C9sxgyQWIUq

-- hugh
 
Sorry for misunderstanding the "Loading" message - It appears after "Add" and is underlined as if it was a list of plugins to be added, so I clicked it and the form appeared.

Also under of why I was getting the error on submitting the changes - I went to record it and the form started saving. In between I have fully left and re-entered editing the form instance so perhaps that cleared a cache issue.

UPDATE:
It works, with no sort is active.
It works with a simple sort active.
It fails if the sort is a CONCAT_WS( ...)
In this case the Save results in a redisplay of the List view with this error:
Error
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '('',
My first column is a databasejoin element that concatinates the first and last names from the joined application. Apologies for testing with my most difficult column.
I'll try again with a simple join of last name.

 
Last edited:
Great Progress - the code is obviously working well.

Apologies in advance if I am being Captain Obvious about WIP. Ideally, this plugin should insert an additional button into the Buttons tab rather than hijaacking the Save button. The Save button should still be available for it's default function of save and return to List. I tried solving this navigation issue (no exit until you finish 100 records) by adding the built-in Back button as a Cancel, but it truly executes a browser "Back" to the previous form in history and not a redisplay of the associated List. I can work around by adding buttons into the form footer text, but a complete solution would be three buttons ... Save and Close, Save and Next, Close (redisplay List). (Again, sorry if I am being Captain Obvious.)

As to what the behavior should be at the end of the array, does it make sense for the Plugin to have a third option - Off, Save and Next/Add, Save and Next/Close? or is it better to default to close and let the user choose to Add from the List view where it will be more obvious that they reached the end of the list?
 
Just a thought - what about implementing a Close button by taking the form URL, truncating at "/form..." and appending the usual List query string (or not if not needed).

For the Form view page
http://mydomain.com/myfabriclist/form/7/213

add Form Close to the list of available buttons and render the Close button as
<a href="http://mydomain.com/myfabriclist">PLG_FORM_CLOSEFORM</a>

This seems like a simple to implement Exit path from an otherwise seemingly endless Save and Next process. Thoughts?

As for changing the redirect based on which Save is hit, does it make sense to pass back in Post a variable for whether to go to Next or Close. Render two save buttons, both as Submit, but somehow they are setting a different flag that the redirect plugin can evaluate and branch on?
(Sorry, way over my head - just tossing ideas for solving the all or nothing approach to the Next executing with every Save.)

Thinking aloud again - On the front end, when the Save button is in Save and Next mode due to the plugin, would it make sense to hook in after the successful commit and redirect to the list URL via JS code that is attached to one submit button instance and hijacks page / redirects back to the list, while the other button instance without JS code does the usual Save and Next.
 
Last edited:
With regards to the list filtering, I think I've kinda hacked that into working, although (for now) it'll be limited to just lists rendered in normal component pages. The problem being, we store the filters in the session using a "render context", which tells us which copy of the list those filters belong to. That context includes the list ID, and whether it's rendered as a component, a module or a content plugin. We have to do this, as it's possible that the same list can be rendered on the same page more than once, with different filters, if (say) someone has a module on the same page as a component view, of the same list.

So the context can be list_com_fabrik_X, or list_mod_fabrik_X or list_content_fabrik_X. And, at the moment, I can't see any way for the redirect plugin to tell which list context the form edit was kicked off from. We've never needed the list render context when processing a form before, so it's not something I've ever thought about. I think the only way to do that would be to add a &listref= query string to the edit links on the list, and use that to add it as a hidden input on the form, but I'd rather find a more elegant solution if I can, before messing with that.

Anyway, for now I've just hardwired list_com_fabrik_X as the listref when the redirect plugin looks up the session filters, and it's now working OK for component mode, i.e. a normal ?option=com_fabrik&view=list&listid=X link and should now correctly redirect to the next rowid in the current filter set.

As for the buttons, I'll have to have a think about that. It would be nice to automatically add a "Save & Next" button if the redirect plugin is present on a form, and the Save & Next feature is enabled. But it won't be trivial to implement. I'll have a look see ...

-- hugh
 
Last edited:
Thanks Hugh -
Appreciate the insights into the complexity. With appropriate user caveats like it only works when one form is published to a page, what you have built is working well.

Since I am not using user-set filtering, only ordering, it works beautifully with everything except a sort on a databasejoin element. That added complexity seems to mess up the query constructor the same way a second databasejoin element to do a lookup from the same table is messing up.

With the sudden 403's solved, the forms are now on the production site. I added hand-coded "Return to List" buttons to the form header to close/return to the list.

A few enhancements remain on my punchlist, but it's quickly getting shorter. Gotta love the ability to add jQuery magic into form_x.js
I am about to try the radiobutton code Rob posted last night for in-page calcs.

I greatly appreciate all your help!
 
Just an update - The Save & Next has a bug in it where logic was added to test if the end of the list has been reached. The test sets the NextID to "" if the next record id in the array matches the last record id. This test is causing the loop to end one record early since what NextID is determining is the record to display after the save of the current record. In other words, once you reach the penultimate record, you cannot get to the ultimate record because the NextID is null and therefore a new record is displayed, skipping over the last record.

Example Using IDs:
For an array of records numbered 1 to 5.
When record 2 is displayed and Save/Next is clicked, record 2 is committed, NextID is 3, Last ID is 5 so record 3 displays as expected.
When record 3 is displayed and Save/Next is clicked, record 3 is committed, NextID is 4, Last ID is 5 so record 4 displays as expected.
When record 4 is displayed and Save/Next is clicked, record 4 is committed, NextID is 5, Last ID is 5 so next record is now set to "" and Add New record displays (or an error is produced if user does not have Add Record access.)
It is impossible to display and edit the last record in the current sort order, Record 5, on a Form that has Save & Next enabled.
The issue is resolved by removing the conditional - "NextID is 5, Last ID is 5 so set next record to "". Leaving it to always have NextID in the array works.

Still to fix, trapping when committing the record with NextID > LastID (undefined) and instead of lunching Add New, trap the error and invoke the normal Save without the plugin firing so it will redisplay the sorted List view.

Also, ideally, this plugin should be able to render its Save and Next button in addition to and not in replacement of the default Save [and Close] button. (So two Save buttons - Save & Next and Save & Close in addition to a Cancel & Close button can all appear on the form.)

No urgency for me - I worked around the issue already.
 
Last edited:
We are in need of some funding.
More details.

Thank you.

Members online

Back
Top