Foliotek / Croppie

A Javascript Image Cropper
http://foliotek.github.io/Croppie
MIT License
2.57k stars 884 forks source link

For everyone struggling with Destroying and initializing croppie when working with multiple instances #749

Open RoflJOE opened 3 years ago

RoflJOE commented 3 years ago

Story

Croppie is not removing html elements and added classes to div's, when using the .destroy() function. This results in errors when trying to destroy and reinitialize croppie.

When Croppie runs, it puts on a "croppie-container" class on the initialized div, and adds multiple Croppie-divs to that InnerHTML of that element.

When running destroy(), that code will not be removed. And when trying to reinitialize Croppie, without a page refresh, it fails because it thinks it's already initialized.

TLDR Fix

I had to manually remove the Class and the InnerHTML from the initialized div, to be able to correctly initialize Croppie again.

document.getElementById("CroppieContainerProductPicCreate").innerHTML = "";
document.getElementById("CroppieContainerProductPicCreate").classList.remove("croppie-container");

Example code

const croppieOptions = {
    showZoomer: true,
    enableOrientation: true,
    enforceBoundary: false,
    //mouseWheelZoom: "ctrl",
    viewport: {
        width: 350,
        height: 350,
        type: "square"
    },
    boundary: {
        width: 370,
        height: 370
    }
};

let croppieCreate = null;
let croppieEdit = null;

//Starting croppie for CREATE product
function InitializeCroppieCreateProduct() {
//Making sure Croppie can be initialized every time this function runs
    document.getElementById("CroppieContainerProductPicCreate").innerHTML = "";
    document.getElementById("CroppieContainerProductPicCreate").classList.remove("croppie-container");
    croppieCreate = new Croppie(document.getElementById("CroppieContainerProductPicCreate"), croppieOptions);

}

//Run when FileUpload for CREATE Product changes
document.getElementById('UploadProductPicCreate').addEventListener('change', (input) => {

    if (input.target.files && input.target.files[0]) {
        var reader = new FileReader();

        reader.onload = function (e) {
            croppieCreate.bind({
                url: e.target.result
            }).then(function () {
                document.getElementsByClassName("cr-slider")[0].setAttribute("min", 0.1000); //Setting the slider min zoom manually, when using enforceBoundary: false
            });

        }
        reader.readAsDataURL(input.target.files[0]); // convert to base64 string

        //Whenever the viewport changes, write the Base64 string to hidden field, so we can use it in backend (NOT OPTIMIZED)
        document.getElementById('CroppieContainerProductPicCreate').addEventListener('update', function () {
            croppieCreate.result({
                type: 'base64',
                quality: 1,
                format: 'jpg'
            }).then(function (resp) {
                // Put the Base64 string in a hidden field
                document.getElementById('CroppieBaseCreate').value = resp;
            });
        });
    }
});

//Starting croppie for EDIT product
function InitializeCroppieEditProduct() {
//Making sure Croppie can be initialized every time this function runs
    document.getElementById("CroppieContainerProductPicEdit").innerHTML = "";
    document.getElementById("CroppieContainerProductPicEdit").classList.remove("croppie-container");

    croppieEdit = new Croppie(document.getElementById("CroppieContainerProductPicEdit"), croppieOptions);
}

//Run when FileUpload for EDIT Product changes
document.getElementById('UploadProductPicEdit').addEventListener('change', (input) => {

    if (input.target.files && input.target.files[0]) {
        var reader = new FileReader();

        reader.onload = function (e) {
            croppieEdit.bind({
                url: e.target.result
            }).then(function () {
                document.getElementsByClassName("cr-slider")[0].setAttribute("min", 0.1000); //Setting the slider min zoom manually, when using enforceBoundary: false
            });
        }
        reader.readAsDataURL(input.target.files[0]); // convert to base64 string

        //Whenever the viewport changes, write the Base64 string to hidden field, so we can use it in backend (NOT OPTIMIZED)
        document.getElementById('CroppieContainerProductPicEdit').addEventListener('update', function () {
            croppieEdit.result({
                type: 'base64',
                quality: 1,
                format: 'jpg'
            }).then(function (resp) {
                // Put the Base64 string in a hidden field
                document.getElementById('CroppieBaseEdit').value = resp;
            });
        });
    }
});
HarrisonCreates commented 2 years ago

If GitHub had upvotes, I'd give one to you for this. Thank you!

Edit: Just realized I could leave a thumbs up lol. Thanks again!