Javascript enhancements for cart address handling
This commit is contained in:
parent
aedda01e58
commit
17dd742c08
3 changed files with 279 additions and 0 deletions
|
|
@ -224,6 +224,30 @@ sub getAddress {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getAddressByLabel ( label )
|
||||
|
||||
Returns an address object.
|
||||
|
||||
=head3 id
|
||||
|
||||
An address object's label, e.g. 'Home', 'Work'
|
||||
|
||||
=cut
|
||||
|
||||
sub getAddressByLabel {
|
||||
my ($self, $label) = @_;
|
||||
my $sql = q{
|
||||
SELECT addressId
|
||||
FROM address
|
||||
WHERE addressBookId = ?
|
||||
AND label = ?
|
||||
};
|
||||
my $id = $self->session->db->quickScalar($sql, [$self->getId, $label]);
|
||||
return $id && $self->getAddress($id);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getAddresses ( )
|
||||
|
||||
Returns an array reference of address objects that are in this book.
|
||||
|
|
@ -470,6 +494,48 @@ sub update {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_ajaxGetAddress ( )
|
||||
|
||||
Gets a JSON object representing the address given by the addressId form
|
||||
parameter
|
||||
|
||||
=cut
|
||||
|
||||
sub www_ajaxGetAddress {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
$session->http->setMimeType('text/plain');
|
||||
|
||||
my $addressId = $session->form->get('addressId');
|
||||
my $address = $self->getAddress($addressId) or return;
|
||||
return JSON->new->encode($address->get);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_ajaxSave ( )
|
||||
|
||||
Saves an address book entry
|
||||
|
||||
=cut
|
||||
|
||||
sub www_ajaxSave {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my $address = JSON->new->decode($session->form->get('address'));
|
||||
my $obj = $self->getAddressByLabel($address->{label});
|
||||
if ($obj) {
|
||||
$obj->update($address);
|
||||
}
|
||||
else {
|
||||
$obj = $self->addAddress($address);
|
||||
}
|
||||
$session->http->setMimeType('text/plain');
|
||||
return $obj->getId;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_deleteAddress ( )
|
||||
|
||||
Deletes an address from the book.
|
||||
|
|
|
|||
|
|
@ -1137,6 +1137,12 @@ sub www_view {
|
|||
|
||||
# render the cart
|
||||
my $template = WebGUI::Asset::Template->new($session, $session->setting->get("shopCartTemplateId"));
|
||||
|
||||
my ($style, $url) = $session->quick('style', 'url');
|
||||
my $yui = $url->extras('/yui/build');
|
||||
$style->setScript("$yui/yahoo/yahoo-min.js");
|
||||
$style->setScript("$yui/json/json-min.js");
|
||||
$style->setScript($url->extras('shop/cart.js'), undef, 1);
|
||||
return $session->style->userStyle($template->process(\%var));
|
||||
}
|
||||
|
||||
|
|
|
|||
207
www/extras/shop/cart.js
Normal file
207
www/extras/shop/cart.js
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
/*global window, document, YAHOO */
|
||||
|
||||
(function () {
|
||||
var $event = YAHOO.util.Event,
|
||||
$connect = YAHOO.util.Connect,
|
||||
$json = YAHOO.lang.JSON,
|
||||
addressCache = {},
|
||||
elements = {
|
||||
dropdowns: {
|
||||
billing: 'billingAddressId_formId',
|
||||
shipping: 'shippingAddressId_formId'
|
||||
}
|
||||
},
|
||||
addressParts = [
|
||||
'label', 'firstName', 'lastName', 'organization', 'address1',
|
||||
'address2', 'address3', 'city', 'state', 'code', 'country',
|
||||
'phoneNumber', 'email'
|
||||
];
|
||||
|
||||
function omap(o, fn) {
|
||||
var r = [], k;
|
||||
for (k in o) {
|
||||
if (o.hasOwnProperty(k)) {
|
||||
r.push(fn.call(o, k, o[k]));
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
function oeach(o, fn) {
|
||||
omap(o, fn);
|
||||
return;
|
||||
}
|
||||
|
||||
function addAddressKind(name) {
|
||||
var i, key, obj = elements[name] = {};
|
||||
for (i = 0; i < addressParts.length; i += 1) {
|
||||
key = addressParts[i];
|
||||
obj[key] = name + '_' + key + '_formId';
|
||||
}
|
||||
}
|
||||
|
||||
function getDomElements(o) {
|
||||
oeach(o, function (k, v) {
|
||||
if (typeof v === 'object') {
|
||||
getDomElements(v);
|
||||
}
|
||||
else {
|
||||
this[k] = document.getElementById(v);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function sameChange() {
|
||||
var d = elements.same.checked;
|
||||
oeach(elements.shipping, function (k, v) {
|
||||
v.disabled = d;
|
||||
});
|
||||
elements.dropdowns.shipping.disabled = d;
|
||||
}
|
||||
|
||||
function updateAddressDropdowns(o) {
|
||||
var label = o.argument.address.label,
|
||||
id = o.responseText;
|
||||
|
||||
function updateOne(dropdown) {
|
||||
var options = dropdown.options, i, opt;
|
||||
for (i = 0; i < options.length; i += 1) {
|
||||
opt = options[i];
|
||||
if (opt.text === label) {
|
||||
opt.value = id;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
opt = document.createElement('option');
|
||||
opt.value = id;
|
||||
opt.text = label;
|
||||
dropdown.appendChild(opt);
|
||||
}
|
||||
|
||||
updateOne(elements.dropdowns.billing);
|
||||
updateOne(elements.dropdowns.shipping);
|
||||
elements.dropdowns[o.argument.name].value = id;
|
||||
}
|
||||
|
||||
function saveAddress(a, name) {
|
||||
var cb = {
|
||||
success: updateAddressDropdowns,
|
||||
argument: { address: a, name: name }
|
||||
},
|
||||
post = 'shop=address;method=ajaxSave;address=' +
|
||||
$json.stringify(a),
|
||||
url = window.location.pathname;
|
||||
|
||||
$connect.asyncRequest('POST', url, cb, post);
|
||||
}
|
||||
|
||||
function validAddress(a) {
|
||||
return a.label &&
|
||||
a.firstName &&
|
||||
a.lastName &&
|
||||
a.address1 &&
|
||||
a.city &&
|
||||
a.state &&
|
||||
a.code &&
|
||||
a.country;
|
||||
}
|
||||
|
||||
function addressChange(name) {
|
||||
var other = name === 'billing' ? 'shipping' : 'billing';
|
||||
return function () {
|
||||
var address = {},
|
||||
els = elements[name],
|
||||
label = els.label.value,
|
||||
oels = elements[other],
|
||||
copy = oels.label.value === label,
|
||||
cached = addressCache[label],
|
||||
dirty;
|
||||
|
||||
if (!cached) {
|
||||
cached = addressCache[label] = {};
|
||||
}
|
||||
|
||||
oeach(elements[name], function (k, v) {
|
||||
v = v.value;
|
||||
address[k] = v;
|
||||
if (cached[k] !== v) {
|
||||
dirty = true;
|
||||
cached[k] = v;
|
||||
}
|
||||
if (copy) {
|
||||
oels[k].value = v;
|
||||
}
|
||||
});
|
||||
if (dirty && validAddress(address)) {
|
||||
saveAddress(address, name);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function addressUpdater(name) {
|
||||
var elems = elements[name];
|
||||
function update(address) {
|
||||
oeach(address, function (k, v) {
|
||||
var dom = elems[k];
|
||||
if (dom) {
|
||||
dom.value = v;
|
||||
}
|
||||
});
|
||||
}
|
||||
return function () {
|
||||
var id = this.value,
|
||||
label = this.options[this.selectedIndex].text,
|
||||
cached = addressCache[label],
|
||||
url, cb;
|
||||
|
||||
if (cached) {
|
||||
return update(cached);
|
||||
}
|
||||
|
||||
url = window.location.pathname +
|
||||
'?shop=address;method=ajaxGetAddress;addressId=' +
|
||||
id;
|
||||
|
||||
cb = {
|
||||
success: function (o) {
|
||||
var address = $json.parse(o.responseText);
|
||||
addressCache[address.label] = address;
|
||||
update(address);
|
||||
}
|
||||
};
|
||||
$connect.asyncRequest('GET', url, cb);
|
||||
};
|
||||
}
|
||||
|
||||
function main() {
|
||||
var checks;
|
||||
addAddressKind('billing');
|
||||
addAddressKind('shipping');
|
||||
getDomElements(elements);
|
||||
|
||||
elements.form = document.forms[0];
|
||||
checks = elements.form.sameShippingAsBilling;
|
||||
elements.same = checks[0];
|
||||
$event.on(checks, 'change', sameChange);
|
||||
sameChange();
|
||||
|
||||
function handleBlur(name) {
|
||||
var values = omap(elements[name], function (k, v) {
|
||||
return v;
|
||||
});
|
||||
$event.on(values, 'focusout', addressChange(name));
|
||||
}
|
||||
handleBlur('billing');
|
||||
handleBlur('shipping');
|
||||
|
||||
function handleDropdown(name) {
|
||||
$event.on(elements.dropdowns[name], 'change', addressUpdater(name));
|
||||
}
|
||||
|
||||
handleDropdown('billing');
|
||||
handleDropdown('shipping');
|
||||
}
|
||||
|
||||
$event.onDOMReady(main);
|
||||
}());
|
||||
Loading…
Add table
Add a link
Reference in a new issue