I would like to use an AJAX call (via jQuery) to change the HTML of a widget during the upcast function of a CKEditor widget. Here is what I have tried:
CKEDITOR.plugins.add('mywidget', {
requires: 'widget',
icons: 'mywidget',
init: function (editor) {
editor.widgets.add('mywidget', {
button: 'My widget',
template: '<p class="mywidget">Initial text.</p>',
allowedContent: 'p(!mywidget)',
upcast: function (element) {
if (element.hasClass('mywidget')) {
element.setHtml('After upcasting.');
$.get('http://example.com')
.done(function (response) {
element.setHtml('Updated text after AJAX.');
});
return true;
}
return false;
},
});
}
});
When the widget is first instantiated, as expected, it says:
"Initial text."
After I click "Source" and then click "Source" again, as expected again, the text has changed to:
"After upcasting"
However, when the AJAX request comes back, the text does not change to "Updated text after AJAX".
Does anyone know how I can get at the element from inside the AJAX callback? If it is too late to access the element from the AJAX callback, is there any way to use the response from the callback to retroactively edit the markup of the already-upcasted widget? Thank you!
$.get() is asynchronous so the .done part is called after the upcasting had already completed. Use $.ajax() instead and set async: false.
The modified widget code:
CKEDITOR.plugins.add('mywidget', {
requires: 'widget',
icons: 'mywidget',
init: function (editor) {
editor.widgets.add('mywidget', {
button: 'My widget',
template: '<p class="mywidget">Initial text.</p>',
allowedContent: 'p(!mywidget)',
upcast: function (element) {
if (element.hasClass('mywidget')) {
element.setHtml('After upcasting.');
$.ajax({
url: 'http://www.example.com',
async: false,
success: function (result) {
element.setHtml('Updated text after AJAX.');
}
});
return true;
}
return false;
},
});
}
});
I've successfully integrated dropzone.js inside an existing form. This form posts the attachments and other inputs like checkboxes, etc.
When I submit the form with attachments, all the inputs post properly. However, I want to make it possible for the user to submit the form without any attachments. Dropzone doesn't allow the form submission unless there is an attachment.
Does anybody know how I can override this default behavior and submit the dropzone.js form without any attachments? Thank you!
$( document ).ready(function () {
Dropzone.options.fileUpload = { // The camelized version of the ID of the form element
// The configuration we've talked about above
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 50,
maxFiles: 50,
addRemoveLinks: true,
clickable: "#clickable",
previewsContainer: ".dropzone-previews",
acceptedFiles: "image/*,application/pdf, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.openxmlformats-officedocument.spreadsheetml.template, application/vnd.openxmlformats-officedocument.presentationml.template, application/vnd.openxmlformats-officedocument.presentationml.slideshow, application/vnd.openxmlformats-officedocument.presentationml.presentation, application/vnd.openxmlformats-officedocument.presentationml.slide, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.openxmlformats-officedocument.wordprocessingml.template, application/vnd.ms-excel.addin.macroEnabled.12, application/vnd.ms-excel.sheet.binary.macroEnabled.12,text/rtf,text/plain,audio/*,video/*,.csv,.doc,.xls,.ppt,application/vnd.ms-powerpoint,.pptx",
// The setting up of the dropzone
init: function() {
var myDropzone = this;
// First change the button to actually tell Dropzone to process the queue.
this.element.querySelector("button[type=submit]").addEventListener("click", function(e) {
// Make sure that the form isn't actually being sent.
e.preventDefault();
e.stopPropagation();
myDropzone.processQueue();
});
// Listen to the sendingmultiple event. In this case, it's the sendingmultiple event instead
// of the sending event because uploadMultiple is set to true.
this.on("sendingmultiple", function() {
// Gets triggered when the form is actually being sent.
// Hide the success button or the complete form.
});
this.on("successmultiple", function(files, response) {
window.location.replace(response.redirect);
exit();
});
this.on("errormultiple", function(files, response) {
$("#notifications").before('<div class="alert alert-error" id="alert-error"><button type="button" class="close" data-dismiss="alert">×</button><i class="icon-exclamation-sign"></i> There is a problem with the files being uploaded. Please check the form below.</div>');
exit();
});
}
}
});
Use the following:
$('input[type="submit"]').on("click", function (e) {
e.preventDefault();
e.stopPropagation();
var form = $(this).closest('#dropzone-form');
if (form.valid() == true) {
if (myDropzone.getQueuedFiles().length > 0) {
myDropzone.processQueue();
} else {
myDropzone.uploadFiles([]); //send empty
}
}
});
Reference: https://github.com/enyo/dropzone/issues/418
You should check if there are files in the queue. If the queue is empty call directly dropzone.uploadFile(). This method requires you to pass in a file. As stated on [caniuse][1], the File constructor isn't supported on IE/Edge, so just use Blob API, as File API is based on that.
The formData.append() method used in dropzone.uploadFile() requires you to pass an object which implements the Blob interface. That's the reason why you cannot pass in a normal object.
dropzone version 5.2.0 requires the upload.chunked option
if (this.dropzone.getQueuedFiles().length === 0) {
var blob = new Blob();
blob.upload = { 'chunked': this.dropzone.defaultOptions.chunking };
this.dropzone.uploadFile(blob);
} else {
this.dropzone.processQueue();
}
Depending on your situation you could simply submit the form:
if (myDropzone.getQueuedFiles().length > 0) {
myDropzone.processQueue();
} else {
$("#my_form").submit();
}
The first approach is kind of too expensive for me, I would not like to dive into the source code and modify it,
If you happen to be like me , use this.
function submitMyFormWithData(url)
{
formData = new FormData();
//formData.append('nameOfInputField', $('input[name="nameOfInputField"]').val() );
$.ajax({
url: url,
data: formData,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
alert(data);
}
});
}
And in your dropzone script
$("#submit").on("click", function(e) {
// Make sure that the form isn't actually being sent.
e.preventDefault();
e.stopPropagation();
if (myDropzone.getQueuedFiles().length > 0)
{
myDropzone.processQueue();
} else {
submitMyFormWithData(ajaxURL);
}
});
I tried Matija Grcic's answer and I got the following error:
Uncaught TypeError: Cannot read property 'name' of undefined
And I didn't want to modify the dropzone source code, so I did the following:
if (myDropzone.getQueuedFiles().length > 0) {
myDropzone.processQueue();
} else {
myDropzone.uploadFiles([{name:'nofiles'}]); //send empty
}
Note: I'm passing an object inside the array to the uploadFiles function.
Then I check server-side, if name != 'nofiles' do upload stuff.
Pretty simple, you stop the propagation ONLY if you have files to be submitted via Dropzone:
// First change the button to actually tell Dropzone to process the queue.
this.element.querySelector("button[type=submit]").addEventListener("click", function(e) {
// Stop the propagation ONLY if you have files to be submitted via Dropzone
if (myDropzone.getQueuedFiles().length > 0) {
e.preventDefault();
e.stopPropagation();
myDropzone.processQueue();
}
});
I have successfully used :
submitButton.addEventListener("click", function () {
if(wrapperThis.files.length){
error = `Please select a file`;
} else {
wrapperThis.processQueue();
}
});
My answer is based on the fact that the other answers don't allow for an Ajax based solution where an actual HTML form isn't actually being used. Additionally you may want the full form contents submitted when sending the Files for upload as well.
As you'll see, my form occurs in a modal outside of any form tag. On completion, the modal is triggered to close.
(FYI getForm returns the form as an object and not directly related to the answer. Also assumes use of jQuery)
init: function() {
var dzClosure = this;
// When saving what are we doing?
$('.saveBtn').off('click').on('click',function(e){
e.preventDefault();
e.stopPropagation();
if (dzClosure.getQueuedFiles().length > 0) {
dzClosure.processQueue();
dzClosure.on('queuecomplete',function(){
$('.modal:visible').modal('hide');
})
} else {
var params = getForm();
$.post(dzClosure.options.url,params,function(){
$('.modal:visible').modal('hide');
})
}
});
dzClosure.on('sending', function (data, xhr, formData) {
var extra = getForm();
for (key in extra){
formData.append(key,extra[key]);
}
});
i have the next code
$(document).ready(function () {
$("#productfilter").validate({
submitHandler: function (form) {
$.ajax({
type: "POST",
url: "listproresult_core.php",
data: $("#productfilter").serialize(),
beforeSend: function () {
$("#contentincore").html("<img src='../loading_core/loading animated/loader.gif'class='clock' border='0' />");
},
success: function (result) {
$("#contentincore").html(result);
}
});
}
});
});
and i wish add the next functions inside and that the results of the form, the links are implemented inside the load function results
$('#contentincore a').click(function (e) {
("#contentincore").on("click", "a:not(.minlink)", function (e) {
("#contentincore").load($(this).attr("href"));
e.preventDefault();
});
});
To bind functions to content that is loaded in with ajax, you have to use .on(). Here's a live example: http://jsfiddle.net/GMDah/ (check the console) When pressing the top link, "pressed" will be printed in the console. When the bottom link with class .minlink is pressed, the code in here is not executed.
The code being:
$("#contentincore a:not(.minlink)").on("click", function (e) {
console.log("pressed");
});
Also, don't forget putting the $-sign or jQuery before your brackets, you seem to have missed a few.
I am loading a PartialView into a Jquery UI dialog and if something went wrong during the post method I reload the PartialView into the dialog again ( ModelState errors for example ) . At this point my ajax sumbit doesn't work anymore. It justs redirect me and it should not.
What is wrong in my code ? Here is what I have tried :
$('#editdialog').dialog({
autoOpen: false,
width: '900px',
modal: true,
open: function (event, ui) {
$(this).load('Controller action', function (html) {
$('#incarcerationForm').submit(function () {
$.ajax({
url: 'Controller action',
data: $("#myForm").serialize(),
type: "POST",
success: function (data) {
$('#editdialog').html(data);
$.validator.unobtrusive.parse($("#myForm"));
if ($("#myForm").valid()) {
GetDetails(#Model.FormModel.ID);
$('#editdialog').dialog('close');
console.log("myForm was edited successfully");
return false;
}
return false;
},
error: function (data) {
$('#editdialog').html(data);
console.log("error at edit myForm");
return false;
}
});
return false;
});
return false;
});
}
});
And my [HttpPost] Controller action :
public ActionResult Create(Mymodel viewModel)
{
return CheckValidBusiness(() =>
{
viewModel.Save(viewModel.FormModel); return true;
})
.Valid(() => PartialView(viewModel))
.Invalid(() => PartialView(viewModel));
}
Replace:
$('#incarcerationForm').submit(function () {
with:
$(document).on('submit', '#incarcerationForm', function () {
so that you subscribe to the submit event of the form in a lively manner which will be resilient to DOM changes. Take a look at the .on() method for more information.
i use the jquery validation plugin to validate form before submit
in submitHandler i use ajax request to post the form with ajax
before i used .ajax to send the request but now the form have image and its so hard to
serialize the file element through the normal ajax request and because of this i used this plugin
http://www.malsup.com/jquery/form/
now after using the plugin the ajax request not working at it all don't know why
this the first example with the normal ajax call
$(document).ready(function(){
$("#categoryForm").validate({
submitHandler: function() {
$.ajax({
type:'POST',
url: 'actions/add-category.php',
data: $("#categoryForm").serialize(),
success: function(response) {
$('#status').html(response);
}
});
return false;
}
});
});
and this one after using the plugin
$(document).ready(function(){
$("#categoryForm").validate({
submitHandler: function() {
$('#categoryForm').ajaxForm(function() {
alert('the form was successfully processed');
});
return false;
}
});
});
second one is not working
Try to invert the functions:
jQuery('#form_id').ajaxForm({
beforeSubmit: function() {
jQuery("#form_id").validate({
rules: {
first_name: "required",
last_name: "required"
},
messages: {
first_name: "Required",
last_name: "Required"
}
});
return jQuery('#form_id').valid();
},
success: function(resp) {
jQuery('#resp').html(resp).fadeIn('fast');
}
});
Where #resp is the ID that will receive the HTML generated from the file your #form_id posted