Skip to content

Commit

Permalink
Added ability to limit the quantity field (#383)
Browse files Browse the repository at this point in the history
Added ability to limit the quantity field
  - Added extension point for `newvalue` in QuantityField
  - disables add button when limit is reached
  - limit will update if changed

Updated how the quantity field returned data
  - now in json format that can be modified
  - simplified js limiting

Updated tasks
  • Loading branch information
mak001 authored Feb 5, 2019
1 parent 3b10379 commit b7d405d
Show file tree
Hide file tree
Showing 11 changed files with 221 additions and 24 deletions.
2 changes: 1 addition & 1 deletion client/dist/css/quantityfield.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion client/dist/javascript/scripts.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/dist/sassmaps/quantityfield.css.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions client/src/css/scss/quantityfield.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
form[id^="FoxyStripePurchaseForm_PurchaseForm_"] {
.quantityField {vertical-align: baseline; margin-bottom: 30px; line-height: 1;
button {-webkit-appearance: none; height: 37px; padding: 6px 12px; font-size: 14px;}
button:disabled,
button[disabled] {
color: grey;
background-color: darkgray;
&:hover, &:focus {
background-color: darkgray;
color: grey;
}

}
input, button { height: 37px; font-size: 20px; line-height: 1; display: inline-block; width: auto; vertical-align: baseline; border-radius: 0; border-color: #e6e7e8; padding: 6px 12px; float: left;}
button {font-size: 20px; line-height: 1; padding: 6px 12px 10px;
&:hover, &:focus {background: #7ba6bb; color: #ffffff; outline: none;}
Expand Down
7 changes: 7 additions & 0 deletions client/src/javascript/bootstrap.bundle.min.js

Large diffs are not rendered by default.

92 changes: 78 additions & 14 deletions client/src/javascript/quantity.js
Original file line number Diff line number Diff line change
@@ -1,55 +1,119 @@
;(function ($) {
var field = $("input[name='x:visibleQuantity']"),
quantityField = $("input[name='quantity']"),
increment = $('.increase'),
decrement = $('.reduced'),
getLink = function (element) {
return element.parent().find("input[name='x:visibleQuantity']").data('link');
},
getCode = function (element) {
return element.parent().find("input[name='x:visibleQuantity']").data('code');
},
getId = function (element) {
return element.parent().find("input[name='x:visibleQuantity']").data('id');
},
getLimit = function (element) {
return element.parent().find("input[name='x:visibleQuantity']").data('limit');
},
updateLimit = function (element, newLimit) {
return element.parent().find("input[name='x:visibleQuantity']").data('limit', newLimit);
},
disableIncreaseButton = function(element) {
element.parent().find("button.increase").attr('disabled', true);
},
enableIncreaseButton = function(element) {
element.parent().find("button.increase").attr('disabled', false);
},
hideButtons = function(element) {
element.parent().find("button.increase, button.reduced")
.attr('disabled', true)
.addClass('hidden');
},
outOfStock = function(element) {
var form = element.parents('form[id^=FoxyStripePurchaseForm_PurchaseForm_]')
var id = form.attr('id');

form.find('fieldset')
.html('<h4 id="' + id + '_unavailableText">Currently Out of Stock</h4>');
form.find('input[name=action_x\\:submit]').remove();
},
disableSubmit = function (element) {
element.parent().parent().parent().find('.fs-add-to-cart-button').attr('disabled', true);
},
enableSubmit = function (element) {
element.parent().parent().parent().find('.fs-add-to-cart-button').attr('disabled', false);
},
queryNewValue = function (code, newValue, link, clicked) {
queryNewValue = function (code, newValue, link, id, clicked) {
var quantData = {
'code': code,
'value': newValue,
'id': id,
'isAjax': 1
};

$.ajax({
type: 'get',
url: link + '?' + $.param(quantData),
}).done(function (response) {
quantityField.val(response);
var data = JSON.parse(response);

if (data.hasOwnProperty('limit')) {
updateLimit(clicked, data.limit);

if (data.limit == 0) {
outOfStock(clicked);
} else if (data.limit == 1) {
hideButtons(clicked);
} else if (data.limit == data.quantity) {
disableIncreaseButton(clicked);
} else {
enableIncreaseButton(clicked);
}
}

clicked.parent().parent().parent().parent().find("input[name='quantity']")
.val(data.quantityGenerated);
enableSubmit(clicked);
}).fail(function (xhr) {
console.log('Error: ' + xhr.responseText);
});//*/
// because the form field no longer exists if it is out of stock
if (xhr.status == 404 &&
xhr.responseText == "I can't handle sub-URLs on class SilverStripe\\Forms\\FormRequestHandler."
) {
outOfStock(clicked);
} else {
console.log('Error: ' + xhr.responseText);
}
});
};

increment.on('click', function (event) {
var currentVal = field.val(),
$(document).on('click', 'button.increase', function (event) {
var visibleQuantity = $(this).parent().parent().find("input[name='x:visibleQuantity']"),
currentVal = visibleQuantity.val(),
newValue = parseInt(currentVal) + 1;

disableSubmit($(this));
queryNewValue(getCode($(this)), newValue, getLink($(this)), $(this));
field.val(newValue);
queryNewValue(getCode($(this)), newValue, getLink($(this)), getId($(this)), $(this));
visibleQuantity.val(newValue);
});

decrement.on('click', function (event) {
var currentVal = field.val(),
$(document).on('click', 'button.reduced', function (event) {
var visibleQuantity = $(this).parent().parent().find("input[name='x:visibleQuantity']"),
currentVal = visibleQuantity.val(),
newValue = parseInt(currentVal) - 1;

if (currentVal > 1) {
disableSubmit($(this));
queryNewValue(getCode($(this)), newValue, getLink($(this)), $(this));
field.val(newValue);
queryNewValue(getCode($(this)), newValue, getLink($(this)), getId($(this)), $(this));
visibleQuantity.val(newValue);
}
});

$(document).ready(function() {
$('button.increase').each(function() {
var limit = getLimit($(this));
if (limit == 1) {
hideButtons($(this));
} else if (limit == 0) {
outOfStock($(this));
}
});
});
}(jQuery));
26 changes: 26 additions & 0 deletions docs/en/userguide/testcontroller.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
##Testing order processing on local
Visiting `/foxytest` in dev mode will generate orders, order details, and members.
It will do this by creating a sample XML document and send it to the `/foxystripe` endpoint.

###Configuration

The data used in the test can be modified, from date to the password of the user.

```yml
Dynamic\FoxyStripe\Controller\DataTestController:
data:
TransactionDate: now
OrderID: auto
Email: auto
Password: password
```
Setting `TransactionDate` to `now` will result in the `<transaction_date>` to be the current time.

Setting `OrderID` or `Email` to `auto` will cause an order id and new email to be generated for every order the endpoint creates.

`Password` is the unencrypted password for the user.
To use an encrypted password use `Salt`, `HashType`, and `HashedPassword`.

#### Order Details
The endpoint will generate an order detail if none is supplied.
66 changes: 63 additions & 3 deletions javascript/quantity.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,31 @@
getId = function (element) {
return element.parent().find("input[name='x:visibleQuantity']").data('id');
},
getLimit = function (element) {
return element.parent().find("input[name='x:visibleQuantity']").data('limit');
},
updateLimit = function (element, newLimit) {
return element.parent().find("input[name='x:visibleQuantity']").data('limit', newLimit);
},
disableIncreaseButton = function(element) {
element.parent().find("button.increase").attr('disabled', true);
},
enableIncreaseButton = function(element) {
element.parent().find("button.increase").attr('disabled', false);
},
hideButtons = function(element) {
element.parent().find("button.increase, button.reduced")
.attr('disabled', true)
.addClass('hidden');
},
outOfStock = function(element) {
var form = element.parents('form[id^=FoxyStripePurchaseForm_PurchaseForm_]')
var id = form.attr('id');

form.find('fieldset')
.html('<h4 id="' + id + '_unavailableText">Currently Out of Stock</h4>');
form.find('input[name=action_x\\:submit]').remove();
},
disableSubmit = function (element) {
element.parent().parent().parent().find('.fs-add-to-cart-button').attr('disabled', true);
},
Expand All @@ -28,11 +53,35 @@
type: 'get',
url: link + '?' + $.param(quantData),
}).done(function (response) {
clicked.parent().parent().parent().parent().find("input[name='quantity']").val(response);
var data = JSON.parse(response);

if (data.hasOwnProperty('limit')) {
updateLimit(clicked, data.limit);

if (data.limit == 0) {
outOfStock(clicked);
} else if (data.limit == 1) {
hideButtons(clicked);
} else if (data.limit == data.quantity) {
disableIncreaseButton(clicked);
} else {
enableIncreaseButton(clicked);
}
}

clicked.parent().parent().parent().parent().find("input[name='quantity']")
.val(data.quantityGenerated);
enableSubmit(clicked);
}).fail(function (xhr) {
console.log('Error: ' + xhr.responseText);
});//*/
// because the form field no longer exists if it is out of stock
if (xhr.status == 404 &&
xhr.responseText == "I can't handle sub-URLs on class SilverStripe\\Forms\\FormRequestHandler."
) {
outOfStock(clicked);
} else {
console.log('Error: ' + xhr.responseText);
}
});
};

$(document).on('click', 'button.increase', function (event) {
Expand All @@ -56,4 +105,15 @@
visibleQuantity.val(newValue);
}
});

$(document).ready(function() {
$('button.increase').each(function() {
var limit = getLimit($(this));
if (limit == 1) {
hideButtons($(this));
} else if (limit == 0) {
outOfStock($(this));
}
});
});
}(jQuery));
22 changes: 19 additions & 3 deletions src/Form/QuantityField.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,20 @@ public function Field($properties = [])


$this->setAttribute('data-link', $this->Link('newvalue'));
$this->setAttribute('data-code', $this->getForm()->getProduct()->Code);
$this->setAttribute('data-id', $this->getForm()->getProduct()->ID);
$this->setAttribute('data-code', $this->getProduct()->Code);
$this->setAttribute('data-id', $this->getProduct()->ID);

return parent::Field($properties);
}

/**
* @return ProductPage
*/
public function getProduct()
{
return $this->getForm()->getProduct();
}

/**
* @param SS_HTTPRequest $request
* @return bool|string
Expand All @@ -53,6 +61,14 @@ public function newvalue(HTTPRequest $request)
return '';
}

return ProductPage::getGeneratedValue($code, 'quantity', $value, 'value');
$this->extend('updateQuantity', $value);

$data = array(
'quantity' => $value,
'quantityGenerated' => ProductPage::getGeneratedValue($code, 'quantity', $value, 'value'),
);

$this->extend('updateData', $data);
return json_encode($data);
}
}
2 changes: 2 additions & 0 deletions tasks/EncryptResponsesTask.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?php

use SilverStripe\Dev\BuildTask;
use Dynamic\FoxyStripe\Model\Order;
use Dynamic\FoxyStripe\Model\FoxyCart;

class EncryptResponsesTask extends BuildTask
{
Expand Down
Loading

0 comments on commit b7d405d

Please sign in to comment.