Displaying a message in a dialog box using AJAX, jQuery, and CakePHP - ajax

I have a form, and when users submit this form, it should pass the data along to a function using AJAX. Then, the result of that is displayed to the user in a dialog box. I'm using CakePHP (1.3) and jQuery to try and accomplish this but I feel like I'm running into the ground.
The form will eventually be used for uploading images with tags, but for now I just want to see a message pop up in the box..
The form:
<?php
echo $this->Form->create('Image', array('type' => 'file', 'controller' => 'images',
'action' => 'upload', 'method' => 'post'));
echo $this->Form->input('Wallpaper', array('type' => 'file'));
echo $this->Form->input('Tags');
echo $this->Form->end('Upload!');
?>
The AJAX:
$(document).ready(function() {
$("#ImageUploadForm").submit(function() {
$.ajax({
type: "POST", url: "/images/upload/",
data: $(this).serialize(),
async: false,
success: function(html){
$("#dialog-modal").dialog({
$("#dialog-modal").append("<p>"+html+"</p>");
height: 140,
modal: true,
buttons: {
Ok: function() {
$(this).dialog('close');
}
}
})
}
});
return false;
});
});
NOTE: if I put $("#dialog-modal").dialog({ height: 140, modal: true }); OUTSIDE of the $.ajax but inside the $("#ImageUploadForm").submit(function() { and comment out the $.ajax stuff, I WILL see a dialog box pop up and then I have to click it for it to go away. After this, it will not forward to the location /images/upload/
The method that AJAX calls:
public function upload()
{
$this->autoRender = false;
if ($this->RequestHandler->isAjax())
{
echo 'Hi!';
exit();
}
}
$this->RequestHandler->isAjax() seems to do either absolutely nothing, or it is always returning false. I have never entered an if statement with that as the condition.
Thanks for all the help, if you need more information let me know.

Try this:
$(document).ready(function(){
$.ajax({
type: "POST", url: "/images/upload/",
data: $(this).serialize(),
async: false,
success: function(html){
//First you must append to div:
$("#dialog-modal").append("<p>"+html+"</p>");
$("#dialog-modal").dialog({
height: 140,
modal: true,
buttons: {
Ok: function() {
$(this).dialog('close');
}
}
}); //dialog
}//success
});//ajax
Note the first sentence:
$("#dialog-modal").append("<p>"+html+"</p>");
it can not be a propertie. You must pass an object as a parameter to dialog() function so properties or member of an object looks like:
{
height:140,
buttons:{},
anotherPropertie: 'value'
}
If you call to dialog() function after ajax(), the dialog will be empty because will execute before success() function declared inside ajax().

Related

Fancybox thumbnail on AJAX

I am using fancybox gallery, that I am loading dynamically. I have always one picture with data-fancybox attribute and with ID.
JS is like this:
$('[data-fancybox]').each(function(e){
var idgal = $(this).data("fancybox");
$(this).fancybox({
loop: false,
onInit: function (instance) {
$.ajax({
type: 'POST',
url: '/loadGallery.php?gallery='+idgal,
dataType: 'json',
success: function (data) {
$.each(data, function (index,src) {
instance.addContent({
'type': 'image',
'src': src.src
});
});
}
});
},
thumbs: {
autoStart: true,
axis : 'x'
}
})
})
Problem is, that I don't get thumbnails of dynamically loaded images. Any ideas? Thanks!
If you ask for the last fancyBox (v 3.5.7), to get thumbnails you also need to proceed thumbnails URL (inside options/opts key). And, most important, at the end, need to reinitialize thumbs (eg. after each loop inside Ajax success block).
Here is only part from your example with changes:
// Ajax success
success: function ( data ) {
$.each(data, function (index, src) {
instance.addContent({
'type': 'image',
'src': src.src,
'opts': {
'thumb': 'thumb.jpg' // thumbnail url (eg. src.opts.thumb)
}
});
});
// reinitialize Thumbs
instance.Thumbs.init(instance);
// optional: to get thumbs autoStart
instance.Thumbs.show();
} // success

AJAX call inside Ckeditor widget's upcast function

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;
},
});
}
});

Yii ajax file upload

I need to upload image with ajax call. But POST field with image always is empty. Part of my form:
<div class="col-lg-6">
<?php echo CHtml::activeFileField($model, 'logo'); ?>
<?php echo CHtml::textField('test', 'test'); ?>
<?php echo CHtml::submitButton('Upload'); ?>
<?php echo CHtml::ajaxSubmitButton('Upload ajax', '#');?>
</div>
If i click submitButton, then i have both test and logo fields - image uploaded.
And if i click ajaxSubmitButton, then i have only test field, logo is empty. What is the solution?
PS: i need non-extension solution.
You cannot upload files with ajaxSubmitButton by default. Use simple submit or some uploader.
If you want to upload image via ajax, here's example:
<?php echo CHtml::link('Upload ajax', '#', array("onclick"=>"js:upload_file(this)"));?>
In your js:
function upload_file(){
var fd = new FormData();
var e = document.getElementById("Model_logo");
fd.append( "Model[logo]", $(e)[0].files[0]);
$.ajax({
url: 'upload',
type: 'POST',
cache: false,
data: fd,
processData: false,
contentType: false,
success: function (data) {
},
error: function () {
alert("ERROR in upload");
}
});
}
Change Model to your model name and this will work. Also now you can append any data to FormData and it will be passed in $_POST and your file in $_FILES.
Be carefull, this way doesn't work on ie7 and ie8 as i remember.
Based on ineersa's answer, I made some improvements:
<?php echo CHtml::link('Upload ajax', '#', array("onclick"=>"upload_file()")); ?>
In your js:
function upload_file(){
var fd = new FormData($('#model-form')[0]);
$.ajax({
url: 'upload',
type: 'POST',
cache: false,
data: fd,
processData: false,
contentType: false,
success: function (data) {
},
error: function () {
alert("ERROR in upload");
}
});
}
This way you don't have to append each form field manually. All form data will be read automatically (including files). Just make sure that #model-form is changed according to your form id.
A way you don't need to call $.ajax(...) by yourself.
$(document).on('ajaxBeforeSend', 'form.my-form', function (event, jqXHR, settings) {
if ((settings.url.indexOf("js_skip") == -1) && $("form.my-form input[type=file]")[0].files.length) {
jqXHR.abort();
settings.cache = false;
settings.contentType = false;
settings.processData = false;
settings.data = new FormData(this);
settings.url = settings.url + "&js_skip=1";
jqXHR = $.ajax(settings);
}
});

Jquery Ajax Post is not calling action method

function CreateModalDialogWindow(urlPath) {
$.ajax({
url: '#Url.Action("Popup","Project")',
type: 'POST',
async: false,
success: function (data) {
debugger;
$('#dialog').html(data).dialog({
autoOpen: true,
width: 400,
resizable: false,
modal: true
});
},
error: function(){
alert('Error!');
}
});
return false;
}
I wanted to call an actionmethod using ajax post. Here is the action method
[HttpPost]
public PartialViewResult Popup()
{
return PartialView("~/Views/Shared/Project/Popup.cshtml");
}
Please let me know what is wrong in the above code.
There might be different reasons why the action method is not being called:
you have some javascript error
you never call the CreateModalDialogWindow function
you call the CreateModalDialogWindow in the click of a link or form submit but you forgot to cancel the default action of this button by returning false.
So start by first calling this code in the document ready to see if it works:
<script type="text/javascript">
$(function() {
$.ajax({
url: '#Url.Action("Popup", "Project")',
type: 'POST',
success: function (data) {
$('#dialog').html(data).dialog({
autoOpen: true,
width: 400,
resizable: false,
modal: true
});
}
});
});
</script>
Now if you put a breakpoint in your controller action it should normally be hit. I would recommend you using a javascript debugging tool such as FireBug which will help you see any possible javascript errors and see the exact requests/responses being sent during AJAX requests.
You will also notice that I have removed the async: false switch because this makes synchronous calls to the server freezing the web browser during the execution of this request and thus you are no longer doing AJAX.

Disable Button while AJAX Request

I'm trying to disable a button after it's clicked. I have tried:
$("#ajaxStart").click(function() {
$("#ajaxStart").attr("disabled", true);
$.ajax({
url: 'http://localhost:8080/jQueryTest/test.json',
data: {
action: 'viewRekonInfo'
},
type: 'post',
success: function(response){
//success process here
$("#alertContainer").delay(1000).fadeOut(800);
},
error: errorhandler,
dataType: 'json'
});
$("#ajaxStart").attr("disabled", false);
});
but the button is not getting disabled. When I remove $("#ajaxStart").attr("disabled", false); the button gets disabled.
While this is not working as expected, I think the code sequence is correct. Any help will be appreciated.
Put $("#ajaxStart").attr("disabled", false); inside the success function:
$("#ajaxStart").click(function() {
$("#ajaxStart").attr("disabled", true);
$.ajax({
url: 'http://localhost:8080/jQueryTest/test.json',
data: {
action: 'viewRekonInfo'
},
type: 'post',
success: function(response){
//success process here
$("#alertContainer").delay(1000).fadeOut(800);
$("#ajaxStart").attr("disabled", false);
},
error: errorhandler,
dataType: 'json'
});
});
This will ensure that disable is set to false after the data has loaded... Currently you disable and enable the button in the same click function, ie at the same time.
In your code, you just disable & enable the button on the same button click,.
You have to enable it inside the completion of AJAX call
something like this
success: function(response){
$("#ajaxStart").attr("disabled", false);
//success process here
$("#alertContainer").delay(1000).fadeOut(800);
},
I have solved this by defining two jquery functions:
var showDisableLayer = function() {
$('<div id="loading" style="position:fixed; z-index: 2147483647; top:0; left:0; background-color: white; opacity:0.0;filter:alpha(opacity=0);"></div>').appendTo(document.body);
$("#loading").height($(document).height());
$("#loading").width($(document).width());
};
var hideDisableLayer = function() {
$("#loading").remove();
};
The first function creates a layer on top of everything. The reason the layer is white and completely opaque, is that otherwise, IE allows you to click through it.
When doing my ajax, i do like this:
$("#ajaxStart").click(function() {
showDisableLayer(); // Show the layer of glass.
$.ajax({
url: 'http://localhost:8080/jQueryTest/test.json',
data: {
action: 'viewRekonInfo'
},
type: 'post',
success: function(response){
//success process here
$("#alertContainer").delay(1000).fadeOut(800);
hideDisableLayer(); // Hides the layer of glass.
},
error: errorhandler,
dataType: 'json'
});
});
I solved this by using global function of ajax
$(document).ajaxStart(function () {
$("#btnSubmit").attr("disabled", true);
});
$(document).ajaxComplete(function () {
$("#btnSubmit").attr("disabled", false);
});
here is documentation link.
The $.ajax() call "will not block" -- that means it will return immediately, and then you enable the button immediately, so the button is not disabled.
You can enable the button when the AJAX is successful, has error, or is otherwise finished, by using complete: http://api.jquery.com/jQuery.ajax/
complete(XMLHttpRequest,
textStatus)
A function to be
called when the request finishes
(after success and error callbacks are
executed). The function gets passed
two arguments: The XMLHttpRequest
object and a string categorizing the
status of the request ("success",
"notmodified", "error", "timeout", or
"parsererror"). This is an Ajax Event.

Resources