通过AJAX和
This is my first ever question here so any help would be appreciated. I've found a great deal of related information but nothing which exactly fits the bill.
I'm trying to add a product with its various options to the cart via an HTML form and AJAX. Adding the product itself was the first obstacle but it now seems like a bit of a hollow victory.
My form looks like this: (there are more products in the list but I have redacted to save space)
<form action="http://[site_url].com/index.php?route=checkout/cart/add/" id="quickQuoteForm" method="post">
<h3>Select your course</h3>
<div class="quickPriceRow1 row1">
<label>Choose a course</label>
<select class="quickPriceSelect" name="product_id" rel="1">
<option selected="selected" value="">Please choose...</option>
<option name="product_id" value="50">Intensive General English - 15 hours per week</option>
<option name="product_id" value="51">Intensive General English Course + Consolidation English/Exam Preparation Workshops (20 hours per week)</option>
</select>
Then, contained in the same form, I have the Product Options like so:
<label>Choose a start date</label>
<select name="start_date" class="quickPriceSelect2" rel="2" id="start_date">
<option value="" selected="selected">Please choose...</option>
<option name="option[5]" value="49">Monday July 28</option>
<option name="option[5]" value="50">Monday August 04</option>
<option name="option[5]" value="51">Monday August 11</option>
<option name="option[5]" value="52">Monday August 18</option>
etc...
</select>
Now, I'm not 100% I've got the "name=..." right but I've tried both 'name="option[5]"' and 'name="option_id[5]"' with no change. The [5] I took from the 'option_description' table and 'option_id' column and the value="50" from the 'option_value_description' table and 'option_value_id' column.
Thanks to this thread How do I add a product to OpenCart from an external site? (and a little tinkering) I've got the product adding to the cart no problem, but the options are stumping me completely.
My jQuery is:
$(document).ready(function() {
$('#quickQuoteForm button').click(function(e) {
e.preventDefault(); // prevent the form from submitting
$.ajax({
type: 'POST',
dataType: 'json',
url: 'http://[site_url].com/index.php?route=checkout/cart/add/',
data: 'product_id=' + $('.quickPriceSelect').val() + '&quantity=1' + '&product_option_id=' + $('.quickPriceSelect2').val() + '&product_option_id=' + $('.quickPriceSelect3').val(),
success: function(json) {
window.location = 'http://[site_url].com/index.php?route=checkout/cart';
}
});
});
});
If anyone could point me in the right direction it'd be a massive help, thank you.
## UPDATE ##
Ok, so I'm no further on with it but I have changed my JS to match what I found in the product.tpl files (both Default and the theme I'm using; Acceptus). I now have:
<script>
$('#button-cart').bind('click', function() {
$.ajax({
url: 'index.php?route=checkout/cart/add',
type: 'post',
data: $('select[name="product_id"], select[name="option[5]"], select[name="option[13]"]'),
dataType: 'json',
success: function(json) {
$('.success, .warning, .attention, information, .error').remove();
if (json['error']) {
if (json['error']['option']) {
for (i in json['error']['option']) {
$('#option-' + i).after('<span class="error">' + json['error']['option'][i] + </span>');
}
}
}
if (json['success']) {
$('#notification').html('<div class="success" style="display: none;">' + json['success'] + '<img src="catalog/view/theme/acceptus/image/icons/remove/close.png" alt="" class="close" /></div>');
$('.success').fadeIn('slow');
$('#cart-total').html(json['total']);
$('html, body').animate({ scrollTop: 0 }, 'slow');
}
if (json['success']) {
window.location = 'http://studioamanchester.com/index.php?route=checkout/cart';
}
}
});
});
</script>'
Again, it's adding the product but none of the options. I've tried on the default theme and installed the site locally to test it but still nothing. Is there anything else to try?
Looking at your JS code I can see some errors in the AJAX request itself:
$.ajax({
type: 'POST',
dataType: 'json',
url: 'http://[site_url].com/index.php?route=checkout/cart/add/',
// there should be no slash at the end of route ---^
data: 'product_id=' + $('.quickPriceSelect').val() + '&quantity=1' + '&product_option_id=' + $('.quickPriceSelect2').val() + '&product_option_id=' + $('.quickPriceSelect3').val(),
// if you send more 'product_option_id' properties, all of them will be overwritten by the last value in the end...
success: function(json) {
window.location = 'http://[site_url].com/index.php?route=checkout/cart';
}
});
We are missing your controller code but let's expect you didn't change it. In this case the POST data is completely incorrect since the cart controller requires to receive product options in option
array with the option_id
as key and production_option_value
as value.
The request should contain POST data like this:
option[208] test
option[209] adsgsdadas
option[217] 3
option[219] 2011-02-20
option[220] 2011-02-20 22:25
option[221] 22:25
option[222]
option[223][] 10
product_id 42
quantity 2
Since you are completely changing the POST that is sent to the server it is understandable that you think it is not possible. Instead of reinventing the wheel you should now focus to fix your code so that it send the AJAX POST request in this way (copied from the default product.tpl
template):
$.ajax({
url: 'index.php?route=checkout/cart/add',
type: 'post',
data: $('.product-info input[type=\'text\'], .product-info input[type=\'hidden\'], .product-info input[type=\'radio\']:checked, .product-info input[type=\'checkbox\']:checked, .product-info select, .product-info textarea'),
dataType: 'json',
success: function(json) {
$('.success, .warning, .attention, information, .error').remove();
if (json['error']) {
if (json['error']['option']) {
for (i in json['error']['option']) {
$('#option-' + i).after('<span class="error">' + json['error']['option'][i] + '</span>');
}
}
}
if (json['success']) {
$('#notification').html('<div class="success" style="display: none;">' + json['success'] + '<img src="catalog/view/theme/default/image/close.png" alt="" class="close" /></div>');
$('.success').fadeIn('slow');
$('#cart-total').html(json['total']);
$('html, body').animate({ scrollTop: 0 }, 'slow');
}
}
});
The line containing the data
has it all - simply it finds any form field within the given div
and pack it's name:value
to the POST (while the option's names are option[<option_id>]
).
As you can see, you're sending your variables as a query string when you should try sending them as POST variables instead. This is what the service expects you to send:
Request URL:http://studioamanchester.com/index.php?route=checkout/cart/add/
Request Method:POST
Query String Parametersview sourceview URL encoded
route:checkout/cart/add/
Form Dataview sourceview URL encoded
product_id:51
quantity:1
product_option_id:56
product_option_id:95
Try this (not sure about the two properties with the same name, but see if it works):
$(document).ready(function() {
$('#quickQuoteForm button').click(function(e) {
e.preventDefault(); // prevent the form from submitting
var obj = {
product_id : $('.quickPriceSelect').val(),
quantity : "1",
product_option_id : $('.quickPriceSelect2').val(),
product_option_id : $('.quickPriceSelect3').val()
};
$.ajax({
type: 'POST',
dataType: 'json',
url: 'http://[site_url].com/index.php?route=checkout/cart/add/',
data: JSON.stringify(obj),
success: function(json) {
window.location = 'http://[site_url].com/index.php?route=checkout/cart';
}
});
});
});