WooCommerce Ajax add to cart with additional custom data - javascript

I am having some difficulties with trying to add to cart with custom data from the front end.
My current PHP from the backend is as follows - this is placed in my functions.php for my child-theme (This code is from the following post: Adding a product to cart with custom info and price - considering I am indeed a PHP-noobie):
<?php // This captures additional posted information (all sent in one array)
add_filter('woocommerce_add_cart_item_data','wdm_add_item_data',1,10);
function wdm_add_item_data($cart_item_data, $product_id) {
global $woocommerce;
$new_value = array();
$new_value['_custom_options'] = $_POST['custom_options'];
if(empty($cart_item_data)) {
return $new_value;
} else {
return array_merge($cart_item_data, $new_value);
}
}
// This captures the information from the previous function and attaches it to the item.
add_filter('woocommerce_get_cart_item_from_session', 'wdm_get_cart_items_from_session', 1, 3 );
function wdm_get_cart_items_from_session($item,$values,$key) {
if (array_key_exists( '_custom_options', $values ) ) {
$item['_custom_options'] = $values['_custom_options'];
}
return $item;
}
// This displays extra information on basket & checkout from within the added info that was attached to the item.
add_filter('woocommerce_cart_item_name','add_usr_custom_session',1,3);
function add_usr_custom_session($product_name, $values, $cart_item_key ) {
$return_string = $product_name . "<br />" . $values['_custom_options']['description'];// . "<br />" . print_r($values['_custom_options']);
return $return_string;
}
//This adds the information as meta data so that it can be seen as part of the order (to hide any meta data from the customer just start it with an underscore)
add_action('woocommerce_add_order_item_meta','wdm_add_values_to_order_item_meta',1,2);
function wdm_add_values_to_order_item_meta($item_id, $values) {
global $woocommerce,$wpdb;
wc_add_order_item_meta($item_id,'item_details',$values['_custom_options']['description']);
wc_add_order_item_meta($item_id,'customer_image',$values['_custom_options']['another_example_field']);
wc_add_order_item_meta($item_id,'_hidden_field',$values['_custom_options']['hidden_info']);
}
and then I have a button on the frontend that runs the following script when pressed - this runs on a custom wordpress post where I have scripted have done some scripting in the background that collects information based on the users actions on the post:
function cartData() {
var metaData = {
description: 'My test Description'
another_example_field: 'test'
};
var activeVariationId = 10335;
var data = {
action: 'wdm_add_item_data',
product_id: 10324,
"add-to-cart": 10324,
quantity: 1,
variation_id: activeVariationId,
cart_item_data: metaData
};
$.ajax({
type: 'post',
url: wc_add_to_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'add-to-cart' ),
data: data,
beforeSend: function (response) {
//$thisbutton.removeClass('added').addClass('loading');
},
complete: function (response) {
//$thisbutton.addClass('added').removeClass('loading');
},
success: function (response) {
if (response.error & response.product_url) {
window.location = response.product_url;
return;
} else {
alert('ajax response recieved');
jQuery( document.body ).trigger( 'added_to_cart', [ response.fragments, response.cart_hash ] );
}
},
});
}
Unfortunately this only seems to add my current variation of the product to the to cart without any more custom information. Any help with nesting in this issue would be highly appreciated. If you need any more information and/or code examples I'd be happy to supply it :)

I think that I might have solved it, or at least parts of it with this PHP (this is really just a small modification of this code - adding $cart_item_data https://quadmenu.com/add-to-cart-with-woocommerce-and-ajax-step-by-step/):
add_action('wp_ajax_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');
add_action('wp_ajax_nopriv_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');
function woocommerce_ajax_add_to_cart() {
$product_id = apply_filters('woocommerce_add_to_cart_product_id', absint($_POST['product_id']));
$quantity = empty($_POST['quantity']) ? 1 : wc_stock_amount($_POST['quantity']);
$variation_id = absint($_POST['variation_id']);
// This is where you extra meta-data goes in
$cart_item_data = $_POST['meta'];
$passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $product_id, $quantity);
$product_status = get_post_status($product_id);
// Remember to add $cart_item_data to WC->cart->add_to_cart
if ($passed_validation && WC()->cart->add_to_cart($product_id, $quantity, $variation_id, $cart_item_data) && 'publish' === $product_status) {
do_action('woocommerce_ajax_added_to_cart', $product_id);
if ('yes' === get_option('woocommerce_cart_redirect_after_add')) {
wc_add_to_cart_message(array($product_id => $quantity), true);
}
WC_AJAX :: get_refreshed_fragments();
} else {
$data = array(
'error' => true,
'product_url' => apply_filters('woocommerce_cart_redirect_after_error', get_permalink($product_id), $product_id));
echo wp_send_json($data);
}
wp_die();
}
Where this is part of the JS-function:
var data = {
action: 'woocommerce_ajax_add_to_cart',
product_id: 10324,
quantity: 1,
variation_id: activeVariationId,
meta: metaData
};
$.ajax({
type: 'post',
url: wc_add_to_cart_params.ajax_url,
data: data, ...........
I am going to have to test it some more, as it seems now that all the data-fields also gets posted in the cart, email etc - I probably have to rewrite something so that some parts of it is hidden for the "non-admin", but available for me later on + adding custom product thumbnail on add to cart.

Related

Targeting ACF sub-fields with Javascript API

How do you target the sub-fields inside a repeater field, so the JS applies to the sub-field when appending new groups???
Been looking, but I got really lost as to where even to start. And the JavaScript API is falling a little short on explaining how to work with repeaters.
I'm working on a form to add orders for a bakery. The form has a repeater which holds the options for each different bread order. In here the select field for TYPE OF DOUGH does much of the pre-selection for the other fields (size, shape, extras).
I've managed to target the select field of TYPE OF DOUGH to send and modify data through AJAX, but when adding another repeater row the code doesn't work.
Here's my code for php and js.
JS
jQuery(document).ready(function ($) {
// field key for TYPE OF DOUGH select field inside repeater field
var field = acf.getField("field_609b103fcd576");
field.on("change", function (e) {
var value = field.val();
console.log(value);
var data = {
"action": "get_size_options",
"type_of_dough": value,
};
$.ajax({
url: ajax_object.ajax_url,
type: "post",
data: data,
dataType: "json",
success: function (data) {
console.log(data);
},
});
});
});
PHP
// enqueue the scripts
function fw_acf_register_scripts() {
// enqueue js file with ajax functions
wp_enqueue_script(
'acf-ajax-script',
get_template_directory_uri() . '/assets/js/autopopulate.js',
['jquery']
);
wp_localize_script(
'acf-ajax-script',
'ajax_object',
['ajax_url' => admin_url('admin-ajax.php')]
);
}
add_action('acf/input/admin_enqueue_scripts', 'fw_acf_register_scripts');
// ex. function to get options for the other fields
function get_size_options() {
$meta_value = fw_get_term_id($_POST['type_of_dough'], 'dough');
// just a function to get the ID for the taxonomy from the slug,
// so it just returns a number, say 501 which is then used for the term query
$size_options = array();
$terms_args = array(
'taxonomy' => 'size',
'hide_empty' => false,
'meta_key' => 'tax_position',
'orderby' => 'tax_position',
'order' => 'ASC',
);
if ($meta_value_masa) {
$terms_args['meta_query'] = array(
array(
'key' => 'dough',
'value' => $meta_value,
'compare' => 'LIKE',
),
);
}
$terms = get_terms($terms_args);
foreach ($terms as $term) {
$size_options[$term->term_id] = $term->name;
}
wp_send_json($size_options);
die();
}
add_action('wp_ajax_get_size_options', 'get_size_options');

Laravel Ajax not updating

I have Laravel project for fire department and I have competitions with results of each team. I made a page where I can edit competition. In result controller
public function update (Request $request){
$item = new Items();
$item->item = $request->item;
$item->data = $request->data;
$item->miejscowosc = $request->miejscowosc;
$item->gmina = $request->gmina;
$item->wojewodztwo = $request->wojewodztwo;
$item->poziom = $request->poziom;
$item->komisja1 = $request->komisja1;
$item->komisja2 = $request->komisja2;
$item->komisja3 = $request->komisja3;
$item->komisja4 = $request->komisja4;
$item->komisja5 = $request->komisja5;
$item->sedzia_glowny = $request->sedzia_glowny;
$item->komisje_powolal = $request->komisje_powolal;
$item->protesty = $request->protesty;
$item->kontuzje = $request->kontuzje;
$item->uwagi = $request->uwagi;
$item->update();
return 'Done';
}
When I change :
$item->update();
To :
$item->save();
It perfectly adds new competition. But when I have
$item->update();
It doesn't update.
Here is my ajax code :
$(document).ready(function() {
$('#updateComp').click(function (event){
$.ajax({
type: 'post',
url: '',
data: {
'_token': $('input[name=_token]').val(),
'item': $("#item").val(),
'data': $('#data').val(),
'miejscowosc': $('#miejscowosc').val(),
'gmina': $('#gmina').val(),
'wojewodztwo': $('#wojewodztwo').val(),
'poziom': $('#poziom :selected').text(),
'komisja1': $('#komisja1').val(),
'komisja2': $('#komisja2').val(),
'komisja3': $('#komisja3').val(),
'komisja4': $('#komisja4').val(),
'komisja5': $('#komisja5').val(),
'sedzia_glowny': $('#sedzia_glowny').val(),
'komisje_powolal': $('#komisje_powolal').val(),
'protesty': $('#protesty').val(),
'kontuzje': $('#kontuzje').val(),
'uwagi': $('#uwagi').val()
},
success: function(data){$('#alert').append('<div class="alert alert-success">Dodano do bazy</div>')},
error: function(){$('#alert').html('<div class="alert alert-danger">Błąd, nie udało się dodać do bazy. Wprowadź dane ponownie</div>')}
});
});
Do I have to change something in ajax code to make it work? Or is it another reason?
(really sorry for other language in project)
For eloquent update, change your code like below code:
Items::find($id)->update(['column' => 'value']);
Here $id is id which you want to update the record. See document
UPDATE
$id = $request->id;//Item id to update...
$arrItem = array(
'item' => $request->item,
'data' => $request->data,
.
.
.
'uwagi' => $request->uwagi,
);
//Update item data...
Items::find($id)->update($arrItem);
you have to send the item id to, so it can point which item need to update
$.ajax({
type: 'post',
url: 'your_url',
data: {
'id':$('#your_id_field'),
'your other field':$('#your_other_field),
.
.
},
success: function(data){$('#alert').append('<div class="alert alert-success">Dodano do bazy</div>')},
error: function(){$('#alert').html('<div class="alert alert-danger">Błąd, nie udało się dodać do bazy. Wprowadź dane ponownie</div>')}
});
//controller, find the data using items model by searching the item's id
public function update (Request $request){
$item = Items::find($request->get('id'));
$item->item = $request->get('item');
.....
.....
....
$item->update();
return 'Done';
}

How to add an AJAX action - Elgg

I'm trying to create an AJAX action in elgg. I have followed this Elgg tutorial: Ajax: Performing actions, but I'm getting nothing so far, apart from the fail error:
Sorry, Ajax only!
The other error is that the page reloads, instead of persisting the data asynchronously.
What am I getting wrong? Thank you all in advance.
Below is my code:
form: views/default/forms/service_comments/add.php
<?php
$url_confirm = elgg_add_action_tokens_to_url("action/service_comments/add?guid={$guid}");
$params_confirm = array(
'href' => $url_confirm,
'text' => elgg_view_icon('upload'),
'is_action' => true,
'is_trusted' => true,
'class' => 'upload-media-update',
);
$confirm = elgg_view('output/url', $params_confirm);
?>
<div class="update-options">
<?= $confirm ?>
</div>
start.php
elgg_register_action("service_comments/add", __DIR__ . "/actions/service_comments/add.php");
action file: actions/service_comments/add.php
<?php
elgg_ajax_gatekeeper();
$arg1 = (int)get_input('arg1');
$arg2 = (int)get_input('arg2');
// will be rendered client-side
system_message('We did it!');
echo json_encode([
'sum' => $arg1 + $arg2,
'product' => $arg1 * $arg2,
]);
Javascript : views/js/service_comments/add.js
var Ajax = require('elgg/Ajax');
var ajax = new Ajax();
ajax.action('service_comments/add', {
data: {
arg1: 1,
arg2: 2
},
}).done(function (output, statusText, jqXHR) {
if (jqXHR.AjaxData.status == -1) {
return;
}
alert(output.sum);
alert(output.product);
});
You have written ajax procedure but not invoking it. Instead you are directly calling it . by making it link.
$params_confirm = array(
'href' => '#',
'text' => elgg_view_icon('upload'),
'onclick' => "myajax_function()",
'class' => 'upload-media-update',
);
$confirm = elgg_view('output/url', $params_confirm);
Then move your JS code inside a function.
function myajax_function(){
var Ajax = require('elgg/Ajax');
var ajax = new Ajax();
ajax.action('service_comments/add', {
data: {
arg1: 1,
arg2: 2
},
}).done(function (output, statusText, jqXHR) {
if (jqXHR.AjaxData.status == -1) {
return;
}
alert(output.sum);
alert(output.product);
});
}

Using Laravel Mentions (at.JS and Laravel) to return A username and their ID

I'm currently building a comment system and would like to include the ability to mention users and tag them, subsequently I would like the tag to have a link to their profile (In this example, it's just /profile/{id})
I am currently using Laravel Mentions to generate the auto filled list from my Users Model. I'm doing it like:
function enableMentions(elem, type, column) {
$(elem).atwho({
at: "#",
limit: 5,
displayTpl: '<li><span>${name}</span></li>',
insertTpl: '${name}',
callbacks: {
remoteFilter: function(query, callback) {
if (query.length <= 1) return;
$.getJSON("/api/mentions/" + type, {
q: query,
c: column
}, function(data) {
callback(data);
});
}
}
});
}
// My api/mentions route: Route::get('/api/mentions/{type}', 'ApiController#index');
//My api controller:
public function index($type, Request $request)
{
try {
$resultColumns = [];
$query = $request->get('q');
$column = $request->get('c');
$model = app()->make(config('mentions.' . $type));
$records = $model->where($column, 'LIKE', "%$query%")
->get();
foreach ($records as $record) {
$resultColumns[] = $record->$column;
}
return response()->json($resultColumns);
} catch (\ReflectionException $e) {
return response()->json('Not Found', 404);
}
}
And finally, initializing the at.js
<script type="text/javascript">
$(function(){
enableMentions("#mention-commentContent", "users", "Username");
});
</script>
<div contentEditable="true" id="mention-commentContent" class="user-form" name="commentContent" type="text"></div>
I'm confused on how I can modify the above to return the username and the ID assigned to them, that way I can change the ${name} to ${id} and have it link through to their profile, right?
This package may help Laravel Mentions or this .
The basic idea is getting the usernames from the database via JSON , here is how they are using it in laracasts:
$("textarea#body").atwho({
at: "#", limit: 5, callbacks: {
remoteFilter: function (t, e) {
t.length <= 2 || $.getJSON("/api/users", {q: t}, function (t) {
e(t)
})
}
}
})

MySQL table update using jQuery/AJAX

I have a main php file and a javascript file. I want to update each field in my form by using jQuery/AJAX. I have all the right database update sql, etc. It's my jQuery that is wrong. I have a table tahts called profiles. Here are the column names:
As of now, when I click the update button, it redirects me to a blank page, with the updated information displayed in the page url. When I check my database, nothing has been saved.
This is a wordpress plugin
Here is my code
jQuery update
jQuery(document).ready(function ($) {
eventHandlers = function () {
$('#cm-list').delegate('.update', 'click', function (event) {
event.preventDefault();
var row = $(this).parent()[0],
htmid = row.id,
id = htmid.replace('no_', ''),
fname = $('.fname', row).val(),
lname = $('.lname', row).val(),
sex = $('.sex', row).val(),
nationality = $('.nation', row).val(),
position = $('.position', row).val(),
json = { 'id': id, 'fname': fname, 'lname': lname, 'sex': sex, 'nationality': nation, 'position': position };
if (fname.length > 1) {
$.post(ajaxurl, { action: 'updateprofile', 'pro_data': json }, function (data) {
if (data) {
$.jGrowl(custom.profile_name + fname + lname + custom.edited, { header: custom.yes });
}
});
}
else {
$.jGrowl(custom.err, { header: custom.no });
}
});
},
cm_init = function () {
eventHandlers();
};
cm_init();
});
Php code just to show you my sql
My function updateprofile() is inside __construct()
add_action(wp_ajax...... ajax hooks
function update() {
if (!isset($_POST['pro_data'])) {
return;
}
$this->db_update($_POST['pro_data']);
}
function db_update($input) {
global $wpdb;
$result = $wpdb->update($wpdb->prefix . CM_PROTBL,
array('fname' => $input->fname,
'lname' => $input->lname,
'sex' => $input->sex,
'nationality' => $input->nationality,
'position' => $input->position
),
array('id' => $input->id),
array('%s',
'%s',
'%s',
'%s',
'$s'
),
array('%d')
);
if ($this->return_result($result)) {
$this->renderprofile($input);
}
}
function renderprofile($input) {
$output = array(
'fname' => $input->fname,
'lname' => $input->lname,
'sex' => $input->sex,
'nationality' => $input->nationality,
'position' => $input->position
);
$this->renjson($output);
}
Unable to find answers for this so any help is appreciated!
Edit: At the moment, no errors with the jQuery. When I click the update button. It brings me to a blank page, with the url containing the information I submitted, which is useless to me. I want it to update instantly and alert the user, etc.
Edit: Getting uncaught syntaxerror: unexpected token if now, If I take out the semi-colon. If I leave it in after the json variable, it gives me unexpected token error, how to solve this?
Edit: I have now fixed this error, it was my mistake, I had an extra bracket. It's not going to a white blank page now. The text is coming up, e.g. Profile John has been modified. But still nothing has changed in the database.

Categories

Resources