Let’s Talk About Repeating Groups, part 5: Building a page nav for our RG with List Shifter, “PREFETCH” Action, setting and tracking a “selected” item when in pagination mode: (edit: here is the correct video!)
Link to Loom video here.
Let’s Talk About Repeating Groups, part 5: Building a page nav for our RG with List Shifter, “PREFETCH” Action, setting and tracking a “selected” item when in pagination mode: (edit: here is the correct video!)
Link to Loom video here.
New Features in List Shifter: “Use Scalar”, “Do Once” Mode of PROCESS List, Lists as Operands in PROCESS List, and other dorking around:
Link to Loom video here.
Over in another thread, someone asked about interleaving two lists. This is easily accomplished with List Shifter’s PROCESS List Action, and I put together a little demo page for that. Editor:
Note: this demo currently uses List Shifter 1.7.3 since v 1.8.0 is borked due to a bug in the plugin editor. 1.7.3 is the most recent stable version (which is unfortunately missing a lot of new sexy from 1.8, but still gets easy jobs like this done in a jiffy).
Run mode view:
“What is a favorite thing for me? Bubble… Outages… ”
Definitely
Just published version 1.9.3 of List Shifter, so now you can actually take advantage of the pagination mode and other features I’ve demonstrated recently (with much more to come)!
Version 1.9.3 is the CORRECTED version of unfortunately borked 1.8 (which, due to some REALLY complicated weirdness with GitHub, had several important Actions and Exposed States missing).
A huge shout out to Chris Rogers at Bubble who helped debug the issues I was having. The things we learned from this would likely be helpful to other Bubble plugin creators and I’ll probably do a video about that sometime soon.
In the meantime, please to enjoy the super-awesome features of List Shifter.
As a reminder, List Shifter is KarmaWare. if you’d like to support the ongoing development of awesomely powerful, but freely-available plug-ins like List Shifter (and its buddies List Popper & Friends), you can show your support by contributing here:
As always, nice one @keith
The pagination feature is pretty awesome.
Thanks @luke2. I need to do more “recipes” for PROCESS List and it occurs to me that certain things one might do with PROCESS List would be easier with some specialized interfaces for filtering and other applications, BUT, in its current form, List Shifter solves a TON of problems that Bubble has as a platform for more diverse types of apps.
Just pushed List Shifter version 1.9.4… which doesn’t have any actual new features, but is to test a fix to the Bubble plugin editor.
If anybody out there is using 1.9.3 and feels like experimenting: Upgrade to 1.9.4 and let me know if you see any issues (I didn’t). You shouldn’t notice anything strange… but let me know if your project complains about any missing List Shifter elements, LS Actions, or LS exposed states. (And, in that case, just revert back to 1.9.3 and all will be well.)
If you check this out, please let me know what you find, either way.
(Sorry to be cryptic, but the bug that – I think – is fixed here is rather obtuse and hard to explain. The thing Bubble has fixed here probably affected nobody but me, but the fix has really huge implications for complex Bubble plugin development. More on that later.)
Hi @keith,
Is it possible to save an entire list via the click of a button?
For example: you have an invoice and invoice lines but I don´t want the invoices lines to be saved to the database whenever they´re added in the front end. Right now when a user creates a new line I´ve to create the record in the database because Bubble won´t let submit a whole list to the database.
That would be awesome if possible.
Thanks a lot and have a good day.
Hi @ryanck: You CAN save an entire list to the database in one fell swoop… IF you are saving to a field that is itself a list field.
The caveat, of course, is that Things can only be created using Create New or Copy List of Things.
So while we can construct and manipulate all sorts of lists in the page, we cannot create a new Thing(s) and put them into a list without interacting with the database.
If you’ve not seen this one before, you might want to watch this video, which is very relevant to the question you’re asking:
Check it out and let me know if that helps you with this issue.
Hey @keith,
I´m checking it out right now.
Would you mind taking a look at this topic because it´s related to your other plugin: ❓ ¿How do you copy a thing and the sublist 24 times?
Thanks a lot.
If you want to learn more about iteration with List Shifter, here are the two things to watch (I know this is a long thread, but everything up here is about how to use List Shifter!):
Recap on Iterate action and the newer Process List action:
Original video about the iterate action in List Shifter – see this reply up the thread:
Just pushed version 1.9.7 of List Shifter, which I believe published correctly.
If some List Shiftin’ user would give it a quick check that the new version doesn’t cause missing element or action weirdness, I’d appreciate it. (I’m always a touch paranoid about that.)
(Snapshot your project, upgrade plugin, give it a quick spin. If you find it borked, let me know and I’ll get it fixed.)
This version adds a couple of new operands for PROCESS List, a new “containsPoint” operator for ranges, better range support in general and a couple obscure bug fixes.
These don’t sound like much, but they enable some very sophisticated scheduling/date/date range manipulation that you can’t do without custom code or specialized plugins.
(A video about that to come.)
@keith I am not sure if this weirdness that I am experiencing is weirdness or expected behavior.
When using the list shifter to store a list of search results I am trying to display the list in a repeating group…there is nothing wrong with that. The issue though is I am trying to only display a certain number of items (25) and I am using pagination (not through list shifter but my own workflows and custom states).
What I have set up is custom states which represent the number of items from and number of items until ( items from 1 : items until 25 ; items from 26 : items until 50 )…I have set my repeating group datasource to be the list shifter original list items from : items until, which is where the problem occurs.
When the items from 26: items until 50 my repeating group doesn’t show only 25 items as expected but instead it shows 50…this behavior continues and if I have items from 51 : items until 75 I get 75 results displayed in the repeating group.
I test this by creating a workflow and a button to display data in the repeating group
What I am noticing is that no matter what the items from number is, I get results displayed totaling the items until number. In the example screen shot above I get 15 items displayed in the repeating group instead of only 8 as would be expected using ‘items from #8: items until #15’
Any ideas why that would be?
Hey @boston85719, this is a good question… The answer is that what you are observing is exactly how your expression works. What you think your expression means and what it actually means is the source of confusion.
We’re talking about this expression:
You are computing:
SomeList :items from X :items until Y
And, in your head, you think: “Ah, this will give me the subset of SomeList starting at value SomeList and ending at SomeList[Y].”
But this is not correct.
Bubble expressions are evaluated from left to right. Each operator is evaluated in sequence. So what your expression means is this:
“Give me the values in SomeList, starting at item X. Now, having that, give me the values in that list, ending with item Y.”
So, let’s say that SomeList is a list of numbers, 1 through 10. We might think of it like this:
SomeList = [1,2,3,4,5,6,7,8,9,10]
And now we evaluate the expression:
SomeList :items from 3 :items until 5
The computation works like this:
[1,2,3,4,5,6,7,8,9,10]
[3,4,5,6,7,8,9,10]
[3,4,5,6,7]
In other words, what you are getting is exactly what you asked for… it’s just not the answer you were expecting.
Here’s a little explorer project that illustrates the same thing:
https://list-shifter-demo.bubbleapps.io/version-test/from-to?debug_mode=true
Editor: List-shifter-demo | Bubble Editor
Aside: This example is more complex than it needs to be… we could do this in a simpler way (no workflows) using multiple List Shifters.
To get the result you expected, (N THE GENERAL CASE) you would want to evaluate an expression like this:
SomeList :items from X :items until (Y-X+1)
Of course, you can’t literally build that expression in Bubble. You must do it in two steps: Compute (Y-X+1), store it somewhere, and then:
SomeList :items from X :items until StoredValue'
NOW: in your case, you always want 25 items, so you don’t need to do this math… you just want;
SomeList :items from X :items until 25
… but I wanted to make this very clear for the general case.
This is, among other reasons, precisely why List Shifter has a pagination mode. It can do all of that for you.
And, BTW, there’s no reason you can’t have multiple List Shifters. For example, say you want to have access to the complete list. Well, have a list shifter (List Shifter 1) whose “List to Shift” is your search. And then, have a second list shifter (List Shifter 2) whose “List to Shift” is List Shifter 1’s Original List… and put List Shifter 2 into pagination mode.
Whenever the results of the search changes, List Shifter 2 will magically change as well.
Continuing on, @boston85719, here’s a simplified version of that “from/until explorer” page, made simpler with List Shifter. Instead of computing custom states on page load and when the inputs are changed, this version uses 4 List Shifters to automagically compute our desired values:
https://list-shifter-demo.bubbleapps.io/version-test/from-to-simplified?debug_mode=true
Note that there are NO WORKFLOWS in this page’s edit mode.
Awesome. Thanks for that explanation. I can’t help but think you had explained that to me in the past as well and it had escaped me.
Also, thanks for the demos. I was planning on diving deeper into list shifter on Monday as my afternoon learning session. I can only imagine how much easier certain functions in my app will be if I know how to harness all of its powers. And to generate that good karma, after I learn how it will be an essential plugin for my app I’ll drop some coin on it.
Cheers
@keith your plugin and videos are great! One thing I cant figure out, and I’m sure it’s simple, but am missing a step:
Say I have a list of Products like in your examples, but I added a DisplayOrder field as well, when I employ the SHIFT UP button (just like in your videos), how do I update the actual DisplayOrder field in the Bubble database with the new order?
I was thinking about pushing it to a custom state then running a workflow to update Bubble’s DB, but I think you may have it more seamless than that.
Thanks
First: welcome! And thanks for exploring List Shifter!
As for ordering of Things and having an “order” field on a Thing like a Product, I’m going to start by saying I don’t see a need to do that in any use case ever in the history of ever. (The point being that the order in which items appear is a DISPLAY issue and should typically be handled by SORTING based on some real criteria that is of importance to the user, NOT some arbitrary order field. As for default sorting, think about ways that you can do that algorithmically, rather than based on a dedicated sort order field.)
The above being said, I realize that sometimes people want to do this anyway.
So, how do we accomplish that in List Shifter?: First, one point of List Shifter is that YOU DO NOT NEED AN ORDER FIELD. Using List Shifter, you can construct an ordered list (by operating on it [the “Original List”] with Shift Up, Swap Items, etc, etc as you are doing) and then that ordered list is available in List Shifter’s Shifted List.
Now that you have Shifted List, you can save it to an appropriate list-type field on any database object with its default order intact. If you retrieve that list from the database and impose no sorting on it, you will get that list back in exactly the order you saved it.
Cool, right?
So in your example (which sounds a lot like my silly store example) let’s say that what you are trying to do is take your Products and put them in a preferred order so that, if the User hasn’t yet set any sorting options, they see your available products in some special order.
Like let’s say due to concerns about Covid, I really want to move all that Canned Cat and Dog Dogs I’ve got sitting in inventory. So maybe I want to have all of my sketchy Chinese-sourced “meat products” at the top of my list of Products. (Let me stress that there have been no confirmed cases of illness due to these products and they are also delicious, but you know how people can be.)
So, I build an admin page that lets me take my list of Products and reorder it (just like my example store project, right?). Once my Products are all reordered, that ordered list is in List Shifter’s Shifted List.
And now I can do something like this: I can create a data type (Thing) in my database. Let’s call it “Default Product List”. It can have just one field on it: “Products” – a list of type Product.
And now, I can do Create a New Thing (what type? Default Product List) and set its Products field to be List Shifter’s Shifted List (my products in their preferred order).
Of course, there should only ever be one “Default Product List” in my database, so if a Default Product List exists (that is, if Do a Search for Default Product List:count is greater than 0), instead of creating a new one, I should just Make Changes to that thing (replace its Products list with List Shifter’s Shifted List).
So now I can always get my list of Products in my default configuration, by just referring to:
Search for Default Product List:first item's Products
For example, when a user loads my shopping page, I populate my list of Products with that Search. Boom, now the user sees them in my preferred order (with my high-quality alternative meat products at top).
If the user chooses to search, we just set our repeating group to be a different source (either sorting the existing list or maybe even just grabbing some other list from the database entirely).
Does the above make sense? That’s how I would use this. Note that no order field is ever required!