Basic local file picker
优质
小牛编辑
127浏览
2023-12-01
While we demonstrate how you can add local file picker to the Image dialog, in order for it to be useful in the real-world scenario, you should also enable image uploading functionality - as a way to transport those local images to a server.
TinyMCE HTML JS Edit on CodePenNote: The following code relies on
URL.createObjectURL()
. To check the level of support for this feature across modern browsers, visit this link.
<textarea id="editor"></textarea>
tinymce.init({
selector: '#editor',
plugins: 'image code',
toolbar: 'undo redo | link image | code',
/* enable title field in the Image dialog*/
image_title: true,
/* enable automatic uploads of images represented by blob or data URIs*/
automatic_uploads: true,
/*
URL of our upload handler (for more details check: https://www.tiny.cloud/docs/configure/file-image-upload/#images_upload_url)
images_upload_url: 'postAcceptor.php',
here we add custom filepicker only to Image dialog
*/
file_picker_types: 'image',
/* and here's our custom image picker*/
file_picker_callback: function (cb, value, meta) {
var input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('accept', 'image/*');
/*
Note: In modern browsers input[type="file"] is functional without
even adding it to the DOM, but that might not be the case in some older
or quirky browsers like IE, so you might want to add it to the DOM
just in case, and visually hide it. And do not forget do remove it
once you do not need it anymore.
*/
input.onchange = function () {
var file = this.files[0];
var reader = new FileReader();
reader.onload = function () {
/*
Note: Now we need to register the blob in TinyMCEs image blob
registry. In the next release this part hopefully won't be
necessary, as we are looking to handle it internally.
*/
var id = 'blobid' + (new Date()).getTime();
var blobCache = tinymce.activeEditor.editorUpload.blobCache;
var base64 = reader.result.split(',')[1];
var blobInfo = blobCache.create(id, file, base64);
blobCache.add(blobInfo);
/* call the callback and populate the Title field with the file name */
cb(blobInfo.blobUri(), { title: file.name });
};
reader.readAsDataURL(file);
};
input.click();
}
});
(function() { var isIE = !!window.MSInputMethodContext && !!document.documentMode; if (isIE && document.getElementsByClassName("ie11_optional")[0] !== undefined) { document.getElementsByClassName("ie11_optional")[0].style.display = 'none'; } })(); (function() { tinymce.init({ selector: '#editor', plugins: 'image code', toolbar: 'undo redo | link image | code', /* enable title field in the Image dialog*/ image_title: true, /* enable automatic uploads of images represented by blob or data URIs*/ automatic_uploads: true, /* URL of our upload handler (for more details check: https://www.tiny.cloud/docs/configure/file-image-upload/#images_upload_url) images_upload_url: 'postAcceptor.php', here we add custom filepicker only to Image dialog */ file_picker_types: 'image', /* and here's our custom image picker*/ file_picker_callback: function (cb, value, meta) { var input = document.createElement('input'); input.setAttribute('type', 'file'); input.setAttribute('accept', 'image/*'); /* Note: In modern browsers input[type="file"] is functional without even adding it to the DOM, but that might not be the case in some older or quirky browsers like IE, so you might want to add it to the DOM just in case, and visually hide it. And do not forget do remove it once you do not need it anymore. */ input.onchange = function () { var file = this.files[0]; var reader = new FileReader(); reader.onload = function () { /* Note: Now we need to register the blob in TinyMCEs image blob registry. In the next release this part hopefully won't be necessary, as we are looking to handle it internally. */ var id = 'blobid' + (new Date()).getTime(); var blobCache = tinymce.activeEditor.editorUpload.blobCache; var base64 = reader.result.split(',')[1]; var blobInfo = blobCache.create(id, file, base64); blobCache.add(blobInfo); /* call the callback and populate the Title field with the file name */ cb(blobInfo.blobUri(), { title: file.name }); }; reader.readAsDataURL(file); }; input.click(); } }); })(); (function() { /* TODO: more js, less jekyll */ var id = "file-picker"; var html = decodeURIComponent("%0A%3Ctextarea%20id=%22editor%22%3E%3C/textarea%3E%0A%0A"); var js = decodeURIComponent("%0Atinymce.init(%7B%0A%20%20selector:%20'#editor',%0A%20%20plugins:%20'image%20code',%0A%20%20toolbar:%20'undo%20redo%20%7C%20link%20image%20%7C%20code',%0A%20%20/*%20enable%20title%20field%20in%20the%20Image%20dialog*/%0A%20%20image_title:%20true,%0A%20%20/*%20enable%20automatic%20uploads%20of%20images%20represented%20by%20blob%20or%20data%20URIs*/%0A%20%20automatic_uploads:%20true,%0A%20%20/*%0A%20%20%20%20URL%20of%20our%20upload%20handler%20(for%20more%20details%20check:%20https://www.tiny.cloud/docs/configure/file-image-upload/#images_upload_url)%0A%20%20%20%20images_upload_url:%20'postAcceptor.php',%0A%20%20%20%20here%20we%20add%20custom%20filepicker%20only%20to%20Image%20dialog%0A%20%20*/%0A%20%20file_picker_types:%20'image',%0A%20%20/*%20and%20here's%20our%20custom%20image%20picker*/%0A%20%20file_picker_callback:%20function%20(cb,%20value,%20meta)%20%7B%0A%20%20%20%20var%20input%20=%20document.createElement('input');%0A%20%20%20%20input.setAttribute('type',%20'file');%0A%20%20%20%20input.setAttribute('accept',%20'image/*');%0A%0A%20%20%20%20/*%0A%20%20%20%20%20%20Note:%20In%20modern%20browsers%20input[type=%22file%22]%20is%20functional%20without%0A%20%20%20%20%20%20even%20adding%20it%20to%20the%20DOM,%20but%20that%20might%20not%20be%20the%20case%20in%20some%20older%0A%20%20%20%20%20%20or%20quirky%20browsers%20like%20IE,%20so%20you%20might%20want%20to%20add%20it%20to%20the%20DOM%0A%20%20%20%20%20%20just%20in%20case,%20and%20visually%20hide%20it.%20And%20do%20not%20forget%20do%20remove%20it%0A%20%20%20%20%20%20once%20you%20do%20not%20need%20it%20anymore.%0A%20%20%20%20*/%0A%0A%20%20%20%20input.onchange%20=%20function%20()%20%7B%0A%20%20%20%20%20%20var%20file%20=%20this.files[0];%0A%0A%20%20%20%20%20%20var%20reader%20=%20new%20FileReader();%0A%20%20%20%20%20%20reader.onload%20=%20function%20()%20%7B%0A%20%20%20%20%20%20%20%20/*%0A%20%20%20%20%20%20%20%20%20%20Note:%20Now%20we%20need%20to%20register%20the%20blob%20in%20TinyMCEs%20image%20blob%0A%20%20%20%20%20%20%20%20%20%20registry.%20In%20the%20next%20release%20this%20part%20hopefully%20won't%20be%0A%20%20%20%20%20%20%20%20%20%20necessary,%20as%20we%20are%20looking%20to%20handle%20it%20internally.%0A%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20var%20id%20=%20'blobid'%20+%20(new%20Date()).getTime();%0A%20%20%20%20%20%20%20%20var%20blobCache%20=%20%20tinymce.activeEditor.editorUpload.blobCache;%0A%20%20%20%20%20%20%20%20var%20base64%20=%20reader.result.split(',')[1];%0A%20%20%20%20%20%20%20%20var%20blobInfo%20=%20blobCache.create(id,%20file,%20base64);%0A%20%20%20%20%20%20%20%20blobCache.add(blobInfo);%0A%0A%20%20%20%20%20%20%20%20/*%20call%20the%20callback%20and%20populate%20the%20Title%20field%20with%20the%20file%20name%20*/%0A%20%20%20%20%20%20%20%20cb(blobInfo.blobUri(),%20%7B%20title:%20file.name%20%7D);%0A%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20reader.readAsDataURL(file);%0A%20%20%20%20%7D;%0A%0A%20%20%20%20input.click();%0A%20%20%7D%0A%7D);%0A"); var css = ""; var tabNames = ["run","html","js"]; /* Note: there are some other fields we could populate here to polish this. */ /* See: https://blog.codepen.io/documentation/api/prefill/ */ var data = { title: "TinyMCE Example", description: '', html: html, css: css, css_external: 'https://www.tiny.cloud/css/codepen.min.css', js: js, js_external: 'https://cloud.tinymce.com/5/tinymce.min.js?apiKey=qagffr3pkuv17a8on1afax661irst1hbr4e6tbv888sz91jc' }; document.getElementById("codepen_data_file-picker").value = JSON.stringify(data); /* TODO: */ var tabs = tabNames.map(function(t) { return { tab: document.getElementById("codepen_tab_" + t + "_" + id), pane: document.getElementById("codepen_pane_" + t + "_" + id) }; }); tabs.forEach(function(t) { t.tab.onclick = function(e) { tabs.forEach(function(tt) { tt.pane.style.display = t === tt ? 'block' : 'none'; tt.tab.className = t === tt ? 'codepen_tab_selected' : 'codepen_tab_deselected'; }); e.preventDefault(); }; }); if (document.getElementById("codepen_tab_codepen_" + id) !== null) { document.getElementById("codepen_tab_codepen_" + id).onclick = function() { document.getElementById("codepen_form_" + id).submit(); }; } })();You might also consider our MoxieManager module, which can hook onto file_picker_callback
and provide feature-rich file manager UI right in the popup (check a demo here). With accompanying plugins it is possible to pick files from Dropbox, Google Drive and much more.