Search code examples
javascriptwtformsfilepond

How to get 2 filepond instance with 2 different settings


I want to be able to upload a profile picture as well as a banner picture on the same page. When I configure filepond in 2 separate elements it adds the options from both elements together. Is there a way to instantiate to separate FilePond complete with their own config settings? I tried using this advice, but it bleeds my options from 1 pond to the other.

Here is my jinja template that shows both fileponds being configured with wtforms:

        <div>
            {{ EditProfileform.banner_id(id="user_banner_upload", class="filepond_banner") }}
            <div id="banner_id" class=""></div>
            <div>
                {{ EditProfileform.avatar_id(id="user_avatar_upload", class="filepond_avatar") }}
                <div id="avatar_id-error" class="invalid-feedback"></div>
                <div id="avatar_id" class=""></div>
            </div>
        </div>

2 scripts on the same page to configure 2 fileponds using different elements. Each one works indiviudally, but when paired together FilePond reads in the options from both.

<script>
    document.addEventListener('DOMContentLoaded', function() {
    // Register any plugins
    FilePond.registerPlugin(FilePondPluginImageExifOrientation, FilePondPluginFileEncode, FilePondPluginImagePreview, FilePondPluginImageCrop, FilePondPluginImageEdit);


    FilePond.setOptions({
        labelIdle: `<img src="{{ current_user.avatar(100) }}" />`,
        imagePreviewHeight: 170,
        imageCropAspectRatio: '1:1',
        imageResizeTargetWidth: 200,
        imageResizeTargetHeight: 200,
        stylePanelLayout: 'compact circle',
        styleLoadIndicatorPosition: 'center bottom',
        styleProgressIndicatorPosition: 'right bottom',
        styleButtonRemoveItemPosition: 'left bottom',
        styleButtonProcessItemPosition: 'right bottom',
        server: {
            process: {
                url: '/pondavatar',
                ondata: (formData) => {
                    console.log()
                    formData.append('csrf_token', document.getElementById('csrf_token').value);
                    formData.append('id', uuidv4());
                    //TODO metadata from FilePond?
                    //formData.append('meta', metadata);
                    return formData;
                },
                onload: onResponse
            },
            revert: revertUpload
        },
    });


    // Create FilePond object
    const inputElement = document.getElementById('user_avatar_upload');
    const pond = FilePond.create(inputElement);
    });

function onResponse(r){
    r=JSON.parse(r);
    let avatar_id = r.id;
    document.getElementById('avatar_id').innerHTML = avatar_id;
}

async function revertUpload() {
    const response = await fetch('/pondavatar', {
        method: 'DELETE',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            csrf_token: document.getElementById('csrf_token').value,
            avatar_id: document.getElementById('avatar_id').innerHTML
        })
    });
    if (response.ok) {
        jFlash('Deleted')
    } else {
        jFlash('Not deleted')
    }
}
</script>

<script>
    document.addEventListener('DOMContentLoaded', function() {
    // Register any plugins
    FilePond.registerPlugin(FilePondPluginImageExifOrientation, FilePondPluginFileEncode, FilePondPluginImagePreview, FilePondPluginImageCrop, FilePondPluginImageEdit);

    FilePond.setOptions({
        {% if current_user.banner_file %}
        labelIdle: "<img src=\"{{ current_user.banner() }}\" class=\"bg-img\">",
        {% else %}
        labelIdle: "<div class=\"card-up aqua-gradient\" style=\"height: 185px;\"></div>",
        {% endif %}
        imagePreviewHeight: 170,
        imageCropAspectRatio: '4:1',
        server: {
            process: {
                url: '/pondavatar',
                ondata: (formData) => {
                    console.log()
                    formData.append('csrf_token', document.getElementById('csrf_token').value);
                    formData.append('id', uuidv4());
                    //TODO metadata from FilePond?
                    //formData.append('meta', metadata);
                    return formData;
                },
                onload: onResponse
            },
            revert: revertUpload
        },
    });


    // Create FilePond object
    const inputElement2 = document.getElementById('user_banner_upload');
    const pond2 = FilePond.create(inputElement2);
    });

function onResponse(r){
    r=JSON.parse(r);
    let banner_id = r.id;
    document.getElementById('banner_id').innerHTML = banner_id;
}

async function revertUpload() {
    const response = await fetch('/pondavatar', {
        method: 'DELETE',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            csrf_token: document.getElementById('csrf_token').value,
            banner_id: document.getElementById('banner_id').innerHTML
        })
    });
    if (response.ok) {
        jFlash('Deleted')
    } else {
        jFlash('Not deleted')
    }
}
</script>

    document.addEventListener('DOMContentLoaded', function() {

    // Register any plugins
    FilePond.registerPlugin(FilePondPluginImageExifOrientation, FilePondPluginFileEncode, FilePondPluginImagePreview, FilePondPluginImageCrop, FilePondPluginImageEdit);


    FilePond.setOptions({
        labelIdle: `<img src="https://robohash.org/90f157b03b8ccee392a640fb82a5f97c?size=100x100" />`,
        imagePreviewHeight: 170,
        imageCropAspectRatio: '1:1',
        imageResizeTargetWidth: 200,
        imageResizeTargetHeight: 200,
        stylePanelLayout: 'compact circle',
        styleLoadIndicatorPosition: 'center bottom',
        styleProgressIndicatorPosition: 'right bottom',
        styleButtonRemoveItemPosition: 'left bottom',
        styleButtonProcessItemPosition: 'right bottom',
        server: {
            process: {
                url: '/pondavatar',
                ondata: (formData) => {
                    console.log()
                    formData.append('csrf_token', document.getElementById('csrf_token').value);
                    formData.append('id', uuidv4());
                    //TODO metadata from FilePond?
                    //formData.append('meta', metadata);
                    return formData;
                },
                onload: onResponse
            },
            revert: revertUpload
        },
    });
    // Create FilePond object
    const inputElement = document.getElementById('avatar_upload');
    const pond = FilePond.create(inputElement);
    });

function onResponse(r){
    r=JSON.parse(r);
    let id = r.id;
    document.getElementById('avatar_id').innerHTML = id;
}

async function revertUpload() {
    const response = await fetch('/pondavatar', {
        method: 'DELETE',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            csrf_token: document.getElementById('csrf_token').value,
            avatar_id: document.getElementById('avatar_id').innerHTML
        })
    });
    if (response.ok) {
        document.getElementById('avatar_id').innerHTML = "";
        jFlash('Deleted')
    } else {
        jFlash('Not deleted')
    }
}
.filepond_avatar {
    position: absolute;
    width: 100px;
    height: 100px;
    margin-top: -55px;
    margin-left: 10px;
    border-radius: 100%;
    opacity: 75%;
}

.aqua-gradient {
  background: linear-gradient(40deg, #2096ff, #05ffa3) !important;
}
<head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <!-- CSS only -->
      <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css">
      <link href="/static/css/style.css" rel="stylesheet">
      <script src="https://js.stripe.com/v3/"></script>
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
      <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
    </head>
<body>

<div class="modal-content" style="background-color: darkgray;">
              <div class="modal-header">
                <h4 id="modal-title" class="modal-title">Edit Profile</h4>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
              </div>
              <div id="modal-body" class="modal-body p-0"><div id="edit_profile_template">
        <div>
            
            <div class="card-up aqua-gradient" style="height: 185px;">
              I want to convert this aqua gradient background to a file pond, but I do no know how to get 2 instanations of FilePond
              <input class="filepond_banner" id="banner_upload" name="avatar_upload" type="file">
            </div>
            
            <div id="banner_id" class=""></div>
            <div>
                <div class="filepond--root filepond_avatar filepond--hopper" id="avatar_upload" data-style-panel-layout="compact circle" data-style-button-remove-item-position="left bottom" data-style-button-process-item-position="right bottom" data-style-load-indicator-position="center bottom" data-style-progress-indicator-position="right bottom" data-style-button-remove-item-align="false" data-style-image-edit-button-edit-item-position="bottom center" style="height: 100px;"><input class="filepond--browser" type="file" id="filepond--browser-6jzrcfwr7" name="avatar_upload" aria-controls="filepond--assistant-6jzrcfwr7" aria-labelledby="filepond--drop-label-6jzrcfwr7"><a class="filepond--credits" aria-hidden="true" href="https://pqina.nl/" target="_blank" rel="noopener noreferrer" style="transform: translateY(100px);">Powered by PQINA</a><div class="filepond--drop-label" style="transform: translate3d(0px, 0px, 0px); opacity: 1;"><label for="filepond--browser-6jzrcfwr7" id="filepond--drop-label-6jzrcfwr7" aria-hidden="true"><img src="https://robohash.org/90f157b03b8ccee392a640fb82a5f97c?size=100x100"></label></div><div class="filepond--list-scroller" style="transform: translate3d(0px, 0px, 0px);"><ul class="filepond--list" role="list"></ul></div><div class="filepond--panel filepond--panel-root" data-scalable="false"><div class="filepond--panel-top filepond--panel-root"></div><div class="filepond--panel-center filepond--panel-root" style="transform: translate3d(0px, 0px, 0px) scale3d(1, 1, 1);"></div><div class="filepond--panel-bottom filepond--panel-root" style="transform: translate3d(0px, 100px, 0px);"></div></div><div class="filepond--drip"></div><span class="filepond--assistant" id="filepond--assistant-6jzrcfwr7" role="status" aria-live="polite" aria-relevant="additions"></span><fieldset class="filepond--data"></fieldset></div>
                <div id="avatar_id-error" class="invalid-feedback"></div>
                <div id="avatar_id" class=""></div>
            </div>
        </div>
        <div>
            <form id="edit_profile_form" class="needs-validation p-2" autocomplete="off">
                <div class="p-2">
                    <div class="comment-input">
                        <div style="color: gray;">Name</div>
                        
                        
                        <input class="comment-input form-control" id="name" maxlength="50" name="name" type="text" value="Bob Marley">
                        
                        <div id="name-error" class="invalid-feedback"></div>
                    </div>
                </div>
                <div class="p-2">
                    <div class="comment-input">
                        <div style="color: gray;">About Me</div>
                        
                        
                        <input class="comment-input form-control" id="about_me" maxlength="140" minlength="0" name="about_me" type="text" value="I love science!">
                        
                        <div id="about_me-error" class="invalid-feedback"></div>
                    </div>
                </div>
                <div class="p-2">
                    <div class="comment-input">
                        <!--TODO Reference cities and autocomplete this-->
                        <div style="color: gray;">Location</div>
                        
                        
                        <input class="comment-input form-control" id="location" maxlength="30" name="location" type="text" value="San Francisco, California">
                        
                        <div id="location-error" class="invalid-feedback"></div>
                    </div>
                </div>
                <input class="btn btn-secondary" id="submit" name="submit" style="width: 100%" type="submit" value="Submit">
            </form>
        </div>
    </div></div>
            </div>
    <script src="https://unpkg.com/filepond-plugin-file-encode/dist/filepond-plugin-file-encode.min.js"></script>
    <script src="https://unpkg.com/filepond-plugin-file-validate-size/dist/filepond-plugin-file-validate-size.min.js"></script>
    <script src="https://unpkg.com/filepond-plugin-image-exif-orientation/dist/filepond-plugin-image-exif-orientation.min.js"></script>
    <script src="https://unpkg.com/filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.js"></script>
    <script src="https://unpkg.com/filepond-plugin-image-edit/dist/filepond-plugin-image-edit.js"></script>
    <link rel="stylesheet" href="https://unpkg.com/filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css">
    <script src="https://unpkg.com/filepond-plugin-image-crop/dist/filepond-plugin-image-crop.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment-with-locales.min.js" integrity="sha512-LGXaggshOkD/at6PFNcp2V2unf9LzFq6LE+sChH7ceMTDP0g2kn6Vxwgg7wkPP7AAtX+lmPqPdxB47A0Nz0cMQ==" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj" crossorigin="anonymous"></script>
    <script src="https://unpkg.com/filepond/dist/filepond.min.js"></script>
    <link href="https://unpkg.com/filepond/dist/filepond.min.css" rel="stylesheet">
</body>


Solution

  • Instead of passing options to the FilePond.setOptions functions pass them as a second parameter to the create method.

    const inputElement = document.getElementById('avatar_upload');
    FilePond.create(inputElement, {
      // options here
    })