Javascript enhancements for cart address handling

This commit is contained in:
Paul Driver 2010-04-28 15:08:55 -07:00
parent aedda01e58
commit 17dd742c08
3 changed files with 279 additions and 0 deletions

View file

@ -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.

View file

@ -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
View 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);
}());