Smarty jQuery/Ajax call barrier - ajax

I'm modifying an existing system which uses Smarty. This particular problem is causing a major stumbling block as I just can't find a way around it.
I have a data-grid, each record has an action which calls ?module=the_module&action=the_action.
My corresponding function function the_module_the_action($postData, $getData) is used to perform the particular request.
The request for this module comes through from a jQuery $.ajax({}) request, simply because I don't want to loose the search form variables. So on success, I'll redirect the page using document.location='index.php?module=&action='.
This is fine as it allows me to detect that the action has been successful whilst maintaining the search filters on the grid.
But, I have a problem when the user action fails. The method the_module_the_action($postData, $getData) return echo 'success'; exit() on success but on a failure it should print out the Smarty template i.e. details of the record.
I believe the problem occurs because of a call through Ajax. The template is being served but because it is a call made using Ajax it isn't displayed.
How can I get around this problem?
Update:-
This is my function which Ajax calls:
public function module_action($post_data) {
$object=new Class((int)$post_data["id"]);
if($object->method()) {
echo "success";
exit();
}
else {
$this->assignToSmarty('_someSmartyVar', $someData);
$this->assignToSmarty('_data', $class->getData());
echo "failed";
}
}
The Ajax used to call this is:-
$(document).ready(function() {
$(".revokeButton").click(function(){
var selected=$(this).attr('id');
var filterBu = $('#filter_bu').val();
var filterJc = $('#filter_jc').val();
if(confirm("Are you sure you want to r.....")) {
$.ajax({
beforeSend: function() { },
url: 'index.php?module=module&action=action',
type: 'POST',
data: ({ bid:selected }),
cache: false,
success: function(data, textStatus) {
if(data == 'success') {
success_message = 'success';
} else if(data == 'failed') {
success_message = 'failed';
}
document.location='index.php?module=module&message='+success_message+'&filter_bu='+filterBu+'&filter_jc='+filterJc;
}
});
}
});
});
The success and failure are echoing out successfully, but the smarty stuff isn't.

I see two problems. First of all, you seem to have forgotten the smarty->display() function call in the failure leg of the module_action function. Secondly, you wrote:
if(data == 'success') {
success_message = 'success';
} else if(data == 'failed') {
success_message = 'failed';
}
This will always only output success or failure. You probably want to do something more like the following:
if(data == 'success') {
success_message = 'success';
} else {
// if got here, 'data' doesn't contain "success!", so it must contain
// something else, likely error data. You could either just display
// data as it is or first do some sort of check to ensure that it
// does, in fact, contain error data, and then display it.
success_message = 'error!<br \>\n' + data;
}

Related

Wordpress Ajax call returns empty

I have a trouble with wordpress ajax call.
Action for admin-ajax.php has been defined correctly.
It returns correct result when user logged in, but it returns empty when user didn't log in.
Here is code for it.
add_action('wp_ajax_thwepo_calculate_extra_cost', array($this, 'wp_ajax_action_calculate_extra_cost_handler'), 10);
add_action('wp_ajax_nopriv_thwepo_calculate_extra_cost', array($this, 'wp_ajax_action_calculate_extra_cost_handler'), 10);
public function wp_ajax_action_calculate_extra_cost_handler() {
$return = array(
'code' => 'E001',
'message' => ''
);
echo json_encode($return);
exit;
}
And here is javascript code.
var data = {
action: "thwepo_calculate_extra_cost",
price_info: JSON.stringify(requestData)
};
currRequest = $.ajax({
type: "POST",
url: args.ajax_url,
data: data,
beforeSend: function() {
null != currRequest && currRequest.abort()
},
success: function(rslt) {
if ("E000" === rslt.code) {
var result = rslt.result;
result && display_new_price(args, result.display_price, isVariableProduct)
} else "E002" === rslt.code && display_new_price(args, rslt.result, isVariableProduct)
},
error: function(data) {
console.log(data);
}
});
Here is screenshot of ajax call.
It returns correct result when page loaded first time.
But when select option (i.e. Classes), it returns empty.
Why is this happened?
Is there anyone who have any idea?
Please let me know if needed any other information.
Page url is https://www.ivybound.net/classes/isee-prep-middle-level/
It can be checked by selecting "What do you need?" select option.

Bind event after login

I have made a filter called auth that check if user is logged. If is not logged it redirect on the main page but if is a call ajax? I just checked if is it. If it is i just send an json status "no-log". Now i received my json response "no-log" on my client and i would like open a modal for ask login and password. The solution that i thougth was put easily for each ajax request an if statement to check if the response status is "no-log" and show the function of modal. BUT OF COURSE is not good for future update, I'm looking for a good solution where i can bind this event and if i want on the future add other status. Any suggest?
Route::filter('auth', function()
{
if (Auth::guest()) {
if ( !Request::ajax() ) {
Session::put('loginRedirect', Request::url());
return Redirect::to('/');
} else {
$status = "no-log";
return json_encode(array('status' => $status));
}
}
});
A example of call ajax
$(document).on("click", ".delete", function() { // delete POST shared
var id_post = $(this);
bootbox.confirm("Are you sure do want delete?", function(result) {
if (result) {
$.ajax({
type: "POST",
url: '/delete_post/' + USER,
data: { id_post: id_post.attr('id') },
beforeSend: function(request) {
return request.setRequestHeader("X-CSRF-Token", $("meta[name='token']").attr('content'));
},
success: function(response) {
if (response.status == "success") {
id_post.parents('div.shared_box').fadeOut();
}
},
error: function(){
alert('error ajax');
}
});
} else {
console.log("close");
}
});
});
After 10 days of exploring an idea I found a way to override ajax comportment:
It just need you replace every $.ajax() by a custom one.
If I re-use your code:
$(document).on("click", ".delete", function() { // delete POST shared
var id_post = $(this);
bootbox.confirm("Are you sure do want delete?", function(result) {
if (result) {
myCustomAjax({ // In place of $.ajax({
type: "POST",
...
Then this custom function allow you to add some action before or after each ajax callback:
For instance checking the JSON return value in order to decide if I trigger the success callback or I show a warning:
function myCustomAjax(options) {
var temporaryVariable = options.success;
options.success = function (data, textStatus, jqXHR) {
// Here you can check jqXHR.responseText which contain your JSON reponse.
// And do whatever you want
// If everithing is OK you can also decide to continue with the previous succeed callback
if (typeof temporaryVariable === 'function')
temporaryVariable(data, textStatus, jqXHR);
};
return $.ajax(options);
}
If you return a 401 for all not loggedin requests, you can use $.ajaxSetup to handle all ajax errors in your application.
$.ajaxSetup({
error: function(jqXHR, exception) {
if (jqXHR.status == 401) {
window.location = 'your-login-page';
}
}
});

How do I call a method in Scala through javascript & ajax?

I do not know if my title was perhaps a little misleading. But here's what I really need help with.
I'm making a get on this url:
$.get("/fb/login/"+fbEmail, function(data){
console.log(data);
});
This is my routes:
GET /fb/login/:email presentation.controllers.Auth.authenticateSocialNetwork(email:String)
And here's my action:
def authenticateSocialNetwork(email:String) = Action {
if(!editorRepo.getEditorByEmail(email).isEmpty){
Redirect(routes.Profile.editorProfile).withSession(Security.username -> email)
} else {
Redirect(routes.Profile.initiatorProfile).withSession(Security.username -> email)
}
}
My expectation from this is that my action gets called and fires of what's inside it. In other words, Redirecting.
But what actually happens, which is not so illogical, is that my $.get call gets a response with my redirect's.
How do I actually call my action-method, without sending a response to javascript?
Here's my function in javascript, posting this snippet for it to be more clear in our discussion in the comments above.
function addClickToLoginButtons(){
$("#loginWithFb").click(function(){
FB.login(function(response){
if(response.authResponse){
FB.api('/me', function(response){
var fbEmail = response.email;
$.get("/fb/isRegisteredAtNetwork/"+fbEmail+"/facebook", function(data){
if(data == "true"){
if(confirm("Do you want to log with facebook-account "+fbEmail+"?")){
$.get("/fb/login/"+fbEmail, function(data){ *//HERE'S WHERE I WOULD WANT TO CALL MY METHOD IN SCALA*
console.log(data);
});
} else {
console.log("try again with a different facebook-account");
} //end confirm else
} else {
console.log("Logged in not in database");
}//end get else
});
});
} else {
console.log("permission not granted");
} // end authResponse else
}, {scope: 'email'});
});
}
In your action, instead of returning Redirect, return Ok(urlToBeRedirectedTo).withSession(...). Once this response received in the javascript code, do your stuff and then call window.location = urlToBeRedirectedTo;.
This will add the email to the session, and will redirect to the wanted URL.

Can a jQuery $.post call itself again from the callback?

The use case would be if the response it gets isn't what it wanted it can call itself again.
$.post(qrLoginAjax.ajaxurl, {
userID : '11234324'
},function( response ) {
if (response.userID != 'undefined'){
//do stuff
} else {
// call $.post again
}
});
How would I do that?
Thanks
You could do something like this:
var sendAjax = function() {
$.post('/foo', function(result) {
if (response.userID != 'undefined') {
// do stuff
} else {
// resend the AJAX request by calling the sendAjax function again
sendAjax();
}
});
};
sendAjax();
But sending AJAX requests like this seems like a bad design decision in my opinion. You should ensure that you don't get into an infinite recursion by using for example a number of retries counter.
You can make it a function, and call itself. For example with $.ajax, you can do this:
function do_stuff(){
$.ajax({
url: 'ajax.php',
success: function(data){
// Stuff
},
error: function(){
do_stuff();
}
});
}
This is the general principle of a recursive function, but it is highly recommended that you test conditions or set a maximum number of tries so it doesn't get stuck in an infinite loop.
Use this keyword of Javascript. As we all know, that refers to the object it belongs to. For example:
$.post(qrLoginAjax.ajaxurl,
{
userID : '11234324'
},
function( response ) {
if (response.userID != 'undefined') {
//do stuff
}
else {
$.post(this);
}
}
);

Showing errors and messages on custom form in jqGrid

What I am trying to achieve it to show messages on a dialog form as asked and answered here. However, while the example above used the default editGridRow in the code, I have a custom dialog form loaded in via JSON. For example the JSON error/validation message returned could be:
{"CustomerName":{"isEmpty":"\u201cthis value is - not to be left empty.\u201d"}}
I need to be able to output them as "Customer Name - this value is not to be left empty" - at the top of the dialog form.
I have tried the solutions in A, B, C and D but I have not been able to customize them to work in my scenario yet.
I have a function call like so:
function LaunchEditForm(dialog)
{
$('form', dialog).submit(function ()
{
$.ajax({
url: '/customer/update-customer/',
type: this.method,
reloadAfterSubmit: true,
data: $(this).serialize(),
success: function (result)
{
if (result.success)
{
console.log(result);
//can I call a function here to prepend modal form
//with success message? how please?
}
else
{
console.log(result);
// can I prepend the dialog to show model errors here?
//var errorDetail = jQuery.parseJSON(result.responseText);
}
}
});
return false;
});
}
I have tried using afterSubmit like so:
afterSubmit: function (response, postdata)
{
if (response.responseText == "Success")
{
jQuery("#success").show();
jQuery("#success").html("Customer successfully updated");
jQuery("#success").fadeOut(6000);
return [true, response.responseText]
}
else
{
return [false, response.responseText]
}
}
This has not worked yet - perhaps I have placed it in a different scope
and also tried errorTextFormat like so:
errorTextFormat: function (data)
{
if (data.responseText.substr(0, 6) == "<html ")
{
return jQuery(data.responseText).html();
}
else
{
return "Status: '" + data.statusText + "'. Error code: " + data.status;
}
}
Please help with this. I know I need some function that parses the JSON successfully and hopefully presents the errors and messages Oleg described

Resources