CKEditor response callback after file attached successfully - javascript

Using CKEditor to send email and upload attachments. Below is the minimal configuration I've from this source.
CKEDITOR.replace('email.Message', {
filebrowserUploadUrl: '/Controller/UploadAttachment',
extraPlugins: 'attach', // attachment plugin
toolbar: this.customToolbar, //use custom toolbar
autoCloseUpload: true, //autoClose attachment container on attachment upload
validateSize: 30, //30mb size limit
onAttachmentUpload: function(response) {
/*
the following code just utilizes the attachment upload response to generate
ticket-attachment on your page
*/
attachment_id = $(response).attr('data-id');
if (attachment_id) {
attachment = $(response).html();
$closeButton = $('<span class="attachment-close">').text('x').on('click', closeButtonEvent)
$('.ticket-attachment-container').show()
.append($('<div>', {
class: 'ticket-attachment'
}).html(attachment).append($closeButton))
.append($('<input>', {
type: 'hidden',
name: 'attachment_ids[]'
}).val(attachment_id));
}
}
});
On the Controller side I've got below code
const string scriptTag = "<script type='text/javascript'>window.parent.CKEDITOR.tools.callFunction({0}, '{1}', '{2}')</script>";
public ContentResult UploadAttachment()
{
string basePath = HttpContext.Server.MapPath("~/assets/Images/");
const string baseUrl = #"/ckfinder/userfiles/";
var funcNum = 0;
int.TryParse(Request["CKEditorFuncNum"], out funcNum);
if (Request.Files == null || Request.Files.Count < 1)
return BuildReturnScript(funcNum, null, "No file has been sent");
if (!System.IO.Directory.Exists(basePath))
return BuildReturnScript(funcNum, null, "basePath folder doesn't exist");
var receivedFile = Request.Files[0];
var fileName = receivedFile.FileName;
if (string.IsNullOrEmpty(fileName)) {
return BuildReturnScript(funcNum, null, "File name is empty");
}
var sFileName = System.IO.Path.GetFileName(fileName);
var nameWithFullPath = System.IO.Path.Combine(basePath, sFileName);
//Note: you may want to consider using your own naming convention for files, as this is vulnerable to overwrites
//e.g. at the moment if two users uploaded a file called image1.jpg, one would clash with the other.
//In the past, I've used Guid.NewGuid() combined with the file extension to ensure uniqueness.
receivedFile.SaveAs(nameWithFullPath);
var url = baseUrl + sFileName;
return BuildReturnScript(funcNum, url, null);
}
private ContentResult BuildReturnScript(int functionNumber, string url, string errorMessage) {
return Content(
string.Format(scriptTag, functionNumber, HttpUtility.JavaScriptStringEncode(url ? ? ""), HttpUtility.JavaScriptStringEncode(errorMessage ? ? "")),
"text/html"
);
}
Below is the response I get back inside onAttachmentUpload - function
<form enctype="multipart/form-data" method="POST" dir="ltr" lang="en" action="/Controller/UploadAttachment?CKEditor=email_Message&CKEditorFuncNum=0&langCode=en">
<label id="cke_73_label" for="cke_74_fileInput_input" style="display:none"></label>
<input style="width:100%" id="cke_74_fileInput_input" aria-labelledby="cke_73_label" type="file" name="attachment" size="38">
</form>
<script>
window.parent.CKEDITOR.tools.callFunction(98);
window.onbeforeunload = function({
window.parent.CKEDITOR.tools.callFunction(99)
});
</script>
But it is expecting some data-id for attachment id. I've no idea what the response should look like. Could someone tell me what the actual response should look like and what is the data-id its expecting as attr in response? Also, is there anyway I can upload multiple files with this?

This is how I am returning the response now and rendering the attached file. Hope it might help someone in future.
[AcceptVerbs(HttpVerbs.Post)]
public ContentResult UploadAttachment() {
string basePath = HttpContext.Server.MapPath("~/somepath");
var funcNum = 0;
int.TryParse(Request["CKEditorFuncNum"], out funcNum);
if (Request.Files == null || Request.Files.Count < 1)
return Content("No file has been sent");
if (!System.IO.Directory.Exists(basePath))
Directory.CreateDirectory(Path.Combine(basePath));
var receivedFile = Request.Files[0];
var fileName = receivedFile.FileName;
if (string.IsNullOrEmpty(fileName)) {
return Content("File name is empty");
}
var sFileName = System.IO.Path.GetFileName(fileName);
var nameWithFullPath = Path.Combine(basePath, sFileName);
receivedFile.SaveAs(nameWithFullPath);
var content = "<span data-href=\"" + nameWithFullPath + "\" data-id=\"" + funcNum + "\"><i class=\"fa fa-paperclip\"> </i> " + sFileName + "</span>";
return Content(content);
}
and on the JS side I have below code to append the uploaded file name:
CKEDITOR.replace('email.Message', {
filebrowserUploadUrl: '/Controller/UploadAttachment',
extraPlugins: 'attach', // attachment plugin
toolbar: this.customToolbar, //use custom toolbar
autoCloseUpload: true, //autoClose attachment container on attachment upload
validateSize: 30, //30mb size limit
onAttachmentUpload: function(response) {
/*
the following code just utilizes the attachment upload response to generate
ticket-attachment on your page
*/
attachment_id = $(response).attr('data-id');
if (attachment_id) {
attachment = response;
$closeButton = '<span class="attachment-close btn btn-danger float-right" style="margin-top:-7px"><i class="fa fa-trash"></i></span>'; //.on('click', closeButtonEvent)
$respDiv = '<ol class="breadcrumb navbar-breadcrumb" style="padding:18px 15px"><li style="display:block">' + attachment + $closeButton + '</li></ol>';
$('.ticket-attachment-container').show()
.append($('<div>', {
class: 'ticket-attachment'
}).html($respDiv))
.append($('<input>', {
type: 'hidden',
name: 'attachment_ids[]'
}).val(attachment_id));
$('.ticket-attachment-container').on('click', '.attachment-close', function() {
$(this).closest('.ticket-attachment').remove();
if (!$('.ticket-attachment-container .ticket-attachment').length)
$('.ticket-attachment-container').hide();
});
}
}
});

Related

How to Drop Multiple files in Dropzone.js in ASP.Net core Razorpages

Im Stuck with the problem that I can't get the "UploadMultiple" to work.
Whenever I try to Drop more than one File at once (drag and dropp 3 selected PDF files for example) I don't recieve any files in the c# controller.
The View seems to work, as there are no errors when dropping the Files.
In the controller however, I don't recieve any files (files.Count = 0).
these are my code snippets:
View HTML:
<div class="col-md-8">
<form id="fileUploadForm" class="text-center dropzone needsclick dz-clickable" method="post" enctype="multipart/form-data" style="min-height: 500px;">
</form>
</div>
JS:
Dropzone.autoDiscover = false;
$("#fileUploadForm").dropzone({
url: "/UploadView",
paramName: "files",
uploadMultiple: true,
parallelUploads: 1,
maxFilesize: 50,
init: function () {
this.on('success', function (file) {
var element = document.getElementById("submitbutton");
element.style.display = "inline";
var args = Array.prototype.slice.call(arguments);
var lowercaseName = file.name.toLowerCase()
if (!lowercaseName.includes(".pdf") && args[1] === "success") {
$("#directUploadDocs").append("<p>" + file.name + "</p><br />");
} else {
switch (args[1]) {
case "HashFailed":
$("#errorDocs").append("<div><h4>CUSTOM_TEXT</h4><p>" + file.name + "</p></div>");
break;
case "UnknownFile":
$("#errorDocs").append("<div><h4>CUSTOM_TEXT</h4><p>" + file.name + "</p></div>");
break;
case "success":
console.log("success");
break;
default:
console.log("sorry an error happened");
}
}
});
},
});
C# Controller:
public async Task<IActionResult> OnPostAsync(ICollection<IFormFile> files)
{
var directoryPath = Path.Combine(_appSettings.UploadFolder, user.SessionID);
Directory.CreateDirectory(directoryPath);
foreach (var file in files)
{
var uploadPath = Path.Combine(_appSettings.UploadFolder, user.SessionID, Guid.NewGuid().ToString() + Path.GetExtension(file.FileName));
if (file.Length > 0)
{
Do Something;
}
}
return Content("success");
}
I know that I wrote pretty custom code additional to the reccomended code from dropzone.js, but I hope its still possible to fix that Problem.
SOLVED!
SOLUTION:
Bruce Adams Posted an answer that actually worked for me:
new C# controller:
public async Task<IActionResult> OnPostAsync()
{
var directoryPath = Path.Combine(_appSettings.UploadFolder, user.SessionID);
Directory.CreateDirectory(directoryPath);
foreach (var file in Request.Form.Files)
{
var uploadPath = Path.Combine(_appSettings.UploadFolder, user.SessionID, Guid.NewGuid().ToString() + Path.GetExtension(file.FileName));
if (file.Length > 0)
{
Do Something;
}
}
return Content("success");
}

How to change qr code filename while downloading the file using html.twig and javascript

I have a qr-code button. On click, qr-code is generated and dialog to save the image format pops-up. In which the filename always comes as "qrcode.png". I have to dynamically change the filename to the name of the files from where the qr-code is generated.
Please, help. I am new to this technology.
HTML TWIG
<th data-field="QR-BTN" data-width="60px" data-orderable="false">{{ 'QR'|trans }}</th>
JAVASCRIPT
var QREXPORT = (function() {
var qrCodeExport = function (e){
e.preventDefault();
//goqr.me api url
const QRCODE_API_URL = "https://api.qrserver.com/v1/create-qr-code/?"; //Library Used
var $form = $('#modal-qr-export-offering'),
qrFormat = $("input[name='qrCodeType']:checked").val(),
jsFormData = $form.data('bs.modal'),
accessCode = jsFormData.options.accesscode;
var params = {
data: "SESSION-" + accessCode,
size: "250x250",
margin: 0,
download: 1,
format: qrFormat,
};
window.location.href = QRCODE_API_URL + $.param(params);
};
return {
init: function() {
$(document).ready(function(){
$('#radioSvg').prop('checked', true);
$('#modal-qr-export-offering').on('hidden.bs.modal', function() {
location.reload();
});
});
$(document).on('click', '.js-btn-submit-form', qrCodeExport);
}
};
})();
QREXPORT.init();
Try using the a tag with download attribute...?
const linkEl = document.createElement('a')
linkEl.href = QRCODE_API_URL + $.param(params);
linkEl.download = 'download-name-here.png'
document.body.appendChild(linkEl)
linkEl.click()
// Maybe remove the link after it worked...?
linkEl.remove()

how to load data using a javascript

I have almost zero experience with Javascript , I need to use this Javascript in my php script .
<script>
let arr = ["alfa", "beta", "charlie"]
const updateResult = query => {
let resultList = document.querySelector(".result");
resultList.innerHTML = "";
arr.map(algo =>{
query.split(" ").map(word =>{
if(algo.toLowerCase().indexOf(word.toLowerCase()) != -1){
resultList.innerHTML += `<li class="list-group-item">${algo}</li>`;
}
})
})
}
updateResult("")
</script>
This script load the data using
let arr =
However suppose I have all the data specified there in a file in this format
c:/data/mydata.txt
and the data.txt contains data in this form (one data per row)
alfa
bravo
charlie
Now how should I change the javascript above to load the data from c:/data/mydata.txt and not using
let arr = ["alfa", "beta", "charlie"]
?
Thank you
You do not need to change your file, but you cannot use it directly due to security issues. If I would write a Javascript which reads your secret files and you load my page, all your secrets would be revealed, therefore, if you want to load a file, you either have to allow your user to upload it and once the user uploads the file do your logic, or, you can request it via AJAX.
How to upload a file
An example for this is
<!DOCTYPE html>
<html>
<body onload="myFunction()">
<input type="file" id="myFile" multiple size="50" onchange="myFunction()">
<p id="demo"></p>
<script>
function myFunction(){
var x = document.getElementById("myFile");
var txt = "";
if ('files' in x) {
if (x.files.length == 0) {
txt = "Select one or more files.";
} else {
for (var i = 0; i < x.files.length; i++) {
txt += "<br><strong>" + (i+1) + ". file</strong><br>";
var file = x.files[i];
if ('name' in file) {
txt += "name: " + file.name + "<br>";
}
if ('size' in file) {
txt += "size: " + file.size + " bytes <br>";
}
}
}
}
else {
if (x.value == "") {
txt += "Select one or more files.";
} else {
txt += "The files property is not supported by your browser!";
txt += "<br>The path of the selected file: " + x.value; // If the browser does not support the files property, it will return the path of the selected file instead.
}
}
document.getElementById("demo").innerHTML = txt;
}
</script>
<p><strong>Tip:</strong> Use the Control or the Shift key to select multiple files.</p>
</body>
</html>
source: https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_fileupload_files
Getting the file via AJAX
In order to do that, you will need to:
send an AJAX request in your javascript code
parse the request and send back the file via PHP
do your logic in Javascript when the request is responded
Example:
HTML
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Download POST Request</title>
</head>
<body>
Enter a text and click the button: <input type="text" id="content" value="Text for the generated pdf">
<button id="download">Send AJAX Request and download file</button>
<script>
document.getElementById('download').addEventListener('click', function () {
var content = document.getElementById('content').value;
var request = new XMLHttpRequest();
request.open('POST', '../server/', true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.responseType = 'blob';
request.onload = function() {
// Only handle status code 200
if(request.status === 200) {
// Try to find out the filename from the content disposition `filename` value
var disposition = request.getResponseHeader('content-disposition');
var matches = /"([^"]*)"/.exec(disposition);
var filename = (matches != null && matches[1] ? matches[1] : 'file.pdf');
// The actual download
var blob = new Blob([request.response], { type: 'application/pdf' });
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
// some error handling should be done here...
};
request.send('content=' + content);
});
</script>
</body>
</html>
PHP
<?php
require_once 'vendor/autoload.php';
if($_SERVER['REQUEST_METHOD'] === 'POST') {
header('Content-type: application/pdf');
http_response_code(200);
// Contents
$pdfContent = !empty($_POST['content']) ? $_POST['content'] : 'no content specified';
// Generate the PDOF
$pdf = new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial','B',16);
$pdf->Cell(40,10, $pdfContent);
return $pdf->Output(null, 'foobar-' . time() . '.pdf');
}
// Bad method
http_response_code(405);
exit();
Source: https://nehalist.io/downloading-files-from-post-requests/
You will of course need to modify the code to comply to your needs. Reading a tutorial would not hurt.
you can use ajax for loading data from external file.
a sample of jquery get call is given below. You can also use the same code with your file path and variables.
$("button").click(function(){
$.get("demo_test.php", function(data, status){
alert("Data: " + data + "\nStatus: " + status);
});
});
if you are using pure java script instead of jQuery you have to use pure ajax calls.
for more details about jQuery ajax check this link

Ajax Call to save images in mvc

I Having issue in uploading images, I want to upload four images individually in MVC as shown in below figure(Please click on "Upload Image File" link to show the image), If we choose one file the particular picture wants to save and it wants to show the preview with proper file name as heading. please help me.. thanks in Advance
Upload Image File
Question is not clear but this is a good solution for uploading in MVC using Ajax:
File Upload HTML
<div style="display:none;">
<img id="image" alt="" src="" class="img-responsive">
</div>
<div id="fileUpload">
<span>Choose Image</span>
<input id="txtUploadFile" type="file" name="files" class="upload" />
</div>
#Html.Partial("~/Views/Shared/_UploadPartial.cshtml")
Create a Partial View or added to HTML
**if you create a partial view for below code can use it anywhere on site, or create a .js file either is way will work well.
<script>
var model = #Html.Raw(Json.Encode(Model));
$('#txtUploadFile').on('change', function (e) {
var files = e.target.files;
if (files.length > 0) {
if (window.FormData !== undefined) {
var data = new FormData();
for (var x = 0; x < files.length; x++) {
data.append("file" + x, files[x]);
}
$.ajax({
type: "POST",
url: '/User/UploadFile/' + model,
contentType: false,
processData: false,
data: data,
success: function (result) {
$('#image').attr('src', '#Url.Content("~/Content/img/")' + result.fileName);
},
error: function (xhr, status, p3, p4) {
var err = "Error " + " " + status + " " + p3 + " " + p4;
if (xhr.responseText && xhr.responseText[0] == "{")
err = JSON.parse(xhr.responseText).Message;
console.log(err);
}
});
} else {
alert("This browser doesn't support HTML5 file uploads!");
}
}
});
Controller Method
[HttpPost]
public JsonResult UploadFile(string id)
{
var path = "";
var fileExtension = "";
var fileName = "";
if (Request.Files.Count > 0)
{
HttpPostedFileBase file = Request.Files[0];
if (file != null && file.ContentLength > 0)
{
fileName = Path.GetFileName(file.FileName);
fileExtension = Path.GetExtension(file.FileName);
if (id != "null")
{
//do bits, save to DB etc./..
file.SaveAs(path);
}
}
}
return Json(new { fileName = fileName });
}
Explanation
The file upload html with id="image" is for when you select a image from your directory after pressing the txtUploadFile input, then the partial view or js file or inline script, depending on approach taken will fire the onchange function: $('#txtUploadFile').on('change', function (e) this will do a ajax call to your method in your controller - you can do all your logic like saving to the database ect... from here.
The controller function is then returning the fileName to the success function of the ajax call, assuming you have saved the image somewhere you can then use result.fileName, or whatever to get your image:
$('#image').attr('src', '#Url.Content("~/Content/img/")' + result.fileName);
As you can see the nested image attribute in the file upload HTML is being changed to the newly uploaded image.
Hope this helps.

Unable to upload multiple files with SAP UI5 FileUploader

I'm using the following code to upload multiple documents to the server.
var docFileUploader = new sap.ui.unified.FileUploader({
name : fileUploaderName,
uploadOnChange: false,
uploadUrl: uploadUrlStr,
multiple:true,
additionaldata : nodeObjId ,
fileSizeExceed: function (oEvent) {
var sName = oEvent.getParameter("fileName");
var fSize = oEvent.getParameter("fileSize");
var fLimit = oFileUploader.getMaximumFileSize();
Messenger().post({
message: "File: " + sName + " is of size " + fSize + " MB which exceeds the file size limit of " + fLimit + " MB.",
type: 'error',
showCloseButton: true
});
},
uploadComplete: function (oEvent) {
var sResponse = oEvent.getParameter("response");
console.log(sResponse);
var thisDlg = this.getParent().getParent().getParent().getParent();
console.log(thisDlg);
if (sResponse) {
var m = /^\[(\d\d\d)\]:(.*)$/.exec(sResponse);
if (m[1] == "200") {
uploadSuccess = true;
thisDlg.setBusy(false);
console.log("The document has been uploaded successfully");
setTimeout(function() { Messenger().post("The document has been uploaded successfully");}, 100);
}
else {
thisDlg.setBusy(false);
setTimeout(function() { Messenger().post({
message: 'Oops! Error in document upload. <br>Please try again or contact your administrator.',
type: 'error',
showCloseButton: true
});},100);
}
}
thisDlg.setBusy(false);
console.log("The document has been uploaded successfully");
setTimeout(function() { Messenger().post("The document has been uploaded successfully");}, 100);
thisDlg.close();
thisDlg.destroy();
setTimeout(function() { reloadPage(attrGrpName); }, 100);
}
});
The controller part is as below:
#RequestMapping(value = "doc/upload", method = RequestMethod.POST, consumes = "multipart/form-data")
public #ResponseBody String uploadDoc(#RequestParam("uploadDoc-data") ObjectId nodeId,
#RequestParam(value = "uploadDoc", required = true) MultipartFile[] files, #RequestParam String userId, #RequestParam String passwd) {
if (files != null) {
return service.uploadDoc(nodeId, files[0], userId, passwd);
} else
return "No files found to upload";
}
Even if I use files[0] gives me an ArrayIndexOutofBound 0 Exception. It means the MultipartFile[] is returning an empty array only. I was able to upload one file without multiple attributes. The problem arises if I set the multiple attributes to 'true'. What am I missing? Please help me.

Categories

Resources