Magento: Get all updated cart items data in AJAX response - ajax

My Cart is looking like this with popup window:
I am updating multiple configurable items in cart with custom options at a time by AJAX Call.
But I am not able to get all items data back to AJAX response.
I am getting just 1st itemPrice and rowTotal. For remaining items itemPrice and rowTotal are set to 0.
Code:
public function updateItemOptionsAction()
{
$cartData = $this->getRequest()->getParam('cart');
Mage::log($cartData);
if (is_array($cartData)) {
$result = array();
$result['data'] = array();
foreach ($cartData as $index => $data) {
$cart = $this->_getCart();
$params = $data;
$id = (int)$data['id'];
if (!isset($params['options'])) {
$params['options'] = array();
}
$result['data'][$index] = array();
$oldQty = null;
$kitType = $params['efk_kType'];
$params['super_attribute'] = array($data['sAttr']=>$kitType);
unset($params['sAttr']);
$stock = null;
try {
if (isset($params['qty'])) {
$product = Mage::getModel("catalog/product")->load($params['product']);
$childProducts = Mage::getModel('catalog/product_type_configurable')->getUsedProducts(null, $product);
foreach($childProducts as $cProd){
if($cProd->getKitType() == $kitType){
$stock = intval(Mage::getModel('cataloginventory/stock_item')->loadByProduct($cProd)->getQty());
}
}
if(intval($params['qty']) > $stock){
$oldQty = intval($params['qty']);
$params['qty'] = $stock;
$result['data'][$index]['revised'] = true;
}
$filter = new Zend_Filter_LocalizedToNormalized(
array('locale' => Mage::app()->getLocale()->getLocaleCode())
);
$params['qty'] = $filter->filter($params['qty']);
}
$quoteItem = Mage::getSingleton('checkout/cart')->getQuote()->getItemById($id);
if (!$quoteItem) {
Mage::throwException($this->__('Quote item is not found.'));
}
//Its going to infinity loop duwe to Varien Object need to check later
//$item = $cart->updateItem($id, new Varien_Object($params));
$item = Mage::getSingleton('checkout/cart')->updateItem($id, $params);
if (is_string($item)) {
Mage::throwException($item);
}
if ($item->getHasError()) {
Mage::throwException($item->getMessage());
}
Mage::log('hi2');
$related = $params['related_product'];
if (!empty($related)) {
Mage::getSingleton('checkout/cart')->addProductsByIds(explode(',', $related));
}
Mage::getSingleton('checkout/cart')->save();
Mage::getSingleton('checkout/session')->setCartWasUpdated(true);
Mage::dispatchEvent('checkout_cart_update_item_complete',
array('item' => $item, 'request' => $this->getRequest(), 'response' => $this->getResponse())
);
$cart->getQuote()->setTotalsCollectedFlag(false);
Mage::getSingleton('checkout/cart')->init();
if (!Mage::getSingleton('checkout/session')->getNoCartRedirect(true)) {
if (!Mage::getSingleton('checkout/cart')->getQuote()->getHasError()) {
Mage::log('hi4');
$result['success'] = true;
if($oldQty > $item->getQty()){
$message = $this->__('%s has been revised due to stock limitations. You may proceed with the order for the revised quantity.', Mage::helper('core')->escapeHtml($item->getProduct()->getName()));
}else{
$message = $this->__('%s was updated in your shopping cart.', Mage::helper('core')->escapeHtml($item->getProduct()->getName()));
}
$result['data'][$index]['message'] = $message;
$result['data'][$index]['itemId'] = $item->getId();
$result['data'][$index]['itemPrice'] = Mage::helper('checkout')->formatPrice($item->getCalculationPrice());
$result['data'][$index]['qty'] = $item->getQty();
$result['data'][$index]['rowTotal'] = Mage::helper('checkout')->formatPrice($item->getRowTotal());
}
}
} catch (Mage_Core_Exception $e) {
$result['success'] = false;
$result['data'][$index]['success'] = 'qty';
$result['data'][$index]['message'] = $e->getMessage();
} catch (Exception $e) {
$result['success'] = false;
$result['data'][$index]['message'] = $e->getMessage();
$result['data'][$index]['secondMessage'] = $this->__('Cannot update the item.');
}
}
$result['data']['grandTotal'] = Mage::helper('checkout')->formatPrice(Mage::getSingleton('checkout/cart')->getQuote()->getGrandTotal());
$result['data']['totalItems'] = Mage::getSingleton('checkout/cart')->getSummaryQty();
$totals = Mage::getSingleton('checkout/cart')->getQuote()->getTotals();
$result['data']['subTotal'] = Mage::helper('checkout')->formatPrice($totals['subtotal']->getValue());
if(isset($totals['discount']) && $totals['discount']->getValue()){
$result['data']['discount'] = Mage::helper('checkout')->formatPrice($totals['discount']->getValue());
}else{
$result['data']['discount'] = Mage::helper('checkout')->formatPrice(0);
}
}
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
}
AJAX Response I'm getting
{
"data": {
"1187": {
"success": true,
"message": "THREE PHASE SOLID STATE RELAY WITH ZVS was updated in your shopping cart.",
"itemId": "1191",
"itemPrice": "<span class=\"price\">20b9 3,799</span>",
"qty": 1,
"rowTotal": "<span class=\"price\">20b9 3,799</span>",
"forLoop": "yes"
},
"1189": {
"success": true,
"message": "AUTO INTENSITY CONTROL OF STREET LIGHTS was updated in your shopping cart.",
"itemId": "1193",
"itemPrice": "<span class=\"price\">20b9 0</span>",
"qty": 1,
"rowTotal": "<span class=\"price\">20b9 0</span>",
"forLoop": "yes"
},
"grandTotal": "<span class=\"price\">20b9 8,798</span>",
"totalItems": 2,
"subTotal": "<span class=\"price\">20b9 8,798</span>",
"discount": "<span class=\"price\">20b9 0</span>"
}
}
I am getting itemPrice and rowTotal for 2nd item as 0. Every time I am getting correct values for 1st item only. If i am update 5 items at a time (say for example) then i am getting correct values for 1st item and for remianing items i am getting 0's.
If i refresh cart once i get AJAX response, then it is showing itemPrice and rowTotal updated values correctly for all items.
Note: 20b9 is HEX Code for Indian Rupee symbol
Please point out where i am wrong.
Thanks in advance.

You're working tooooo hard... try updating the items in the controller server side as you sort of are, saving the current quote... and then just have a controller method that loads the current .phtml and returns the html as json for the cart block, and replace the whole cart html block (div) with the new one.
At the end of your controller method
$this->getResponse()->setBody( json_encode(
array("html" =>
Mage::app()->getLayout()->createBlock('checkout/[[whatevertag_is_to_cart_div phtml block]]')->toHtml()
)
);

Related

Doing live search in codeigniter via ajax , mongodb

This is my ajax code which fetches all data from data and display in the table, but when I input an alphabet in search-box, it again fetches complete data inside the table
<script>
$(document).ready(function(){
load_data();
function load_data(query)
{
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "<?php echo base_url() ?>Appconfig/get_masteradmin_data?query="+query,true);
xhttp.onload= function()
{
if (xhttp.status >=200 && xhttp.status <400)
{
var data= JSON.parse(xhttp.responseText);
var html = '';
var i;
for(i=0; i<data.length; i++){
html +='<tr>'+
'<td>'+data[i].full_name+'</td>'+
'<td>'+data[i].username+'</td>'+
'<td>'+data[i].designation+'</td>'+
'<td>'+data[i].department+'</td>'+
'<td>'+data[i].official_mobile_no+'</td>'+
'<td>'+data[i].official_email_id+'</td>'+
'<td>'+data[i].select_user_type+'</td>'+
'<td>'+data[i].permission+'</td>'+
'</tr>';
}
showdata.insertAdjacentHTML('beforeend',html);
}
else
{
console.log("Try again after some time");
}
};
xhttp.send();
}
$('#search').keyup(function(){
var search = $(this).val();
//console.log(search);
if(search != '')
{
load_data(search);
}
else
{
load_data();
}
});
});
</script>
This is my model for fetching data from my mongodb collection.
public function get_masteradmin_data($query)
{
$mongo = new \MongoDB\Driver\Manager('mongodb://localhost:27017');
$query= '';
//$filter = ['full_name' => 'www'];
$regex = new MongoDB\BSON\Regex ($query);
$filter = ['full_name'=>$regex,];
$options =[
'projection' => [
'_id' => 0,
'full_name' => 1,
'username' => 1,
'designation'=> 1,
'department'=> 1,
'official_mobile_no'=> 1,
'official_email_id'=> 1,
'select_user_type'=> 1,
'permission'=> 1,
],
'sort' => [
'_id' => -1
],
];
$query = new MongoDB\Driver\Query($filter, $options);
//$readPreference = new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY);
$result = $mongo->executeQuery('justrack_db.master_admin', $query);
$res = array();
foreach($result as $r)
{
$res[] = $r;
}
return json_encode($res,true);
//return $res;
}
This is my controller for displaying data. I am not sure, but I think there is some issue in my controller, as I tried to echo $query but it shows nothing. I am not able to understand how to fix this.
public function get_masteradmin_data()
{
$query = '';
$this->load->model('AppconfigModel');
$this->master_admin();
if($this->input->post('query'))
{
$query = $this->input->post('query');
}
$result= $this->AppconfigModel->get_masteradmin_data($query);
echo ($result);
}

Regnerate all files in the preview with Dropzone after an error occured

I am trying to use dropzone.js combined with other form elements and everything is working fine except one thing. I have some validation rules for other form elements and when one of the validation rules fails, it sends errors with ajax response. When an error occurs all dropzone files gets cancelled from the queue. Then I need to add dropped files manually again and submit the form. Is there any way to keep all image files in the queue even if an error occurs so that I can try re-sending them again ?
here is my dropzone configuration :
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 5,
maxFiles: 5,
addRemoveLinks:true,
This is the method which is called after form submit:
public function save($request)
{
$request = $request->all();
// Create a new validator instance from our validation rules
$validator = Validator::make($request, $this->validationRules);
// If validation fails, we'll exit the operation now.
if ($validator->fails())
{
// Ooops.. something went wrong
$this->errors = $validator->errors();
return false;
}
$user_id = getLoggedInId();
$request['operator_id'] = $this->operator->getId($user_id);
$result = $this->visit->add($request);
if ($result == 'updated')
{
$this->success = 'Successfully Updated!';
return $result;
}
elseif ($result == 'failed')
{
$this->errors = 'failed!';
return false;
}
elseif ($result == 'notAllowed')
{
$this->errors = 'Not Allowed to update this record';
return false;
}
else
{
if (Input::file('file'))
{
$visit_id = $result->id;
$files = Input::file('file');
$today = Carbon::now();
$patient_id = Input::get('patient_uid'); //need more validation later on
$center_id = substr($patient_id, 0, 3);
$uid = substr($patient_id, -5);
$upload_dir = $center_id . '/' . $today->year . '/' . $today->month . '/';
foreach ($files as $file)
{
// public/uploads
$response = $this->report->upload($file, $upload_dir, $visit_id, $uid);
if ($response['error'])
{
$this->errors = $response['message'];
return false;
}
}
}
$this->success = trans('patients/visit_form.successfully_created');
return $result;
}
and this is the logic for submitting form:
this.element.querySelector("input[type=submit]").addEventListener("click", function(e) {
// Make sure that the form isn't actually being sent.
e.preventDefault();
e.stopPropagation();
if (myDropzone.getQueuedFiles().length > 0)
{
myDropzone.processQueue();
} else {
submitVisitForm();
}
});

Why does this webform uploaded file via ajax throw an error in Drupal 7?

I have a webform and mymodule which alters it. The webform has a field stelle which gets populated based on the url query. For instance, if ?stelle=10 the field gets populated by the title of node with nid 10. If the query ?stelle is non-existant or followed by a nid which does not exist (is not of a certain content type) or does not contain a certain string the form will be redirecting to mynode?stelle=initiativ. The form has 2 fields to upload files via ajax, works good so far. Here is my code:
<?php
/**
* Altering the form! this will add class to the file upload/ remove buttons
*/
function mymodule_form_alter(&$form, &$form_state, $form_id) {
$conf = mymodule_defaults();
if ($form_id == 'webform_client_form_' . $conf['nid']) {
if (isset($form['submitted']['field1'])) {
$form['submitted']['field1']['#process'] = array('mymodule_my_file_element_process');
}
if (isset($form['submitted']['field2'])) {
$form['submitted']['field2']['#process'] = array('mymodule_my_file_element_process');
}
$nid = $form['#node']->nid;
$form['actions']['submit']['#ajax'] = array(
'callback' => 'mymodule_webform_js_submit',
'wrapper' => 'webform-client-form-' . $nid,
'method' => 'replace',
'effect' => 'fade',
);
$redirect_form = false;
$maintenance = false;
if (isset($form['submitted']['stelle']['#default_value']) && $form['submitted']['stelle']['#default_value'] !== '') {
$hide_components = array(
'einleitung_standard',
'einleitung_initiativ',
);
$unhide_components = array();
if ($form['submitted']['stelle']['#default_value'] == '') {
$redirect_form = true;
}
elseif (is_numeric($form['submitted']['stelle']['#default_value'])) {
$nid = $form['submitted']['stelle']['#default_value'];
$node = node_load($nid);
if ($node === false || (isset($node->type) && $node->type !== 'job')) {
$redirect_form = true;
}
else {
$type = $node->type;
if ($type == 'job') {
$form['submitted']['stelle']['#default_value'] = $node->title;
$form['submitted']['stelle']['#attributes']['disabled'] = 'disabled';
$form['submitted']['related']['#value'] = $nid;
$unhide_components = array(
'einleitung_standard'
);
}
}
}
elseif ($form['submitted']['stelle']['#default_value'] == 'initiativ') {
// unset($form['submitted']['stelle']);
$form['submitted']['related']['#value'] = 'initiativ';
$unhide_components = array(
'einleitung_initiativ'
);
}
}
else {
// $redirect_form = true;
// this causes an error
}
This is the weird part:
$redirect_form = false;
$maintenance = false;
if (isset($form['submitted']['stelle']['#default_value']) && $form['submitted']['stelle']['#default_value'] !== '') {
...
else {
// $redirect_form = true;
// this causes an error
}
When I active the line to redirect the form when the if condition is false, the button to upload a file via ajax throws an error alert on click (see bottom for error). To me, this looks like the form alter hook is being called again when the file upload button is clicked without having my field stelle available - is that right? How to fix this?
And now the rest of the module, basically just alterings:
else {
// $redirect_form = true;
// this causes an error
}
foreach ($unhide_components as $key => $component) {
if (is_array($component)) {
foreach ($component as $_key => $_component) {
$index = array_search($_component, $hide_components[$key]);
if ($index !== false) {
unset($hide_components[$key][$index]);
}
}
}
else {
$index = array_search($component, $hide_components);
if ($index !== false) {
unset($hide_components[$index]);
}
}
}
// hide
foreach ($hide_components as $k=>$hc1){
if (is_array($hc1)) {
foreach ($hc1 as $hc2) unset($form['submitted'][$k][$hc2]);
} else {
unset($form['submitted'][$hc1]);
}
}
if ($redirect_form) drupal_goto('node/'.$conf['nid'], array('query'=>array('stelle'=>'initiativ')), 301);
}
}
function mymodule_my_file_element_process($element, &$form_state, $form) {
$element = file_managed_file_process($element, $form_state, $form);
$element['upload_button']['#attributes'] = array('class' => array('button'));
$prefix = '<label class="browse-slave">';
$prefix .= '<span class="button">' . t('Choose a file') . '</span>';
$element['upload']['#prefix'] = $prefix;
$element['upload_button']['#prefix'] = '</label>';
$element['remove_button']['#attributes'] = array('class' => array('button'));
$element['remove_button']['#prefix'] = '</label>';
return $element;
}
function mymodule_webform_js_submit($form, $form_state) {
// define the $sid variable (submission id from webform)
$sid = $form_state['values']['details']['sid'];
// if we have a sid then we know the form was properly submitted, otherwise, we'll just return the existing $form array
if ($sid) {
// first we have to load up the webform node object
$node = node_load($form_state['values']['details']['nid']);
// create an array up with the confirmation message, retreived from the webform node
$confirmation = array(
'#type' => 'markup',
'#markup' => check_markup($node->webform['confirmation'], $node->webform['confirmation_format'], '', TRUE),
);
// return the confirmation message
return $confirmation;
}
else {
// return the form
return $form;
}
}
The AJAX error is something like described here. Changing server/php settings didnt help it.
Thanks!
The form builder (and any hook alters) will be run when a form is validated, which happens on #ajax actions.
I like to throw static custom data in $form['#someProperty'] so that it's available in the build, validate, and submit functions. Something like this should help you:
function mymodule_form_alter(&$form, &$form_state, $form_id) {
// ...
if (isset($_GET['stelle'])) {
$form['#stelle'] = $_GET['stelle']; // This will always be there.
}
// ...
}
Another option would be to throw the $node that you load in the form, like $form['#stelle_node'] = node_load(...) and obviously only do that when the nid is actually available to you, so that you don't overwrite it with empty data when the form builder runs again in the future.
When i was working with ajax in drupal 6 the hash symbol in url or request caused an error everytime..... so i replaced url with this
data.url.replace(/%2523/, '%23');

Remove 1 qty of product Magento

I'm implementing custom sidebar cart of Magento, which will feature incrementation and decrementaton of products in this cart, refreshed in ajax.
AJAX is possible to work just with HTML, isn't working as return value is whole cart.
I'm adding 1 quantity of product using CartController: /checkout/cart/add/uenc/aHR0cDovL3BsYXkudGhlaGFwcHlwZWFyLm5ldC9zaG9wL2RyaW5rcw,,/product/586/
Is it possible to just remove 1 quantity of product? Do I have to create new custom function in CartController?
Thanks,
Adam
ANSWER:
you can call this link with
/checkout/cart/remove/id/ $ITEMID /uenc/aHR0cDovL3BsYXkudGhlaGFwcHlwZWFyLm5ldC9zaG9w/ (depending on your magento settings link could be different)
Copy into CartController.php
public function removeAction()
{
$cart = $this->_getCart();
$params = $this->getRequest()->getParams();
try {
if (isset($params['qty'])) {
$filter = new Zend_Filter_LocalizedToNormalized(
array('locale' => Mage::app()->getLocale()->getLocaleCode())
);
$params['qty'] = $filter->filter($params['qty']);
}
$product = $this->_initProduct();
$related = $this->getRequest()->getParam('related_product');
/**
* Check product availability
*/
$id = (int) $this->getRequest()->getParam('id');
$items = $cart->getItems();
foreach ($items as $item) {
if ($item->getProduct()->getId() == $id) {
if( $item->getQty() == 1 ){
$cart->removeItem($item->getItemId())->save();
}
else if($item->getQty() > 1){
$item->setQty($item->getQty() - 1);
$cart->save();
}
break;
}
}
$this->_getSession()->setCartWasUpdated(true);
/**
* #todo remove wishlist observer processAddToCart
*/
Mage::dispatchEvent('checkout_cart_add_product_complete',
array('product' => $product, 'request' => $this->getRequest(), 'response' => $this->getResponse())
);
if (!$this->_getSession()->getNoCartRedirect(true)) {
if (!$cart->getQuote()->getHasError()){
//$message = $this->__('%s was added to your shopping cart.', Mage::helper('core')->escapeHtml($product->getName()));
//$this->_getSession()->addSuccess($message);
}
$this->_goBack();
}
} catch (Mage_Core_Exception $e) {
if ($this->_getSession()->getUseNotice(true)) {
$this->_getSession()->addNotice(Mage::helper('core')->escapeHtml($e->getMessage()));
} else {
$messages = array_unique(explode("\n", $e->getMessage()));
foreach ($messages as $message) {
$this->_getSession()->addError(Mage::helper('core')->escapeHtml($message));
}
}
$url = $this->_getSession()->getRedirectUrl(true);
if ($url) {
$this->getResponse()->setRedirect($url);
} else {
$this->_redirectReferer(Mage::helper('checkout/cart')->getCartUrl());
}
} catch (Exception $e) {
$this->_getSession()->addException($e, $this->__('Cannot add the item to shopping cart.'));
Mage::logException($e);
$this->_goBack();
}
}

Magento - remove one quantity from cart

I am trying to remove just one qty from my cart rather than all, but to no avail.
Can anybody help?
Here is the code I have got so far...
require_once 'app/Mage.php';
Mage::app("default");
Mage::getSingleton("core/session", array("name" => "frontend"));
$session = Mage::getSingleton("customer/session");
$yourProId = $_POST['prodID'];
$qty = 1;
foreach (Mage::getSingleton('checkout/session')->getQuote()->getItemsCollection() as $item) {
if ($yourProId == $item->getProductId()) {
Mage::getSingleton('checkout/cart')->removeItem($item->getId())->save();
}
}
UPDATE: Here is the code that works, thanks to R.S. for this!
$yourProId = $_POST['prodID'];
$qty=1;
$cartHelper = Mage::helper('checkout/cart');
$items = $cartHelper->getCart()->getItems();
foreach ($items as $item) {
if ($item->getProduct()->getId() == $yourProId) {
$qty = $item->getQty() - 1; // check if greater then 0 or set it to what you want
if($qty == 0) {
Mage::getSingleton('checkout/cart')->removeItem($item->getId());
} else {
$item->setQty($qty);
}
$cartHelper->getCart()->save();
break;
}
}
Try
$cartHelper = Mage::helper('checkout/cart');
$items = $cartHelper->getCart()->getItems();
foreach ($items as $item) {
if ($item->getProduct()->getId() == $yourProId) {
if( $item->getQty() == 1 ){
$cartHelper->getCart()->removeItem($item->getItemId())->save();
}
else if($item->getQty() > 1){
$item->setQty($item->getQty() - 1)
$cartHelper->getCart()->save();
}
break;
}
}
Take a look # /app/code/core/Mage/Checkout/controllers/CartController.php
See http://www.magentocommerce.com/boards/viewthread/30113/
You can alter or remove qty using $quoteItem->setData('qty', $avl_qty);
Please refer to code for more help.
$quoteItem = $observer->getEvent()->getQuoteItem();
$avl_qty = 1;
if ($avl_qty == '0') {
$quoteItem->getQuote()->removeItem($quoteItem->getItemId());
throw new LocalizedException(__("This product is currently out of stock."));
}
elseif ($order_qty > $avl_qty) {
$quoteItem->setData('qty', $avl_qty);
$this->_cart->save();
$this->messageManager->addNoticeMessage('Sorry we have only '.$avl_qty.' qty of this product available');
}
else {
}
For Magento 2
you can utilize
https://yourdomain.com/rest/V1/carts/mine/items
API with Auth token and Body
{
"cartItem": {
"item_id": 49388,//item_id not SKU
"qty": 1, //This will overwrite quantity
"quote_id": {{QuoteId}}
}
}

Resources