问题
Currently modifying a Magento add to cart functionality...
What we're attempting to achieve here is:-
From the category listing:-
Scenario 1
When add to cart button is clicked, if product has options, show options in fancybox before the option to proceed to checkout is given.
Screenshot:
Live example: Pretty much any product on this page.
This is working as expected.
Scenario 2
When add to cart button is clicked, if product has no options, show a 'product has been added to cart successfully' message with an option to 'checkout' or 'continue shopping' in fancybox.
Issue: Unable to achieve the desired on this one. What we do currently have is a popup notification that almost does the job which can be seen at this page (just select any product near the top to see in action).
This doesn't use fancybox however, it is a custom implementation that uses the following markup:-
<div id="fancybox<?php echo $_product->getId()?>" class="fancybox fancy-popupbox" style="position:absolute; display:none;">
<div class="popup-text"></div>
<div class="popup-buttons">
<div style="float:left">
<button onclick="setLocation('')" class="button btn-shop" title="Continue Shopping" type="button"><span><span><?php echo $this->__('Continue Shopping') ?></span></span></button>
</div>
<div style="float:right">
<button onclick="setLocation('<?php echo $this->getBaseUrl();?>checkout/onepage')" class="button btn-checkout" title="Proceed to Checkout" type="button"><span><span><?php echo $this->__('Proceed to Checkout') ?></span></span></button>
</div>
</div>
</div>
Which is then called with:-
jQuery('.popup-text').html(data.message);
jQuery('.fancy-popupbox').show();
From within the success function in setLocationAjax function:-
function setLocationAjax(url,id){
url += 'isAjax/1';
url = url.replace("checkout/cart","ajax/index");
jQuery('#ajax_loader'+id).show();
try {
jQuery.ajax( {
url : url,
dataType : 'json',
success : function(data) {
jQuery('#ajax_loader'+id).hide();
jQuery('.popup-text').html(data.message);
jQuery('.fancy-popupbox').show();
setAjaxData(data,false);
}
});
} catch (e) {
}
}
Where this function is called from a modification to the add to cart button:-
<button type="button" title="<?php echo $this->__('Add to Cart') ?>" class="button btn-cart" onclick="setLocationAjax('<?php echo $this->getAddToCartUrl($_product) ?>','<?php echo $_product->getId()?>')"><span><span><?php echo $this->__('Add to Cart') ?></span></span></button>
You can see the complete markup at the pages linked to above or you can take a look at the complete list.phtml file in use at this pastebin (includes full script also).
So, to summarise, we essentially want to modify scenario 2 so that it operates like scenario 1.
Edit 1 from @JFK's Answer
It didn't seem to like your suggestion.
When I implemented...
jQuery.fancybox.open('.fancy-popupbox');
Console returned...
Uncaught TypeError: Object function (obj){var opts;if(busy){return;}
busy=true;opts=typeof arguments[1]!=='undefined'?arguments[1]:{};selectedArray=[];selectedIndex=parseInt(opts.index,10)||0;if($.isArray(obj)){for(var i=0,j=obj.length;i<j;i++){if(typeof obj[i]=='object'){$(obj[i]).data('fancybox',$.extend({},opts,obj[i]));}else{obj[i]=$({}).data('fancybox',$.extend({content:obj[i]},opts));}}
selectedArray=jQuery.merge(selectedArray,obj);}else{if(typeof obj=='object'){$(obj).data('fancybox',$.extend({},opts,obj));}else{obj=$({}).data('fancybox',$.extend({content:obj},opts));}
selectedArray.push(obj);}
if(selectedIndex>selectedArray.length||selectedIndex<0){selectedIndex=0;}
_start();} has no method 'open'
So the complete script looked like this after implementation...
jQuery.noConflict();
jQuery(document).ready(function(){
jQuery('.fancybox').fancybox(
{
hideOnContentClick : true,
width: 382,
autoDimensions: true,
type : 'iframe',
showTitle: false,
scrolling: 'no',
onComplete: function(){
jQuery('#fancybox-frame').load(function() { // wait for frame to load and then gets it's height
jQuery('#fancybox-content').height(jQuery(this).contents().find('body').height()+30);
jQuery.fancybox.resize();
});
}
}
);
});
function showOptions(id){
jQuery('#fancybox'+id).trigger('click');
}
function setAjaxData(data,iframe){
if(data.status == 'ERROR'){
alert(data.message);
}else{
if(jQuery('.block-cart')){
jQuery('.block-cart').replaceWith(data.sidebar);
}
if(jQuery('.header .links')){
jQuery('.header .links').replaceWith(data.toplink);
}
jQuery.fancybox.close();
}
}
function setLocationAjax(url,id){
url += 'isAjax/1';
url = url.replace("checkout/cart","ajax/index");
jQuery('#ajax_loader'+id).show();
try {
jQuery.ajax( {
url : url,
dataType : 'json',
success : function(data) {
jQuery('#ajax_loader'+id).hide();
jQuery('.popup-text').html(data.message);
//jQuery('.fancy-popupbox').show();
jQuery.fancybox.open('.fancy-popupbox');
setAjaxData(data,false);
}
});
} catch (e) {
}
}
Please point out if a further tweak would have been necessary. Thanks.
Edit 2 Updated Fancybox
I've updated Fancybox from 1.3.4 to 2.1.4 (but this isn't on the live site linked to - it's updated on a dev version). So what we have needs rewriting to work with Fancybox 2 then it seems now.
Edit3 Progress Update
I feel I'm almost there, I just need help on converting the below to the correct syntax (I think). If anyone could assist with this, that would be fab.
jQuery.noConflict();
jQuery(document).ready(function( $ ){
$('.fancybox').fancybox(
{
hideOnContentClick : true,
width: 382,
autoDimensions: true,
type : 'iframe',
showTitle: false,
scrolling: 'no',
onComplete: function(){
$('#fancybox-frame').load(function() { // wait for frame to load and then gets it's height
$('#fancybox-content').height(jQuery(this).contents().find('body').height()+30);
$.fancybox.resize();
});
}
}
);
});
function showOptions(id){
$('#fancybox'+id).trigger('click');
}
function setAjaxData(data,iframe){
if(data.status == 'ERROR'){
alert(data.message);
}else{
if(jQuery('.block-cart')){
jQuery('.block-cart').replaceWith(data.sidebar);
}
if(jQuery('.header .links')){
jQuery('.header .links').replaceWith(data.toplink);
}
jQuery.fancybox.close();
}
}
function setLocationAjax(url,id){
url += 'isAjax/1';
url = url.replace("checkout/cart","ajax/index");
$('#ajax_loader'+id).show();
try {
jQuery.ajax( {
url : url,
dataType : 'json',
success : function(data) {
//jQuery('#ajax_loader'+id).hide();
//jQuery('.popup-text').html(data.message);
//jQuery('.fancy-popupbox').show();
//jQuery.fancybox.open('.fancy-popupbox');
jQuery.fancybox.open('.fancy-popupbox',{
// API options here
});
setAjaxData(data,false);
}
});
} catch (e) {
}
}
回答1:
If what you want to display in fancybox is the contents of
<div id="fancybox<?php echo $_product->getId()?>" class="fancybox fancy-popupbox" style="position:absolute; display:none;">
...
</div>
then, instead of this line in your ajax success
callback
jQuery('.fancy-popupbox').show();
try this
jQuery.fancybox.open('.fancy-popupbox');
assuming that you have properly loaded fancybox js/css files
If you want to add API options to fancybox, try this
jQuery.fancybox.open('.fancy-popupbox',{
// API options here
});
来源:https://stackoverflow.com/questions/18380380/showing-message-in-fancybox-after-button-set-location-in-ajax