File: D:/HostingSpaces/SBogers10/topswtw.komma.pro/wwwroot/js/app/pages/return.js
define([], function () {
if(document.getElementById('returnform')) { //Only load the controller when we have the returnform
//Define the return controller "class"
var returnController = (function () {
var ordernumberInput = document.getElementById('ordernumber');
var postalcodeInput = document.getElementById('postalcode');
var housenumberInput = document.getElementById('housenumber');
var searchOrder = document.getElementById('search-order');
var orderInfoValidation = document.getElementById('order-information-validation');
var orderInfoValidationSuccessMessage = orderInfoValidation.querySelector('.success');
var orderInfoValidationFalseMessage = orderInfoValidation.querySelector('.false');
var orderInfoValidationButton = orderInfoValidation.querySelector('.btn');
var orderInfoFormPart = document.getElementById('orderinfoformpart'); //Holds all things that need to be visible only when the order is validated successfully
var articlesSelector = document.getElementById('articlesselector'); //product selection table holder
var articleTableBody = (articlesSelector) ? articlesSelector.getElementsByTagName('tbody')[0] : undefined;
var translationYes = (articlesSelector) ? articlesSelector.getAttribute('data-translation-yes') : 'yes';
var translationNo = (articlesSelector) ? articlesSelector.getAttribute('data-translation-no') : 'no';
var translationFree = (articlesSelector) ? articlesSelector.getAttribute('data-translation-free') : 'free';
var translationAmount = (articlesSelector) ? articlesSelector.getAttribute('data-translation-amount') : '';
var translationReturnAmount = (articlesSelector) ? articlesSelector.getAttribute('data-translation-return-amount') : '';
var returnReasonRadio1 = document.getElementById('returnreason1');
var returnReasonRadio2 = document.getElementById('returnreason2');
var returnReasonRadio3 = document.getElementById('returnreason3');
var returnActionRadio1 = document.getElementById('returnaction1');
var returnActionRadio2 = document.getElementById('returnaction2');
var returnActionRadio3 = document.getElementById('returnaction3');
var knownfilterarticlenumber = document.getElementById('knownfilterarticlenumber');
var unknownFilterUnitbrand = document.getElementById('unknownfilterunitbrand');
var unknownFilterLength = document.getElementById('unknownfilterlength');
var unknownFilterWidth = document.getElementById('unknownfilterwidth');
var unknownFilterHeight = document.getElementById('unknownfilterheight');
var unknownFilterClass = document.getElementById('unknownfilterclass');
var unknownFilterPhoto = document.getElementById('unknownfilterphoto');
var returnReasonSelector = document.getElementById('returnreasonselector');
var actionTopsSelector = document.getElementById('actiontopsselector');
var returnForKnownFilterFormPart = document.getElementById('returnforknownfilterformpart');
var returnForUnknownFilterFormPart = document.getElementById('returnforunknownfilterformpart');
var returnForRefundFormPart = document.getElementById('returnforrefundformpart');
var damagedFilterForm = document.getElementById('damagedformpart');
var damagedFilterAmount = document.getElementById('damagedfilteramount');
var damagedFilterArticleNumber = document.getElementById('damagedfilterarticlenumber');
var damagedFilterPhoto = document.getElementById('damagedfilterphoto');
var notesForm = document.getElementById('notes');
var fakeSubmitWrapper = document.getElementsByClassName('return_submit')[0];
var submitButton = document.getElementsByClassName('return_submit')[0].getElementsByTagName('input')[0];
//console.log(returnReasonSelector);
//console.log(actionTopsSelector);
var self = {
validateOrderUrl: undefined,
validateArticleUrl: undefined,
ordervalid: false,
articlenumbervalid: false,
damagedArticleNumberValid: false,
amountOfCheckedProducts: 0,
returnReason: returnReasonRadio1.id,
returnReasonValue: returnReasonRadio1.value,
returnAction: returnActionRadio1.value,
initialize: function (validateOrderUrl, validateArticleUrl) {
console.log('initialize');
this.validateOrderUrl = validateOrderUrl;
this.validateArticleUrl = validateArticleUrl;
this.validateFormAndManageSubmitButton();
this.orderValidStatusChanged(false, 'initialize');
this.activateOrderAndArticleNumberListeners();
this.activateReturnReasonRadioListeners();
this.activateActionTopsRadioListeners();
this.activateFormValidationListeners();
this.activatePhotoUploadListeners();
returnReasonRadio1.click();
returnActionRadio1.click();
},
activateFormValidationListeners: function()
{
//The ordernumber, postalcode, and housnumber, article and damaged article fields already cause form validation because they use ajax. Reason and action changed fields radios also trigger form validation
unknownFilterUnitbrand.onchange = unknownFilterUnitbrand.onkeyup = this.validateFormAndManageSubmitButton.bind(this);
unknownFilterLength.onchange = unknownFilterLength.onkeyup = this.validateFormAndManageSubmitButton.bind(this);
unknownFilterWidth.onchange = unknownFilterWidth.onkeyup = this.validateFormAndManageSubmitButton.bind(this);
unknownFilterHeight.onchange = unknownFilterHeight.onkeyup = this.validateFormAndManageSubmitButton.bind(this);
unknownFilterClass.onchange = unknownFilterClass.onkeyup = this.validateFormAndManageSubmitButton.bind(this);
// unknownFilterPhoto.onchange = unknownFilterPhoto.onkeyup = this.validateFormAndManageSubmitButton.bind(this);
damagedFilterAmount.onchange = damagedFilterAmount.onkeyup = this.validateFormAndManageSubmitButton.bind(this);
// damagedFilterPhoto.onchange = damagedFilterPhoto.onkeyup = this.validateFormAndManageSubmitButton.bind(this);
},
activateOrderAndArticleNumberListeners: function () {
ordernumberInput.onkeyup = ordernumberInput.onchange = this.debounce(this.validateOrder.bind(this), 500);
postalcodeInput.onkeyup = postalcodeInput.onchange = this.debounce(this.validateOrder.bind(this), 500);
housenumberInput.onkeyup = housenumberInput.onchange = this.debounce(this.validateOrder.bind(this), 500);
knownfilterarticlenumber.onkeyup = knownfilterarticlenumber.onchange = this.debounce(this.validateArticleNumber.bind(this), 500);
damagedFilterArticleNumber.onkeyup = damagedFilterArticleNumber.onchange = this.debounce(this.validateDamagedArticleNumber.bind(this), 500);
orderInfoValidationButton.onclick = this.showOrderInfoFormPart.bind(this);
},
activateReturnReasonRadioListeners: function () {
//console.log('activating change listeners for reason radios');
returnReasonRadio1.onchange = this.reasonChanged.bind(this);
returnReasonRadio2.onchange = this.reasonChanged.bind(this);
returnReasonRadio3.onchange = this.reasonChanged.bind(this);
},
activateActionTopsRadioListeners: function () {
//console.log('activating change listeners for action radios');
returnActionRadio1.onchange = this.actionChanged.bind(this);
returnActionRadio2.onchange = this.actionChanged.bind(this);
returnActionRadio3.onchange = this.actionChanged.bind(this);
},
activatePhotoUploadListeners: function (){
unknownFilterPhoto.addEventListener('change', self.updatePhotoField, false);
damagedFilterPhoto.addEventListener('change', self.updatePhotoField, false);
},
updatePhotoField: function(){
var files = this.files;
var numFiles = files.length;
var fileNames = '';
for (var i = 0; i < numFiles; i++) {
var file = files[i];
if(i !== 0) fileNames = fileNames + ', ';
fileNames = fileNames + file.name;
}
// Update label sibling
this.parentNode.querySelector('label').innerHTML = fileNames;
self.validateFormAndManageSubmitButton();
},
validateOrder: function (changeEvent) {
var ordernumber = ordernumberInput.value;
var postalcode = postalcodeInput.value;
var housenumber = housenumberInput.value;
var queryString = this.encodeQueryData({
'ordernumber': ordernumber,
'postalcode': postalcode,
'housenumber': housenumber
});
var url = this.validateOrderUrl + '?' + queryString;
//console.log('validating order using url: ' + url);
var controller = this;
$.ajax({
url: url,
async: true,
dataType: 'json',
success: function (response) {
controller.orderValidStatusChanged(response.valid, response)
},
error: function (jqXHR, textStatus, errorThrown) {
var error = 'status code: ' + jqXHR.status + ' errorThrown: ' + errorThrown + 'jqXHR.responseText:' + jqXHR.responseText;
controller.orderValidStatusChanged(false, 'request error');
console.error(error);
}
});
},
// orderValidStatusChanged: function (valid, response) {
// //console.log('orderValid: ' + valid);
// orderInfoFormPart.classList.remove('show');
// if (valid) {
// orderInfoFormPart.classList.add('show');
// this.setArticles(response.products);
// }
// this.ordervalid = valid;
// this.validateFormAndManageSubmitButton();
// },
orderValidStatusChanged: function (valid, response) {
//console.log('orderValid: ' + valid);
if (valid) {
orderInfoValidationSuccessMessage.classList.add('show');
orderInfoValidationFalseMessage.classList.remove('show');
orderInfoValidationButton.classList.add('enabled');
this.setArticles(response.products);
}
else{
if(ordernumberInput.value !== '' && postalcodeInput.value !== '' && housenumberInput.value !== '')
{
orderInfoValidationFalseMessage.classList.add('show');
orderInfoValidationSuccessMessage.classList.remove('show');
orderInfoValidationButton.classList.remove('enabled');
orderInfoFormPart.classList.remove('show');
}
}
this.ordervalid = valid;
this.validateFormAndManageSubmitButton();
},
showOrderInfoFormPart: function(changeEvent) {
if(this.ordervalid){
orderInfoFormPart.classList.add('show');
searchOrder.classList.add('inactive');
orderInfoValidation.classList.add('hide');
}
else{
orderInfoFormPart.classList.remove('show');
searchOrder.classList.remove('inactive');
orderInfoValidation.classList.remove('hide');
}
},
validateArticleNumber: function (changeEvent) {
var articleNumber = knownfilterarticlenumber.value;
this.validateArticleNumberUsingCallback(articleNumber, this.articleNumberValidStatusChanged.bind(this))
},
validateDamagedArticleNumber: function (changeEvent) {
var articleNumber = damagedFilterArticleNumber.value;
this.validateArticleNumberUsingCallback(articleNumber, this.articleNumberDamagedValidStatusChanged.bind(this))
},
validateArticleNumberUsingCallback: function(articleNumber, callback)
{
var url = this.validateArticleUrl + '?articlenumber=' + articleNumber;
//console.log('validating article using url: ' + url);
$.ajax({
url: url,
async: true,
dataType: 'json',
success: function (response) {
callback(response.valid, response);
},
error: function (jqXHR, textStatus, errorThrown) {
var error = 'status code: ' + jqXHR.status + ' errorThrown: ' + errorThrown + 'jqXHR.responseText:' + jqXHR.responseText;
callback(false, 'request error');
// console.error(error);
}
});
},
validateFormAndManageSubmitButton: function()
{
//console.log('validateFormAndManageSubmitButton');
//console.log(this);
var isValid = false;
if(!this.ordervalid) {
this.enableOrDisableSubmitButton(isValid);
return isValid;
}
var reason = this.returnReasonValue;
if(reason === 'article_does_not_fit' || reason === 'article_expectations')
{
var action = this.returnAction;
// console.log(action);
if(action === 'return_for_known_filter') {
isValid = this.articlenumbervalid;
} else if(action === 'return_for_unknown_filter') {
//brand, length, width, height and photo must be present
isValid = (
unknownFilterUnitbrand.value !== '' &&
unknownFilterLength.value !== '' &&
unknownFilterWidth.value !== '' &&
unknownFilterHeight.value !== ''
// unknownFilterClass !== '' && //Currently may be empty
// unknownFilterPhoto.value !== '' //Currently may be empty
);
// console.log('return_for_unkown_filter');
//console.log('brand: '+unknownFilterUnitbrand.value+' length: '+unknownFilterLength.value+' width: '+unknownFilterWidth.value+' height: '+unknownFilterHeight.value+' photo: '+unknownFilterPhoto.value+' valid: '+isValid);
} else if(action === 'return_for_refund') {
//noting to validate
isValid = true;
// console.log('return_for_refund');
}
} else if(reason === 'article_damaged') {
//Article number, filter and package photo + filter amount
isValid = (
damagedFilterAmount.value > 0 &&
this.damagedArticleNumberValid === true &&
damagedFilterPhoto.value !== ''
);
// console.log('article_damaged');
//console.log('Damaged filter amount: '+damagedFilterAmount.value+' article number valid: '+this.damagedArticleNumberValid+' photo: '+damagedFilterPhoto.value+' valid: '+isValid)
}
// console.log(isValid);
this.enableOrDisableSubmitButton(isValid);
return isValid;
},
enableOrDisableSubmitButton: function(isValid)
{
// console.log('enableOrDisableSubmitButton: '+isValid);
//console.log(this);
console.log(isValid);
fakeSubmitWrapper.classList.add('enabled');
submitButton.disabled = false;
if(!isValid) {
fakeSubmitWrapper.classList.remove('enabled');
submitButton.disabled = true;
}
},
articleNumberValidStatusChanged: function (valid, response) {
//console.log('article valid: ' + valid);
knownfilterarticlenumber.classList.remove('invalid');
if(!valid) knownfilterarticlenumber.classList.add('invalid');
this.articlenumbervalid = valid;
this.validateFormAndManageSubmitButton();
},
articleNumberDamagedValidStatusChanged: function (valid, response) {
//console.log('damaged article valid: ' + valid);
damagedFilterArticleNumber.classList.remove('invalid');
if(!valid) damagedFilterArticleNumber.classList.add('invalid');
this.damagedArticleNumberValid = valid;
this.validateFormAndManageSubmitButton();
},
setArticles: function (productsArray) {
//clear all rows
while (articleTableBody.firstChild) {
articleTableBody.removeChild(articleTableBody.firstChild);
}
//add rows
var productsCount = productsArray.length;
for (var index = 0; index < productsCount; index++) {
var product = productsArray[index];
var row = this.createProductRow(false, product.internal_article_number, product.title, product.quantity, product.discount_number_of_items_for_free);
articleTableBody.appendChild(row);
}
},
createProductRow: function (ret, articlenumber, title, quantity, quantityForFree) {
//Create row and td's and link them
var row = document.createElement('tr');
var returnDataElement = document.createElement('td');
returnDataElement.className = 'returnProductCheckbox';
var articleNumberDataElement = document.createElement('td');
var quantityDataElement = document.createElement('td');
var quantityReturnDataElement = document.createElement('td');
returnDataElement.colSpan = 3;
articleNumberDataElement.colSpan = 4;
quantityDataElement.colSpan = 1;
quantityReturnDataElement.colSpan = 4;
row.appendChild(returnDataElement);
row.appendChild(articleNumberDataElement);
row.appendChild(quantityDataElement);
row.appendChild(quantityReturnDataElement);
//Create td contents and bind them to their tds
var returnCheckboxInput = document.createElement('input');
returnDataElement.appendChild(returnCheckboxInput);
var returnCheckboxTextNo = document.createElement('p');
returnCheckboxTextNo.innerText = translationNo;
returnCheckboxTextNo.className = 'no-text';
var returnCheckboxTexYes = document.createElement('p');
returnCheckboxTexYes.innerText = translationYes;
returnCheckboxTexYes.className = 'yes-text';
returnDataElement.appendChild(returnCheckboxTextNo);
returnDataElement.appendChild(returnCheckboxTexYes);
var articleNumberParagraph = document.createElement('span');
var articleNumberText = document.createTextNode(articlenumber);
articleNumberParagraph.appendChild(articleNumberText);
articleNumberDataElement.appendChild(articleNumberParagraph);
var articleDescriptionParagraph = document.createElement('p');
var articleDescriptionText = document.createTextNode(title);
articleDescriptionParagraph.appendChild(articleDescriptionText);
articleNumberDataElement.appendChild(articleDescriptionParagraph);
var quantityParagraph = document.createElement('p');
var quantityText = document.createTextNode(quantity);
quantityParagraph.appendChild(quantityText);
if(parseInt(quantityForFree) > 0) {
var forFreeText = document.createTextNode(' + ' + quantityForFree + ' ' + translationFree + '');
quantityParagraph.appendChild(forFreeText);
}
if(translationAmount !== ''){
var quantityTranslationSpan = document.createElement('span');
quantityTranslationSpan.className = 'mobile-title';
var quantityTranslationText = document.createTextNode(translationAmount);
quantityTranslationSpan.appendChild(quantityTranslationText);
quantityDataElement.appendChild(quantityTranslationSpan);
}
quantityDataElement.appendChild(quantityParagraph);
var quantityReturnLessButton = document.createElement('span');
var currentQuantitySpan = document.createElement('span');
var quantityReturnMoreButton = document.createElement('span');
var returnAmountRealInput = document.createElement('input');
quantityReturnLessButton.className = 'button less';
currentQuantitySpan.className = 'value';
quantityReturnMoreButton.className = 'button more';
var quantityReturnDataWrapper = document.createElement('div');
quantityReturnDataWrapper.className = 'wrapper';
quantityReturnDataWrapper.appendChild(quantityReturnLessButton);
quantityReturnDataWrapper.appendChild(currentQuantitySpan);
quantityReturnDataWrapper.appendChild(quantityReturnMoreButton);
if(translationReturnAmount !== ''){
var returnAmountTranslationSpan = document.createElement('span');
returnAmountTranslationSpan.className = 'mobile-title';
var returnAmountTranslationText = document.createTextNode(translationReturnAmount);
returnAmountTranslationSpan.appendChild(returnAmountTranslationText);
quantityReturnDataElement.appendChild(returnAmountTranslationSpan);
}
quantityReturnDataElement.appendChild(quantityReturnDataWrapper);
quantityReturnDataElement.appendChild(returnAmountRealInput);
//Further build the td contents
returnCheckboxInput.setAttribute('type', 'checkbox');
returnCheckboxInput.setAttribute('name', 'return_checkbox[]');
returnCheckboxInput.setAttribute('value', articlenumber);
returnCheckboxInput.parentNode.classList.add('enabled');
returnCheckboxInput.addEventListener('click', function () {
if(this.checked) this.parentNode.classList.add('enabled');
else this.parentNode.classList.remove('enabled');
self.showReturnReasons();
// var yesNoParagraph = returnCheckboxText;
// return function (changeEvent) {
// yesNoParagraph.innerText = (this.value) ? translationYes : translationNo;
// }
});
// var lessTextNode = document.createTextNode('<');
// quantityReturnLessButton.appendChild(lessTextNode);
// var moreTextNode = document.createTextNode('>');
// quantityReturnMoreButton.appendChild(moreTextNode);
var currentQuantityTextNode = document.createTextNode(parseInt(quantity) + parseInt(quantityForFree));
currentQuantitySpan.appendChild(currentQuantityTextNode);
// currentQuantitySpan.dataset.max = quantity;
currentQuantitySpan.setAttribute('data-max', ""+(parseInt(quantity) + parseInt(quantityForFree)));
returnAmountRealInput.setAttribute('type', 'hidden');
returnAmountRealInput.setAttribute('name', 'return_amount_'+articlenumber);
returnAmountRealInput.setAttribute('value', (parseInt(quantity) + parseInt(quantityForFree)));
//Bind listeners
quantityReturnMoreButton.addEventListener('click', (function (controller) {
var quantityModifier = 1;
var span = currentQuantitySpan;
return function (mouseEvent) {
controller.changedReturnQuantity(span, returnAmountRealInput, quantityModifier)
}
})(this));
quantityReturnLessButton.addEventListener('click', function (controller) {
var quantityModifier = -1;
var span = currentQuantitySpan;
return function (mouseEvent) {
controller.changedReturnQuantity(span, returnAmountRealInput, quantityModifier)
}
}(this));
return row;
},
changedReturnQuantity: function (span, returnAmountRealInput, modifier) {
var currentQuantity = parseInt(span.innerText);
// var maxQuantity = span.dataset.max;
var maxQuantity = span.getAttribute('data-max');
//check bounds and if out of bounds return.
if (modifier !== -1 && modifier !== 1) return;
if (modifier === -1 && currentQuantity === 1) return;
if (modifier === 1 && currentQuantity >= maxQuantity) return;
span.removeChild(span.firstChild);
var newReturnAmount = parseInt(currentQuantity + modifier);
var currentQuantityTextNode = document.createTextNode('' + newReturnAmount);
returnAmountRealInput.value = newReturnAmount;
span.appendChild(currentQuantityTextNode);
},
showReturnReasons: function() {
var checkedProducts = articleTableBody.querySelectorAll('.returnProductCheckbox.enabled');
self.amountOfCheckedProducts = checkedProducts.length;
if(self.amountOfCheckedProducts >= 1){
self.showReturnReasonsFormPart(true);
self.showReasonSubPart();
}
else{
self.showReturnReasonsFormPart(false);
self.showReasonSubPart();
}
},
reasonChanged: function (changeEvent) {
var selectedRadioButtonElement = changeEvent.target;
self.returnReason = selectedRadioButtonElement.id;
self.returnReasonValue = selectedRadioButtonElement.value;
self.showReasonSubPart();
this.validateFormAndManageSubmitButton();
},
showReasonSubPart: function(){
if(self.amountOfCheckedProducts !== 0){
this.showNotesFormPart(true);
switch (self.returnReason) {
case 'returnreason1':
this.showActionFormPart(true);
this.showDamagedFormPart(false);
break;
case 'returnreason2':
this.showDamagedFormPart(true);
this.showActionFormPart(false);
break;
case 'returnreason3':
this.showActionFormPart(true);
this.showDamagedFormPart(false);
break;
}
}
else{
this.showActionFormPart(false);
this.showDamagedFormPart(false);
this.showNotesFormPart(false);
}
},
actionChanged: function (changeEvent) {
//console.log(this.getAction());
var selectedRadioButtonElement = changeEvent.target;
this.returnAction = selectedRadioButtonElement.value;
this.showReturnForKnownFilterFormPart(false);
this.showReturnForUnknownFilterFormPart(false);
this.showReturnForRefundFormPart(false);
switch (selectedRadioButtonElement.id) {
case 'returnaction1':
this.showReturnForKnownFilterFormPart(true);
break;
case 'returnaction2':
this.showReturnForUnknownFilterFormPart(true);
break;
case 'returnaction3':
this.showReturnForRefundFormPart(true);
break;
}
this.validateFormAndManageSubmitButton();
},
showReturnReasonsFormPart: function (show) {
returnReasonSelector.classList.remove('show');
if (show) returnReasonSelector.classList.add('show');
},
showActionFormPart: function (show) {
actionTopsSelector.classList.remove('show');
if (show) actionTopsSelector.classList.add('show');
},
showDamagedFormPart: function (show) {
damagedFilterForm.classList.remove('show');
if (show) damagedFilterForm.classList.add('show');
},
showReturnForKnownFilterFormPart: function (show) {
returnForKnownFilterFormPart.classList.remove('show');
if (show) returnForKnownFilterFormPart.classList.add('show');
},
showReturnForUnknownFilterFormPart: function (show) {
returnForUnknownFilterFormPart.classList.remove('show');
if (show) returnForUnknownFilterFormPart.classList.add('show');
},
showReturnForRefundFormPart: function (show) {
returnForRefundFormPart.classList.remove('show');
if (show) returnForRefundFormPart.classList.add('show');
},
showNotesFormPart: function (show) {
notesForm.classList.remove('show');
if (show) notesForm.classList.add('show');
},
getReason: function () {
return document.getElementById('returnform').returnreason.value
},
getAction: function () {
return document.getElementById('returnform').returnaction.value
},
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
debounce: function (func, wait, immediate) {
var timeout;
return function () {
var context = this, args = arguments;
var later = function () {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
},
encodeQueryData: function (data) {
var ret = [];
for (var d in data)
ret.push(encodeURIComponent(d) + '=' + encodeURIComponent(data[d]));
return ret.join('&');
}
};
return self;
})();
//start the class. You can see the initialize function as a classic class constructor.
returnController.initialize('returnordervalidator', 'returnarticlenumbervalidator');
}
});