简体   繁体   中英

Make Javascript Variable Available Outside Function

I'm building a custom CKFinder plugin for use on an in-house CMS and am having some trouble with 'undefined' variables.

What I'm doing is pulling copyright information for uploaded images from a database - the details of which are retrieved from a JSON file. I've managed to do that, but my issue seems to revolve around calling variables that are within a function.

Here is my code:

function fileShare( data ) {

var fileName = data.file.getUrl();

var xmlhttp = new XMLHttpRequest();

xmlhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        var json = JSON.parse(this.responseText);

        var copyright = '';
        var watermark = '';

        for ( var i = 0; i < json.image.length; i++) {
            if(json.image[i].image_path == fileName) {

                copyright += json.image[i].copyright;

                if(json.image[i].watermark == 1) {
                    watermark += ' checked';
                }
            }
        }
        return false;
    }
};

xmlhttp.open("GET", "copyright.json", true);
xmlhttp.send();

// Dialog Box Content
finder.request( 'dialog', {
    name: 'CopyrightDialog',
    title: 'Copyright Information',
    template: '<p>Type the name of the copyright holder:</p>' +
    '<input type="text" name="copyright" value="' + copyright + '" placeholder="Image Credit...">' +
    '<p>Protect the image with a watermark?</p>' +
    '<label><input type="checkbox" name="watermark" value="watermark"' + watermark + '>Enable Watermark?</label>',
    buttons: [ 'ok', 'cancel' ]
} ); }

If you look at the final few lines of the code, I am attempting to call copyright and watermark but am obviously having issues with that due to them being defined within a function.

I've removed var from both, without success, so any support would be much appreciated.

The problem with dialog not updating is due to CKFinder's template caching mechanism. The first use of template will cache it.

The proper way to pass data to a dialog's template is by templateModel property.

function makeDialog( copyright, watermark ) {
    finder.request( 'dialog', {
        name: 'CopyrightDialog',
        title: 'Copyright Information',
        template: '<p>Type the name of the copyright holder:</p>' +
        '<input type="text" name="copyright" value="{{= it.copyright }}" placeholder="Image Credit...">' +
        '<p>Protect the image with a watermark?</p>' +
        '<label><input type="checkbox" name="watermark" value="watermark" {{= it.watermark }}>Enable Watermark?</label>',
        buttons: [ 'ok', 'cancel' ],
        templateModel: new Backbone.Model( {
            copyright: copyright,
            watermark: watermark
        } )
    } );
}

You should call this above function in your xmlhttp.onreadystatechange handler after copyright and watermark are created.

Also check dialog guide in docs .

Having asked the people behind CKFinder whether there was any precedent for a plugin such as this, their response was 'no' so I'm happy to share my code.

As a starting point, I dipped into their 'Custom Dialog' sample code on Github and worked from there.

https://github.com/ckfinder/ckfinder-docs-samples/blob/master/CustomDialog/CustomDialog.js

My final result, posted below, adds an extra button to the main toolbar of CKFinder once an image has been selected. Once clicked, it gathers information from a JSON file - which is generated by a database - and displays this in a dialog box.

From here, I am able to edit information - in my case, copyright and watermark - and save directly to the database through an AJAX call to a PHP script.

Here is the Javascript code I have used. Again, I'm a novice at JS so if anybody is able to provide any improvements please feel free to do so.

CKFinder.define( [ 'jquery', 'backbone' ], function( jQuery, Backbone ) {
    'use strict';

    return {
        init: function( finder ) {

            // Use the white icon as default
            var icon = 'copyright-white.svg';

            // If the .ui-alt-icon class is present, use the black icon as an alternative
            if ( jQuery( 'body' ).hasClass( 'ui-alt-icon' ) ) {
                icon = 'copyright-black.svg';
            }
            this.addCss( '.ui-icon-share:after { background-image: url(' + this.path + 'icon/' + icon + '); }' );

            // Add a button to the "Main" toolbar.
            finder.on( 'toolbar:reset:Main:file', function( evt ) {
                var file = evt.data.file;
                evt.data.toolbar.push( {
                    name: 'Copyright',
                    label: 'Copyright',
                    priority: 105,
                    icon: 'share',
                    action: function() {
                        finder.request( 'imageCopyright', { file: file } );
                    }
                } );
            } );

            // Find the individual properties of the selected image
            function imageCopyright( data ) {

                // Retrieve the URL of the image (data was passed in finder.request)
                var path = data.file.getUrl();

                // Define credit and watermark
                var credit    = '';
                var watermark = '';

                // Use an AJAX call to retrieve the copyright information
                var xmlhttp = new XMLHttpRequest();
                xmlhttp.onreadystatechange = function() {

                    // If the request is complete and OK, pull the data for the selected image
                    if (this.readyState == 4 && this.status == 200) {
                        var json = JSON.parse(this.responseText);
                        for ( var i = 0; i < json.img.length; i++) {
                            if(json.img[i].path == path) {

                                // Overwrite the value of credit
                                credit += json.img[i].credit;

                                // If a watermark is required, overwrite the value of watermark
                                if(json.img[i].watermark == 1) {
                                    watermark += ' checked';
                                }
                            }
                        }

                        // Dialog Box Content
                        function makeDialog( credit, path, watermark ) {
                            finder.request( 'dialog', {
                                name: 'CopyrightDialog',
                                title: 'Copyright Information',
                                template: '<p>Type the name of the copyright holder:</p>' +
                                '<input type="text" name="credit" value="{{= it.credit }}" placeholder="Image Credit...">' +
                                '<p>Protect the image with a watermark?</p>' +
                                '<label><input type="checkbox" name="watermark" value="watermark"{{= it.watermark }}>Enable Watermark?</label>' +
                                '<input type="hidden" name="path" value="{{= it.path }}">',
                                buttons: [ 'ok', 'cancel' ],
                                templateModel: new Backbone.Model( {
                                    credit   : credit,
                                    path     : path,
                                    watermark: watermark
                                } )
                            } );
                        }
                        makeDialog( credit, path, watermark );
                    }
                };

                // JSON file in which copyright data is stored
                xmlhttp.open("GET", "path/to/data.json", true);
                xmlhttp.send();

                // Action to take upon 'ok' click
                finder.on( 'dialog:CopyrightDialog:ok', function( evt ) {

                    // Define the value of the copyright credit
                    var credit    = evt.data.view.$el.find( '[name="credit"]' ).val();

                    // Define the value of the image path
                    var path      = evt.data.view.$el.find( '[name="path"]' ).val();

                    // Define whether a watermark has been requested
                    var watermark = evt.data.view.$el.find( '[name="watermark"]' ).is( ':checked' );

                    // Destroy the dialog.
                    finder.request( 'dialog:destroy' );

                    // Determine whether a watermark was requested
                    if ( watermark === true ) {
                        watermark = 1;
                    } else {
                        watermark = 0;
                    }

                    // Send the copyright information to the database via an AJAX request
                    if (window.XMLHttpRequest) {
                        var xmlhttp = new XMLHttpRequest();
                    }
                    xmlhttp.open("POST", "path/to/database.php", true);
                    xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
                    xmlhttp.send("path=" + path + "&watermark=" + watermark + "&credit=" + credit);
                    return false;
                } );
            }

            // Update the handler
            finder.setHandler( 'imageCopyright', imageCopyright, this );
        }
    };} );

Again, this isn't something I'll be maintaining as an official plugin but feel free to use for your own means.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM