Use Ajax to change payment plugins state - ajax

I tried to create plugin that to customize woocommerce payments setting page , I create it with ajax code but i cant complete the plugin and make it work.
My js code
(function ($) {
$(document).on('change', '.wsd-plugin-controller-toggle', function () { //checkbox
let initiator = $(this),
data = {
'action_type': initiator.data('state'),
'plugin_slug': initiator.data('plugin-slug')
};
$.ajax({
url: plugins_controller.rest.endpoints.update_state,
type: "POST",
data: data,
beforeSend: function (xhr) {
xhr.setRequestHeader('X-WP-Nonce', plugins_controller.rest.nonce);
initiator.closest('.wsd-toggler').find('.wsd-loading').toggleClass('visible');
},
success: function (response) {
console.log(response);
initiator.data('state', response.state);
if (initiator.data('reload')) {
location.reload();
}
$(document).trigger('wsd-plugin-state-updated', [initiator, response]);
initiator.closest('.wsd-toggler').find('.wsd-loading').toggleClass('visible');
},
error: function (response) {
console.log('error ', response);
initiator.prop('checked', false);
$(document).trigger('wsd-plugin-state-update-failed', [initiator, response]);
initiator.closest('.wsd-toggler').find('.wsd-loading').toggleClass('visible');
}
});
});
})(jQuery);
and my html code
<td class="title">
My Fatoorah
</td>
<td class="status">
<div class="wsd-toggler">
<input id="toggler-csCeE5" type="checkbox" class="wsd-toggler-input wsd-plugin-controller-toggle" data-plugin-slug="myfatoorah-woocommerce/myfatoorah-woocommerce.php" data-state="activate">
<label for="toggler-csCeE5" class="check-trail wsd-toggler-shape">
<span class="check-handler wsd-toggler-handler"></span>
</label>
<img src="\wordpress\wp-content\plugins\store_settings\assets\images\spinner.svg" class="wsd-loading" alt="loading">
</div>
</td>
<td class="moderate">
<select class="wsd-payment-popup-select wsd-hidden" onchange="location = this.value;">
<option selected="" disabled="" hidden="">إدارة</option>
<option value="/wordpress/wp-admin/admin.php?page=wc-settings&tab=checkout&section=myfatoorah_direct">
الدفع المباشر
</option>
<option value="/wordpress/wp-admin/admin.php?page=wc-settings&tab=checkout&section=myfatoorah_v2">
كارت
</option>
</select>
</td>
</tr>
And my main page php i add
add_action('admin_enqueue_scripts', 'load_payment_style');
function load_payment_style()
{
wp_enqueue_style('plugins_controller_style', plugins_url('style.css', __FILE__));
wp_enqueue_script('plugins_controller', plugins_url('plugins_controller.js', __FILE__));
wp_localize_script( 'plugins_controller', 'plugins_controller',
array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ,
'ajax_nonce' => wp_create_nonce( 'plugins_controller' ) ) );
}
I need to chang payment state (active / deactive) by toggler like this
payment setting page
thank you

Related

How to send other variable datas along with new FormData() inside AJAX?

Here I am sending the upload files into FormData() to be accessed in expressjs. And it is working perfectly.
$(".commonForm").submit(function (e) { //For Submitting the Uploaded Files
e.preventDefault();
if(validateForm($(this).attr('name'), text))
{
$.LoadingOverlay("show");
var formData = new FormData(this);
$.ajax({
type: "POST",
url: $(this).attr('action'),
data: formData,
processData: false,
contentType: false,
dataType: "json",
success: function(response){
if (response.status == '200') {
$.LoadingOverlay("hide");
swal({
title: "Excellent!",
text: "Files submitted successfully!",
icon: "success",
button: "Ok",
showCancelButton: true
}).then((result) => {
if (result) {
window.location.reload();
}
});
}
},
error: function (e) {
console.log("some error", e);
}
});
}
});
But along with that I want to send one another field data along with formData.
var text = 'Done';
How to send this along with formData in data ?
I am trying this:
data : {
formData:formData,
text:text
}
But then I don't think that I will be able to retrieve the uploaded files data directly with req.files
UPDATE:
route code/expressjs
router.post('/api/upload/:cid',function(req,res,next){
console.log("req.body.text = " + req.body.text + req.query.text);
upload2(req,res,function(err) {
if(err) {
console.log("Error is important = "+ err);
}
else
{
console.log("Uploaded successfully.");
}
})
})
MULTER CODE:
var upload2 = multer({storage: storage2, limits: { fileSize: 1024 * 1024 * 1 }}).array('FileUploadForClient',4);
HTML HANDLEBAR FORM CODE:
<form name="{{this.status}}" class="commonForm" enctype="application/x-www-form-urlencoded" action="/api/upload/{{this.commonID}}" method="post">
<td class="col-sm-2">
<div class="center">
<select name="sourcesSelect" id="{{this.commonID}}" data-notUse="{{this._id}}" data-Id4AddtasksBigpaths="{{this.Id4AddtasksBigpaths}}" class="custom-select sources" placeholder="{{this.status}}" style="font-size:20px; background: {{this.background}}; color: white;" {{this.statusDisabled}}>
<option value="0" >In Progress</option>
<option value="1" >Done</option>
<option value="2" >Rejected</option>
</select>
</div>
</td>
<!-- <td class="col-sm-2"><span id="deadline" style="font-size:14px"><input type="text" class="form-control" value="{{this.deadline}}" readonly/></span></td> -->
<td class="col-sm-1">
<!-- <input type="file" class="btn btn-light" name="FileUploadForClient" multiple required/> -->
<input type="file" id="{{this._id}}" class="form-control" name="FileUploadForClient" multiple required {{this.statusDisabled}} />
</td>
<td>
<button type="submit" class="btn btn-primary btn-block col-sm-2" style="font-size:16px" {{this.statusDisabled}}>Submit</button>
</td>
</form>
Use the method append to add another parameter to the request
var formData = new FormData(this);
formData.append('text', 'text to send in the request ');

WordPress AJAX 400 Bad request while submitting form

I am poor in AJAX and trying to submit the form and insert the record to the custom table since a couple of days but not getting it to work.
I am getting 400 Bad request error on console. Please have a look at the code.
In fact, I have tried multiple ways to submit data but none of them
works.
HTML
<form class="addtocartform" id="gsAddToCart" method="POST">
<label class="gs-label" for="options">Options</label>
<select class="gs-select-box" id="product_option" name="product_option">
<option value="0">Somnath</option>
<option value="1">Dwarka</option>
<option value="2">Rameshwaram</option>
</select>
<label class="gs-label" for="qty">Qty.</label>
<input class="gs-number" id="qty" min="1" name="qty" step="1" type="number" value="1">
<button class="gs-button order-button add-to-cart-button">
<i class="fa fa-cart-plus"></i>
<span class="gs-button-label">Add to Cart</span>
</button>
<input id="product" name="product" type="hidden" value="160"/>
<input id="group_id" name="group_id" type="hidden" value="194"/>
</input>
</form>
WordPress Hooks - Enqueue scripts
function gs_enqueue_ajax_scripts()
{
wp_register_script('gs-ajax', GROUP_SHOP_ROOT . 'public/js/add-to-cart-ajax.js', ['jquery'], 1.0, TRUE);
wp_localize_script('gs-ajax', 'ajax_vars', [
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('gs_nonce'),
]);
wp_enqueue_script('gs-ajax');
}
add_action('wp_enqueue_scripts', 'gs_enqueue_ajax_scripts');
WordPress Hooks - Process and Insert Data
function gs_add_to_cart_ajax()
{
check_ajax_referer('gs_nonce', $_POST[ 'nonce' ], FALSE);
// validating stuffs ..
$cart = new Group_Shop_Cart();
$cart->add_to_cart($_POST[ 'group_id' ], $_POST[ 'product' ], $_POST[ 'qty' ], $_POST[ 'product_option' ]);
wp_die();
}
add_action('wp_ajax_gs_add_to_cart_ajax', 'gs_add_to_cart_ajax');
add_action('wp_ajax_nopriv_gs_add_to_cart_ajax', 'gs_add_to_cart_ajax');
Javascript
(function ($) {
$(document).on("click", ".add-to-cart-button", function () {
let data = JSON.stringify({
action: 'gs_add_to_cart_ajax',
group_id: $('#group_id').val(),
product: $('#product').val(),
qty: $('#qty').val(),
product_option: $('#product_option').val(),
});
$('form.addtocartform').on('submit', function (e) {
e.preventDefault();
$.ajax({
method: 'POST',
dataType: 'json',
nonce: ajax_vars.nonce,
url: ajax_vars.ajax_url,
data: data,
success: function (response) {
alert("Success");
}
});
});
});
})(jQuery);
I have no idea what is wrong in this code that not submitting.
Modified Code
$.ajax({
method: 'POST',
dataType: 'json',
nonce: ajax_vars.nonce,
url: ajax_vars.ajax_url,
data: {
action: 'gs_add_to_cart_ajax',
group_id: $('#group_id').val(),
product: $('#product').val(),
qty: $('#qty').val(),
product_option: $('#product_option').val(),
},
success: function (response) {
alert("Success");
}
});

Laravel 5 multi dynamic dropdown

I'm trying to use the data of the first dropdown, to fill the second.
An example here:
https://gitlab.com/Bons/laravel5.3_dynamic_dropdown/blob/master/readme.md
Controller functon return data, but second dropdown is empty.
First dropdown:
<span>Country: </span>
<select style="width: 200px" class="country" id="id_country">
<option value="0" disabled="true" selected="true">-Select-</option>
#foreach($countries as $contry)
<option value="{{$contry->id_country}}">{{$contry->name}}</option>
#endforeach
</select>
linked dropdown:
<label>City
<select id="region" class="form-control input-sm" name="region_id">
<option value=""></option>
</select>
</label>
Script:
<script type="text/javascript">
$(document).ready(function(){
$(document).on('change','.country',function(){
console.log("hmm its change");
var id=$(this).val();
console.log(id)
$.ajax({
type:'get',
url:'{!!URL::to('findRegions')!!}',
data:{'id':id},
success:function(data) {
console.log("success");
console.log(data.length);
console.log(data);
$.each(data, function(index,subCatObj){
// console.log(subCatObj.name)
$('#region').append(''+subCatObj.name+'');
});
},
error:function(){
console.log("error");
}
});
});
});
</script>
Route:
Route::get('/findRegions/','GirlsController#findRegions');
Controller function:
public function findRegions(Request $request){
$id=$request->id;
$regions=Region::select('name')
->where('id_country',$id)
->get();
dump($regions);
return $regions;
}
Here is how i did it,
in routes/web.php
Route::post('select-ajax', 'Main#selectAjax')->name('select-ajax');
in Controller : Main.php
public function __construct()
{
View::share('selectAllCountries', Country::pluck("name","id")->all());
}
public function selectAjax(Request $request)
{
if($request->ajax())
{
$getRegion = Region::where('id_country',$request->id)->pluck("nameOfTheRegion","id")->all();
$data = view('ajax-select',compact('getRegion'))->render();
return response()->json(['options'=>$data]);
}
}
then create a simple blade file name ajax-select.blade.php
<option selected disabled>--- Select Region---</option>
#if(!empty($getRegion))
#foreach($getRegion as $key => $value)
<option value="{{ $key }}">{{ $value }}</option>
#endforeach
#endif
Ajax call
{!! Form::select('country',[' '=>'--- Select Country ---']+$selectAllCountries,null,['class'=>'form-control']) !!}
{!! Form::select('region',[' '=>'--- Select Region---'],null,['class'=>'form-control']) !!}
<script>
$("select[name='country']").change(function(){
var id = $(this).val();
var token = $("input[name='_token']").val();
$.ajax({
url: "{{ route('select-ajax') }}",
method: 'POST',
data: {'id':id, '_token':token},
success: function(data) {
$("select[name='region']").html('');
$("select[name='region']").html(data.options);
},
error:function(){
alert("error!!!!");
}
});
});
</script>
Hope this helps

How to create drop down

I want to generate a list on items in a drop down based on a previous choice from another select. All items ar in the database.
Here is what I did:
Javascript:
$(document).ready(function () {
$(document).on('change', '#province_name', function() {
var province_id = $(this).val();
var div = $(this).parent();
var op = " ";
$.ajax({
type: 'get',
url: '{!!URL::to('admin/findIDProvince')!!}',
data: {'id':province_id},
success: function(data){
for (var i = 0; i < data.length; i++){
op += '<option value="'+data[i].id+'">'+data[i].city_name+'</option>';
}
div.find('#city').html(" ");
div.find('#city').append(op);
},
error: function(){
console.log('success');
},
});
});
});
Routes (web.php):
Route::namespace('Admin')->prefix('admin')->middleware('auth', 'CheckAdmin')->group(function (){
$this->get('/findIDProvince', 'SchoolsListController#findIDProvince');
});
Controller (Admin/SchoolsListController.php):
public function findIDProvince(Request $request)
{
$data = City::select('name', 'id')->where('province_id', $request->id)->take(100)->get();
return response()->json($data);
}
HTML (view.blade.php)
<div class="form-group">
<label class="col-md-3" for="province_name">province_name</label>
<div class="col-md-9">
<select id="province_name" name="province_name" class="form-control col-md-12" required>
#foreach($province_names as $province_name)
<option value="{{ $province_name->id }}">{{ $province_name->province_name }}</option>
#endforeach
</select>
</div>
</div>
<div class="form-group">
<label class="col-md-3" for="city_name">city_name</label>
<div class="col-md-9">
<select id="city_name" name="city_name" class="form-control col-md-12" required>
</select>
</div>
</div>
What am I doing wrong?
First, create a hidden filed with the value for which the option that need to be selected.
<input type="hidden" value="{{ $yourOptionValueToSelect }}" id="selectThis">
Then with jQuery find the matching value from your option and change the corresponding attribute as selected.
$('option').each(function() {
if (this.value == $('#selectThis').val()) {
this.setAttribute('selected', 'selected');
}
});
Example:
<input type="hidden" value="2" id="selectThis">
<select>
<option value="1">Hello</option>
<option value="2">World</option>
</select>
Here Option 2 will be selected by default with the above jQuery Code.
In your view it will be changed to:
<option value="2" selected="selected">World</option>
// prepend : attach default value to the begining of the dropdown for region
// $('.region').prepend('<option value="default" selected="selected">Please select</option>');
$('.region').on('change', function(e) {
$('.select2-selection__placeholder').css("font-size", '11px'); // change the font size of the select box
var region = e.target.value;
$.ajax({
url: "{{ url('/dropdown/station?region')}}=" + region, // value.id refers to ring_id
type: "get",
cache: false,
beforeSend: function() {
$('.ajax-loader').css("visibility", "visible");
},
complete: function() {
$('.ajax-loader').css("visibility", "hidden");
},
dataType: 'json',
success: function(data) {
// empty the option before we populate the dropdown
$('#station').empty();
// define default value
$('#station').append('<option value="default" selected="selected" disabled hidden></option>');
$.each(data, function(index, subCatObj) {
// alert(subCatObj.substation_name);
$('#station').append($('<option>').text(index).attr('value', index));
$('#station').append('' + index + '');
});
},
error: function(error) {
console.log(error);
}
});
});
$('.station').on('change', function(e) {
var station = e.target.value;
$.ajax({
url: "{{ url('/dropdown/kv-station?station')}}=" + station, // value.id refers to ring_id
type: "get",
cache: false,
beforeSend: function() {
$('.ajax-loader').css("visibility", "visible");
},
complete: function() {
$('.ajax-loader').css("visibility", "hidden");
},
dataType: 'json',
success: function(data) {
// empty the option before we populate the dropdown
$('#kvStation').empty();
// define default value
$('#kvStation').append('<option value="default" selected="selected" disabled hidden></option>');
$.each(data, function(index, subCatObj) {
// alert(subCatObj.substation_name);
$('#kvStation').append($('<option>').text(index).attr('value', index));
$('#kvStation').append('' + index + '');
});
},
error: function(error) {
console.log(error);
}
});
});
// kv station dropdown event
$('.kvStation').on('change', function(e) {
var station = e.target.value;
$.ajax({
url: "{{ url('/dropdown/ring?station') }}=" + station, // value.id refers to ring_id
type: "get",
cache: false,
beforeSend: function() {
$('.ajax-loader').css("visibility", "visible");
},
complete: function() {
$('.ajax-loader').css("visibility", "hidden");
},
dataType: 'json',
success: function(data, jqXHR) {
// remove the previous data ferom select
$('#ring').empty();
// checking the status code; if 204: no content, then
if (jqXHR.status === 204) {
$('#ring').append('<option value="default" selected="selected">No data</option>');
} else {
$('#ring').append('<option value="default" selected="selected" disabled hidden></option>');
}
// empty the option before we populate the dropdown
$.each(data, function(index, subCatObj) {
$('#ring').append($('<option>').text(subCatObj).attr('value', index));
$('#ring').append('' + index + '');
});
},
error: function(error) {
console.log(error);
}
});
// ring dropdown event
$('.ring').on('change', function(e) {
var id = e.target.value;
window.open('{{url(' / ring ')}}/' + id, '_blank');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="bottom">
<ul>
<li>
<label>Region
<select id="region-select" class=" form-control select2 region" name="region">
<option></option>
#foreach($regions as $region)
<option value="{{$region->region}}">
{{$region->region}}
</option>
#endforeach
</select>
{{--        {!! Form::select('region', $regions,'Please select ...', ['class' => 'region form-control select2', 'id' => 'region-select']) !!}--}}
</label>
</li>
<li>
<label>Station
<select id="station" class=" selectpicker station form-control input-sm" name="station">
<option value=""></option>
</select>
</label>
</li>
<li>
<label>KV Station
<select id="kvStation" class="kvStation form-control input-sm" name="kv-station">
<option value=""></option>
</select>
</label>
</li>
<li>
<label>Ring
<select id="ring" class="ring form-control input-sm" name="ring">
<option value=""></option>
</select>
</label>
</li>
</ul>
<i id="loading-image" hidden class="livicon" data-name="spinner-three" data-size="50" data-c="#fff" data-hc="#fff" data-loop="true"></i>
<div class="ajax-loader">
<img id="loading-image" class="loading-image img-responsive" src="{{ asset('images/ajax-loader.gif') }}">
</div>
</div>

laravel search - returning all results even if no match and make delay to ajax

I have a problem with my search.
Problem 1
Currently if I type in the field it is searching however the search never ever stops, so if I type hello, it will make about 500 requests within a minute.
Problem 2
I am searching in film table to find matching 'title' as well as find business name corresponding to business_id in business table.
Problem 3
Each time request is made it brings back master page again i.e. loading all js and css (which might be why it is making so many requests?) but if I don't extend master, result blade doesn't work.
however even if I input 'e' it brings me back 'guardians of the galaxy' which doesn't have 'e' My thoughts are that it is searching throught business table as well somehow. They have both eloquent one to one relationships
Controller:
public function cinema_search($cinema_value) {
$cinema_text = $cinema_value;
if ($cinema_text==NULL) {
$data = Film::all();
} else {
$data = Film::where('title', 'LIKE', '%'.$cinema_text.'%')->with('business')->get();
}
return view('cinemasearch')->with('results',$data);
}
Form::
<form id="cinema_display">
<div class="form-group">
<input type="text" class="form-control" id="search_cinemas" onkeyup="search_cinema(this.value);" placeholder="Search film">
</div>
<div id="show"
</div>
</div>
</form>
ajax:
function search_cinema(cinema_value) {
$.ajax({
url: '/cinemasearch/' + cinema_value,
type: 'post',
dataType: 'html',
success: function(data) {
$('#show').append(data);
$('.se-pre-con').fadeOut('slow', function () {
$(".container").css({ opacity: 1.0 });
});
},
error: function(data) {
},
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
}
});
}
cinemasearch.blade(results):
#extends('master') #section('title', 'Live Oldham') #section('content')
#section('content')
<table style="width:100%">
#if (isset($results) && count($results) > 0)
#foreach( $results as $film )
<tr>
<td>{{ $film->business->name }}</td>
<td>{{ $film->title }}</td>
<td>{{ $film->times}}</td>
</tr>
#endforeach
#endif
</table>
#endsection
function search_data(search_value) {  
$.ajax({
        url: '/searching/' + search_value,
        type: 'post',
        dataType: 'html',
        success: function(data) {
            $('#show_search_result').append(data);
            $('.se-pre-con').fadeOut('slow', function () {
$(".container").css({ opacity: 1.0 });
            });
        },
        error: function(data) {
            $('body').html(data);
        },
        headers: {
        'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
        }
    });
}
function tram_stops(tram_value) {
    $.ajax({
        url: '/tramsearch/' + tram_value,
        type: 'post',
        dataType: 'html',
        success: function(data) {
            $("#display").html(data);
            var tram_value = tram_value;
        },
        error: function(data) {
            
        },
        headers: {
        'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
        }
    });
}
/*
setInterval(tram_stops, (30 * 1000));
*/
function search_cinema(cinema_value) {
    $.ajax({
        url: '/cinemasearch/' + cinema_value,
        type: 'post',
        dataType: 'html',
        success: function(data) {
                var items = JSON.parse(data);
                var showElement = $('#show');
                showElement.html('');
                $.each(data, function() {
                   showElement.append(this.title +' '+ this.times+'<br />');
                });
        },
        error: function(data) {
        },
        headers: {
        'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
        }
    });
}
You are returning the wrong response type from cinema_search. Ajax expects a JsonResponse, not what the view helper returns which is \Illuminate\Http\Response. Put your search results in:
return response()->json(['results' => $data]);
to start with if you just want the data. If you want to actually return the rendered view file, you would need to do:
return response()->json(['results' => view('cinemasearch')->with('results',$data)->render()]);
then inject that into your DOM. The problem with rendering server side is nothing is bound client side so if you have any interaction requiring JS, you'll need to create those manually in your success callback.
Problem 1:
Remove the keyUp event in your html and add an event in Jquery.
Your HTML structure is not correct
This:
<form id="cinema_display">
<div class="form-group">
<input type="text" class="form-control" id="search_cinemas" onkeyup="search_cinema(this.value);" placeholder="Search film">
</div>
<div id="show"
</div>
</div>
</form>
Should be:
<form id="cinema_display">
<div class="form-group">
<input type="text" class="form-control" id="search_cinemas" onkeyup="search_cinema(this.value);" placeholder="Search film">
<div id="show">
</div>
</div>
</form>
Then again you should consider to remove the onkeyup event. And change add it in Jquery to something like this:
Problem 2 & 3: I would recommend a raw Query and return an json instead of a view. And you shouldn't check if($cinema_text === NULL) this won't be the case ever. Unless you put NULL in your url and even then it will be an String and not NULL and if('NULL' === NULL) returns false look at this post for the diff of == and ===.
public function cinema_search($cinema_value) {
$cinema_text = $cinema_value;
if (empty($cinema_text)) {
$data = Film::all();
} else {
$data = DB::select('*')
->from('films')
->join('businesses', 'businesses.id', '=', 'films.business_id')
->where('films.title', 'LIKE', '%'.$cinema_text.'%')
->orWhere('bussiness.title', 'LIKE', '%'.$cinema_text.'%')
->get();
}
return response()->json(['results' => $data]);
}
Then in your JavaScript do something like this:
$( document ).ready(function() {
console.log( "ready!" );
$( "#search_cinemas" ).change(function() {
search_cinema(this.value);
console.log( "New value"+this.value+"!" );
});
function search_cinema(cinema_value) {
console.log('setup ajax');
$.ajax({
url: '/cinemasearch/' + cinema_value,
type: 'post',
success: function(data) {
console.log('success!');
var showElement = $('#show');
showElement.html('');
$.each(items, function() {
showElement.append(this.title +' '+ this.times+'<br />');
});
},
error: function(data) {
console.log(data);
},
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
}
});
}
});

Resources