// These first three must match the constants of the same names at the top of
// ...\Common\BusinessLogic\OfferManagement\basic\InvisibleBll.cs
// see the comments in that location.
//
// (I seriously considered copying them from the BLL into the ViewBag via
// the two controllers, but decided it wasn't worth it for just three variables
// that are only declared in two places.)
var MENU_DELIMITER_SIMPLE = "`";
var MENU_DELIMITER_CRUMB = "~";
var MENU_DELIMITER_SELECTION = "|";
// Constants for the global UserMode variable
var USERMODE_SELECT = 1;
var USERMODE_CUSTOMIZE = 2;
// This was requested in the requirements but it looks horrible.
var globalUseAlternateBackgrounds = false;
// Some functions need to know whether they're being called while the page is being loaded.
var interactive = false;
var classNameHoverSel = "hoverselected";
// These are declared here but assigned real values in the .cshtml file
var globalMenuId = 0;
var globalUserMode = 0;
var globalUrlGatherMajors = '';
var globalUrlGatherMinors = '';
var globalUrlGatherItems = '';
var globalUrlCustomize = '';
var globalOriginalChoices = null;
// The word "choices" means selected (in SELECT mode) or deleted (in DELETE mode)
var currentChoices = new Array();
var originalRadio = 0;
var currentRadio = 0;
var currentMajorName = '';
var currentMinorName = '';
var currentMajorId = 0;
var currentMinorId = 0;
function splitFullNameArray(listOfFullNames) {
if (listOfFullNames == null || listOfFullNames == '') {
return new Array();
}
return listOfFullNames.split(MENU_DELIMITER_SELECTION).sort();
}
function getSimpleName(fullName, which) {
if (fullName != null) {
var simpleNames = fullName.split(MENU_DELIMITER_CRUMB);
if (0 < which && which <= simpleNames.length) {
return simpleNames[which - 1];
}
}
return null;
}
function parseSimpleNameForLevel(simpleName) {
return (simpleName == null) ? 0 : parseInt(simpleName.substr(0, 1));
}
function parseSimpleNameForName(simpleName) {
if (simpleName != null) {
var tokens = simpleName.substr(1).split(MENU_DELIMITER_SIMPLE);
return tokens[0];
}
return "?";
}
function parseSimpleNameForId(simpleName) {
if (simpleName != null) {
var tokens = simpleName.substr(1).split(MENU_DELIMITER_SIMPLE);
if (tokens.length >= 2) {
return tokens[1];
}
}
return "";
}
function parseSimpleNameForQuantity(simpleName) {
if (simpleName != null) {
var tokens = simpleName.substr(1).split(MENU_DELIMITER_SIMPLE);
if (tokens.length >= 3) {
return tokens[2];
}
}
return "";
}
function buildCrumbTrail(fullName) {
var trail = "no crumbs";
var crumb1 = parseSimpleNameForName(getSimpleName(fullName, 1));
var crumb2 = parseSimpleNameForName(getSimpleName(fullName, 2));
var crumb3 = parseSimpleNameForName(getSimpleName(fullName, 3));
var whichLevel = parseSimpleNameForLevel(fullName);
if (whichLevel == globalLevelMajor) {
trail = crumb1;
}
else if (whichLevel == globalLevelMinor) {
trail = crumb2 + " -> " + crumb1;
}
else if (whichLevel == globalLevelItem) {
trail = crumb3 + " -> " + crumb2 + " -> " + crumb1;
}
return trail;
}
function buildSimpleName(whichLevel, posName, targetId, quantity) {
return '' + whichLevel + posName + MENU_DELIMITER_SIMPLE + targetId + MENU_DELIMITER_SIMPLE + quantity;
}
function buildFullName(whichLevel, posName, targetId, quantity) {
var result = buildSimpleName(whichLevel, posName, targetId, quantity);
if (whichLevel == globalLevelItem) {
result += MENU_DELIMITER_CRUMB + buildSimpleName(globalLevelMinor, currentMinorName, currentMinorId, 0);
}
if (whichLevel == globalLevelItem || whichLevel == globalLevelMinor) {
result += MENU_DELIMITER_CRUMB + buildSimpleName(globalLevelMajor, currentMajorName, currentMajorId, 0);
}
return result;
}
function buildListOfFullNames(whichArray) {
var listOfFullNames = '';
for (var j in whichArray) {
listOfFullNames += MENU_DELIMITER_SELECTION + whichArray[j];
}
return listOfFullNames.substr(1);
}
function showColumn(whichLevel) {
$jq("#" + prefixMainColumn + whichLevel).show();
}
function hideColumn(whichLevel) {
$jq("#" + prefixMainColumn + whichLevel).hide();
}
function clearAllChoices() {
hideColumn(globalLevelMinor);
hideColumn(globalLevelItem);
// quick & dirty way of clearing this
currentChoices = new Array();
}
// Remember that we can't use indexOf() because it is not available under IE6.
function thisIsChosen(fullName) {
for (var j in currentChoices) {
if (getSimpleName(currentChoices[j], 1) == getSimpleName(fullName, 1)) {
return true;
}
}
return false;
}
function addToChosenArray(fullName) {
if (!thisIsChosen(fullName)) {
currentChoices.push(fullName);
currentChoices.sort();
resetClearButton();
}
}
function removeFromChosenArray(fullName) {
for (var j in currentChoices) {
if (getSimpleName(currentChoices[j], 1) == getSimpleName(fullName, 1)) {
currentChoices.splice(j, 1);
resetClearButton();
break;
}
}
}
function radioChecked(value) {
currentRadio = value;
resetSaveButton();
}
// This is only used during SELECT ITEM mode.
function itemWasChecked($inputObj) {
var $aObj = $inputObj.parent().find("a");
var fullName = $aObj.attr("fullName");
if ($inputObj.attr('checked')) {
addToChosenArray(fullName);
}
else {
removeFromChosenArray(fullName);
}
updateDisplayedList();
updateDelimitedList();
resetSaveButton();
}
// It's safe to do this, because if the user cancels,
// the Save function does not get called and therefore
// the value doesn't get copied back to the true field.
function updateDelimitedList() {
$jq("#DelimitedListOfSelectedItems").val(buildListOfFullNames(currentChoices));
}
function applyEffectToChosenName(fullName) {
var whichLevel = parseSimpleNameForLevel(fullName);
var effect = null;
if (whichLevel == globalLevelMajor) {
effect = 'strong';
}
else if (whichLevel == globalLevelMinor) {
effect = 'em';
}
var result = parseSimpleNameForName(fullName);
if (effect != null) {
result = '<' + effect + '>' + result + '' + effect + '>';
}
return result;
}
function setTargetAsSelected(id) {
if (id > 0) {
var $aObj = $jq('[targetid="' + id + '"]');
if ($aObj != null) {
// A is child of LI is child of UL, which can have at most one LI with this class
var $liObj = $aObj.parent();
var $ulObject = $liObj.parent();
var $currentLI = $ulObject.find('.' + classNameHoverSel);
if ($currentLI != null) {
$currentLI.removeClass(classNameHoverSel);
}
$liObj.addClass(classNameHoverSel);
}
}
}
function revealSelection(fullName) {
var simpleName = getSimpleName(fullName, 1);
var targetId = parseSimpleNameForId(simpleName);
var whichLevel = parseSimpleNameForLevel(simpleName);
if (whichLevel == globalLevelMajor) {
hideColumn(globalLevelMinor);
hideColumn(globalLevelItem);
}
else if (whichLevel == globalLevelMinor) {
// full name looks like MINOR~MAJOR
simpleName = getSimpleName(fullName, 2);
if (simpleName != null) {
currentMajorId = parseSimpleNameForId(simpleName);
currentMajorName = parseSimpleNameForName(simpleName);
setTargetAsSelected(currentMajorId);
updateMinorColumn(currentMajorId);
}
}
else if (whichLevel == globalLevelItem) {
// full name looks like ITEM~MINOR~MAJOR
simpleName = getSimpleName(fullName, 3);
if (simpleName != null) {
currentMajorId = parseSimpleNameForId(simpleName);
currentMajorName = parseSimpleNameForName(simpleName);
updateMinorColumn(currentMajorId);
setTargetAsSelected(currentMajorId);
}
simpleName = getSimpleName(fullName, 2);
if (simpleName != null) {
currentMinorId = parseSimpleNameForId(simpleName);
currentMinorName = parseSimpleNameForName(simpleName);
updateItemColumn(currentMajorId, currentMinorId);
setTargetAsSelected(currentMinorId);
}
}
setTargetAsSelected(targetId);
}
function buildDisplayedList(arrayOfChoices, verb, limitOfItemsToDisplay) {
var displayedList = '';
if (arrayOfChoices.length == 0) {
if (verb != null) {
displayedList = 'There are no items ' + verb;
}
}
else {
var trueLimit = arrayOfChoices.length;
if (limitOfItemsToDisplay > 0 && trueLimit > limitOfItemsToDisplay) {
trueLimit = limitOfItemsToDisplay;
}
for (var j = 0; j < trueLimit; j++) {
var oneEntry = applyEffectToChosenName(arrayOfChoices[j]);
if (limitOfItemsToDisplay > 0) {
oneEntry = '
";
var undisplayed = numberOfItemsChosen - limitOfItemsToDisplay;
if (undisplayed > 0) {
listOfItems += "" + undisplayed + " more . . .";
}
}
}
return listOfItems;
}
// Those are not typos in the delimiters for fullname . . . double quotes are allowed
// in a POSNAME while single quotes are not, so we reverse the usual punctuation.
function buildAnchorElement(whichLevel, posName, majorId, minorId, targetId, fullName) {
var element = '' + posName + '';
return element;
}
function getImageClassName(isVisible) {
return (isVisible) ? 'deleteIcon' : 'restoreIcon';
}
function getImageFullClassName(isVisible) {
return 'icon ' + ((isVisible) ? 'deleteIcon' : 'restoreIcon');
}
function buildInputElement(isChosen, isVisible) {
var element;
if (globalUserMode == USERMODE_CUSTOMIZE) {
element = '';
}
else {
var modifier = (isChosen) ? 'checked="checked" ' : '';
element = '';
}
return element;
}
function buildColumn(whichLevel, entries) {
// Show/hide the appropriate columns and mark them active/inactive.
var higherLevel = 0;
clearList(whichLevel);
showColumn(whichLevel);
if (whichLevel == globalLevelMajor) {
clearList(globalLevelMinor);
clearList(globalLevelItem);
hideColumn(globalLevelMinor);
hideColumn(globalLevelItem);
}
else if (whichLevel == globalLevelMinor) {
higherLevel = globalLevelMajor;
clearList(globalLevelItem);
hideColumn(globalLevelItem);
}
else if (whichLevel == globalLevelItem) {
higherLevel = globalLevelMinor;
}
if (higherLevel > 0) {
$jq("#" + prefixMainColumn + higherLevel + " .active").removeClass('active');
}
$jq("#" + prefixMainColumn + whichLevel + " .active").addClass('active');
// Loop through all of the entries, adding each to the column's UL
// unless it is marked as "deleted" and we are in SELECT mode.
//
// THU 1 SEP 2011: TP 8309 says
// The "Deleted Items" Section within the Menu Selection Popup should not be there
// so we can simply not add those at all.
var $mainList = $jq("#" + prefixMainList + whichLevel);
var targetId = 0;
var majorId = 0;
var minorId = 0;
var newLI = '';
for (var j = 0; j < entries.length; j++) {
if (entries[j].Visible || globalUserMode == USERMODE_CUSTOMIZE) {
if (whichLevel == globalLevelMajor) {
targetId = entries[j].MajorId;
majorId = entries[j].MajorId;
minorId = 0;
}
else if (whichLevel == globalLevelMinor) {
targetId = entries[j].MinorId;
majorId = entries[j].MajorId;
minorId = entries[j].MinorId;
}
else {
targetId = entries[j].ItemId;
majorId = entries[j].MajorId;
minorId = entries[j].MinorId;
}
var fullName = buildFullName(whichLevel, entries[j].Name, targetId, 1);
newLI = '
// This is only used when globalUserMode is USERMODE_CUSTOMIZE
function deleteOrRestoreItem($inputObj) {
var deleting = itemIsDeleteable($inputObj);
var $liObj = $inputObj.parent();
var $aObj = $liObj.find("a");
var fullName = $aObj.attr("fullName");
var whichLevel = parseSimpleNameForLevel(fullName);
if (interactive) {
if (whichLevel == globalLevelMajor) {
hideColumn(globalLevelItem);
hideColumn(globalLevelMinor);
clearList(globalLevelItem);
clearList(globalLevelMinor);
}
else if (whichLevel == globalLevelMinor) {
hideColumn(globalLevelItem);
clearList(globalLevelItem);
}
else {
// Nothing to do at the item level
}
}
// change the icon from trashcan to doublearrow, or vice-versa.
// Note the horrible adjustment needed
$inputObj.removeAttr("class").addClass(getImageFullClassName(!deleting));
if (deleting) {
addToChosenArray(fullName);
}
else {
removeFromChosenArray(fullName);
}
updateDisplayedList();
if (interactive) {
resetSaveButton();
}
}
function getItemsAndDisplay(url, data, success) {
$jq.ajax({
global: false,
async: false,
url: url,
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(data),
success: success,
error: function (msg) {
// a real weird problem is happening which causes a json parse error, when the json is just fine
// proved by doing a parseJSON of the msg.responseText property.
if (msg.statusText == "parsererror" && msg.status == 200) {
if (msg.responseText.substr(0, 12) == '[{"MajorId":') {
var data = $jq.parseJSON(msg.responseText);
success(data);
}
}
}
});
}
function updateMajorColumn() {
getItemsAndDisplay(globalUrlGatherMajors, { menuId: globalMenuId }, function (data) { buildColumn(globalLevelMajor, data); });
}
function updateMinorColumn(majorId) {
getItemsAndDisplay(globalUrlGatherMinors, { menuId: globalMenuId, menuMajorGroupId: majorId }, function (data) { buildColumn(globalLevelMinor, data); });
}
function updateItemColumn(majorId, minorId) {
getItemsAndDisplay(globalUrlGatherItems, { menuId: globalMenuId, menuMajorGroupId: majorId, menuMinorGroupId: minorId }, function (data) { buildColumn(globalLevelItem, data); });
}
function showMenuItemsSelectionModal(buying, fieldId) {
clearAllChoices();
currentRadio = buying ? currentOnlyOne : currentSelectOpt;
originalRadio = currentRadio;
// fill the line at the top which the user sees
var listOfFullNames = $jq("#" + fieldId).val();
globalOriginalChoices = splitFullNameArray(listOfFullNames);
currentChoices = globalOriginalChoices.slice();
resetSaveButton();
resetClearButton();
updateDisplayedList();
updateDelimitedList();
// pop it up. fieldId always begins with "RestValue".
var currentTitle = (currentChoices == '') ? "Choosing " : "Editing ";
currentTitle += fieldId.substr(9) + " from menu " + globalMenuId + " . . .";
var popupbox = $jq("#MenuItemsSelection").dialog({
modal: true,
width: 1000,
position: 'top',
maxHeight: false,
maxWidth: false,
draggable: true,
minHeight: 100,
resizable: false,
title: currentTitle,
open: function () {
$jq("#HowToGroupItems").toggle(buying);
$jq("#HowToSelectItems").toggle(!buying);
}
});
popupbox.parent().css({ "margin-top": "110px" });
updateMajorColumn();
$jq("#Column" + globalLevelMajor).find("li").removeClass(classNameHoverSel);
}
function restoreAllClicked() {
if (globalUserMode == USERMODE_SELECT) {
if (confirm("Are you sure you want to drop all " + currentChoices.length + " selected items?")) {
clearAllChoices();
resetSaveButton();
resetClearButton();
updateDisplayedList();
updateDelimitedList();
}
}
else {
if (currentChoices.length == 0) {
alert("There are no deleted items to restore");
}
else {
var prompt = (currentChoices.length == 1) ? "the deleted item?" : "all " + currentChoices.length + " deleted items?";
if (confirm("Are you sure you want to restore " + prompt)) {
currentChoices = new Array();
resetSaveButton();
resetClearButton();
updateDisplayedList();
$jq("#DynamicDrillDown").find("input").removeClass().addClass(getImageFullClassName(true));
}
}
}
}
function undoAllClicked() {
if (confirm("Are you sure you want to undo your changes?")) {
window.location.reload();
}
}
function cancelClicked() {
if (confirm('If you are sure you want to cancel your changes, click "OK" and you will be redirected to the Store Selection page.')) {
backToGrid();
}
}
function saveClicked() {
// Must send a valid array, even if it consists of a single empty string
if (currentChoices.length == 0) {
currentChoices.push('');
}
$jq.ajax({
async: false,
url: globalUrlCustomize,
type: "POST",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(
{
menuId: globalMenuId,
arrayOfFullNames: currentChoices
}),
success: saveSucceeded
});
}
function saveSucceeded(data, textStatus, jqXHR) {
// The Save() method in the controller _always_ succeeds (see comments in MenuManagementController.cs)
// to prevent the error from being caught at a higher level. We check here to see the true outcome.
var prompt;
if (jqXHR.responseText == 'OK') {
prompt = 'Your changes were saved successfully';
} else {
prompt = 'Your changes --- ' + currentChoices + ' --- could not be saved. Message is' + jqXHR.responseText;
}
prompt += '\n\nClick OK to be redirected back to the Store Selection page.';
alert(prompt);
backToGrid();
}
function backToGrid() {
window.location.href = "/OfferManagement/MenuManagement" + window.location.search;
}
function itemIsDeleteable($inputObj) {
return $inputObj.hasClass(getImageClassName(true));
}
function itemNameWasClicked(obj) {
var $aObj = $jq(obj);
var $liObj = $aObj.parent();
var $inputObj = $liObj.find("input");
if (globalUserMode == USERMODE_SELECT || itemIsDeleteable($inputObj)) {
var whichLevel = $aObj.attr("level");
if (whichLevel == globalLevelMajor) {
currentMajorName = obj.firstChild.nodeValue;
currentMajorId = $aObj.attr("majorid");
updateMinorColumn(currentMajorId);
}
else if (whichLevel == globalLevelMinor) {
currentMinorName = obj.firstChild.nodeValue;
currentMinorId = $aObj.attr("minorid");
updateItemColumn(currentMajorId, currentMinorId);
}
else {
// nothing to do for globalLevelItem
}
$liObj.prevAll().removeClass(classNameHoverSel);
$liObj.nextAll().removeClass(classNameHoverSel);
$liObj.addClass(classNameHoverSel);
}
}
$jq(document).ready(function () {
if (globalUserMode == USERMODE_CUSTOMIZE) {
currentChoices = globalOriginalChoices.slice();
updateDisplayedList();
resetClearButton();
updateMajorColumn();
}
var $ddd = $jq("#DynamicDrillDown");
$ddd.delegate("li", "mouseout", function (event) { var $this = $jq(this); $this.removeClass('hover'); });
$ddd.delegate("li", "mouseover", function (event) { var $this = $jq(this); $this.addClass('hover'); });
interactive = true;
});