Quill: Loading data from database shows 'True' instead of stored value - javascript

I'm using Quill as an editor. One of the functions I made adds timestamps to the text. The blot works fine and timestamps are added as expected. When the data is loaded back into the Quill editor from the database, though, instead of the timestamp value, Quill marks it as 'True' instead. The timestamp data is saved in the database properly. I'm having an issue figuring out how to make Quill load that data properly.
This is what the timestamp looks like in the editor:
enter image description here
This is what it looks like when inspected:
enter image description here
Here's what it looks like after loading (editor view and code in inspector):
enter image description here
enter image description here
Here's the code I have for my blot currently:
var Embed = Quill.import('blots/embed');
class QuillHashtag extends Embed {
static create(value) {
let node = super.create(value);
node.innerHTML = `${value}`;
node.setAttribute("data", value);
return node;
}
static formats(node) {
// We will only be called with a node already
// determined to be a Link blot, so we do
// not need to check ourselves
return node.getAttribute('data');
}
}
QuillHashtag.blotName = 'timeStamp';
QuillHashtag.className = 'quill-hashtag';
QuillHashtag.tagName = 'timeStamp';
Quill.register({
'formats/timeStamp': QuillHashtag
});
Here's my code for saving the editor:
function saveTrascription() {
var file_data = document.getElementById("transcriptEditorBox").innerHTML;
var jobID = document.getElementById("jobSelect").value;
var set = "set";
$.ajax({
type: "POST",
url: "/transcribe/worker.php",
data: {
transcriptionText: file_data,
saveTranscription: set,
jobID: jobID
},
success: function (response) {
toastr.success(response);
}
});
}
Here's my code for loading the data:
function getTranscriptionJob() {
var jobID = document.getElementById("jobSelect").value;
var audioPlayer = document.getElementById("audioPlayerDiv");
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var returnedData = JSON.parse(this.responseText);
if (
returnedData.transcriptionText ==
"Transcription job not finshed. Try again shortly."
) {
toastr.warning("Transcription job not finshed. Try again shortly.");
return true;
} else {
document.getElementById("jobSelectRow").style.display = "none";
document.getElementById("editorRow").style.display = "block";
var delta = quill.clipboard.convert(returnedData.transcriptionText);
quill.setContents(delta, 'silent');
//quill.clipboard.dangerouslyPasteHTML(0, returnedData.transcriptionText);
audioPlayer.innerHTML =
'<audio onloadeddata="initProgressBar()" onplay="showPauseButton()" onpause="showPlayButton()" ontimeupdate="updateProgressBar()" controls id="audioPlayer" ><source src="' +
returnedData.audioFile +
'" type="audio/mpeg" >Your browser does not support the audio element.</audio>';
toastr.info("Press Alt+P to play/pause the audio file.");
return true;
}
}
};
var url = "/transcribe/worker.php?getTranscriptionJob=set&jobID=" + jobID;
xhttp.open("GET", url, true);
xhttp.send();
}
Any help with this is really appreciated! I'm very lost on what is going wrong. I think it has something to do with that formats snippet in the blot code, but not entirely sure.

Related

Why I cannot open a CSV file using JQuery and FileContentResult

I'm trying to make an ajax call (I specifically don't want to do it using ActionLink).
I'm having a controller that is like this:
public IActionResult ExportUsers(List<string> listOfEmails)
{
/*some data processing*/
return File(result, "text/csv", "ExportCandidates.csv");
}
On the other side with ajax I do this simple call:
$.ajax({
url: '/Admin/Testcenter/GenerateInvitationPreview',
type: 'post',
data: {
//some input data to send to the controller ​
​},
​success: function (response) {
​)
​}
​});
I know there exists something for pdf files where you return a base64 file and with the response in the ajax call you just write something like pdfWindow.document.write(...) and this will open a new window with a pdf file.
Is there a way to extract the response for my CSV file and generate it so the user downloads it ?
USE NPOI Library for Excel Sheet Generation
//Generate Excel Sheet
try
{
Guid gid = Guid.NewGuid();
string ext = ".xls";
string[] Headers = { "Appointments Id", "Date of Appointment", "Doctor Name", "Patient Name", "Visit Type", "Status" };
string fileName = "AppointmentsExcelSheet_" + gid.ToString() + ext;
var serverpath = _env.ContentRootPath;
string rootpath = serverpath + "/wwwroot/ExcelSheets/" + fileName;
FileInfo file = new FileInfo(Path.Combine(rootpath, fileName));
var memorystream = new MemoryStream();
using (var fs = new FileStream(rootpath, FileMode.Create, FileAccess.Write))
{
IWorkbook workbook = new XSSFWorkbook();
ISheet excelSheet = workbook.CreateSheet("Appointments List");
IRow row = excelSheet.CreateRow(0);
var font = workbook.CreateFont();
font.FontHeightInPoints = 11;
font.FontName = "Calibri";
font.Boldweight = (short)FontBoldWeight.Bold;
for (var i = 0; i < Headers.Length; i++)
{
var cell = row.CreateCell(i);
cell.SetCellValue(Headers[i]);
cell.CellStyle = workbook.CreateCellStyle();
cell.CellStyle.SetFont(font);
}
var result = _Appointment.GetAppoinmentsPDf();
int index = 1;
foreach (var app in result.Items)
{
//var PatientDob = Convert.ToDouble(app.PatientDOB);
row = excelSheet.CreateRow(index);
row.CreateCell(0).SetCellValue(app.AppointmentId);
row.CreateCell(1).SetCellValue(app.DateofAppointment+" "+app.TimeofAppointment);
row.CreateCell(2).SetCellValue(app.DoctorFullName);
row.CreateCell(3).SetCellValue(app.SelectedPatientName);
row.CreateCell(4).SetCellValue(app.PurposeofVisit);
if (app.IsActive == false)
{
row.CreateCell(5).SetCellValue("Inactive");
}
else
{
row.CreateCell(5).SetCellValue("Active");
}
index++;
}
workbook.Write(fs);
}
using (var filestream = new FileStream(rootpath, FileMode.Open))
{
filestream.CopyToAsync(memorystream);
}
memorystream.Position = 0;
//send filepath to JQuery function
response.Msg = "/ExcelSheets/" + fileName;
}
catch (Exception Ex)
{
//exception code
}
return Ok(reponse.Msg)
//JavaScript
function AppointmentsExcelSheet() {
//var token = Token;
//var link = path;
debugger
$.ajax({
//'Content-Type': 'application/pdf.',
type: "GET",
url: "/api/Appointments/GetAppointmentsExcelSheet",
beforeSend: function () {
$.blockUI({
message: ('<img src="/images/FadingLines.gif"/>'),
css: {
backgroundColor: 'none',
border: '0',
'z-index': 'auto'
}
});
},
complete: function () {
$.unblockUI();
},
success: function (data) {
debugger
//downloads your Excel sheet
window.location.href = data.msg;
}
});
}
The best way to do what you want to do is to not use AJAX, but use either a link click that opens a new window (since you are passing in parameters) If you could use a
<form target="_blank">
to open a form response. Inside the form can be a field or fields that contains the list of emails (it can be one field, or multiple input fields with the same name). Your action handler can accept that list, parse it, and return a File response, and the natural result of opening the new window from the form post operation is a file that opens up.

asynchronous HTTP (ajax) request works in script tag but not in js file

I have this ajax call here in a script tag at the bottom of my page. Everything works fine! I can set a breakpoint inside the 'updatestatus' action method in my controller. My server gets posted too and the method gets called great! But when I put the javascript inside a js file the ajax call doesn't hit my server. All other code inside runs though, just not the ajax post call to the studentcontroller updatestatus method.
<script>
$(document).ready(function () {
console.log("ready!");
alert("entered student profile page");
});
var statusdropdown = document.getElementById("enumstatus");
statusdropdown.addEventListener("change", function (event) {
var id = "#Model.StudentId";
var url = '#Url.Action("UpdateStatus", "Student")';
var status = $(this).val();
$.post(url, { ID: id, Status: status }, function (data) {
// do something with the returned value e.g. display a message?
// for example - if(data) { // OK } else { // Oops }
});
var e = document.getElementById("enumstatus");
if (e.selectedIndex == 0) {
document.getElementById("statusbubble").style.backgroundColor = "#3fb34f";
} else {
document.getElementById("statusbubble").style.backgroundColor = "#b23f42";
}
}, false);
</script>
Now I put this at the bottom of my page now.
#section Scripts {
#Scripts.Render("~/bundles/studentprofile")
}
and inside my bundle.config file it looks like this
bundles.Add(new ScriptBundle("~/bundles/studentprofile").Include(
"~/Scripts/submitstatus.js"));
and submitstatus.js looks like this. I know it enters and runs this code because it I see the alert message and the background color changes. So the code is running. Its just not posting back to my server.
$(document).ready(function () {
console.log("ready!");
alert("submit status entered");
var statusdropdown = document.getElementById('enumstatus');
statusdropdown.addEventListener("change", function (event) {
var id = "#Model.StudentId";
var url = '#Url.Action("UpdateStatus", "Student")';
var status = $(this).val();
$.post(url, { ID: id, Status: status }, function (data) {
// do something with the returned value e.g. display a message?
// for example - if(data) { // OK } else { // Oops }
});
var e = document.getElementById('enumstatus');
if (e.selectedIndex == 0) {
document.getElementById("statusbubble").style.backgroundColor = "#3fb34f";
} else {
document.getElementById("statusbubble").style.backgroundColor = "#b23f42";
}
}, false);
});
In the console window I'm getting this error message.
POST https://localhost:44301/Student/#Url.Action(%22UpdateStatus%22,%20%22Student%22) 404 (Not Found)
Razor code is not parsed in external files so using var id = "#Model.StudentId"; in the main view will result in (say) var id = 236;, in the external script file it will result in var id = '#Model.StudentId'; (the value is not parsed)
You can either declare the variables in the main view
var id = "#Model.StudentId";
var url = '#Url.Action("UpdateStatus", "Student")';
and the external file will be able to access the values (remove the above 2 lines fro the external script file), or add them as data- attributes of the element, for example (I'm assuming enumstatus is a dropdownlist?)
#Html.DropDownListFor(m => m.enumStatus, yourSelectList, "Please select", new { data_id = Model.StudentId, data_url = Url.Action("UpdateStatus", "Student") })
which will render something like
<select id="enumStatus" name="enumStatus" data-id="236" data-url="/Student/UpdateStatus">
Then in the external file script you can access the values
var statusbubble = $('#statusbubble'); // cache this element
$('#enumStatus').change(function() {
var id = $(this).data('id');
var url = $(this).data('url');
var status = $(this).val();
$.post(url, { ID: id, Status: status }, function (data) {
....
});
// suggest you add/remove class names instead, but if you want inline styles then
if (status == someValue) { // the value of the first option?
statusbubble.css('backgroundColor', '#3fb34f');
} else {
statusbubble.css('backgroundColor', '#b23f42');
};
});

Load a JavaScript event the last in CRM form

I have one image saved in Notes with every form in my CRM Online 2013 custom entity. I am using the following code to query the image and show it in an Image tag in a Web Resource on the form. For debugging purposes I was calling the following code through a button, but I want this process of querying the Notes and displaying the image in the web resource to be automatic when the form load. Here is my code:
<html><head><meta charset="utf-8"></head>
<body>
<img id="image" src="nothing.jpg" style="width: 25%; height: auto;" />
<script type="text/javascript">
$(windows).load(function()
{
var recordId = window.parent.Xrm.Page.data.entity.getId();
var serverUrl = Xrm.Page.context.getServerUrl().toString();
var ODATA_ENDPOINT = "XRMServices/2011/OrganizationData.svc";
var objAnnotation = new Object();
ODataPath= serverUrl+ODATA_ENDPOINT;
var temp= "/AnnotationSet?$select=DocumentBody,FileName,MimeType,ObjectId&$filter=ObjectId/Id eq guid'" + recordId + "'";
var result =serverUrl + ODATA_ENDPOINT + temp;
var retrieveRecordsReq = new XMLHttpRequest();
retrieveRecordsReq.open('GET', ODataPath + temp, false);
retrieveRecordsReq.setRequestHeader("Accept", "application/json");
retrieveRecordsReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
retrieveRecordsReq.onreadystatechange = function ()
{
if (this.readyState == 4 /* complete */)
{
if (this.status == 200)
{
this.onreadystatechange = null; //avoids memory leaks
var data = JSON.parse(this.responseText, SDK.REST._dateReviver);
if (data && data.d && data.d.results)
{
SuccessFunc(JSON.parse(this.responseText, SDK.REST._dateReviver).d.results);
}
}
else
{
alert(SDK.REST._errorHandler(this));
}
}
};
var x = new XMLHttpRequest();
x.open("GET", result, true);
x.onreadystatechange = function ()
{
if (x.readyState == 4 && x.status == 200)
{
var doc = x.responseXML;
var title = doc.getElementsByTagName("feed")[0].getElementsByTagName("entry")[0].getElementsByTagName("content")[0].getElementsByTagName("m:properties")[0].getElementsByTagName("d:DocumentBody")[0].textContent;
document.getElementById('image').src ="data:image/png;base64,"+title;
}
};
x.send(null);
});
</script>
</body></html>
I have removed the button tag..now I want this the query to happen on page Load, but nothing happens when I refresh the form. In my opinion the function loads before the annotation loads. Is there a way to make it wait and load the last?
If you want to wait for the parent window to load I think $(windows).load(myFunction); should do the trick.
Maybe $ is undefined because you did not add jQuery to your webressource.
There are also a few little mistakes and unattractive things:
First:
You will get a wrong server url.
If you want to access the Xrm-object in a webresource you always have to use window.parent.Xrm or you put it in a variable var Xrm = window.parent.Xrm;
For example:
var Xrm = window.parent.Xrm;
var recordId = Xrm.Page.data.entity.getId();
var serverUrl = Xrm.Page.context.getServerUrl().toString();
Second:
The ODataPath variable is not declared. Use var ODataPath= serverUrl+ODATA_ENDPOINT; instead. By the way the value of the ODataPath has nothing to do with OData. It is more the REST-Endpoint of Dynamics CRM.
My script would look like this:
var Xrm, recordId, serverUrl, restEndpointUrl, odataQuery, fullRequestUrl, xmlRequest;
Xrm = window.parent.Xrm;
recordId = Xrm.Page.data.entity.getId();
serverUrl = Xrm.Page.context.getServerUrl().toString();
restEndpointUrl = serverUrl + "/XRMServices/2011/OrganizationData.svc";
^ I think a '/' was missing there
odataQuery = "/AnnotationSet?$select=DocumentBody,FileName,MimeType,ObjectId&$filter=ObjectId/Id eq guid'" + recordId + "'";
fullRequestUrl = restEndpointUrl + odataQuery;
I also dont understand why you use the second HttpRequest.
All of this code is not tested.

AJAX File Upload with XMLHttpRequest that support i.e 9

I am trying to upload a file using ajax. The code below works perfectly on all browsers except i.e 9 and previous versions. Unfortunately I am forced to support these browsers so I am wondering how I could modify this code so it will work on i.e.
I have seen some posts suggest using an iframe but i fail to see how this fixes my problem.
I have tried using fileInput.name since it seems that i.e doesn't allow me to have an array of files, this meant that I could actually get to the line where it sends but I wasn't sure what that line should be. xhr.send(fileInput); didn't seem to work.
Also attempted using formdata but then also fould that ie9 didn't support that.
Your help would be greatly appreciated.
<script>
function uploadFile(fileInput, label1, label2, filename) {
var fileInput = document.getElementById(fileInput);
var xhr;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.open('POST', 'Create/Upload');
xhr.setRequestHeader('Content-type', 'multipart/form-data');
//Appending file information in Http headers
//xhr.setRequestHeader('X-File-Name', filename);
xhr.setRequestHeader('X-File-Type', fileInput.files[0].name);
xhr.setRequestHeader('X-File-Type', fileInput.files[0].type);
xhr.setRequestHeader('X-File-Size', fileInput.files[0].size);
xhr.setRequestHeader('X-Type', label1);
//Sending file in XMLHttpRequest
xhr.send(fileInput.files[0]);
//xhr.send(fileInput);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
$('#' + label1).text(xhr.responseText.replace(/\"/g, ""));
document.getElementById(label1).style.color = "green";
document.getElementById(label2).style.display = 'none';
}
else {
$('#' + label1).text("File upload failed");
document.getElementById(label1).style.color = "red";
}
}
}
document.getElementById('uploaderAuto').onsubmit = function () {
myfile = $('#fileInputAuto').val();
var ext = myfile.split('.').pop();
ext = ext.toLowerCase();
if (ext == "pdf" || ext == "docx" || ext == "doc" || ext == "odf" || ext == "rtf") {
uploadFile('fileInputAuto', 'Auto', "AutoView", myfile);
} else {
alert("The following is a list of accepted file types:\n\n - Word Document (*.doc)\n - Word Document (*.docx)\n - Portable Document Format (*.pdf)\n - Open Document Format (*.odf)\n - Rich Text Format (*.rtf)\n\nPlease choose a file with one of these file types.");
}
return false;
}
document.getElementById('uploaderOther1').onsubmit = function () {
myfile = $('#fileInputOther1').val();
uploadFile('fileInputOther1', 'Other1', 'Other1View', myfile);
return false;
}
document.getElementById('uploaderOther2').onsubmit = function () {
myfile = $('#fileInputOther2').val();
uploadFile('fileInputOther2', 'Other2', 'Other2View', myfile);
return false;
}
</script>
I ended up using the script from here: http://www.phpletter.com/Our-Projects/AjaxFileUpload/ and it works very well.
I was using asp.net server side so this tutorial helped: http://totalpict.com/b/asp.net%20generic/5/34396

Function can be bypassed by page refresh

I've searched for hours to get a solution for my problem. But I have to ask the community now. I've programmed an ajax file upload system. Here is the Javascript:
var handleUpload = function(event) {
event.preventDefault();
event.stopPropagation();
var fileInput = document.getElementById('fileAvatar');
var data = new FormData();
data.append('ajax', true);
data.append('avatar', fileInput.files[0]);
var request = new XMLHttpRequest();
request.upload.addEventListener('error', function(event) {
alert('Upload Failed');
});
request.addEventListener('readystatechange',function(event) {
if (this.readyState == 4) {
if (this.status == 200) {
var uploaded = this.response.split("|");
// DO SOME ERROR HANDLING IN THIS AREA
if (uploaded[0] == 'upload_success') {
$('.avatarCropImage').attr('src','<?php echo USERFILES;?><?php echo $log_username; ?>/' + uploaded[1]);
$('.cropInput').attr('type',uploaded[2]);
showPopup('cropAvatar');
/************************/
/***** Problem Area *****/
/************************/
} else {
showPopup('errorNotification');
_('popupError').innerHTML = 'Something went wrong. Please try again.';
}
} else {
alert('Error' + this.status);
}
}
});
request.open('POST','<?php echo $url_data; ?>');
request.setRequestHeader('Cashe-Control', 'no-cashe');
request.send(data);
}
window.addEventListener('load', function() {
var submit = document.getElementById('submitAvatar');
submit.addEventListener('click',handleUpload);
});
The file upload works fine and as you can see, after the file was uploaded I push the uploaded image into a popup called cropAvatar.
Then the user has to crop an area to get a thumbnail of his avatar. If he selects an area and clicks on the Crop-Button, the Crop-Function will be run:
function cropImage() {
var top = $('.cropBox').position().top - 3;
var left = $('.cropBox').position().left - 3;
var width = $('.cropBox').width();
var height = $('.cropBox').height();
var src = $('.avatarCropImage').attr('src');
var type = $('.cropInput').attr('type');
var ajax = ajaxObj("POST", "<?php echo $url_data; ?>");
ajax.onreadystatechange = function() {
if(ajaxReturn(ajax) == true) {
if (ajax.responseText == "") {
$('.buttonClose').click();
$('.avatarImage').attr('src',src);
$('.cropAvatar').css('display','none');
} else {
alert(ajax.responseText);
showPopup('errorNotification');
_('popupError').innerHTML = 'Something went wrong. Please try again.';
}
}
}
ajax.send("action=avatar&top="+top+"&left="+left+"&width="+width+"&height="+height+"&src="+src+"&type="+type);
}
This also works pretty well. The problem now is that the user can bypass the Crop-Function when he reloads the page. Do you have any solution for that?
I also tried to fix this problem by entering the following code into the Problem Area:
// cropImage() is the Crop-Function
window.unload = cropImage();
Thanks for helping.
Don't save the avatar until the user has done the cropping step.
Leave the file as a dangling temp file until the user has completed the whole upload wizard.
I can come up with a similar scenario:
When you paste a link into a Facebook post, Facebook will give you a thumbnail image for the link. What if you then cancel the post? Where does the thumbnail go, or actually, where has it been since there was no post yet? It's all in a temporary structure until you commit, ie. complete the post.

Categories