I have a problem with my Yii Form-Submission via Ajax:
Everything worked fine on my local machine but on the Webserver I always get the error Alert...
The Ajax Error is thrown every time the function is called...
although the data is properly POST'ED and the function in the URL did what it should..
So basically everything works but the Ajax Error is thrown every time
SO here is my code:
function merge()
{
var productA = $('#Product_selected_product').val();
var productB = $('#product_dd').val();
<?php echo CHtml::ajax(
array(
'url'=>CController::createUrl('product/companyItems'),
'data'=>array('productA' => 'js:$(\'#Product_selected_product\').val()', 'productB' => 'js:$(\'#product_dd\').val()','checker' => 'erwin'),
'type'=>'post',
'dataType'=>'json',
'error'=>"function() { alert('ERROR'); }",
'success'=> "function(){window.location.href = '../product/'+productB+''}"
)
);
?>
return false;
}
The companyItems Action searches for entrys in a table with the ID of ProductA and replaces it with the ID of ProductB.
Controller Action : CompanyItems:
public function actionCompanyItems(){
if(isset($_POST['checker'])) {
$productA = $_POST['productA'];
$productB = $_POST['productB'];
$commandMerge = Yii::app()->db
->createCommand("UPDATE ebay SET product_id = :productB WHERE product_id=:productA")
->bindValues(array(':productB' => $productB ,':productA' => $productA))
->execute();
$commandDelete = Yii::app()->db
->createCommand("UPDATE product SET is_deleted = '1' WHERE id = :productA")
->bindValues(array(':productA' => $productA))
->execute();
}
I hope someone can help me....
Dave
Related
Have a function that makes a change to taxonomy term via AJAX. This works great, except the content remains unchanged on window.location.reload(true) even though the change has been made. See the code and GIF below to understand.
This is an example that adds the button and reloads page on click
if ( 'publish' === $post->post_status && $post->post_type === 'campaigns' ) {
$text = (in_category( 'live') ? 'Activate' : 'Activate');
echo '<li>' . $text . '</li>';
}
So, is there another way that I can reload the page onClick that may help? Also, the post modified date is not updating, yet changes have been made to the post.
Thanks in advance for your help
EDIT -
I have already tried
location.href = location.href; and
document.location.reload();
ADDITIONAL INFO -
Function
add_action('wp_ajax_toggle_live', function(){
// Check ID is specified
if ( empty($_REQUEST['post']) ) {
die( __('No post ID specified.') );
}
// Load post
$post_id = (int) $_REQUEST['post'];
$post = get_post($post_id);
if (!$post) {
die( __('You attempted to edit an item that doesn’t exist. Perhaps it was deleted?') );
}
// Check permissions
$post_type_object = get_post_type_object($post->post_type);
if ( !current_user_can($post_type_object->cap->edit_post, $post_id) ) {
die( __('You are not allowed to edit this item.') );
}
// Load current categories
$terms = wp_get_post_terms($post_id, 'campaign_action', array('fields' => 'ids'));
// Add/remove Starred category
$live = get_term_by( 'live', 'campaign_action' );
$index = array_search($live, $terms);
if ($_REQUEST['value']) {
if ($index === false) {
$terms[] = $live;
}
} else {
if ($index !== false) {
unset($terms[$index]);
}
}
wp_set_object_terms( $post_id, 'live', 'campaign_action' );
die('1');
});
JS
function toggleLive(caller, post_id)
{
var $ = jQuery;
var $caller = $(caller);
var waitText = ". . .";
var liveText = ". . .";
var deactivateText = ". . .";
// Check there's no request in progress
if ($caller.text() == waitText) {
return false;
}
// Get the new value to set to
var value = ($caller.text() == liveText ? 1 : 0);
// Change the text to indicate waiting, without changing the width of the button
$caller.width($caller.width()).text(waitText);
// Ajax request
var data = {
action: "toggle_live",
post: post_id,
value: value
};
jQuery.post("<?php bloginfo( 'wpurl' ); ?>/wp-admin/admin-ajax.php", data, function(response)
{
if (response == "1") {
// Success
if (value) {
$caller.text(deactivateText);
} else {
$caller.text(liveText);
}
} else {
// Error
alert("Error: " + response);
// Reset the text
if (value) {
$caller.text(deactivateText);
} else {
$caller.text(liveText);
}
}
// Reset the width
$caller.width("auto");
});
// Prevent the link click happening
return false;
}
IT WORKS RIGHT ON PAGE THAT ISN'T SINGULAR
Is toggleLive the function that makes the AJAX request? You are calling reload immediately on click before changes are reflected on the backend. If you are using Jquery include your reload code in the complete callback function that indicates completion of your AJAX request.
Try using Live Query plug-in in jquery instead of live .
I was able to achieve this by setting return trueOrFalse(bool); in the JS and adding the permalink for the page into <a href=""> within the function.
I believe #cdoshi was correct in their answer, yet I was unable to achieve this. I am sure that a little further exploration would make this possible, yet my fix achieved what I wanted with little change to my code.
i have a simple form: when i submit it without javascript/jquery, it works fine, i have only one insertion in my data base, everything works fine.
I wrote some jquery to have result in ajax above the input button, red message if there was an error, green if the insertion was done successfully. I also display a small gif loader.
I don't understand why when i use this jquery, two loaders appear at the same time and two insertions are done in my database.
I reapeat that when i comment the javascript, it works fine, i'm totally sure that my php is ok.
$('#addCtg').submit(function () {
var action = $(this).attr('action');
var name = $('#name').val() ;
$('.messages').slideUp('800', function() {
$('#addCtg input[type="submit"]').hide().after('<img src="spin.gif" class="loader">');
$.post(action, {
name: name
}, function (data) {
$('.messages').html(data);
$('.messages').slideDown('slow');
$('.loader').fadeOut();
$('#addCtg input[type="submit"]').fadeIn();
});
});
return false;
});
I really don't understand why it doesn't work, because i use the 'return false' to change the basic behaviour of the submit button
Basic php just in case:
<?php
require_once('Category.class.php');
if (isset($_POST['name'])) {
$name = $_POST['name'] ;
if ($name == "") {
echo '<div class="error">You have to find a name for your category !</div>' ;
exit();
} else {
Category::addCategory($name) ;
echo '<div class="succes">Succes :) !</div>' ;
exit();
}
} else {
echo '<div class="error">An error has occur: name not set !</div>';
exit();
}
And finnaly my function in php to add in the database, basic stuff
public static function addCategory($name) {
$request = myPDO::getInstance()->prepare(<<<SQL
INSERT INTO category (idCtg, name)
VALUES (NULL, :name)
SQL
);
$r = $request->execute(array(':name' => $name));
if ($r) {
return true ;
} else {
return false ;
}
}
I rarely ask for help, but this time i'm really stuck, Thank you in advance
You're calling: $('.messages') - I bet you have 2 elements with the class messages. Then they will both post to your server.
One possible reason could be because you are using button or submit to post ajax request.
Try this,
$('#addCtg').submit(function (e) {
e.preventDefault();
var action = $(this).attr('action');
var name = $('#name').val() ;
$('.messages').slideUp('800', function() {
$('#addCtg input[type="submit"]').hide().after('<img src="spin.gif" class="loader">');
$.post(action, {
name: name
}, function (data) {
$('.messages').html(data);
$('.messages').slideDown('slow');
$('.loader').fadeOut();
$('#addCtg input[type="submit"]').fadeIn();
});
});
return false;
});
I'm trying to retrieve multiple $_GET variables within PHP. Javascript is sending the URL and it seems to have an issue with the '&' between variables.
One variable works:
//JAVASCRIPT
var price = "http://<site>/realtime/bittrex-realtime.php?symbol=LTC";
//THE PHP END
$coinSymbol = $_GET['symbol'];
echo $coinSymbol
OUTPUT: LTC
With two variables:
//JAVASCRIPT
var price = "http://<site>/realtime/bittrex-realtime.php?type=price&symbol=LTC";
//THE PHP END
$coinSymbol = $_GET['symbol'];
$type = $_GET['type'];
echo $coinSymbol
echo $type
OUTPUT: price
It just seems to ignore everything after the '&'. I know that the PHP end works fine because if I manually type the address into the browser, it prints both variables.
http://<site>/realtime/bittrex-realtime.php?type=price&symbol=LTC
OUTPUT ON THE PAGE
priceLTC
Any ideas? It's driving me nuts - Thanks
UPDATE - JAVASCRIPT CODE
jQuery(document).ready(function() {
refresh();
jQuery('#bittrex-price').load(price);
});
function refresh() {
setTimeout( function() {
//document.write(mintpalUrl);
jQuery('#bittrex-price').fadeOut('slow').load(price).fadeIn('slow');
refresh();
}, 30000);
}
Separate the url and the data that you will be sending
var price = "http://<site>/realtime/bittrex-realtime.php";
function refresh() {
var params = {type:'price', symbol: 'LTC'};
setTimeout( function() {
//document.write(mintpalUrl);
jQuery('#bittrex-price').fadeOut('slow').load(price, params).fadeIn('slow');
refresh();
}, 30000);
}
And in your PHP use $_POST or you can do it like this
$coinSymbol = isset($_POST['symbol']) ? $_POST['symbol'] : $_GET['symbol'];
Refer to here for more information jquery .load()
I am using forms to process my entity data via ajax to an api-method.
My Type Class:
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add(
$builder->create('basicdata', 'form', array('virtual' => true))
->add('firstname', null, array('required' => true))
->add('lastname', null, array('required' => true))
);
$builder->add('contactdetails', new ContactdetailsType());
$builder->add('medialinks', new MedialinksType());
}
As u can see i seperate my form in 3 sections, one with basedata and 2 additional entities to keep contactdetails and medialinks.
In my JavaScript i have the following listener on the create button:
$('#player_form_create').on('click', function(e){
e.preventDefault();
$.ajax({
type: "POST",
url: remotePathPlayerCreate,
data: $('.form').serialize()
});
});
According to chromes developer tool the POST data look like following:
player_form[basicdata][firstname]:Harvey
player_form[basicdata][lastname]:Specter
player_form[contactdetails][email]:h.specter#pearson.com
player_form[medialinks][website]: http://
In my API action i wanna handle the request and save a new player record:
public function cpostAction()
{
$player = new Player();
$form = $this->createForm(new PlayersType(), $player);
$form->handleRequest($this->getRequest());
if($form->isValid()){
$em = $this->getDoctrine()->getManager();
$em->persist($player);
$em->persist($player->getContactdetails());
$em->persist($player->getMedialinks());
$em->flush();
return $this->redirectView(
$this->generateUrl(
'get_player',
array('id' => $player->getId())
),
Codes::HTTP_CREATED
);
}
return array(
'processedForm' => $form
);
}
As u might allready know, the problem happens while i want to handle the request. I guess $this->getRequest() does not contain the POST data information in the format needed by the request handler.
When i post data like this, i get a 500 with Expected argument of type \"Symfony\\Component\\HttpFoundation\\Request\", \"array\" given.
How can i achieve that my POST data is submited as an request object?
I ran into the same problem when building an app with Symfony on server side and AngularJS on client side. Handling the form this way worked:
$content = $this->get('request')->getContent();
if (!empty($content)) { $params = json_decode($content, true); }
else { // return an error or whatever }
$defaultOptions = array('csrf_protection' => false);
$form = $this->createFormBuilder(null, $defaultOptions)
->add('email', 'email', array(
'constraints' => new Constraints\Email(array('message' => 'emailError'))
))
->getForm();
$form->submit($params);
if ($form->isValid()) {
...
}
Of course here I'm not using a type to create the form like you but the result is the same. This assumes that the request payload is something like this:
{email: 'test#example.com'}
Ok i have found the solution: According to the page How to use the submit() Function to handle Form Submissions i now use $form->submit to submit my array-data to the form:
$form->submit($this->getRequest()->request->get($form->getName()));
I have been delving into the world of Javascript and AJAX. I am super close, but for some reason I do not think I am hooking into wordpress ajax functions right. I have poured through the docs and this and think it is 99% there.
Is what this app does is there is a list of items. Each one with a + button. Clicking the button pops up a confirm box, and if confirmed grabs the needed data to pass to the php. The php adds the item into mysql with wpdb->insert. It also does some changes if you buy.
The js works all the way up to the call, grabbing the right values etc. Testing the php separately works as well if I hard code the values it is supposed to grab from POST. So I KNOW both pieces run, I just can't get the js to call the ajax api right. Can someone please take a look at this and let me know how to hook these together so the ajax call actually runs the php?
Here is the code.
<?php
add_action( 'admin_footer', 'addItemAJAX_javascript' );
function addItemAJAX_javascript() {
$adminAJAX = admin_url('admin-ajax.php');
?>
<script type="text/javascript" language="JavaScript">
$(function() {
$( "input[name=btnAddItem]" )
.button()
.click(function( event ) {
event.preventDefault();
var confirmAction = confirm('Are you sure you want to add this item to your character?');
if (confirmAction==true) {
// build data for AJAX call
var cID = $('#hdnCharID').val();
cID = cID*1;
var charMoney = $('#hdnCharMoney').val();
var thisValue = $(this).val();
var iID = $(this).prev('input[id="hdnItemID"]').val()
iID = iID*1;
//Add or Buy Item
if (thisValue != "+") {
var buy = 1;
}
else {
var buy = 0;
}
var ajaxurl = <?php echo json_encode($adminAJAX); ?>;
console.log('cID = ' + cID);
console.log('charMoney = ' + charMoney);
console.log('thisValue = ' + thisValue);
console.log('iID = ' + iID);
console.log('buy = ' + buy);
console.log('ajaxurl = ' + ajaxurl);
var data = {
action: 'addItemAJAX',
charID: cID,
itemID: iID,
buyItem: buy
};
console.log('data = ' + data);
console.log(data);
//WP ajax call
$.post(ajaxurl, data, function(response) {
alert('Got this from the server: ' + response);
});
}
else {
console.log('add item aborted');
}
});
});
</script>
<?php
};
addItemAJAX_javascript();
// PHP SIDE OF AJAX - Handeling Request //// AJAX PROCESSING /////////////////////////////////
add_action('wp_ajax_addItemAJAX', 'addItemAJAX_callback');
function addItemAJAX_callback() {
global $wpdb;
$charID = intval($_POST['charID']);
$itemID = intval($_POST['itemID']);
$buyItem = intval($_POST['buyItem']);
// //get item details
$getItemDetailsSQL = "
Select
fyxt_wp_db_fatcow.fyxt_items.idfyxt_items,
fyxt_wp_db_fatcow.fyxt_items.fyxt_item_name,
fyxt_wp_db_fatcow.fyxt_items.fyxt_item_description,
fyxt_wp_db_fatcow.fyxt_items.fyxt_item_cost,
fyxt_wp_db_fatcow.fyxt_items.fyxt_item_weight
From
fyxt_wp_db_fatcow.fyxt_items
Where
fyxt_wp_db_fatcow.fyxt_items.idfyxt_items = $itemID";
$getItemDetailsResults = $wpdb->get_row($getItemDetailsSQL);
$iID = $getItemDetailsResults->idfyxt_items;
$iName = $getItemDetailsResults->fyxt_item_name;
$iDesc = $getItemDetailsResults->fyxt_item_description;
$iCost = $getItemDetailsResults->fyxt_item_cost;
$iWeight = $getItemDetailsResults->fyxt_item_weight;
$charItemTable = fyxt_char_items;
$wpdb->insert(
$charItemTable,
array (
idfyxt_item => $iID,
idfyxt_character => $charID,
item_name => $iName,
item_desc => $iDesc,
item_cost => $iCost,
item_weight => $iWeight,
item_quant => 1,
equip => 0,
carried => 1
)
);
$wpdb->print_error();
$newItemAdded = $wpdb->insert_id;
//remove cash if item is bought
if ($buyItem == 1 ) {
$curCharMoneySQL =
"Select
fyxt_wp_db_fatcow.fyxt_characters.char_money
From
fyxt_wp_db_fatcow.fyxt_characters
Where
fyxt_wp_db_fatcow.fyxt_characters.idfyxt_character = $charID";
$curCharCash = $wpdb->get_var($curCharMoneySQL);
$wpdb->print_error();
$newCash = $curCharCash - $iCost;
$changeCashSQL = "
UPDATE fyxt_characters
SET
char_money = $newCash
WHERE
idfyxt_character = $charID";
$changeCash = $wpdb->query($changeCashSQL);
$wpdb->print_error();
}
$debugArray = Array();
array_push($debugArray,$charID, $itemID, $buyItem, $getItemDetailsSQL, $getItemDetailsResults,$newItemAdded, $newCash);
echo $debugArray ;
die();
}
?>
I am pretty sure it is 1 (or 2) of 2 things. I am not sure if I am hooking these functions to wordpress right. Or there might be issues with nested functions I have for the jQuery button. I doubt it is number 2 though because it seems to work... I just get a 0 back from the server without any database activity. Here is what the log says.
cID = 112 ?charID=112:538
charMoney = 9990 ?charID=112:539
thisValue = + ?charID=112:540
iID = 664 ?charID=112:541
buy = 0 ?charID=112:542
ajaxurl = http://localhost/nnnnnnnn.com/wp-admin/admin-ajax.php ?charID=112:543
data = [object Object] ?charID=112:550
Object {action: "addItemAJAX", charID: 112, itemID: 664, buyItem: 0} ?charID=112:551
XHR finished loading: "http://localhost/nnnnnnnn.com/wp-admin/admin-ajax.php". jquery-1.9.1.js:8526
send jquery-1.9.1.js:8526
jQuery.extend.ajax jquery-1.9.1.js:7978
jQuery.(anonymous function) jquery-1.9.1.js:7614
(anonymous function) ?charID=112:554
jQuery.event.dispatch jquery-1.9.1.js:3074
elemData.handle
Thank you very much for all of the help and suggestions!
First of all you need to add hooks in proper way
// For the users that are not logged in
add_action( 'wp_ajax_nopriv_addItemAJAX', 'addItemAJAX_callback' );
// For the users that are logged in:
add_action( 'wp_ajax_addItemAJAX', 'addItemAJAX_callback' );
// ajax handler
function addItemAJAX_callback()
{
// code goes here
// since $debugArray is an array, so
die(json_encode($debugArray)); // last line
}
One hook will work when user is logged in and another will work when user is not logged in (for any user). If you are making ajax request for logged in users then, wp_ajax_nopriv_ hook is required.
Keep your js/ajax code in a separate file in yourthemefolder/js/myAjaxScript.js and also keep following code in your functions.php file
add_action('wp_enqueue_scripts', 'my_load_scripts');
function my_load_scripts()
{
// for pluggin, you may use "plugin_dir_url( __FILE__ )"
wp_enqueue_script( 'my_ajax-script', get_stylesheet_directory_uri() . '/js/myAjaxScript.js', array('jquery') );
// Following code will let you use "ajaxObj.ajax_url" to get the
// ajax url (admin-ajax.php) in your my_ajax_scriptjs file
wp_localize_script(
'my_ajax-script', 'ajaxObj', array( 'ajax_url' => admin_url( 'admin-ajax.php' )
));
}
In your my_ajax_script.js file, you may code like this
var data = {
action: 'addItemAJAX_callback',
// ...
};
$.getJson(ajaxObj.ajax_url, data, function(response) {
// response is an object
// ...
});
Alos remember, when using ajax from admin panel, you don't need to use wp_localize_script, since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php.
I won't go through your code as it seems a bit hard to replicate (see SSCCE for this matter). But I'll outline how to work with Ajax and WordPress (from How to Use AJAX in a WordPress Shortcode?):
1) Enqueue and localize the JavaScript file.
Instead of enqueueing, we could print directly in the head or footer, but it's not good practice. And the localization will pass PHP values to JS in a clean fashion.
I'm assuming you're working with a theme, otherwise change get_stylesheet_directory_uri() to plugins_url().
add_action( 'wp_enqueue_scripts', 'enqueue_so_19721859' );
function enqueue_so_19721859()
{
# jQuery will be loaded as a dependency
## DO NOT use other version than the one bundled with WP
### Things will BREAK if you do so
wp_enqueue_script(
'my-handler',
get_stylesheet_directory_uri() . '/js/ajax.js',
array( 'jquery' )
);
# Here we send PHP values to JS
wp_localize_script(
'my-handler',
'my_handler',
array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'ajaxnonce' => wp_create_nonce( 'my_ajax_validation' ) // <--- Security!
)
);
}
2) Ajax for logged and non-logged users
You gotta add a public Ajax callback too with no_priv_:
add_action('wp_ajax_addItemAJAX', 'addItemAJAX_callback');
add_action('wp_ajax_no_priv_addItemAJAX', 'addItemAJAX_callback');
3) Ajax Callback and Response
The Ajax callback has security checks and uses wp_send_json_* to handle the response:
function addItemAJAX_callback()
{
check_ajax_referer( 'my_ajax_validation', 'security' );
$my_thing = something();
if( !$my_thing )
wp_send_json_error( array( 'error' => __( 'Could not retrieve a post.' ) ) );
else
wp_send_json_success( $my_thing );
}
4) Finally, the script
It's essential to wrap all jQuery with noConflict mode.
You can pass whatever info you need through the localized object my_handler. We check 3 things from the response:
total failure: couldn't reach the callback or didn't pass security
partial failure: the callback was reached but returned json_error
success: proceed with your thing
jQuery( document ).ready( function( $ ) {
var data = {
action: 'addItemAJAX_callback',
security: my_handler.ajaxnonce
};
$( '#my-submit' ).click( function(e) {
e.preventDefault();
$.post(
my_handler.ajaxurl,
data,
function( response ) {
// ERROR HANDLING
if( !response.success ) {
// No data came back, maybe a security error
if( !response.data )
$( '#my-answer' ).html( 'AJAX ERROR: no response' );
else
$( '#my-answer' ).html( response.data.error );
}
else
$( '#my-answer' ).html( response.data );
}
);
});
});