FLOPPY: Plugin for localStorage, sessionStorage, IndexedDB storage, List Creation/Manipulation, Iteration, and More! Now with even more video docs!

Ha - yep! I haven’t looked at the Bubble Security Checker thing just yet. What do you think about it, @bubble.trouble?

And wait a moment because I’ve got more. You know I can’t just push a release and not push an update immediately afterward…

:boom:BECAUSE I :heart: YOU :boom:: Hot on the heels of Floppy 1.9.0 comes version 1.9.1… And no, it’s not a bugfix release.

The long-term plan for Floppy has been to become a not just a solution for browser storage, but a place to share other interesting plugins, including ones that are somewhat experimental. So, 1.9.1 adds two element plugins that I hadn’t worked on in quite a while and never before made available to other users.

Longtime forum dwellers might remember a couple of mysterious videos that I posted long ago showing an animation plugin called REANIMATOR. A still-experimental, but usable and slightly cleaned-up version of REANIMATOR is included here as “Z: REANIMATOR”.

REANIMATOR also has a friend, “Inline SVG” that does what it says on the tin (it’s a visual element that you can put SVG code into). It’s available here as “Z: Inline SVG”.

The “Z: Series” plugins are works in progress. While I’ll try not to introduce breaking changes to them, there’s no guarantee that I won’t. But mostly, anything I introduce as a “Z” plugin is just something that will get built out over time.

Now, the docs for these are rather minimal at the moment and they will take a little video or two to explain (and show how you can use REANIMATOR and Inline SVG together), but well now you have it.


Another Little Update: Just published Floppy version 1.9.3 which adds yet another plugin (Floppy Rehydrator), which solves the problem described in this thread:

Basically you can send lists of texts that represent Bubble unique IDs to Floppy Rehydrator and it rehydrates them into the Things they represent.

I know this seems like a weird thing – like, where might those IDs come from? Well, it turns out that they might come as a list of UIDs passed via a URL parameter. Stupidly, Get Data from URL… seems not to be able to read lists of UIDs, even though “Send Data to page…” lets us send them. Bubble is so dumb sometimes. :man_shrugging:

But I suppose this also might be useful if you have some API that is sending you Bubble UIDs as text or something. Anyway, look at all the value you’re getting from your smart investment in Floppy!

1 Like

I am loving the Inline SVG feature!

As someone who works with Illustrator daily, this opens up many creative opportunities for me without having to worry about storage space!

I tip my hat to you good sir. As always you are a legend.

1 Like

Did you manage to make it work? (I mean, it works, but thought it might need some more docs or guidance.) I don’t think it supports click actions yet (though I forget where I left that). But yes it works great with Illustrator SVG code and, when it doesn’t with certain SVG’s, this site:

Is an awesome help.

BTW, the element itself publishes path data that can be used with Reanimator (which is my very much in progress implementation of anime.js, which is a wonderful library, but has an interface that is very difficult to adapt in a meaningful way to Bubble programming) to do things like animate path drawing and morph between paths with the same number of points.

The interface for that is very obtuse at the moment and needs explanation.

Beyond that, Reanimator is sort of in a state where you can use it to design and execute animations, but where I really wanted to go with it was to design some actions that can be used to implement pre-designed animations, too. It has a lot of capabilities that are not fully or well exposed at the moment.

But I thought it was worth “resurrecting” to see what folks might make of it. (I hadn’t done anything with it since sometime in 2020, but with a couple of bug fixes and minifying the code to get all the console log statements out of it, I realized that it’s still sort of useful even in its current state.)

The in-line SVG element is much closer to a competed idea, though I’m not sure that it plays well with the new responsive engine (the canvas just does what it does). The “grid” feature is cool though and you can use that with Reanimator, too.

As you probably noticed, it also implements a library called Rough, which lets you give clean SVG outlines and fills a hand-drawn look, which is pretty fun if not super useful!

Thanks for checking these out, @ihsanzainal84 and let me know what issues or questions you find!

1 Like

BTW, I missed the fact that one of you fantastic Floppy users posted a terrific review of Floppy on its plugin page about a month ago. Thank you, nameless Floppy user! Tip ‘o’ the :tophat: to you.

I had just been musing to myself that I hadn’t seen any reviews for Floppy yet (and then saw one, hooray!).

If you’re so inclined, and you’re thrilled with Floppy, please take a moment to give it a review over there on the plugin page (or wherever you do that).

And, if Floppy hasn’t met your expectations yet, please let me know – either in a DM or here in the thread – what I could do to meet them!

Cheers, @keith

1 Like

+1 for Rehydrate - that could solve a major issue for me where I have a list of 4000+ records returned from a backend compute.

I have stored the backend UID’s in Bubble and have to do a big recursive lookup to a load table & suck this data back in (it takes ages . . . . ) I could do the opposite and store & return Bubble’s UID and just rehydrate. . . . .

Another similar issue is bulk load API only accepts text so date strings (which happily auto convert when you do a bulk load through Bubble’s App data page - grr) have to be sucked in as text in the API as well and then converted (hello second recursive workflow) . Ive been using Parallels SSA to help me with that as it handles the destination Zone.

1 Like

Hey, @johnnyweb - the version of Rehydrate that I published last night is a client-side element, but I could pretty easily churn out an SSA version. Have you tried it in your page yet? (If I did turn it into an SSA, it should be able to easily handle a list of 4000-ish UIDs.)

Also, it’s a little more work, but would it be helpful to have a version of SS Parallel Date that accepted a list of date strings to parse? (It’s unclear to me if it would be helpful to you in this particular case. What it would do is spit out a list of parsed dates rather than a single one. However, if you would still need to recurse over that list of dates anyway, this might not be much of an efficiency gain. LMK.)


No I’ll have a play with rehydrate and if it looks the goods (as Im sure it is!) I’ll need to go back and change a LOT of API’s and get the UID data into the backend. But this process takes over an hour at the moment (theres a bunch of UID’s to match) so we could be on a winner. Its 4000 records but there’s 4 UID’s that get matched per record :smiley:

My experience is batching works well with large lists (say 50 records at a time with a small delay) but in this case Im also rolling start end end times to nearest 15 minutes so not sure if it would work in this case heres my BE workflow for date conversion

I’ll DM you on what Im doing with the UID’s - Thanks for the awesome support!

1 Like

Oh, I see. Steps 2 and 3 are both SS Parallel Date actions, right? In each recursion, are is the parallel date conversion always to the same timezone? Or do they vary per step?

If they don’t vary, it actually would be a bit of a resource saver to bulk convert all the start and end dates in the kickoff step (that would basically take the same time as a single conversion, really) and then you wouldn’t have two SSA steps in each recursion. Just something to think about.

As for “rehydrate” it’s just super-simple as this is just a core part of the plugin API. When we use the instance.publishState() method to publish values for a Thing, we can send it either the original Bubble object(s) for the Thing, or just the unique ID that represents that Thing and the plugin builder API magically converts them back.

So all it does is read the list of UIDs that get sent as text and then publish them to a properly typed output (you tell the plugin what type the UIDs represent in the main interface) and once there they are magically Things again.

Oh hai: I put a YouTube playlist together with 6 of my videos about Floppy (which may or may not be all of them?), but anyway if you like youtube and you haven’t had a chance to see or find all of them here, it’s a convenient way to do so:


Am I right in thinking I could potentially make my users experience ‘faster’ if I save lists to floppy in a storage like ram?

I have a job listings site. Would there be a way to basically save that list to users once that day (when the load the site) and then update it the list if the list has changed (we added more jobs)?

Oh hai - here’s a new freestyle video where I talk about synchronous vs asynchronous actions (in general) and then demonstrate the new Sync Trigger feature in Floppy.

I kind of departed from my intended script here, so I’ll probably do a followup, but this should be helpful to someone…

Oh, and here’s the very helpful post I mentioned in the video, wherein Tip: Order of Operation - #2 by aschofer @ashofer from Bubble gave some helpful insights into synchronicity/asynchronicity of Bubble workflow actions.


Lol does this mean anything to what I just posted above? If so, that would be crazy.

No, it’s just “synchronous posting”! :stuck_out_tongue_winking_eye:

Hey @bkerryk - well, not really. Sounds like you might be a bit confused by the “RAM” nomenclature. I just use that cheeky naming convention to distinguish the in-memory (volatile) storage from the persistent (browser) storage in Floppy.

Now, you can use Floppy to save data into the user’s browser storage (session, local, or IndexedDB without interacting with the Bubble database, but this is really only true for simple data types. Once we’re talking about Things, there’s always interaction with the database, but it can still be more performant than doing a Search.

As an example, suppose you construct a “Wish List” of Products (a thing, a custom datatype) that a user wants to buy. You can store such a list in localStorage or IndexedDB without having to create a field on the User object in your database to hold it. (Although the Products themselves will just be stored as their unique IDs in browser storage and so, when you load the items in the Wish List they will still be fetched from the database, but you don’t have to do any sort of query to know what they are! And you don’t have to write anything to the database to change that list.)

@keith In your video example with the Custom Event, the only way to succeed is to have several Custom Events next to each other. Then the whole thing will be synchronous. It’s a bit absurd but it works.

1 Like

Hey @JohnMark, when you posted this I was like, “Oh yeah, that might work.” But it actually turns out that it doesn’t in this particular case. Pretty wild. So using the “Sync Trigger” feature seems to be necessary in this specific context (that is, when making sure that a “Create New Thing” or “Make Changes…” action waits for Floppy’s RAM List / RAM Scalar values to be updated). :man_shrugging:

1 Like

@keith I forgot a small detail… when using customs in series, it is necessary to force the detection of a change of condition otherwise the old values of the Bubble “buffer” are taken into account and give erroneous results. This discovery surprised me a lot. Inside a Custom I voluntarily create an addition in a status (simple text variable) into my database. For example I add a symbol :small_red_triangle: and then I validate the rest of the sequence by replacing the symbol :small_red_triangle: by another symbol :white_check_mark:. Technically, it forces the execution of the operation and it validates the conditions correctly. I sometimes call 5 sequences one after the other thanks to this technique with the right values from one to the other. Without this, it doesn’t work. I’m sorry for my somewhat lame explanation… but I hope this is clearer.

Hey @JohnMark - I don’t quite understand your expanded explanation here. Are you saying you do some database interaction? (That’s not particularly desirable as there’s no reason for us to do that - also such an approach can fool us - are we merely slowing things down enough such that by the time we reach the Action we desire to be synchronous, our previous action that wasn’t awaited is now finished?.)

Note that in my example, surely the Create action is triggered only a ms or 2 before the RAM List value is updated. In fact they may happen within a ms of each other and so may even appear to happen at the same JS time value, the resolution of which is limited to one millisecond (which certainly isn’t granular enough on my system, which can initialize several complex plugins in the same millisecond).

Are you a Floppy user (Bubble doesn’t tell us who our purchaser/subscribers are)?

If so, I’d appreciate an example of what I demonstrate in that video (modify Floppy’s RAM List and trigger Create a New Thing where some field on the Thing successfully gets the values from the RAM List, without resorting to an arbitrary pause, an intervening unrelated database interaction, or Floppy’s own sync trigger/RAM List Updated events).

Because I can’t make that happen! (If such a solution actually works it should work with any other combination of actions of any sort and would be a very valuable tip!)