ordersprinter/products.html

630 lines
25 KiB
HTML

<html>
<head>
<title>Ansicht Produkte</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<link rel="stylesheet" type="text/css" href="css/bestformat.css">
<link rel="stylesheet" href="php/3rdparty/orderstyle/orderstyle.min.css" />
<link rel="stylesheet" href="php/3rdparty/orderstyle/jquery.mobile.icons.min.css" />
<link rel="stylesheet" href="php/3rdparty/jquery.mobile-1.4.0.min.css" type="text/css" />
<script src="php/3rdparty/jquery-2.0.3.min.js"></script>
<script src="php/3rdparty/jquery.mobile-1.4.0.min.js"></script>
<script src="utilities.js"></script>
</head>
<body>
<script>
function showDbProducts() {
doAjax("GET","php/contenthandler.php?module=products&command=getAllAvailProdsAlphaSorted",null,saveProdsGetHierarchy,"keine Produktinformation bekommen");
}
function saveProdsGetHierarchy(prods) {
$("#info-page").data("allprods",prods);
doAjax("GET","php/contenthandler.php?module=products&command=showDbProducts",null,fillLevel0WithProductOverview,"keine Produkthierarchyinformation bekommen");
}
function getAudioFiles() {
doAjax("GET","php/contenthandler.php?module=products&command=getAudioFiles",null,setAvailableAudioFiles,"keine Audiofiles-Info bekommen");
}
function setAvailableAudioFiles(audioFiles) {
$("#info-page").data("audioFiles",audioFiles);
}
function fillLevel0WithProductOverview(prodInfo) {
displayProductOverview_level0(prodInfo,"componentStructure");
}
// only set available switch
function setRadioButton(avail_elem,valueToSet) {
var flipName = avail_elem.find("input").attr("name");
var newSwitchHtmlText = switchElement(flipName,valueToSet, "Verfügbar");
// does not work
// $("input[type='radio']").checkboxradio("refresh");
// therefore replace html content in div #avalaible - dirty, but works
var partToSubst = avail_elem.parent().parent().parent().find("#availablepart");
partToSubst.html(newSwitchHtmlText);
}
// only set audio selection
function setAudioFile(container_elem,valueToSet) {
var audioElem = container_elem.find("select").attr("id");
htmlText = fillAudioList(valueToSet);
$("#" + audioElem).html(htmlText);
$("#" + audioElem).selectmenu('refresh', true);
}
function applyProductChange(id,longname,shortname,priceA,priceB,priceC,avail,audioFile) {
var data = {
id: id,
longname: longname,
shortname: shortname,
priceA: priceA,
priceB: priceB,
priceC: priceC,
available: avail,
audioFile: audioFile
};
doAjax("POST","php/contenthandler.php?module=products&command=applySingleProdData",data,null,"Keine Produktmodifikation");
}
function createProduct(longname,shortname,priceA,priceB,priceC,avail,prodTypeId,audioFile) {
var data = {
longname: longname,
shortname: shortname,
priceA: priceA,
priceB: priceB,
priceC: priceC,
available: avail,
prodTypeId: prodTypeId,
audioFile: audioFile
};
doAjax("POST","php/contenthandler.php?module=products&command=createProduct",data,location.reload(),"Neues Produkt nicht anlegbar");
}
function applyTypeChange(id,name,kind,usekitchen,usesupply) {
var data = {
id: id,
name: name,
kind: kind,
usekitchen: usekitchen,
usesupply: usesupply
}
doAjax("POST","php/contenthandler.php?module=products&command=applyType",data,null,"Cannot apply Type Change");
}
function resetDataOfSingleProd(id,longname_elem,shortname_elem,price_elemA,price_elemB,price_elemC,avail_elem,container_elem) {
var jsonContent = '';
$.ajax({ type: "GET",
dataType: "json",
url: "php/contenthandler.php",
data : {
module: "products",
command: "getSingleProdData",
id: id
},
async: false,
success : function(jsonContent)
{
longname_elem.val(jsonContent.longname);
shortname_elem.val(jsonContent.shortname);
price_elemA.val(jsonContent.priceA);
price_elemB.val(jsonContent.priceB);
price_elemC.val(jsonContent.priceC);
var audio = jsonContent.audio;
if ((audio == '') || (audio == null)) {
audio = "Kein Ton";
}
setAudioFile(container_elem,audio);
var avail = jsonContent.available;
setRadioButton(avail_elem,avail);
$('#componentStructure').trigger('create');
},
error: function( text ) {
alert( "Sorry, there was a problem getDataOfSingleProd !" + text);
}
});
return jsonContent;
}
function reassignProd (prodid,typeid) {
var data = {
productid : prodid,
typeid : typeid
};
doAjax("POST","php/contenthandler.php?module=products&command=reassign",data,reloadPageWithTimeout,"Produkt nicht zuweisbar");
}
// reload, also for Chrome working
function reloadPageWithTimeout(result) {
if (result != "OK") {
alert("Fehler aufgetreten - bitte Aktion wiederholen!");
}
setTimeout(function(){document.location.href = "products.html"},500);
}
function new_prod_details_content() {
return ('<h3>Neues Produkt</h3>' + prod_details_content_by_vars("-1","","",1,"","","","","",false,true));
}
function prod_details_content(entry,flip_elemid) {
var id = entry.id;
var longname = entry.longname;
var shortname = entry.shortname;
var available = entry.available;
var priceA = entry.priceA;
var priceB = entry.priceB;
var priceC = entry.priceC;
var audio = entry.audio;
if (audio == '') {
audio = "Kein Ton";
}
return ('<h3>' + longname + '</h3>' + prod_details_content_by_vars(id,longname,shortname,available,priceA,priceB,priceC,audio,flip_elemid,true,false));
}
function fillAudioList(selectedAudio) {
audioList = $("#info-page").data("audioFiles");
var text = "<option>Kein Ton</option>";
$.each(audioList, function (i, anAudioFile) {
var audioFile = anAudioFile;
if (audioFile == selectedAudio) {
text += '<option selected>' + audioFile + '</option>';
} else {
text += '<option>' + audioFile + '</option>';
}
});
return text;
}
function prod_details_content_by_vars(id,longname,shortname,available,priceA,priceB,priceC,audio,flip_elemid,cancelAndConfirm,fillAllAudios) {
longname = longname.replace(/"/g, '&quot;');
shortname = shortname.replace(/"/g, '&quot;');
var aText = '<p><input type="hidden" name="prodid" value="' + id + '" id="id"></input></p>';
aText += ' <p><div data-role="fieldcontain">';
aText += ' <label for="basic">Langname:</label>';
aText += ' <input type="text" name="longname" id="longname" value="' + longname + '" />';
aText += ' </div></p>';
aText += ' <p><div data-role="fieldcontain">';
aText += ' <label for="basic">Kurzname:</label>';
aText += ' <input type="text" name="shortname" id="shortname" value="' + shortname + '" />';
aText += ' </div></p>';
aText += ' <p><div data-role="fieldcontain">';
aText += ' <label for="priceA">Preis (A):</label>';
aText += ' <input type="text" name="priceA" id="priceA" value="' + priceA.replace(".",",") + '" />';
aText += ' <label for="priceB">Preis (B):</label>';
aText += ' <input type="text" name="priceB" id="priceB" value="' + priceB.replace(".",",") + '" />';
aText += ' <label for="priceC">Preis (C):</label>';
aText += ' <input type="text" name="priceC" id="priceC" value="' + priceC.replace(".",",") + '" />';
aText += ' </div></p>';
aText += ' <p><div data-role="fieldcontain">';
aText += ' <label for="audiolistselection">Audiofile:</label>';
aText += ' <select name="audiolistselection" id="audiosel_' + flip_elemid + '" class="audiolistselection" data-theme="f">';
if (fillAllAudios) {
aText += fillAudioList('');
} else {
aText += fillAudioList(audio);
}
aText += ' </select>';
aText += ' </div></p>';
var buttonAreaId = flip_elemid + 'buttonarea';
aText += '<div data-role="fieldcontain" id="availablepart">';
aText += switchElement (flip_elemid,available,"Verfügbar");
aText += '</div>';
if (cancelAndConfirm) {
aText += ' <p><fieldset class="ui-grid-a" id="' + buttonAreaId + '">';
aText += ' <div class="ui-block-a"><button type="submit" data-theme="c" class="cancelButton" data-icon="back">Abbrechen</button></div>';
aText += ' <div class="ui-block-b"><button type="submit" data-theme="b" class="applyButton" data-icon="check">Anwenden</button></div> ';
aText += ' </fieldset>';
aText += ' </p>';
} else {
aText += '<button type="submit" data-theme="b" class="applyButton" data-icon="check">Anwenden</button>';
}
return aText;
}
function cb_showPriceLevels(jsonContent) {
var selectedLevel = jsonContent.currentId;
var selectedLevelName = jsonContent.currentName;
var levels = jsonContent.levels;
var aText = '<div data-role="collapsible" id="pricelevelcollapsible" data-theme="c" data-collapsed="false"><h3>Preisstufe: ' + selectedLevelName + '</h3><p>';
aText += '<fieldset data-role="controlgroup" id="pricelevelfieldset" >';
var htmlTextA = getPriceLevelRadio("radio-pricelevel-a",levels[0]["name"] + ": " + levels[0]["info"],levels[0]["selected"]);
var htmlTextB = getPriceLevelRadio("radio-pricelevel-b",levels[1]["name"] + ": " + levels[1]["info"],levels[1]["selected"]);
var htmlTextC = getPriceLevelRadio("radio-pricelevel-c",levels[2]["name"] + ": " + levels[2]["info"],levels[2]["selected"]);
aText += htmlTextA + htmlTextB + htmlTextC;
aText += '</fieldset></p></div>';
$("#pricelevelswitch").html(aText);
$("#pricelevelcollapsible").trigger('create');
$("#pricelevelswitch").trigger('create');
}
function showPriceLevels() {
var jsonContent = '';
doAjax("POST","php/contenthandler.php?module=products&command=getPriceLevelInfo",null,cb_showPriceLevels,"Preislevel");
}
function setPriceLevel(priceLevelId) {
$.ajax({ type: "POST",
dataType: "json",
url: "php/contenthandler.php?module=products&command=setPriceLevelInfo",
data : {
priceLevelId: priceLevelId
},
async: false,
success : function(jsonContent)
{
showPriceLevels();
binding();
},
error: function( text ) {
alert( "Sorry, there was a problem setting price level: " + text);
}
});
}
function getPriceLevelRadio (idname, priceinfo, checked) {
var aText = '<input type="radio" name="radio-pricelevel" id="' + idname + '" value="choice-level" data-theme="f" />';
if (checked == "1") {
aText = '<input type="radio" name="radio-pricelevel" id="' + idname + '" value="choice-level" checked="checked" data-theme="f"/>';
}
aText += '<label for="' + idname + '">' + priceinfo + '</label>';
return aText;
}
function switchElementWithFreeOptions(flip_elemid,available,displayText,firstOptionText,secondOptionText) {
var flip_elem_yes = flip_elemid + '_yes';
var flip_elem_no = flip_elemid + '_no';
var flip_name = flip_elemid;
var aText = '<fieldset data-role="controlgroup" data-type="horizontal">';
aText += ' <legend>' + displayText + ':</legend>';
if (available == '0') {
aText += ' <input type="radio" name="' + flip_name+ '" id="' + flip_elem_yes + '" value="choice-yes" />';
aText += ' <label for="' + flip_elem_yes+ '">' + firstOptionText + '</label>';
aText += ' <input type="radio" name="' + flip_name + '" id="' + flip_elem_no + '" value="choice-no" checked="checked"/>';
aText += ' <label for="' + flip_elem_no + '">' + secondOptionText + '</label>';
} else {
aText += ' <input type="radio" name="' + flip_name+ '" id="' + flip_elem_yes+ '" value="choice-yes" checked="checked" />';
aText += ' <label for="' + flip_elem_yes+ '">' + firstOptionText + '</label>';
aText += ' <input type="radio" name="' + flip_name + '" id="' + flip_elem_no + '" value="choice-no" />';
aText += ' <label for="' + flip_elem_no + '">' + secondOptionText + '</label>';
}
aText += '</fieldset>';
return aText;
}
function switchElement(flip_elemid,available,displayText) {
return(switchElementWithFreeOptions(flip_elemid,available,displayText,"Ja","Nein"));
}
function displayProductOverview_level0(jsonContent,elemid) {
var elems = jsonContent.length;
var idcounter = 0;
$.each(jsonContent, function (i, prodOrType) {
var prod = prodOrType;
var name = prod.entry.name;
++idcounter;
var newid = elemid + '_' + idcounter;
$('<div data-role="collapsible" data-content-theme="e" id="'+newid+'" data-collapsed="false" data-theme="c"><h3>'+name + '</h3>').appendTo('#'+elemid);
if (prod.entry.type == 't') {
idcounter = displayProductOverview_deeper_level(prod.content,newid,idcounter,prod.entry.id,name,prod.entry.kind,prod.entry.usekitchen,prod.entry.usesupplydesk,false);
}
});
$('#' + elemid).trigger('create');
}
function freeFlipElem(label,firstOptionText,secondOptionText,whichOptionSelected,elemid) {
var htmlText = '<div class="ui-field-contain">';
htmlText += '<label for="'+ elemid + '">' + label + ':</label>';
htmlText += '<select name="select-native-1" id="'+ elemid + '">';
if (whichOptionSelected == 1) {
htmlText += '<option value="1" selected>' + firstOptionText + '</option>';
htmlText += '<option value="2">' + secondOptionText + '</option>';
} else {
htmlText += '<option value="1">' + firstOptionText + '</option>';
htmlText += '<option value="2" selected>' + secondOptionText + '</option>';
}
htmlText += '</select>';
htmlText += '</div>';
return htmlText;
}
function htmlOfTypeProperties(name,kind,useKitchen,useSupply,setId) {
name = name.replace(/\"/g, "&quot;");
var html = '<form id="typeform_' + setId + '">';
html += freeFlipElem("Art","Speisen","Getränke",1-kind,setId + "_kind");
html += freeFlipElem("Küchen/Bar","Durchlaufe Küche/Bar","Durchlaufe nicht Küche/Bar",useKitchen,setId + "_usekitchen");
html += freeFlipElem("Bereitstellung","Durchlaufe Bereitstellung","Durchlaufe nicht Bereitstellung",useSupply,setId + "_usesupply");
html += ' <p><div data-role="fieldcontain">';
html += ' <label for="' + setId + '_name">Name:</label>';
html += ' <input type="text" name="' + setId + '_name" id="' + setId + '_name" value="' + name + '" />';
html += ' </div></p>';
html += ' <p><fieldset class="ui-grid-a" id="' + setId + "_buttonarea" + '">';
html += ' <div class="ui-block-a"><button type="submit" data-theme="c" class="cancelTypeButton" data-icon="back">Abbrechen</button></div>';
html += ' <div class="ui-block-b"><button type="submit" data-theme="b" class="applyTypeButton" data-icon="check">Anwenden</button></div> ';
html += ' </fieldset>';
html += ' </p>';
html += '</form>';
return html;
}
function displayProductOverview_deeper_level(jsonContent,elemid,idcounter,typeId,name,kind,usekitchen,usesupply,displayNewEntry) {
// show type/category properties
var kindText = htmlOfTypeProperties(name,kind,usekitchen,usesupply,typeId);
$(kindText).appendTo('#'+elemid);
var elems = jsonContent.length;
$.each(jsonContent, function (i, prod) {
var name = prod.entry.name;
++idcounter;
var newid = elemid + '_' + idcounter;
if (prod.entry.type == 't') {
// a type
$('<div data-role="collapsible" class="prodtype" data-content-theme="f" id="'+newid+'"><h3>'+name + '</h3>').appendTo('#'+elemid);
idcounter = displayProductOverview_deeper_level(prod.content,newid,idcounter,prod.entry.id,name,prod.entry.kind,prod.entry.usekitchen,prod.entry.usesupplydesk,true);
} else {
// is a product
var prodDetails = prod_details_content(prod.entry,"flip_" + newid);
$('<div data-role="collapsible" data-content-theme="a" id="'+newid+'">' + prodDetails).appendTo('#'+elemid);
var flipName = "flip_" + newid;
var aValue = $(flipName).val();
$("flip_" + newid).val('on').slider("refresh");
}
});
$('#'+elemid).data("prodtype",typeId);
if (displayNewEntry) {
// (on highest level no products)
var newProduct = new_prod_details_content();
$('<div data-role="collapsible" data-theme="d" data-content-theme="d">' + newProduct).appendTo('#'+elemid);
}
var newTypeButton = '<div class="ui-field-contain">';
newTypeButton += '<input type="text" value="" data-mini="true" placeholder="Neue Kategorie" id="newtype_' + typeId + '"/>';
newTypeButton += '<button data-theme="d" data-icon="plus" class="newTypeButtonClass">Neue Kategorie</button>';
newTypeButton += '</div>';
$(newTypeButton).appendTo('#'+elemid);
if (displayNewEntry) {
var selectOptions = selectProdForTypeAssign(typeId);
var assignProdButton = '<p><fieldset class="ui-grid-a">';
assignProdButton += ' <div class="ui-block-a">' + selectOptions + '</div>';
assignProdButton += ' <div class="ui-block-b"><button data-theme="d" data-icon="plus" class="assignProductButtonClass">Produkt zuweisen</button></div>';
assignProdButton += '</fieldset></p>';
$(assignProdButton).appendTo('#'+elemid);
}
return idcounter;
}
function selectProdForTypeAssign($type) {
var elname = "prodsel_" + $type;
var selecthtml = '<select name="' + elname + '" id="' + elname + '">';
var allprodtypes = $("#info-page").data("allprods");
var prods = null;
var i=0;
for (i=0;i<allprodtypes.length;i++) {
var aType = allprodtypes[i];
if (aType.type == $type) {
prods = aType.prods;
var j=0;
for (j=0;j<prods.length;j++) {
var aProd = prods[j];
var prodname = aProd.name;
prodname = prodname.replace(/"/g, '&quot;');
selecthtml += '<option value="' + aProd.id + '">' + prodname + '</option>';
}
}
}
selecthtml += '</select>';
return selecthtml;
}
function convertToDecimalPoint(aVal) {
if (aVal != null) {
var strVal = aVal.toString().replace(",",".");
if ($.isNumeric(strVal)) {
return [true, strVal];
}
}
return [false];
}
function handleAnswerOfCreateProdType(jsonText) {
if (jsonText.status == "OK") {
location.reload()
} else {
alert("Fehler " + jsonText.code + ": " + jsonText.msg);
}
}
function binding() {
$(".newTypeButtonClass").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
var prodContainerElem = $(this).closest(".ui-collapsible");
var prodtypeId = prodContainerElem.data("prodtype");
var newTypeName = $("#newtype_"+ prodtypeId).val();
if ((newTypeName == null) || (newTypeName.replace(/ /g,"") == "")) {
alert ("Name der neuen Produktkategorie eingeben!");
} else {
var data = {
refid: prodtypeId,
name: newTypeName
}
doAjax("POST","php/contenthandler.php?module=products&command=createProdType",data,handleAnswerOfCreateProdType,"Neue Kategorie nicht anlegbar");
}
});
$(".assignProductButtonClass").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
var prodContainerElem = $(this).closest(".ui-collapsible");
var prodtypeId = prodContainerElem.data("prodtype");
var selBox = "prodsel_" + prodtypeId;
var selectedProd = $("#" + selBox + " option:selected").val();
reassignProd (selectedProd,prodtypeId);
});
$(".applyButton").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
var prodContainerElem = $(this).closest(".ui-collapsible");
var longname = prodContainerElem.find("#longname").val();
var shortname = prodContainerElem.find("#shortname").val();
var priceA_Arr = convertToDecimalPoint(prodContainerElem.find("#priceA").val());
var priceB_Arr = convertToDecimalPoint(prodContainerElem.find("#priceB").val());
var priceC_Arr = convertToDecimalPoint(prodContainerElem.find("#priceC").val());
var selectedAudioFile = prodContainerElem.find(".audiolistselection option:selected").text();
if (selectedAudioFile == 'Kein Ton') {
selectedAudioFile = '';
}
if (priceA_Arr[0] && priceB_Arr[0] && priceC_Arr[0]) {
var priceA = priceA_Arr[1];
var priceB = priceB_Arr[1];
var priceC = priceC_Arr[1];
var avail_elem = prodContainerElem.find(".ui-controlgroup-controls");
var checkInput = avail_elem.find( "input:checked" );
var text = checkInput.val();
var avail = 0;
if (text == 'choice-yes') {
avail = 1;
}
var idOfProd = prodContainerElem.find("#id").val();
if (parseInt(idOfProd) < 0) {
// new product!
var prodContainerElem = $(this).closest(".prodtype");
var prodtypeId = prodContainerElem.data("prodtype");
createProduct(longname,shortname,priceA,priceB,priceC,avail,prodtypeId,selectedAudioFile);
} else {
applyProductChange(idOfProd,longname,shortname,priceA,priceB,priceC,avail,selectedAudioFile);
}
} else {
alert("Falsches Zahlenformat oder fehlender Eintrag!");
}
});
$(".cancelButton").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
// getDataOfSingleProd(12);
var prodContainerElem = $(this).closest(".ui-collapsible");
var idOfProd = prodContainerElem.find("#id").val();
var longname_elem = prodContainerElem.find("#longname");
var shortname_elem = prodContainerElem.find("#shortname");
var price_elemA = prodContainerElem.find("#priceA");
var price_elemB = prodContainerElem.find("#priceB");
var price_elemC = prodContainerElem.find("#priceC");
var avail_elem = prodContainerElem.find(".ui-controlgroup-controls");
var prodElem = resetDataOfSingleProd(idOfProd,longname_elem,shortname_elem,price_elemA,price_elemB,price_elemC,avail_elem,prodContainerElem);
});
$("#radio-pricelevel-a").off("click").on("click", function (e) {
setPriceLevel(1);
});
$("#radio-pricelevel-b").off("click").on("click", function (e) {
setPriceLevel(2);
});
$("#radio-pricelevel-c").off("click").on("click", function (e) {
setPriceLevel(3);
});
$(".applyTypeButton").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
var formContainer = $(this).closest("form");
var idOfCat = (formContainer[0].id).split("_")[1];
// 1 = Food, 2=Drinks -> minus 1 give DB val
var kindVal = parseInt(formContainer.find("#" + idOfCat+"_kind").find( ":selected" ).val()) - 1;
// 1 = use, 2 = do not use
var useKitVal = parseInt(formContainer.find("#" + idOfCat+"_usekitchen").find( ":selected" ).val());
var useSupplyVal = parseInt(formContainer.find("#" + idOfCat+"_usesupply").find( ":selected" ).val());
// convert do DB val
if (useKitVal == 2) {
useKitVal = 0;
}
if (useSupplyVal == 2) {
useSupplyVal = 0;
}
var theNewName = formContainer.find("#" + idOfCat+"_name").val();
applyTypeChange(idOfCat,theNewName,kindVal,useKitVal,useSupplyVal);
location.reload();
});
$(".cancelTypeButton").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
location.reload();
//alert("Cancel Kategorie");
});
}
$(document).on("pageinit", "#info-page", function () {
initializeMainMenu("#modulemenu");
hideMenu();
getAudioFiles();
showDbProducts();
showPriceLevels();
binding();
});
</script>
<div data-role="page" id="info-page">
<div data-role="panel" id="modulepanel" data-position="right" data-display="overlay">
<ul data-role="listview" id="modulemenu" data-divider-theme="a" data-inset="true">
<li data-role="list-divider" data-theme="b" data-role="heading">Module</li>
</ul>
</div><!-- /panel -->
<div data-role="header" data-theme="b" data-position="fixed" id="theheader">
<h1>Angebot</h1>
<div data-type="horizontal" style="top:0px;position:absolute;float:right;z-index:10;display:inline;" align="right" class="ui-btn-right">
<a href="#" data-role="button" data-icon="arrow-d" data-ajax="false" id="menuswitch">Module</a>
</div>
</div>
<div data-role="content" id="Content">
<div id="pricelevelswitch"></div>
<div id="componentStructure"></div>
</div>
<div data-role="footer" data-theme="b" id="thefooterr">
<div class="ui-grid-a">
<div class="ui-block-a userinfo" id="loggedinuser"></div>
<div class="ui-block-b grid_right" id="versioninfo"></div>
</div><!-- /grid-a -->
</div> <!-- footer -->
</div>
</body>
</html>