Select2: how to make xhr calls on init - ajax

I do some ajax calls for onChange event in Select2. But i need to do similar calls when Select2 is initialized/opened.
How to do it?
$this->widget('ext.select2.ESelect2', array(
'model'=> $model,
'attribute'=> 'PaymentType',//'open'=>'js:{alert("init");}',
'data' => CHtml::listData(PaymentMethod::model()->findall(), 'id','name'),
'htmlOptions'=>array(
//'onInit'=>'js:{alert("init");}', // this does not work!!
'onChange'=>CHtml::ajax(array('type'=>'GET',
'url'=>$this->createUrl('user/cashlessUser', array ('id'=>Yii::app()->user->id)),
'data'=>'js:{PaymentMethod: this.value }',
'success'=>"js:function(data){ alert(data); }",
)),
),
'options'=> array('allowClear'=>true,
'width' => '250',
'placeholder' => '',
),
));
Update
I've found the eSelect2 specification on events here
But it works for pure js, while i need to do it for Yii plugin, where events (except onChange) are not properly fired:
'htmlOptions'=>array(
'select2-opening'=> 'js: console.log("smth"); ',
'select2-opening'=> ' console.log("smth"); ',
'select2-opening'=> ' alert("smth"); ',
's2id_Events_PaymentType.open'=> 'js: console.log("open"); ',
'onFocus'=> 'js: console.log("smth"); ',
'onOpen'=> 'js: console.log("smth"); ',
s2id_Events_PaymentType is an id of this particular eSelect.
All these are not fired, though issue no errors.
Update 2
I've tried to bind logic thru script but with no avail:
Yii::app()->clientScript->registerScript('some-script', "
jQuery('#s2id_Events_PaymentType').on('select2-open', function(e) { console.log('open'); });
");

You should have a look at select2 events in the docs.
I would use these two events:
change - for the AJAX events needed to execute after change
$el.on("change", function (e) {
$.ajax({...});
});
id - Since there is no select2 create or init event we need to override some of the public properties available to us, for example "id" and place our AJAX requests in it.
$el.select2({
id: function (e) {
// execute AJAX calls on init
$.ajax({...});
return e == undefined ? null : e.id;
}
});
And here is an example fiddle: http://jsfiddle.net/dn43uv4c/

Related

Dynamically remove cart fees Woocommerce

I have a WordPress store using the Woocommerce plugin. I am currently able to add fees dynamically at checkout using the $woocommerce->cart->add_fee() function, assigned to the woocommerce_cart_calculate_fees hook. However, I would also like to be able to remove fees at checkout as well, but I haven't managed to make it work. I am attempting to trigger a PHP function via AJAX that will then clear the fees using this method.
When I simply echo 'success' from the clearfees() function, the AJAX call completes successfully. However, when I try calling $WC()->cart->remove_all_fees() AJAX fails with a 500 error.
Remove fees AJAX call from Javascript
function clear_fees() {
$.ajax({
type: 'GET',
url: entrada_params.admin_ajax_url,
data: { action : 'clear_fees' }
}).done( function( data ) {
console.log(data);
} )
.fail( function( jqXHR, textStatus, errorThrown ) { // HTTP Error
console.error( errorThrown );
} );
}
The clearfees function in my theme's functions.php
function clearfees() {
$WC()->cart->remove_all_fees();
wp_die();
}
// creating Ajax call for WordPress
add_action('wp_ajax_clear_fees', 'clearfees');
add_action('wp_ajax_nopriv_clear_fees', 'clearfees');
In my searching I've found very little information on the remove_all_fees() function in practice but it seems like the logical solution if I can get it to work.
i am doing this as i am apply fees in function.php
add_action( 'woocommerce_cart_calculate_fees', 'custom_fee_based_on_cart_total', 10, 1 );
function custom_fee_based_on_cart_total( $cart_object ) {
if(isset($_GET['implementation'])){
$charges = (int)$_GET['charges'];
$cart_total = (int)$cart_object->cart_contents_total;
$fees = $cart_total + $charges;
$applyfee = $_SESSION['applyfee'] ? $_SESSION['applyfee'] : 'true';
if($applyfee == 'true'){
$cart_object->add_fee( __( "Implementation Charges", "woocommerce" ), $charges, false );
}else{
$charges = 0;
$cart_object->add_fee( __( "Implementation Charges", "woocommerce" ), $charges, false );
}
}
}
and if i select remove fees option
function clearfees() {
$_SESSION['applyfee'] = 'false';
}
// creating Ajax call for WordPress
add_action('wp_ajax_clear_fees', 'clearfees');
add_action('wp_ajax_nopriv_clear_fees', 'clearfees');
and at last refresh cart page as i get success responce.

AJAX to update mySQL in Wordpress Custom Table

I have followed Matt Van Andel's Custom List Table Example to create an admin table which displays enquiries to a website via an external MySql database.
Having implemented the displaying of my data correctly, I have added a select box column which will allow the admin to update the 'status' of the enquiry (Awaiting Response, Responded etc.) and I need this to update my database via AJAX.
I need a change in these select boxes to trigger an AJAX call which will update the database with the new value but I seem to be struggling to link my external AJAX file to my plugins .php file correctly.
I have reached a point where (in the Network tab) I can see I am loading the .js file like so:
Code in list-table.php:
function ajax_test_enqueue_scripts() {
wp_enqueue_script( 'list-table', plugins_url( 'js/list-table.js', __FILE__ ), array('jquery'));
}
add_action( 'admin_enqueue_scripts', 'ajax_test_enqueue_scripts' );
And my AJAX:
jQuery('.status-select').on( 'change', function ajaxSubmit() {
alert("IT WORKED!");
$.ajax({
url: ajaxurl,
type: "POST",
cache: false,
data: this.val()
})
});
At the moment the file is showing but the 'on change' part doesn't seem to be firing (hence the 'alert' in the .js).
Apologies if this question is worded or organised poorly, it is my first time posting!
Hope someone can explain what/ where I am going wrong.
This is quite a specific requirement but for anyone else using custom tables in WordPress and wanting to update an external myqsl database via AJAX - here's how I did it.
The AJAX side of things -
<script>
jQuery('select.status').on('change', function() {
var $statusSelect = jQuery( this );
var $statusSelectCell = $statusSelect.parent();
var enquiryStatusValue = $statusSelect.val();
var currentBackgroundColor = $statusSelectCell.parent().css("backgroundColor");
var ajaxData = {
'action': 'update_status_db',
'currentId': $statusSelect.attr('id'),
'data': enquiryStatusValue
}
jQuery.ajax({
type: "POST",
url: "/wp-admin/admin-ajax.php",
data: ajaxData,
success: function( response ) {
console.log("Data returned: " + response );
$statusSelectCell.parent().css({"background-color": "#b3e6b3"});
$statusSelectCell.parent().animate({backgroundColor: currentBackgroundColor}, 1200);
},
error: function() {
alert("FAILED TO POST DATA!!");
}
});
})
</script>
Note, the users success confirmation in this case is for the specific row to flash green. This is optional.
Next, the PHP to process the AJAX request. This is to be written outside the tables class.
wp_enqueue_script('jquery');
add_action( 'wp_ajax_update_status_db', 'update_status_db_callback' );
function update_status_db_callback(){
global $wpdb;
$newStatus = $_POST['data'];
$currentId = $_POST['currentId'];
$table = 'wp_enquiryinfo';
$result = $wpdb->update( $table, array( 'status' => $newStatus ), array( 'id' => $currentId ));
echo $_POST['data'];
if (!$result) {
echo "FAILED TO UPDATE";
} else {
$result;
echo "WILL UPDATE SUCCESSFULLY - CALL RESULT FUNCTION";
};
wp_die();
}
Here are a couple of the things I was getting wrong originally:
Firstly, the callback function HAS to end with _callback. Secondly, I didn't call the wp_die function at the end of this - this again is required.
Hopefully this may be of use to someone in the future.

How to get data back from a $.post call?

I don't want to refresh a page when I am searching through a database eg. on post, so I had help in using a $.post call which works for sending information. There is a .done(function( data ){ line which I haven't used yet.
I also came across this question which I'm not sure if this ties to my question.
Return $.get data in a function using jQuery
I'm trying to search through a database, string match, and return the rows with matching strings. But I want to do this without refreshing the page so I would think that I am using the $.post call and using the .done(function( data ){ which is triggered by javascript (a button).
So I have two parts, the page I'm on and a separate PHP page that processes the call when made.
How do I make the bridge where I can return the data back? Or is there an easier way to do this?
The method .done(function(){}) is exactly what You would like to use, but You can also take a look at third argument (callback) of $.post function.
On server side, do all the queries and prepare the stuff in jsoned array like:
// set up data to send
$contentArray = [
'content' => 'Some content',
'foo' => 'bar',
];
$jsonResults = json_encode($contentArray);
// you can always send header('Content-Type: application/json'); instead of using simple die function.
die($jsonResults);
Then on client side:
<div class="content-container"></div>
<script type="text/javascript">
function someFunc() {
(...)
$.post(addr, values, function(res) {
var response = $.parseJSON(res);
$('.content-container').html(response.content);
});
}
</script>
This should update the content of the .content-container class only. You can send as much as you want, even prepared view to be displayed in the container. This is up to You.
EDIT:
Just to be sure, you're calling someFunc() on some button click event, right? If not, do it as follows:
<div class="content-container"></div>
Click here
<script type="text/javascript">
function changePageContent(addr, contentId) {
$.post(addr, {contentId:contentId}, function(res) {
var response = $.parseJSON(res);
$('.content-container').html(response.content);
});
}
$('.callMe').on('click', function() {
changePageContent($(this).attr('href'), $(this).attr('data-content-id'));
return false;
});
</script>
someScript.php:
<?php
// you should force your script to allow only XML HTTP request here
if(empty($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') {
die('AJAX requests only..');
}
// always remember to escape somehow your post values before you use them
$contentId = is_numeric($_POST['contentId']) ? intval($_POST['contentId']) : null;
if (null == $contentId) (...) // throw exception or return status=false
// do your mysql query like: "SELECT * FROM content WHERE id=".$contentId;
// well, it would be better to send headers instead of that
die(json_encode([
'status' => true, // this is a good practice to send some info, if everything is fine, if mysql row has been found etc..
'result' => $result, // mysql row, this is just in case you need other values to display
'content' => $result['content'], // I assume you have 'content' column in your mysql
]));
?>
Take a look at the docs for Ajax, there really is a lot of info there which will help.
In short, you could do something like this:
function myPost() {
// Set the data
var data = {
'key' : 'value',
'key_2' : 'value_2'
};
// Do the post
$.post( '/your-url/', data, callBack );
}
function callBack( data ) {
// If the $.post was successful
success: function( data ) {
// do stuff
console.log( data ); // returned from your endpoint
},
// If there was an error
error: function( jqXHR, textStatus ) {
// do stuff
console.log( "Request failed: " + textStatus );
}
}
// On click of your element, fire the post request
$('#element').on('click', function() {
myPost();
});

Localize script not working in ajax

I am testing ajax in wordpress, and it basically works but I do not want the url to be hardcoded, so I tried using wp_localize_script to get an object to use, but I get an error saying: "ReferenceError: WPURLS is not defined" when alerting the siteurl in ajax_script.js.
functions.php
function my_scripts_method() {
wp_enqueue_script(
'ajax_script',
get_stylesheet_directory_uri() . '/js/ajax_script.js',
array( 'jquery' )
);
}
add_action( 'wp_enqueue_scripts', 'my_scripts_method' );
wp_localize_script('ajax_script', 'WPURLS', array( 'siteurl' => get_option('siteurl') ));
ajax_script.js
$(function () {
$('#vru-btn').click(function() {
// alert('code');
$.post( 'wp-content/themes/wpcleantheme/ajax/test.php', function(data) {
$('#vru-div').html(data);
});
});;
alert(WPURLS.siteurl);
});
wp_localize_script( 'ajax_script', 'WPURLS',array('siteurl' => get_option('siteurl')));
Then in script:
WPURLS.siteurl will contain the url.
When wp_localize_script is called, it takes your data and passes it through to the script in object form.
Also keep in mind, localize_script needs to be called AFTER a script is registered and enqueued.

CakePHP - DatePicker and TimePicker doesnt work when I make a request ajax ('change')

i'm using CakePHP with a datepicker and a timepicker. In my CakePHP aplicattion i use
$this->Js->get('#tes')->event('change', $this->Js->request
to populate different dropdown lists according to the choices.
but when i choose an element of a dropdownlists and my request (js->get(#tes) ...) are made, my date/time picker the are crazy:
The datepicker not get with the current date selected.
The TimePicker, whenever I try to change the time (it does not allow) and
always comes back to the previous hour.
how can i resolve my problem?
is there any way in javascript file, check if a request was made ​​"change" and reset the time / datepicker?
MY JAVASCRIPT FILE TO TIMEPICKER
(function($) {
$(document).ready(function() {
$('#timepicker').timepicker();
});
})(jQuery);
MY JAVASCRIPT FILE TO DATEPICKER
(function($) {
$(document).ready(function() {
var today = new Date(),
t = today.getDate() + "-" + (today.getMonth() + 1) + "-" + today.getFullYear();
$("#dp3").datepicker(
{
format: 'yyyy-mm-dd'
}
).on('show', function(e) {
$("#dp3").datepicker('setValue', t);
});
if (document.getElementById("date")) {
document.getElementById("date").value = document.getElementById("date").defaultValue = t;
}
});
})(jQuery);
CODE IN MY VIEW THAT CHANGE DROPDOWNLISTS
$this->Js->get('#example')->event('change', $this->Js->request(array(
'controller' => 'Example',
'action' => 'getmylist'
), array(
'update' => '#example2',
'async' => true,
'method' => 'post',
'dataExpression' => true,
'data' => $this->Js->serializeForm(array(
'isForm' => true,
'inline' => true
))
)));
I just can not explain what happens to the datepicker. he turns around at the time. back to 1928 and not to the current date.
Thanks

Resources