Javascript list back into Bubble!

Can someone give us a quicker pointer on how to make this work? It’s driving me up the wall now!

I have an HTML element that when clicked, opens up an file input and allows me to select multiple image files. When you sect one or more files, it gets the base64 image data and then fires it into the JavascriptToBubble function. The code looks like this…

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />

        <style>
            .image-upload > input {
                display: none;
            }
        </style>
    </head>

    <body>
        <form>
            <div class="image-upload">
                <label for="file-input">
                    <img src="https://s3.amazonaws.com/appforest_uf/f1600002509614x764946865802154500/camera-28060.svg" style="width: 90px; height: 76px; cursor: pointer;" />
                </label>

                <input id="file-input" type="file" accept="image/*" multiple />
            </div>
        </form>
        <script type="text/javascript">
            function readFile() {
                if (this.files) {
                    for (i = 0; i < this.files.length; i++) {
                        var FR = new FileReader();
                        FR.onload = function (e) {
                            bubble_fn_base64_image(e.target.result);
                        };
                        FR.readAsDataURL(this.files[i]);
                    }
                }
            }

            document.getElementById("file-input").addEventListener("change", readFile, false);
        </script>
    </body>
</html>

I have a JavascriptToBubble workflow created which when triggered, puts the base64 image data straight into a custom state. All works fine so far.

The JavascriptToBubble element looks like the below, but what I really need is to change it to a list, but when I do that, I can’t get the list of base64 values out of the Javascript within the HTML element to through in one hit. I don’t really want to fire off the workflow for each file when I can do it once within a list.

image

Whenever I try to change the JS, I keep running into problems, mainly scoping problems, just wondered if someone knew how to do it?

Thanks!

If I change the JS to this:

function readFile() {
                var base64_images = [];
                if (this.files) {
                    for (i = 0; i < this.files.length; i++) {
                        var FR = new FileReader();
                        FR.onload = function (e) {
                            base64_images.push(e.target.result);
                            //bubble_fn_base64_image(e.target.result);
                        };
                        FR.readAsDataURL(this.files[i]);
                    }
                }
                bubble_fn_base64_images(base64_images);
            }

            document.getElementById("file-input").addEventListener("change", readFile, false);

And tick the list option in the JsToBubble element, then I get nothing in JavascripttoBubble C’s value list, no console errors either. I thought the way to do it would be to push all into an array first.

If I pop a console.log(base64_images); line in there, then I see the array in the console but I can’t get the list into Bubble! Arrggghhh!!

image

I encountered similar issue where I needed to send a JS array into Bubble’s closed framework.

Here’s a solution that worked great for me:

  1. In the second script you posted, make your var base64_images just an empty string var instead of an array.
  2. In the FOR loop, rather than pushing the base64 data, append it like so:
    base64_images += e.target.result + '#';
    You’ll end up with a long string of # tag separated base64 files.
  3. Pass it to JavascriptToBubble as a simple text
  4. In Bubble, use the expression JavacscriptToBubble C's value:extract with Regex where the Regex expression is [^#]+.
    The output of this expression will be a nice Bubble list of text containing the base64 data.

The # tag is used as a separator; it can be any character that is not part of the base64 table

By the way, you do not need to include , and tags in your HTML element since those are just a

in which you throw anything you want…

Hope this help

Marvellous, I can work with that! thank you for the reply. Interesting work around to which I really should have thought of.

1 Like

Since Bubble runs on JS, I believe there must be a way to pass the array directly with a specific Bubble syntax but haven’t take time to work on it…

I’m wondering if I have a scoping issue here, this is what I’ve just changed it to:

function readFile() {
                var base64_images = '';
                if (this.files) {
                    for (i = 0; i < this.files.length; i++) {
                        var FR = new FileReader();
                        FR.onload = function (e) {
                            //base64_images += 'test' + '#';
                            base64_images += e.target.result + '#';
                        };
                        FR.readAsDataURL(this.files[i]);
                    }
                }
                //console.log(base64_images);
                bubble_fn_base64_images(base64_images);
            }

            document.getElementById("file-input").addEventListener("change", readFile, false);

But I still get nothing in the Javascript element. Notice those 2 commented out lines, if I un-comment those, nothing gets printed in the console either and I would have expected something like test#test#test (if I selected 3 files for example). I’ll have a play around with it some more anyway.

Maybe you could console.log a message in your FOR loop just to see if the loop is called at all.

Sorry don’t have time right now. If you’re still stuck next week let me know.

All done, thanks for the tips

This works as I need it to

<script type="text/javascript">
    function readFile() {
        var base64_images = '';
        if (this.files) {
            var file_count = this.files.length;
            for (i = 0; i < this.files.length; i++) {
                var FR = new FileReader();
                FR.onload = function(e) {
                    base64_images += e.target.result + '#';
                    if (!--file_count)
                        bubble_fn_base64_images(base64_images);
                };
                FR.readAsDataURL(this.files[i]);
            }
        }
    }

    document.getElementById("file-input").addEventListener("change", readFile, false);
</script>

This topic was automatically closed after 70 days. New replies are no longer allowed.