You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by jf...@apache.org on 2014/09/11 18:01:49 UTC

svn commit: r1624325 [12/13] - in /vcl/trunk/web: ./ .ht-inc/ .ht-inc/authmethods/ css/ js/ js/resources/

Added: vcl/trunk/web/js/resources.js
URL: http://svn.apache.org/viewvc/vcl/trunk/web/js/resources.js?rev=1624325&view=auto
==============================================================================
--- vcl/trunk/web/js/resources.js (added)
+++ vcl/trunk/web/js/resources.js Thu Sep 11 16:01:48 2014
@@ -0,0 +1,376 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+function Resource() {}
+
+Resource.prototype.DeleteBtn = function(rscid, rowIndex) {
+	var rowdata = this.grid.getItem(rowIndex);
+	if(! ('deleted' in rowdata) || rowdata.deleted == '0')
+		var label = 'Delete';
+	else
+		var label = 'Undelete';
+	var btn = new dijit.form.Button({
+		label: label,
+		onClick: function() {
+			toggleDeleteResource(rscid);
+		}
+	});
+	btn._destroyOnRemove = true;
+	return btn;
+}
+
+Resource.prototype.EditBtn = function(rscid, rowIndex) {
+	var rowdata = this.grid.getItem(rowIndex);
+	if(! ('deleted' in rowdata) || rowdata.deleted == '0')
+		var disable = false;
+	else
+		var disable = true;
+	var btn = new dijit.form.Button({
+		label: 'Edit',
+		disabled: disable,
+		onClick: function() {
+			editResource(rscid);
+		}
+	});
+	btn._destroyOnRemove = true;
+	return btn;
+}
+
+Resource.prototype.colformatter = function(value, rowIndex, obj) {
+	return value;
+}
+
+Resource.prototype.GridFilter = function() {
+	var name = '.*';
+	if(dijit.byId('namefilter') && dijit.byId('namefilter').get('value').length)
+		name += dijit.byId('namefilter').get('value') + '.*';
+	if(! dijit.byId('showdeleted')) {
+		resourcegrid.setQuery({name: new RegExp(name, 'i')});
+		return;
+	}
+	if(dijit.byId('showdeleted').get('value'))
+		var deleted = '*';
+	else
+		var deleted = '0';
+	resourcegrid.setQuery({name: new RegExp(name, 'i'),
+	                       deleted: deleted});
+}
+
+Resource.prototype.addRemItem = function(contid, objid1, objid2) {
+	// TODO check for selection on other tabs and update if needed
+	var obj = dojo.byId(objid1);
+	var id = obj.options[obj.selectedIndex].value;
+
+	obj = window[objid2];
+	var items = obj.selection.getSelected();
+	var listids = "";
+	for(var i = 0; i < items.length; i++) {
+		listids = listids + ',' + items[i].id;
+	}
+	if(listids == "")
+		return;
+	document.body.style.cursor = 'wait';
+	var data = {continuation: dojo.byId(contid).value,
+	            listids: listids,
+	            id: id};
+	RPCwrapper(data, this.addRemItemCB, 1);
+}
+
+Resource.prototype.addRemItemCB = function(data, ioArgs) {
+	if(data.items.status == 'success') {
+		window[data.items.inselobj].selection.clear();
+		window[data.items.outselobj].selection.clear();
+		var store = window[data.items.inselobj].store;
+		store.fetch({query: {id:new RegExp(data.items.regids)},
+			onItem: function(item, request) {
+				if(item.inout[0] == 0)
+					store.setValue(item, 'inout', 1);
+				else
+					store.setValue(item, 'inout', 0);
+			},
+			onComplete: function(item, request) {
+				setTimeout(function() {
+					// TODO maintain scroll position
+					window[data.items.inselobj].setQuery({inout: 1});
+					window[data.items.outselobj].setQuery({inout: 0});
+				}, 1);
+			}
+		});
+	}
+	else if(data.items.status == 'noaccess') {
+		alert('You do not have access to the submitted resource or group');
+	}
+	document.body.style.cursor = 'default';
+}
+
+Resource.prototype.toggleResFieldDisplay = function(obj, field) {
+	for(var i in resourcegrid.layout.cells) {
+		if(resourcegrid.layout.cells[i].field == field) {
+			if(obj.checked)
+				resourcegrid.layout.setColumnVisibility(i, true);
+			else
+				resourcegrid.layout.setColumnVisibility(i, false);
+			break;
+		}
+	}
+}
+
+Resource.prototype.nocasesort = function(a, b) {
+	var al = a.toLowerCase();
+	var bl = b.toLowerCase();
+	if(al < bl)
+		return -1;
+	if(bl < al)
+		return 1;
+	return 0;
+}
+
+var resource = new Resource();
+
+var timeout = null;
+var ownervalid = false;
+var ownerchecking = false;
+
+var resourcetogroupsdata = {
+	identifier: 'id',
+	label: 'name',
+	items: [{id: 1, name: 'foo1'},{id:2,name:'foo2'}]
+}
+
+var grouptoresourcesdata = {
+	identifier: 'id',
+	label: 'name',
+	items: []
+}
+
+var mapbyresgroupdata = {
+	identifier: 'id',
+	label: 'name',
+	items: []
+}
+
+var mapbymaptogroupdata = {
+	identifier: 'id',
+	label: 'name',
+	items: []
+}
+
+var resourcetogroupsstore;
+var grouptoresourcesstore;
+var mapbyresgroupstore;
+var mapbymaptogroupstore;
+
+var ignorecasemap = {};
+ignorecasemap['name'] = resource.nocasesort;
+
+function toggleCmapFieldDisplay(obj, field) {
+	for(var i in configmapgrid.layout.cells) {
+		if(configmapgrid.layout.cells[i].field == field) {
+			if(obj.checked)
+				configmapgrid.layout.setColumnVisibility(i, true);
+			else
+				configmapgrid.layout.setColumnVisibility(i, false);
+			break;
+		}
+	}
+}
+
+function toggleDeleteResource(rscid) {
+	var data = {continuation: dojo.byId('deleteresourcecont').value,
+	            rscid: rscid};
+	RPCwrapper(data, toggleDeleteResourceCB, 1);
+}
+
+function toggleDeleteResourceCB(data, ioArgs) {
+	if(data.items.status == 'success') {
+		dijit.byId('toggleDeleteDialog').set('title', data.items.title);
+		dojo.byId('toggleDeleteHeading').innerHTML = data.items.title;
+		dojo.byId('toggleDeleteQuestion').innerHTML = data.items.question;
+		dojo.byId('toggleDeleteBtn').innerHTML = data.items.btntxt;
+		dojo.byId('confdelrescontent').innerHTML = data.items.html;
+		dojo.byId('submitdeletecont').value = data.items.cont;
+		dijit.byId('toggleDeleteDialog').show();
+	}
+	else if(data.items.status == 'noaccess') {
+		alert(data.items.msg);
+	}
+}
+
+function submitToggleDeleteResource() {
+	var data = {continuation: dojo.byId('submitdeletecont').value};
+	RPCwrapper(data, submitToggleDeleteResourceCB, 1);
+}
+
+function submitToggleDeleteResourceCB(data, ioArgs) {
+	if(data.items.status == 'error') {
+		alert('Problem encountered while attempting to delete resource. Please contact a system administrator.');
+		return;
+	}
+	else if(data.items.status == 'success') {
+		resourcegrid.store.fetch({query: {id: data.items.rscid}, onComplete:
+			function(items, request) {
+				if(! dijit.byId('showdeleted')) {
+					resourcestore.deleteItem(items[0]);
+				}
+				else {
+					var newval = (parseInt(items[0]['deleted']) + 1) % 2;
+					resourcestore.setValue(items[0], 'deleted', newval);
+				}
+				resourcegrid.update();
+				// TODO maintain scroll position
+				resource.GridFilter();
+			}
+		});
+		clearHideConfirmDelete();
+	}
+}
+
+function editResource(rscid) {
+	var data = {continuation: dojo.byId('editresourcecont').value,
+	           inline: 0,
+	           rscid: rscid};
+	data['inline'] = 1;
+	RPCwrapper(data, inlineEditResourceCB, 1);
+}
+
+function checkFirstAdd() {
+	if(typeof resourcegrid !== 'undefined')
+		return;
+	window.location.href = dojo.byId('reloadpageurl').value;
+}
+
+function caselessSort(a, b) {
+	return a.toLowerCase().localeCompare(b.toLowerCase());
+}
+
+function clearHideConfirmDelete() {
+	dijit.byId('toggleDeleteDialog').hide();
+	dojo.byId('confdelrescontent').innerHTML = '';
+}
+
+/*function finishUnselect(id) {
+	var obj = dijit.byId(id);
+	for(var i = 0; i < obj.options.length; i++) {
+		if(obj.options[i].selected)
+			return;
+	}
+	dojo.query("[widgetid='" + id + "'] > div > div").forEach(
+		function(node, index, nodelist) {
+			dojo.removeClass(node, 'dojoxMultiSelectSelectedOption');
+		}
+	);
+}*/
+
+function editGroupMapInit() {
+	// getImagesButton getGroupsButton getMapCompGroupsButton getMapImgGroupsButton
+	if(dijit.byId('groupbyresourcediv'))
+		populateLists('resources', 'ingroups', 'inresourcename', 'outresourcename', 'resgroupinggroupscont');
+	if(dijit.byId('groupbygroupdiv'))
+		populateLists('resgroups', 'inresources', 'ingroupname', 'outgroupname', 'resgroupingresourcescont');
+	if(dojo.byId('domapping').value == '1') {
+		if(dijit.byId('mapbyresgroupdiv'))
+			populateLists('groups', 'inmapgroups', 'inmapgroupname', 'outmapgroupname', 'mapbyresgroupcont');
+		if(dijit.byId('mapbymaptogroupdiv'))
+			populateLists('maptogroups', 'inmaptogroups', 'inmaptogroupname', 'outmaptogroupname', 'mapbymaptogroupcont');
+	}
+}
+
+function populateLists(selobj, inselobj, intitle, outtitle, cont) {
+	document.body.style.cursor = 'wait';
+	if(! (inselobj in window)) {
+		setTimeout(function() {
+			populateLists(selobj, inselobj, intitle, outtitle, cont);
+		}, 100);
+		return;
+	}
+	var obj = dojo.byId(selobj);
+	var id = obj.options[obj.selectedIndex].value;
+	var resname = obj.options[obj.selectedIndex].text;
+
+	dojo.byId(intitle).innerHTML = resname;
+	dojo.byId(outtitle).innerHTML = resname;
+
+	var data = {continuation: dojo.byId(cont).value,
+	            id: id};
+	RPCwrapper(data, populateListsCB, 1);
+}
+
+function populateListsCB(data, ioArgs) {
+	if(data.items.status == 'noaccess') {
+		document.body.style.cursor = 'default';
+		alert('You do not have access to the submitted resource or group');
+		return;
+	}
+	var oldstore = window[data.items.intitle].store;
+	var items = data.items.items;
+	var newdata = {
+		identifier: 'id',
+		label: 'name',
+		items: data.items.items
+	}
+	var newstore = new dojo.data.ItemFileWriteStore({data: newdata});
+	if(! newstore.comparatorMap)
+		newstore.comparatorMap = {};
+	newstore.comparatorMap['name'] = resource.nocasesort;
+	window[data.items.intitle].selection.clear();
+	window[data.items.outtitle].selection.clear();
+	window[data.items.intitle].setStore(newstore);
+	window[data.items.outtitle].setStore(newstore);
+	window[data.items.intitle].setQuery({inout: 1});
+	window[data.items.outtitle].setQuery({inout: 0});
+	delete oldstore;
+	document.body.style.cursor = 'default';
+}
+
+function setOwnerChecking() {
+	ownerchecking = true;
+}
+
+function checkOwner(val, constraints) {
+	if(! dijit.byId('owner')._hasBeenBlurred)
+		return true;
+	if(timeout != null)
+		clearTimeout(timeout);
+	timeout = setTimeout(checkOwner2, 700);
+	return ownervalid;
+}
+
+function checkOwner2() {
+	ownerchecking = true;
+	var data = {user: dijit.byId('owner').textbox.value,
+	            continuation: dojo.byId('valuseridcont').value};
+	RPCwrapper(data, checkOwnerCB, 1);
+}
+
+function checkOwnerCB(data, ioArgs) {
+	var obj = dijit.byId('owner');
+	if(data.items.status && data.items.status == 'invalid') {
+		obj.attr('state', 'Error');
+		obj._setStateClass();
+		obj.displayMessage(obj.getErrorMessage('Unknown user'));
+		ownervalid = false;
+	}
+	else {
+		obj.attr('state', 'Normal');
+		obj._setStateClass();
+		obj.displayMessage(null);
+		ownervalid = true;
+	}
+	ownerchecking = false;
+}
+
+

Added: vcl/trunk/web/js/resources/computer.js
URL: http://svn.apache.org/viewvc/vcl/trunk/web/js/resources/computer.js?rev=1624325&view=auto
==============================================================================
--- vcl/trunk/web/js/resources/computer.js (added)
+++ vcl/trunk/web/js/resources/computer.js Thu Sep 11 16:01:48 2014
@@ -0,0 +1,1068 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+function Computer() {
+	Resource.apply(this, Array.prototype.slice.call(arguments));
+	this.selids = [];
+	this.selectingall = false;
+}
+Computer.prototype = new Resource();
+
+var filterstore;
+var filtercbstores = {};
+var extrafiltergrid;
+var savescroll = 0;
+var editobj;
+var addedit = 'edit';
+var lastselected = {blade: {provisioningid: '', stateid: ''},
+                    lab: {provisioningid: '', stateid: ''},
+                    virtualmachine: {provisioningid: '', stateid: ''}};
+var filterdelay;
+
+String.prototype.ucfirst = function() {
+	return this.charAt(0).toUpperCase() + this.slice(1);
+}
+
+Computer.prototype.DeleteBtn = function(rscid, rowIndex) {
+	var rowdata = this.grid.getItem(rowIndex);
+	if(! ('deleted' in rowdata) || rowdata.deleted == '0') {
+		var id = 'chkb' + rowdata.id; 
+		if(dojo.indexOf(resource.selids, id) != -1)
+			var checked = true;
+		else
+			var checked = false;
+		var cb = new dijit.form.CheckBox({
+			id: id,
+			value: rowdata.id,
+			checked: checked,
+			onClick: selectRow
+		});
+		cb._destroyOnRemove = true;
+		return cb;
+	}
+	// resource has deleted set
+	return '&nbsp;';
+}
+
+Computer.prototype.EditBtn = function(rscid, rowIndex) {
+	var rowdata = this.grid.getItem(rowIndex);
+	if(! ('deleted' in rowdata) || rowdata.deleted == '0') {
+		var btn = new dijit.form.Button({
+			label: 'Edit',
+			onClick: function() {
+				editResource(rscid);
+			}
+		});
+	}
+	else {
+		var btn = new dijit.form.Button({
+			label: 'Undelete',
+			onClick: function() {
+				toggleDeleteResource(rscid);
+			}
+		});
+	}
+	btn._destroyOnRemove = true;
+	return btn;
+}
+
+Computer.prototype.colformatter = function(value, rowIndex, obj) {
+	if(obj.field == 'state') {
+		if(value == 'failed')
+			return '<span class="rederrormsg">failed</span>';
+		if(value == 'available')
+			return '<span class="ready">available</span>';
+		if(value == 'reloading')
+			return '<span class="wait">reloading</span>';
+	}
+	else if(obj.field == 'notes' && value) {
+		return value.replace('@', '<br>').replace(/\n/g, '<br>');
+	}
+	else if(obj.field == 'deleted') {
+		if(value == "0")
+			return '<span class="rederrormsg">false</span>';
+		if(value == "1")
+			return '<span class="ready">true</span>';
+	}
+	return value;
+}
+
+Computer.prototype.toggleResFieldDisplay = function(obj, field) {
+	for(var i in resourcegrid.layout.cells) {
+		if(resourcegrid.layout.cells[i].field == field) {
+			if(obj.checked) {
+				resourcegrid.layout.setColumnVisibility(i, true);
+				extrafiltergrid.layout.setColumnVisibility(i, true);
+			}
+			else {
+				resourcegrid.layout.setColumnVisibility(i, false);
+				extrafiltergrid.layout.setColumnVisibility(i, false);
+				delete resourcegrid.query[field];
+				resourcegrid.setQuery(resourcegrid.query);
+			}
+			break;
+		}
+	}
+}
+
+Computer.prototype.GridFilter = function() {
+	if(dijit.byId('showdeleted').get('value')) {
+		var width = '5.1em';
+		var showdeleted = '*';
+	}
+	else {
+		var width = '3em';
+		var showdeleted = '0';
+	}
+	resourcegrid.setCellWidth(1, width);
+	resourcegrid.layout.cells[1].view.update();
+	extrafiltergrid.setCellWidth(1, width);
+	extrafiltergrid.layout.cells[1].view.update();
+
+	var query = resourcegrid.query;
+	query['deleted'] = showdeleted;
+
+	resourcegrid.setQuery(query);
+}
+
+function filterKeyDown(e) {
+	if(e.keyCode == dojo.keys.ENTER) {
+		dojo.stopEvent(e);
+		dijit.byId('ownercb').focus();
+		var focusnext = 0;
+		var cells = extrafiltergrid.layout.cells;
+		for(var i = 2; i < cells.length; i++) {
+			if(focusnext && ! cells[i].hidden) {
+				dijit.byId(cells[i].field + 'cb').focus();
+				focusnext = 2;
+				break;
+			}
+			if(cells[i].field + 'cb' == e.target.id) {
+				focusnext = 1;
+				continue;
+			}
+		}
+		if(focusnext == 1)
+			dijit.byId(cells[2].field + 'cb').focus();
+	}
+}
+
+Computer.prototype.Selection = function() {
+	// TODO this messes up when all rows have been selected with selectAllRows
+	//      and then a row is unselected because this function only handles
+	//      rendered rows
+	var sel = resourcegrid.selection.selected;
+	if(! resource.selectingall) {
+		dojo.forEach(resource.selids, function(id) {
+			if(dijit.byId(id))
+				dijit.byId(id).set('checked', false);
+		});
+		resource.selids = [];
+	}
+	for(var i = 0; i < sel.length; i++) {
+		if(sel[i]) {
+			var comp = resourcegrid.getItem(i);
+			if(! resource.selectingall) {
+				if(! parseInt(comp.deleted))
+					resource.selids.push('chkb' + comp.id);
+				else
+					resourcegrid.selection.deselect(comp);
+			}
+			if(dijit.byId('chkb' + comp.id))
+				dijit.byId('chkb' + comp.id).set('checked', true);
+		}
+	}
+	//console.log(resource.selids.length + ":" + resourcegrid.rowCount);
+	if(resource.selids.length != resourcegrid.rowCount)
+		dijit.byId('selectallchkb').set('checked', false);
+	else
+		dijit.byId('selectallchkb').set('checked', true);
+}
+
+Computer.prototype.nocasesort = function(a, b) {
+	var al = a.toLowerCase();
+	var bl = b.toLowerCase();
+	if(al.match(/[0-9]/) ||
+	   bl.match(/[0-9]/)) {
+		return resource.comparehostnames(al, bl);
+	}
+	if(al < bl)
+		return -1;
+	if(bl < al)
+		return 1;
+	return 0;
+}
+
+Computer.prototype.comparehostnames = function(a, b) {
+	// get hostname
+	var tmp = a.split('.');
+	var h1 = tmp.shift();
+	var letters1 = h1.replace(/([^a-zA-Z])/g, '');
+
+	tmp = b.split('.');
+	var h2 = tmp.shift();
+	var letters2 = h2.replace(/([^a-zA-Z])/g, '');
+
+	// if non-numeric part is different, return based on that
+	cmp = letters1.localeCompare(letters2);
+	if(cmp)
+		return cmp;
+
+	// at this point, the only difference is in the numbers
+	var digits1 = h1.replace(/([^\d-])/g, '');
+	var digits1Arr = digits1.split('-');
+	var digits2 = h2.replace(/([^\d-])/g, '');
+	var digits2Arr = digits2.split('-');
+
+	var len1 = digits1Arr.length;
+	var len2 = digits2Arr.length;
+	for(var i = 0; i < len1 && i < len2; i++) {
+		if(parseInt(digits1Arr[i]) < parseInt(digits2Arr[i]))
+			return -1;
+		else if(parseInt(digits1Arr[i]) > parseInt(digits2Arr[i]))
+			return 1;
+	}
+
+	return 0;
+}
+
+var resource = new Computer();
+
+function initPage() {
+	if(dojo.byId('reloadpageurl'))
+		return;
+   document.body.style.cursor = 'wait';
+	if(! ('resourcegrid' in window)) {
+		setTimeout(function() {
+			initPage();
+		}, 100);
+		return;
+	}
+	else {
+		document.body.style.cursor = 'default';
+		buildExtraFilters();
+		
+		// set width of first column
+		resourcegrid.setCellWidth(0, '18px');
+		resourcegrid.layout.cells[0].view.update();
+
+		// connect selection
+		dojo.connect(resourcegrid, 'onSelectionChanged', this, resource.Selection);
+
+		// hide resource name filter
+		dojo.addClass('namefilter', 'hidden');
+
+		// connect scrolling stuff
+		dojo.connect(resourcegrid, 'postrender', setScroll);
+		dojo.connect(resourcegrid.views.views[0].scrollboxNode, 'onscroll', saveScroll);
+
+		// select all computer groups
+		for(var i = 0; i < dojo.byId('filtercompgroups').options.length; i++) {
+			dojo.byId('filtercompgroups').options[i].selected = true;
+		}
+		clearTimeout(filterdelay);
+	}
+}
+
+function selectRow(e) {
+	var id = this.id.replace('chkb', '');
+	if(this.checked) {
+		resource.selids.push(this.id);
+		resourcestore.fetchItemByIdentity({
+			identity: id,
+			onItem: function(item, req) {
+				resourcegrid.selection.addToSelection(resourcegrid.getItemIndex(item));
+			}
+		});
+	}
+	else {
+		var index = resource.selids.indexOf(id);
+		if(index > -1)
+			resource.selids.splice(index, 1);
+		resourcestore.fetchItemByIdentity({
+			identity: id,
+			onItem: function(item, req) {
+				resourcegrid.selection.deselect(resourcegrid.getItemIndex(item));
+			}
+		});
+	}
+	dojo.stopEvent(e);
+}
+
+function selectAllRows() {
+	resourcestore.fetch({
+		query: resourcegrid.query,
+		onComplete: function(items, request) {
+			resource.selectingall = true;
+			if(resource.selids.length) {
+				dojo.forEach(resource.selids, function(id) {
+					if(dijit.byId(id))
+						dijit.byId(id).set('checked', false);
+				});
+				resource.selids = [];
+				resourcegrid.selection.clear();
+				dijit.byId('selectallchkb').set('checked', false);
+			}
+			else {
+				resource.selids = [];
+				dojo.forEach(items, function(item) {
+					if(! parseInt(item.deleted)) {
+						resource.selids.push('chkb' + item.id);
+						resourcegrid.selection.addToSelection(resourcegrid.getItemIndex(item));
+					}
+				})
+				dijit.byId('selectallchkb').set('checked', true);
+			}
+			resource.selectingall = false;
+		}
+	});
+}
+
+function buildExtraFilters() {
+	// create grid layout
+	var obj = {};
+	var layout = [];
+	var cells = resourcegrid.layout.cells;
+	for(var i = 0; i < cells.length; i++) {
+		var litem = {};
+		obj[cells[i].field] = '';
+		litem['field'] = cells[i].field;
+		if(cells[i].field == 'id')
+			litem['name'] = '&nbsp;';
+		else
+			litem['name'] = cells[i].name;
+		litem['hidden'] = cells[i].hidden;
+		if(i == 0)
+			litem['width'] = '18px';
+		else if(typeof cells[i].width != 'undefined')
+			litem['width'] = cells[i].width;
+		litem['editable'] = false;
+		if(i == 0) {
+			litem['formatter'] = function(value, index, item) {
+				var cb = new dijit.form.CheckBox({
+					id: 'selectallchkb',
+					checked: false,
+					onClick: selectAllRows,
+					_destroyOnRemove: true
+				});
+				return cb;
+			}
+		}
+		if(i == 1) {
+			litem['formatter'] = function(value, index, item) {
+				item.customStyles.push('background-color: #e8e8e8');
+				item.customStyles.push('border: 1px solid black');
+				item.customStyles.push('text-align: center');
+				return '<span id=\"applyextrafilters\">Apply</span>';
+			}
+		}
+		else if(i > 1) {
+			litem['formatter'] = function(value, index, item) {
+				if(dijit.byId(item.field + 'cb'))
+					return dijit.byId(item.field + 'cb');
+				if(item.field in filtercbstores)
+					var store = filtercbstores[item.field];
+				else
+					var store = dojo.data.ItemFileReadStore({});
+				var cb = new dijit.form.ComboBox({
+					selectOnClick: true,
+					store: store,
+					id: item.field + "cb",
+					required: false,
+					query: {id: '*'},
+					onChange: applyExtraFilters,
+					field: item.field,
+					queryExpr: '*${0}*',
+					autoComplete: false,
+					searchAttr: 'value'
+				});
+				if(typeof item.width != 'undefined') {
+					var newwidth = parseInt(item.width) - 0.6;
+					cb.set('style', {width: newwidth + "em"});
+				}
+				else if(typeof item.unitWidth != 'undefined') {
+					var newwidth = parseInt(item.unitWidth) - 0.6;
+					cb.set('style', {width: newwidth + "em"});
+				}
+				return cb;
+			};
+		}
+		layout.push(litem);
+	}
+	var data = {items: [obj]};
+	filterstore = new dojo.data.ItemFileReadStore({data: data});
+	extrafiltergrid = new dojox.grid.DataGrid({
+		query: {name: '*'},
+		store: filterstore,
+		structure: layout,
+		canSort: function() {return false;},
+		onCellClick: combofocus
+	}, document.createElement('div'));
+	dojo.byId('extrafiltersdiv').appendChild(extrafiltergrid.domNode);
+	extrafiltergrid.startup();
+	var cells = extrafiltergrid.layout.cells;
+	for(var i = 2; i < cells.length; i++) {
+		dojo.connect(dijit.byId(cells[i].field + 'cb'), 'onKeyDown', null, filterKeyDown);
+	}
+
+	// create stores for comboboxes
+	resourcestore.fetch({
+		onComplete: function(items, request) {
+			var data = {};
+			var seen = {};
+			var cells = resourcegrid.layout.cells;
+			dojo.forEach(items, function(item) {
+				for(var i = 0; i < cells.length; i++) {
+					if(cells[i].field == 'id')
+						continue;
+					var field = cells[i].field;
+					if(! (field in seen)) {
+						seen[field] = [];
+						data[field] = [];
+					}
+					if(dojo.indexOf(seen[field], item[field]) == -1) {
+						seen[field].push(item[field].toString());
+						data[field].push({id: item.id.toString(), value: item[cells[i].field].toString()});
+					}
+				}
+			});
+			for(var i = 0; i < cells.length; i++) {
+				if(cells[i].field == 'id')
+					continue;
+				var field = cells[i].field;
+				var store = new dojo.data.ItemFileReadStore({data: {identifier:'id', label:'value', items: data[field]}});
+				filtercbstores[field] = store;
+				dijit.byId(field + 'cb').set('store', store);
+			}
+		}
+	});
+}
+
+function combofocus(obj) {
+	if(dijit.byId(obj.cell.field + "cb"))
+		dijit.byId(obj.cell.field + "cb").focus();
+}
+
+function applyExtraFilters(value) {
+	delete resourcegrid.query[this.field];
+	if(value == 'inuse')
+		resourcegrid.query[this.field] = value;
+	else if(value != '')
+		resourcegrid.query[this.field] = new RegExp('.*' + value + '.*', 'i');
+	resourcegrid.setQuery(resourcegrid.query);
+
+	var savelist = resource.selids;
+	resourcegrid.selection.clear();
+	var newselids = [];
+	for(var i = 0; i < resourcegrid.rowCount; i++) {
+		var row = resourcegrid.getItem(i);
+		if(! row)
+			continue;
+		var id = 'chkb' + row.id;
+		if(dojo.indexOf(savelist, id) != -1) {
+			newselids.push(id);
+			resourcegrid.selection.addToSelection(resourcegrid.getItemIndex(row));
+			dijit.byId(id).set('checked', true);
+		}
+	}
+	resourcegrid.selids = newselids;
+}
+
+function addNewResource(title) {
+		if(dijit.byId('scheduleid').options.length == 0) {
+			dijit.byId('noschedulenoadd').show();
+			return;
+		}
+	addedit = 'add';
+	resetEditResource();
+	dijit.byId('type').reset();
+	selectType();
+	dijit.byId('addeditdlg').set('title', title);
+	dijit.byId('addeditbtn').set('label', title);
+	dojo.byId('editresid').value = 0;
+	dojo.removeClass('singlemultiplediv', 'hidden');
+	dojo.addClass('notesspan', 'hidden');
+	dojo.addClass('vmprofilespan', 'hidden');
+	dojo.addClass('curimgspan', 'hidden');
+	dojo.addClass('compidspan', 'hidden');
+	dijit.byId('addeditdlg').show();
+}
+
+function toggleSingleMultiple() {
+	if(dijit.byId('mode').get('value') == 'single')
+		toggleAddSingle();
+	else
+		toggleAddMultiple();
+}
+
+function toggleAddSingle() {
+	dojo.addClass('multiplenotediv', 'hidden');
+	dojo.addClass('startenddiv', 'hidden');
+	dojo.addClass('multiipmacdiv', 'hidden');
+	dojo.removeClass('singleipmacdiv', 'hidden');
+	dijit.byId('name').set('regExp', '^([a-zA-Z0-9_][-a-zA-Z0-9_\.]{1,35})$');
+	dijit.byId('addeditbtn').setLabel('Add Computer');
+	recenterDijitDialog('addeditdlg');
+}
+
+function toggleAddMultiple() {
+	dojo.removeClass('multiplenotediv', 'hidden');
+	dojo.removeClass('startenddiv', 'hidden');
+	dojo.removeClass('multiipmacdiv', 'hidden');
+	dojo.addClass('singleipmacdiv', 'hidden');
+	dijit.byId('name').set('regExp', '^([a-zA-Z0-9_%][-a-zA-Z0-9_\.%]{1,35})$');
+	dijit.byId('addeditbtn').setLabel('Add Computers');
+	recenterDijitDialog('addeditdlg');
+}
+
+function inlineEditResourceCB(data, ioArgs) {
+	dojo.addClass('singlemultiplediv', 'hidden');
+	toggleAddSingle();
+	if(data.items.status == 'success') {
+		addedit = 'edit';
+		editobj = data.items.data;
+		dojo.addClass('cancelvmhostinuseokdiv', 'hidden');
+		if(data.items.showcancel) {
+			dojo.removeClass('cancelvmhostinusediv', 'hidden');
+			dojo.byId('tohostcancelcont').value = data.items.tohostcancelcont;
+			if(data.items.tohostfuture) {
+				dojo.addClass('tohostnowspan', 'hidden');
+				dojo.removeClass('tohostfuturespan', 'hidden');
+				dojo.byId('tohostfuturetimespan').innerHTML = data.items.tohoststart;
+			}
+			else {
+				dojo.removeClass('tohostnowspan', 'hidden');
+				dojo.addClass('tohostfuturespan', 'hidden');
+			}
+		}
+		else {
+			dojo.addClass('cancelvmhostinusediv', 'hidden');
+		}
+		dijit.byId('type').set('value', data.items.data.type);
+		selectType();
+		dijit.byId('provisioningid').set('value', data.items.data.provisioningid);
+		selectProvisioning();
+		lastselected[data.items.data.type]['provisioningid'] = data.items.data.provisioningid;
+		dijit.byId('stateid').set('value', data.items.data.stateid);
+		lastselected[data.items.data.type]['stateid'] = data.items.data.stateid;
+		dojo.byId('saveresourcecont').value = data.items.cont;
+		dijit.byId('addeditdlg').set('title', data.items.title);
+		dijit.byId('addeditbtn').set('label', 'Save Changes');
+		dijit.byId('addeditbtn').set('disabled', false);
+		dojo.byId('editresid').value = data.items.resid;
+		dijit.byId('name').set('value', data.items.data.hostname);
+		dijit.byId('owner').set('value', data.items.data.owner);
+		dijit.byId('ipaddress').set('value', data.items.data.IPaddress);
+		dijit.byId('privateipaddress').set('value', data.items.data.privateIPaddress);
+		dijit.byId('publicmac').set('value', data.items.data.eth1macaddress);
+		dijit.byId('privatemac').set('value', data.items.data.eth0macaddress);
+		if('notes' in data.items.data && data.items.data.notes) {
+			if(data.items.data.notes.match(/@/))
+				dijit.byId('notes').set('value', data.items.data.notes.split('@')[1]);
+			else
+				dijit.byId('notes').set('value', data.items.data.notes);
+		}
+		dijit.byId('vmprofileid').set('value', data.items.data.vmprofileid);
+		dijit.byId('platformid').set('value', data.items.data.platformid);
+		dijit.byId('scheduleid').set('value', data.items.data.scheduleid);
+		dojo.byId('curimg').innerHTML = data.items.data.currentimg;
+		dijit.byId('ram').set('value', data.items.data.ram);
+		dijit.byId('cores').set('value', data.items.data.procnumber);
+		dijit.byId('procspeed').set('value', data.items.data.procspeed);
+		dijit.byId('network').set('value', data.items.data.network);
+		dojo.byId('compid').innerHTML = data.items.data.id;
+		dijit.byId('location').set('value', data.items.data.location);
+		dojo.byId('addeditdlgerrmsg').innerHTML = '';
+		dijit.byId('addeditdlg').show();
+	}
+	else if(data.items.status == 'noaccess') {
+		alert('Access denied to edit this item');
+	}
+}
+
+function selectType() {
+	var type = dijit.byId('type').get('value');
+	var obj = dijit.byId('provisioningid');
+	obj.options = [];
+	dojo.forEach(options[type]['provisioning'], function(prov) {
+		obj.addOption(prov);
+	});
+	dijit.byId('provisioningid').set('value', lastselected[type]['provisioningid']);
+	var obj = dijit.byId('stateid');
+	obj.options = [];
+	if(addedit == 'edit') {
+		if(type == 'virtualmachine' && parseInt(editobj.vmhostid) > 0 &&
+		   editobj.state != 'available')
+			obj.addOption({value: '2', label: 'available'});
+		obj.addOption({value: editobj.stateid, label: editobj.state});
+	}
+	dojo.forEach(options[type]['states'], function(state) {
+		if(addedit == 'edit' && state.value == editobj.stateid)
+			return;
+		if(addedit == 'add' && state.label == 'vmhostinuse' &&
+	      dijit.byId('provisioningid').attr('displayedValue') != 'None')
+			return;
+		obj.addOption({value: state.value, label: state.label});
+	});
+	dijit.byId('stateid').set('value', lastselected[type]['stateid']);
+	if(type == 'blade' &&
+	   dijit.byId('provisioningid').attr('displayedValue') == 'None' &&
+	   dijit.byId('stateid').attr('displayedValue') == 'vmhostinuse')
+		dojo.removeClass('vmprofilespan', 'hidden');
+	else if(dijit.byId('stateid').attr('displayedValue') != 'vmhostinuse')
+		dojo.addClass('vmprofilespan', 'hidden');
+	if(addedit == 'edit' && dijit.byId('stateid').attr('displayedValue') == 'maintenance')
+		dojo.removeClass('notesspan', 'hidden');
+	else
+		dojo.addClass('notesspan', 'hidden');
+}
+
+function selectProvisioning() {
+	lastselected[dijit.byId('type').get('value')]['provisioningid'] = dijit.byId('provisioningid').get('value');
+	var obj = dijit.byId('stateid');
+	obj.options = [];
+	if(addedit == 'edit') {
+		if(dijit.byId('type').get('value') == 'virtualmachine' &&
+		   parseInt(editobj.vmhostid) > 0 &&
+		   editobj.state != 'available')
+			obj.addOption({value: '2', label: 'available'});
+		var addedexisting = false;
+	}
+	dojo.forEach(options[dijit.byId('type').get('value')]['states'], function(state) {
+		if(((dijit.byId('type').get('value') == 'blade' &&
+		   dijit.byId('provisioningid').attr('displayedValue') == 'None') ||
+		   (addedit == 'add' && dijit.byId('type').get('value') == 'virtualmachine')) &&
+		   state.label == 'available')
+			return;
+		if(addedit == 'add' && state.label == 'vmhostinuse' &&
+	      dijit.byId('provisioningid').attr('displayedValue') != 'None')
+			return;
+		if(addedit == 'edit' && state.value == editobj.stateid)
+			addedexisting = true;
+		obj.addOption({value: state.value, label: state.label});
+	});
+	if(addedit == 'edit' && ! addedexisting)
+		obj.addOption({value: editobj.stateid, label: editobj.state});
+	dijit.byId('stateid').set('value', lastselected[dijit.byId('type').get('value')]['stateid']);
+}
+
+function selectState() {
+	lastselected[dijit.byId('type').get('value')]['stateid'] = dijit.byId('stateid').get('value');
+	if(dijit.byId('type').get('value') == 'blade' &&
+	   dijit.byId('stateid').attr('displayedValue') == 'vmhostinuse')
+		dojo.removeClass('vmprofilespan', 'hidden');
+	else if(dijit.byId('stateid').attr('displayedValue') != 'vmhostinuse')
+		dojo.addClass('vmprofilespan', 'hidden');
+	if(addedit == 'edit' && dijit.byId('stateid').attr('displayedValue') == 'maintenance')
+		dojo.removeClass('notesspan', 'hidden');
+	else
+		dojo.addClass('notesspan', 'hidden');
+}
+
+function resetEditResource() {
+	var fields = ['name', 'owner', 'type', 'ipaddress', 'privateipaddress',
+	              'publicmac', 'privatemac', 'provisioningid', 'stateid',
+	              'vmprofileid', 'platformid', 'scheduleid', 'ram', 'cores',
+	              'procspeed', 'network', 'location', 'startnum', 'endnum',
+	              'startpubipaddress', 'endpubipaddress', 'startprivipaddress',
+	              'endprivipaddress', 'startmac', 'notes'];
+	for(var i = 0; i < fields.length; i++) {
+		dijit.byId(fields[i]).reset();
+	}
+	dojo.byId('curimg').innerHTML = '';
+	dojo.byId('compid').innerHTML = '';
+	dojo.byId('addeditdlgerrmsg').innerHTML = '';
+	dojo.removeClass('notesspan', 'hidden');
+	dojo.removeClass('vmprofilespan', 'hidden');
+	dojo.removeClass('curimgspan', 'hidden');
+	dojo.removeClass('compidspan', 'hidden');
+}
+
+function saveResource() {
+	var errobj = dojo.byId('addeditdlgerrmsg');
+	if(addedit == 'edit' || dijit.byId('mode').get('value') == 'single')
+		var fields = ['name', 'owner', 'ipaddress', 'privateipaddress', 'publicmac',
+		              'privatemac', 'ram', 'cores', 'procspeed', 'location'];
+	else
+		var fields = ['name', 'startnum', 'endnum', 'owner', 'startpubipaddress',
+		              'endpubipaddress', 'startprivipaddress', 'endprivipaddress',
+		              'startmac', 'ram', 'cores', 'procspeed', 'location'];
+	for(var i = 0; i < fields.length; i++) {
+		if(! checkValidatedObj(fields[i], errobj))
+			return;
+	}
+
+	if(addedit == 'add')
+		var data = {continuation: dojo.byId('addresourcecont').value};
+	else
+		var data = {continuation: dojo.byId('saveresourcecont').value};
+
+	if(addedit == 'edit' && dijit.byId('stateid').attr('displayedValue') == 'maintenance') {
+		if(! dijit.byId('notes').get('value').match(/^([-a-zA-Z0-9_\. ,#\(\)=\+:;]{0,5000})$/)) {
+			errobj.innerHTML = "Maintenance reason can be up to 5000 characters long and may only<br>contain letters, numbers, spaces and these characters: - , . _ # ( ) = + : ;";
+			return;
+		}
+		else
+			data['notes'] = dijit.byId('notes').get('value');
+	}
+	else
+		data['notes'] = '';
+
+	for(var i = 0; i < fields.length; i++) {
+		data[fields[i]] = dijit.byId(fields[i]).get('value');
+	}
+	data['type'] = dijit.byId('type').get('value');
+	data['provisioningid'] = dijit.byId('provisioningid').get('value');
+	data['stateid'] = dijit.byId('stateid').get('value');
+	data['vmprofileid'] = dijit.byId('vmprofileid').get('value');
+	data['platformid'] = dijit.byId('platformid').get('value');
+	data['scheduleid'] = dijit.byId('scheduleid').get('value');
+	data['network'] = dijit.byId('network').get('value');
+	data['addmode'] = dijit.byId('mode').get('value');
+
+	dijit.byId('addeditbtn').set('disabled', true);
+	RPCwrapper(data, saveResourceCB, 1);
+}
+
+function saveResourceCB(data, ioArgs) {
+	if(data.items.status == 'error') {
+		dojo.byId('addeditdlgerrmsg').innerHTML = '<br>' + data.items.msg;
+		dijit.byId('addeditbtn').set('disabled', false);
+	}
+	else if(data.items.status == 'adderror') {
+		alert(data.items.errormsg);
+	}
+	else if(data.items.status == 'success') {
+		if(data.items.action == 'add') {
+			if(data.items.addmode == 'single') {
+				if(typeof resourcegrid !== 'undefined') {
+					resourcegrid.store.newItem(data.items.data);
+					resourcegrid.sort();
+				}
+				dojo.forEach(dijit.findWidgets(dojo.byId('groupdlgcontent')), function(w) {
+					w.destroyRecursive();
+				});
+				if(data.items.nogroups == 0) {
+					dojo.byId('groupdlgcontent').innerHTML = data.items.groupingHTML;
+					AJdojoCreate('groupdlgcontent');
+					dojo.byId('resources').value = data.items.data.id;
+					populateLists('resources', 'ingroups', 'inresourcename', 'outresourcename', 'resgroupinggroupscont');
+					dijit.byId('groupdlg').show();
+					dijit.byId('groupingnote').show();
+				}
+			}
+			else {
+				if(typeof resourcegrid !== 'undefined') {
+					for(var i = 0; i < data.items.data.length; i++) {
+						resourcegrid.store.newItem(data.items.data[i]);
+					}
+					resourcegrid.sort();
+				}
+				dojo.forEach(dijit.findWidgets(dojo.byId('groupdlgcontent')), function(w) {
+					w.destroyRecursive();
+				});
+				if(data.items.nogroups == 0) {
+					dojo.byId('groupdlgcontent').innerHTML = data.items.groupingHTML;
+					dojo.byId('groupbyresourcedesc').innerHTML = data.items.grouphelp;
+					dojo.addClass('groupbyresourcesel', 'hidden');
+					AJdojoCreate('groupdlgcontent');
+					dojo.byId('resources').value = data.items.data[0].id;
+					populateLists('resources', 'ingroups', 'inresourcename', 'outresourcename', 'resgroupinggroupscont');
+					dojo.byId('inresourcename').innerHTML = 'new computer set';
+					dojo.byId('outresourcename').innerHTML = 'new computer set';
+					dojo.byId('addgrpcont').value = data.items.addcont;
+					dojo.byId('remgrpcont').value = data.items.remcont;
+					dijit.byId('groupdlg').show();
+					dijit.byId('groupingnote').show();
+				}
+			}
+		}
+		else {
+			resourcegrid.store.fetch({
+				query: {id: data.items.data.id},
+				onItem: function(item) {
+					resourcegrid.store.setValue(item, 'name', data.items.data.hostname);
+					resourcegrid.store.setValue(item, 'owner', data.items.data.owner);
+					resourcegrid.store.setValue(item, 'state', data.items.data.state);
+					resourcegrid.store.setValue(item, 'platform', data.items.data.platform);
+					resourcegrid.store.setValue(item, 'schedule', data.items.data.schedule);
+					resourcegrid.store.setValue(item, 'currentimg', data.items.data.currentimg);
+					resourcegrid.store.setValue(item, 'nextimg', data.items.data.nextimg);
+					resourcegrid.store.setValue(item, 'ram', data.items.data.ram);
+					resourcegrid.store.setValue(item, 'procnumber', data.items.data.procnumber);
+					resourcegrid.store.setValue(item, 'procspeed', data.items.data.procspeed);
+					resourcegrid.store.setValue(item, 'network', data.items.data.network);
+					resourcegrid.store.setValue(item, 'IPaddress', data.items.data.IPaddress);
+					resourcegrid.store.setValue(item, 'privateIPaddress', data.items.data.privateIPaddress);
+					resourcegrid.store.setValue(item, 'eth0macaddress', data.items.data.eth0macaddress);
+					resourcegrid.store.setValue(item, 'eth1macaddress', data.items.data.eth1macaddress);
+					resourcegrid.store.setValue(item, 'type', data.items.data.type);
+					resourcegrid.store.setValue(item, 'deleted', data.items.data.deleted);
+					resourcegrid.store.setValue(item, 'notes', data.items.data.notes);
+					resourcegrid.store.setValue(item, 'vmhost', data.items.data.vmhost);
+					resourcegrid.store.setValue(item, 'location', data.items.data.location);
+					resourcegrid.store.setValue(item, 'provisioning', data.items.data.provisioning);
+				},
+				onComplete: function(items, result) {
+					// when call resourcegrid.sort directly, the table contents disappear; not sure why
+					setTimeout(function() {resourcegrid.sort();}, 10);
+				}
+			});
+		}
+		dijit.byId('addeditdlg').hide();
+		resetEditResource();
+		if('promptuser' in data.items) {
+			dijit.byId('confirmactiondlg').set('title', data.items.title);
+			dijit.byId('submitactionbtn').setLabel(data.items.btntxt);
+			dojo.removeClass('submitactionbtnspan', 'hidden');
+			dijit.byId('actionmsg').set('content', data.items.msg);
+			dojo.byId('submitcont').value = data.items.cont;
+			dijit.byId('confirmactiondlg').show();
+		}
+		else if('promptuserfail' in data.items) {
+			dijit.byId('confirmactiondlg').set('title', data.items.title);
+			dojo.addClass('submitactionbtnspan', 'hidden');
+			dijit.byId('cancelactionbtn').setLabel('Close');
+			dijit.byId('actionmsg').set('content', data.items.msg);
+			dijit.byId('confirmactiondlg').show();
+		}
+		else if('multirefresh' in data.items) {
+			refreshcompdata(data.items.multirefresh);
+		}
+		else
+			setTimeout(function() {dijit.byId('addeditbtn').set('disabled', false);}, 250);
+	}
+}
+
+function cancelScheduledtovmhostinuse() {
+	var data = {continuation: dojo.byId('tohostcancelcont').value};
+	RPCwrapper(data, cancelScheduledtovmhostinuseCB, 1);
+}
+
+function cancelScheduledtovmhostinuseCB(data, ioArgs) {
+	if(data.items.status == 'success') {
+		dojo.byId('cancelvmhostinuseokdiv').innerHTML = data.items.msg;
+		dojo.addClass('cancelvmhostinusediv', 'hidden');
+		dojo.removeClass('cancelvmhostinuseokdiv', 'hidden');
+	}
+	else if(data.items.status == 'failed') {
+		dojo.byId('cancelvmhostinusediv').innerHTML = "An error was encountered that prevented the reservation to place this computer in the vmhostinuse state from being deleted.";
+	}
+}
+
+function confirmReload() {
+	var data = {continuation: dojo.byId('reloadcont').value,
+	            imageid: dijit.byId('reloadimageid').get('value')};
+	confirmAction(data);
+}
+
+function confirmDelete() {
+	var data = {continuation: dojo.byId('deletecont').value};
+	confirmAction(data);
+}
+
+function confirmStateChange() {
+	var data = {continuation: dojo.byId('statechangecont').value,
+	            stateid: dijit.byId('newstateid').get('value')};
+	confirmAction(data);
+}
+
+function confirmScheduleChange() {
+	var data = {continuation: dojo.byId('schedulecont').value,
+	            schid: dijit.byId('newscheduleid').get('value')};
+	confirmAction(data);
+}
+
+function confirmProvisioningChange() {
+	var data = {continuation: dojo.byId('provisioningchangecont').value,
+	            provisioningid: dijit.byId('newprovisioningid').get('value')};
+	confirmAction(data);
+}
+
+function generateDHCPdata(type) {
+	var data = {continuation: dojo.byId(type + 'dhcpcont').value,
+	            type: type};
+	if(dijit.byId('mnprivipaddr'))
+		data['mnip'] = dijit.byId('mnprivipaddr').get('value');
+	if(type == 'private') {
+		if(dojo.byId('preth0rdo').checked)
+			data['nic'] = 'eth0';
+		else
+			data['nic'] = 'eth1';
+	}
+	else {
+		if(dojo.byId('pueth0rdo').checked)
+			data['nic'] = 'eth0';
+		else
+			data['nic'] = 'eth1';
+	}
+	confirmAction(data);
+}
+
+function hostsData() {
+	var data = {continuation: dojo.byId('hostsdatacont').value};
+	confirmAction(data);
+}
+
+function confirmAction(data) {
+	dijit.popup.close(dijit.byId('actionmenu'));
+	var compids = [];
+	dojo.forEach(resource.selids, function(id) {
+		compids.push(id.replace('chkb', ''));
+	});
+	if(compids.length == 0) {
+		alert('No computers selected');
+		return;
+	}
+	data['compids[]'] = compids;
+	RPCwrapper(data, confirmActionCB, 1);
+}
+
+function confirmActionCB(data, ioArgs) {
+	if(data.items.status == 'error') {
+		dijit.byId('confirmactiondlg').set('title', 'Error');
+		dijit.byId('cancelactionbtn').setLabel('Close');
+		dojo.addClass('submitactionbtnspan', 'hidden');
+		dijit.byId('actionmsg').set('content', data.items.errormsg);
+		dijit.byId('confirmactiondlg').show();
+	}
+	else if(data.items.status == 'success') {
+		dijit.byId('confirmactiondlg').set('title', data.items.title);
+		dijit.byId('submitactionbtn').setLabel(data.items.btntxt);
+		dijit.byId('actionmsg').set('content', data.items.actionmsg);
+		//AJdojoCreate('actionmsg');
+		if('complist' in data.items)
+			dojo.byId('complist').innerHTML = data.items.complist;
+		dojo.byId('submitcont').value = data.items.cont;
+		if('disablesubmit' in data.items && data.items.disablesubmit == 1)
+			dijit.byId('submitactionbtn').set('disabled', true);
+		dijit.byId('confirmactiondlg').show();
+	}
+	else if(data.items.status == 'onestep') {
+		dijit.byId('confirmactiondlg').set('title', data.items.title);
+		dijit.byId('cancelactionbtn').setLabel('Close');
+		dojo.addClass('submitactionbtnspan', 'hidden');
+		dijit.byId('actionmsg').set('content', data.items.actionmsg);
+		//AJdojoCreate('actionmsg');
+		if('complist' in data.items)
+			dojo.byId('complist').innerHTML = data.items.complist;
+		dijit.byId('confirmactiondlg').show();
+	}
+}
+
+function cancelAction() {
+	dijit.byId('confirmactiondlg').hide();
+	dijit.byId('confirmactiondlg').set('title', '');
+	dijit.byId('actionmsg').set('content', '');
+	dojo.byId('complist').innerHTML = '';
+	dijit.byId('submitactionbtn').setLabel('Submit');
+	dijit.byId('submitactionbtn').set('disabled', false);
+	dojo.removeClass('submitactionbtnspan', 'hidden');
+	dijit.byId('cancelactionbtn').setLabel('Cancel');
+}
+
+function submitAction() {
+	var data = {continuation: dojo.byId('submitcont').value};
+	if(dijit.byId('utilnotes'))
+		data['notes'] = dijit.byId('utilnotes').get('value');
+	if(dijit.byId('profileid'))
+		data['profileid'] = dijit.byId('profileid').get('value');
+	if(dojo.byId('modedirect')) {
+		if(dojo.byId('modedirect').checked)
+			data['mode'] = 'direct';
+		else
+			data['mode'] = 'reload';
+	}
+	RPCwrapper(data, submitActionCB, 1);
+}
+
+function submitActionCB(data, ioArgs) {
+	if(data.items.status == 'error') {
+		dijit.byId('confirmactiondlg').set('title', 'Error');
+		dijit.byId('cancelactionbtn').setLabel('Close');
+		dojo.addClass('submitactionbtnspan', 'hidden');
+		dijit.byId('actionmsg').set('content', data.items.errormsg);
+		dojo.byId('complist').innerHTML = '';
+		dijit.byId('confirmactiondlg').show();
+		return;
+	}
+	if(('clearselection' in data.items && data.items.clearselection == 1) ||
+	   (dijit.byId('statecb').value != '' && data.items.newstate != dijit.byId('statecb').value))
+		resourcegrid.selection.clear();
+	if('refreshcount' in data.items && parseInt(data.items.refreshcount) > 0) {
+		var cnt = parseInt(data.items.refreshcount) - 1;
+		refreshcompdata(cnt);
+	}
+	dijit.byId('confirmactiondlg').set('title', data.items.title);
+	dijit.byId('cancelactionbtn').setLabel('Close');
+	dojo.addClass('submitactionbtnspan', 'hidden');
+	dijit.byId('actionmsg').set('content', data.items.msg);
+	dojo.byId('complist').innerHTML = '';
+	dojo.byId('submitcont').value = '';
+	recenterDijitDialog('confirmactiondlg');
+}
+
+function refreshcompdata(refreshcount) {
+	var url = resourcestore.url;
+	resourcestore.close();
+	resourcestore = new dojo.data.ItemFileWriteStore({url: url});
+	resourcestore.comparatorMap = {name: resource.nocasesort};
+	resourcestore.fetch();
+	savescroll = resourcegrid.scrollTop;
+	resourcegrid.setStore(resourcestore, resourcegrid.query);
+	if(refreshcount)
+		setTimeout(function() {refreshcompdata(--refreshcount);}, 5000);
+}
+
+function setScroll() {
+	if(savescroll != 0)
+		resourcegrid.scrollTo(savescroll);
+}
+
+function saveScroll(scrollobj) {
+	if(resourcegrid.scrollTop != 0)
+		savescroll = 0;
+}
+
+function delayedCompGroupFilterSelection() {
+	if(filterdelay)
+		clearTimeout(filterdelay);
+	filterdelay = setTimeout(compGroupFilterSelection, 1500);
+}
+
+function compGroupFilterSelection() {
+	var selected = new Array();
+	var selobj = dojo.byId('filtercompgroups');
+	for(var i = 0; i < selobj.options.length; i++) {
+		if(selobj.options[i].selected)
+			selected.push(selobj.options[i].value);
+	}
+	var data = {groupids: selected.join(','),
+	            continuation: dojo.byId('filtercompgroupscont').value};
+	RPCwrapper(data, compGroupFilterSelectionCB, 1);
+}
+
+function compGroupFilterSelectionCB(data, ioArgs) {
+	if(data.items.status == 'error') {
+		alert(data.items.errormsg);
+		return;
+	}
+	var query = resourcegrid.query;
+	query['id'] = new RegExp(data.items.regids);
+
+	resourcegrid.setQuery(query);
+}

Added: vcl/trunk/web/js/resources/config.js
URL: http://svn.apache.org/viewvc/vcl/trunk/web/js/resources/config.js?rev=1624325&view=auto
==============================================================================
--- vcl/trunk/web/js/resources/config.js (added)
+++ vcl/trunk/web/js/resources/config.js Thu Sep 11 16:01:48 2014
@@ -0,0 +1,792 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+var cfgvartimeout = null;
+var nocfgvarupdates = 1;
+var newcfgvarid = 15000001;
+var newsubimageid = 15000001;
+
+function addNewResource(title) {
+	dijit.byId('addeditdlg').set('title', title);
+	dijit.byId('addeditbtn').set('label', title);
+	dojo.removeClass('configvariables', 'hidden');
+	dojo.addClass('editcfgvardiv', 'hidden');
+	dojo.byId('editresid').value = 0;
+	configSetType();
+	dijit.byId('type').set('disabled', false);
+	dijit.byId('name').reset();
+	dijit.byId('owner').reset();
+	dijit.byId('optionalchk').reset();
+	dijit.byId('subimageid').reset();
+	var newdata = {
+		identifier: 'id',
+		label: 'name',
+		items: []
+	}
+	var newstore = new dojo.data.ItemFileWriteStore({data: newdata});
+	newstore.comparatorMap = {'name': caselessSort};
+	subimagegrid.setStore(newstore);
+	dijit.byId('vlanid').reset();
+	resetCfgVarFields();
+	dojo.byId('data').value = '';
+	dojo.byId('addeditdlgerrmsg').innerHTML = '';
+	var vardata = {identifier: 'id', label: 'name', items: []};
+	newstore = new dojo.data.ItemFileWriteStore({data: vardata});
+	var oldstore = configvariablegrid.store;
+	configvariablegrid.setStore(newstore);
+	delete oldstore;
+	dijit.byId('addeditdlg').show();
+}
+
+function inlineEditResourceCB(data, ioArgs) {
+	if(data.items.status == 'success') {
+		dojo.byId('saveresourcecont').value = data.items.cont;
+		dijit.byId('addeditdlg').set('title', data.items.title);
+		dijit.byId('addeditbtn').set('label', 'Save Changes');
+		dojo.byId('editresid').value = data.items.resid;
+		dijit.byId('type').set('value', data.items.data.configtypeid);
+		dijit.byId('type').set('disabled', true);
+		configSetType();
+		dijit.byId('name').set('value', data.items.data.name);
+		dijit.byId('owner').set('value', data.items.data.owner);
+		var vars = data.items.data.variables;
+		if(data.items.data.optional == 0)
+			dijit.byId('optionalchk').set('checked', false);
+		else
+			dijit.byId('optionalchk').set('checked', true);
+		if(data.items.data.configtype == 'Cluster') {
+			nocfgvarupdates = 1;
+			var vardata = {identifier: 'id', label: 'name', items: vars};
+			var newstore = new dojo.data.ItemFileWriteStore({data: vardata});
+			newstore.comparatorMap = {'name': caselessSort};
+			var oldstore = subimagegrid.store;
+			subimagegrid.setStore(newstore);
+			if(subimagegrid.selection.selectedIndex >= 0)
+				subimagegrid.selection.setSelected(subimagegrid.selection.selectedIndex, false);
+			subimagegrid.selection.lastindex = -1;
+			subimagegrid.setQuery({deleted: '0'});
+			setTimeout(function() {subimagegrid.update();}, 1);
+			delete oldstore;
+		}
+		else if(data.items.data.configtype == 'VLAN') {
+			nocfgvarupdates = 1;
+			dijit.byId('vlanid').set('value', data.items.data.data);
+		}
+		else {
+			nocfgvarupdates = 0;
+			dojo.byId('data').value = data.items.data.data;
+			resetCfgVarFields();
+			var vardata = {identifier: 'id', label: 'name', items: vars};
+			var newstore = new dojo.data.ItemFileWriteStore({data: vardata});
+			var oldstore = configvariablegrid.store;
+			configvariablegrid.setStore(newstore);
+			if(configvariablegrid.selection.selectedIndex >= 0)
+				configvariablegrid.selection.setSelected(configvariablegrid.selection.selectedIndex, false);
+			configvariablegrid.selection.lastindex = -1;
+			setTimeout(function() {configvariablegrid.update();}, 1);
+			delete oldstore;
+		}
+		dijit.byId('addeditdlg').show();
+	}
+	else if(data.items.status == 'noaccess') {
+		alert('Access denied to edit this item');
+	}
+}
+
+function saveResource() {
+	if(! updateConfigVariable())
+		return;
+	var submitbtn = dijit.byId('addeditbtn');
+	var errobj = dojo.byId('addeditdlgerrmsg');
+	if(! checkValidatedObj('name', errobj))
+		return;
+	/*if(! dijit.byId('owner')._hasBeenBlurred && dijit.byId('owner').get('value') == '') {
+		dijit.byId('owner')._hasBeenBlurred = true;
+		dijit.byId('owner').validate();
+		submitbtn.set('disabled', true);
+		setTimeout(function() {
+			saveResource();
+			submitbtn.set('disabled', false);
+		}, 1000);
+		return;
+	}*/
+	if(ownerchecking) {
+		submitbtn.set('disabled', true);
+		setTimeout(function() {
+			saveResource();
+			submitbtn.set('disabled', false);
+		}, 1000);
+		return;
+	}
+	if(! checkValidatedObj('owner', errobj))
+		return;
+	if(dojo.byId('editresid').value == 0)
+		var data = {continuation: dojo.byId('addresourcecont').value};
+	else
+		var data = {continuation: dojo.byId('saveresourcecont').value};
+	var type = dijit.byId('type').get('displayedValue');
+	if(! dojo.hasClass('configdatadiv', 'hidden')) {
+		if(dojo.byId('data').value == '') {
+			var typename = dojo.byId('datalabel').innerHTML;
+			errobj.innerHTML = typename + ' cannot be empty';
+			return;
+		}
+		data['data'] = dojo.byId('data').value;
+		data['configvariables'] = serializeConfigVars();
+	}
+	if(type == 'Cluster') {
+		data['subimages'] = serializeConfigSubimages();
+		if(data['subimages'] == '') {
+			errobj.innerHTML = 'No subimages assigned';
+			return;
+		}
+	}
+	else if(type == 'VLAN') {
+		if(! checkValidatedObj('vlanid', errobj))
+			return;
+		data['vlanid'] = dijit.byId('vlanid').get('value');
+	}
+	data['typeid'] = dijit.byId('type').get('value');
+	data['name'] = dijit.byId('name').get('value');
+	data['owner'] = dijit.byId('owner').get('value');
+	if(dijit.byId('optionalchk').checked)
+		data['optional'] = 1;
+	else
+		data['optional'] = 0;
+	submitbtn.set('disabled', true);
+	RPCwrapper(data, saveResourceCB, 1);
+}
+
+function saveResourceCB(data, ioArgs) {
+	if(data.items.status == 'error') {
+		if(data.items.msg == 'cannot be empty')
+			data.items.msg = dojo.byId('datalabel').innerHTML + ' cannot be empty';
+		dojo.byId('addeditdlgerrmsg').innerHTML = data.items.msg;
+		dijit.byId('addeditbtn').set('disabled', false);
+		return;
+	}
+	else if(data.items.status == 'success') {
+		if(data.items.action == 'add') {
+			resourcegrid.store.newItem(data.items.item);
+			resourcegrid.sort();
+		}
+		else {
+			resourcegrid.store.fetch({
+				query: {id: data.items.data.id},
+				onItem: function(item) {
+					resourcegrid.store.setValue(item, 'name', data.items.data.name);
+					resourcegrid.store.setValue(item, 'owner', data.items.data.owner);
+					resourcegrid.store.setValue(item, 'data', data.items.data.data);
+					resourcegrid.store.setValue(item, 'optional', data.items.data.optional);
+				},
+				onComplete: function(items, result) {
+					// when call resourcegrid.sort directly, the table contents disappear; not sure why
+					setTimeout(function() {resourcegrid.sort();}, 10);
+				}
+			});
+		}
+		dijit.byId('type').reset();
+		dijit.byId('name').reset();
+		dijit.byId('owner').reset();
+		dijit.byId('optionalchk').reset();
+		dijit.byId('subimageid').reset();
+		dijit.byId('vlanid').reset();
+		dojo.byId('data').value = '';
+		dojo.byId('addeditdlgerrmsg').innerHTML = '';
+		dijit.byId('addeditdlg').hide();
+		setTimeout(function() {dijit.byId('addeditbtn').set('disabled', false);}, 250);
+	}
+}
+
+// --------------------------------------
+
+function resetCfgVarFields() {
+	dojo.byId('varid').value = '';
+	dijit.byId('varname').reset();
+	dijit.byId('varidentifier').reset();
+	dijit.byId('cfgvartype').reset();
+	setCfgVarType(1);
+	resetCfgVarTypeValues();
+	dijit.byId('varrequired').reset();
+	dijit.byId('varask').reset();
+	dojo.addClass('editcfgvardiv', 'hidden');
+}
+
+function resetCfgVarTypeValues() {
+	var options = dijit.byId('cfgvartype').options;
+	for(var i = 0; i < options.length; i++)
+		dijit.byId('vartype' + options[i].label).reset();
+}
+
+function setCfgVarType(noupdate) {
+	if(typeof noupdate === 'undefined')
+		noupdate = 0;
+	var type = dijit.byId('cfgvartype').get('displayedValue');
+	var options = dijit.byId('cfgvartype').options;
+	for(var i = 0; i < options.length; i++) {
+		var t = options[i].label;
+		dojo.addClass('vartype' + t + 'span', 'hidden');
+	}
+	dojo.removeClass('vartype' + type + 'span', 'hidden');
+	if(noupdate)
+		return;
+	updateConfigVariable();
+}
+
+function configVarAllowSelection(row) {
+	if(row == configvariablegrid.selection.lastindex)
+		return true;
+	if(! updateConfigVariable()) {
+		setTimeout(function() {
+			configvariablegrid.selection.setSelected(configvariablegrid.selection.lastindex, true);
+		}, 1);
+		return false;
+	}
+}
+
+function configVarSelected(row) {
+	if(! updateConfigVariable())
+		return;
+	dojo.removeClass('editcfgvardiv', 'hidden');
+	var item = configvariablegrid.getItem(row);
+	if(! item)
+		return;
+	nocfgvarupdates = 1;
+	if(item.deleted == 1) {
+		dojo.addClass('editcfgvardiv', 'hidden');
+		dojo.removeClass('undeletecfgvardiv', 'hidden');
+	}
+	else {
+		dojo.addClass('undeletecfgvardiv', 'hidden');
+		dojo.removeClass('editcfgvardiv', 'hidden');
+	}
+	dijit.byId('deletecfgvarbtn').set('disabled', false);
+	dojo.byId('varid').value = item.id;
+	dijit.byId('varname').set('value', item.name);
+	dijit.byId('varidentifier').set('value', item.identifier);
+	resetCfgVarTypeValues();
+	dijit.byId('cfgvartype').set('value', parseInt(item.datatypeid));
+	var type = dijit.byId('cfgvartype').get('displayedValue');
+	if(type == 'text')
+		dijit.byId('vartypetext').set('value', new String(item.defaultvalue));
+	else
+		dijit.byId('vartype' + type).set('value', item.defaultvalue);
+	setCfgVarType();
+	if(item.required == 1)
+		dijit.byId('varrequired').set('checked', true);
+	else
+		dijit.byId('varrequired').set('checked', false);
+	if(item.ask == 1)
+		dijit.byId('varask').set('checked', true);
+	else
+		dijit.byId('varask').set('checked', false);
+	configvariablegrid.selection.lastindex = row;
+	nocfgvarupdates = 0;
+}
+
+function addCfgSubimage() {
+	var min = new dijit.form.NumberSpinner({
+		value: 1,
+		smallDelta: 1,
+		constraints: {min: 1, max: 5000, places: 0},
+		style: 'width: 40px'
+	});
+	var item = {id: newsubimageid,
+	            imageid: dijit.byId('subimageid').get('value'),
+	            name: dijit.byId('subimageid').get('displayedValue'),
+	            min: 1,
+	            max: 1,
+	            deleted: '0'};
+	subimagegrid.store.newItem(item);
+	subimagegrid.sort();
+	setTimeout(function() {
+		if(subimagegrid.selection.selectedIndex >= 0)
+			subimagegrid.selection.setSelected(subimagegrid.selection.selectedIndex, false);
+		// TODO fix problem of another row being highlighted due to being the focused row
+		for(var i = 0, last = subimagegrid.rowCount; i < last; i++) {
+			if((subimagegrid.getItem(i)) && subimagegrid.getItem(i).id == newsubimageid) {
+				subimagegrid.selection.setSelected(i, true);
+				break;
+			}
+		}
+		newsubimageid++;
+		subimagegrid.scrollToRow(subimagegrid.selection.selectedIndex);
+		subimagegrid.update();
+	}, 1);
+}
+
+function removeSubimages() {
+	var items = subimagegrid.selection.getSelected();
+	for(var i = 0; i < items.length; i++) {
+		subimagegrid.store.fetch({
+			query: {id: items[i].id[0]},
+			onItem: function(item) {
+				subimagegrid.store.setValue(item, 'deleted', '1');
+			}
+		});
+	}
+	subimagegrid.selection.clear();
+	subimagegrid.sort();
+}
+
+function addNewConfigVar() {
+	if(! updateConfigVariable()) {
+		return;
+	}
+	var item = {id: newcfgvarid,
+	            name: 'new variable',
+	            identifier: '',
+	            datatypeid: '1',
+	            defaultvalue: 0,
+	            required: 0,
+	            ask: 1,
+	            deleted: 0,
+	            configid: dojo.byId('editresid').value};
+	configvariablegrid.store.newItem(item);
+	configvariablegrid.sort();
+	setTimeout(function() {
+		if(configvariablegrid.selection.selectedIndex >= 0)
+			configvariablegrid.selection.setSelected(configvariablegrid.selection.selectedIndex, false);
+		// TODO fix problem of another row being highlighted due to being the focused row
+		for(var i = 0, last = configvariablegrid.rowCount; i < last; i++) {
+			if((configvariablegrid.getItem(i)) && configvariablegrid.getItem(i).id == newcfgvarid) {
+				configvariablegrid.selection.setSelected(i, true);
+				break;
+			}
+		}
+		newcfgvarid++;
+		configvariablegrid.scrollToRow(configvariablegrid.selection.selectedIndex);
+		configvariablegrid.update();
+	}, 1);
+}
+
+function updateConfigVariable() {
+	if(nocfgvarupdates)
+		return 1;
+	if(dojo.hasClass('editcfgvardiv', 'hidden'))
+		return 1;
+	var varid = dojo.byId('varid').value;
+	if(varid == '')
+		return 1;
+	if(! checkValidatedObj('varname', null))
+		return 0;
+	if(! checkValidatedObj('varidentifier', null))
+		return 0;
+	var name = dijit.byId('varname').get('value');
+	var identifier = dijit.byId('varidentifier').get('value');
+	var type = dijit.byId('cfgvartype').get('displayedValue');
+	var typeid = dijit.byId('cfgvartype').get('value');
+	if(type == 'bool') {
+		var defaultvalue = dijit.byId('vartypebool').get('value');
+	}
+	else if(type == 'text') {
+		var defaultvalue = dijit.byId('vartypetext').get('value');
+	}
+	else {
+		if(! checkValidatedObj('vartype' + type, null))
+			return 0;
+		var defaultvalue = dijit.byId('vartype' + type).get('value');
+	}
+	if(dijit.byId('varrequired').get('checked'))
+		var required = 1;
+	else
+		var required = 0;
+	if(dijit.byId('varask').get('checked'))
+		var ask = 1;
+	else
+		var ask = 0;
+	configvariablegrid.store.fetch({
+		query: {id: varid},
+		onItem: function(item) {
+			var store = configvariablegrid.store;
+			store.setValue(item, 'name', name);
+			store.setValue(item, 'identifier', identifier);
+			store.setValue(item, 'datatypeid', typeid);
+			store.setValue(item, 'defaultvalue', defaultvalue);
+			store.setValue(item, 'required', required);
+			store.setValue(item, 'ask', ask);
+		}
+	});
+	return 1;
+}
+
+function delayedUpdateConfigVariable() {
+	clearTimeout(cfgvartimeout);
+	cfgvartimeout = setTimeout(updateConfigVariable, 1000);
+}
+
+function deleteConfigVariable() {
+	if(dojo.byId('varid').value == '')
+		return;
+	dojo.addClass('editcfgvardiv', 'hidden');
+	dojo.removeClass('undeletecfgvardiv', 'hidden');
+	configvariablegrid.store.fetch({
+		query: {id: dojo.byId('varid').value},
+		onItem: function(item) {
+			var store = configvariablegrid.store;
+			store.setValue(item, 'deleted', 1);
+		}
+	});
+}
+
+function undeleteConfigVariable() {
+	if(dojo.byId('varid').value == '')
+		return;
+	var node = configvariablegrid.views.views[0].getCellNode(configvariablegrid.selection.selectedIndex, 0);
+	dojo.removeClass(node, 'strikethrough');
+	dojo.addClass('undeletecfgvardiv', 'hidden');
+	dojo.removeClass('editcfgvardiv', 'hidden');
+	configvariablegrid.store.fetch({
+		query: {id: dojo.byId('varid').value},
+		onItem: function(item) {
+			var store = configvariablegrid.store;
+			store.setValue(item, 'deleted', 0);
+		}
+	});
+}
+
+function configVarListStyle(row) {
+	var item = configvariablegrid.getItem(row.index);
+	if(item) {
+		var deleted = configvariablegrid.store.getValue(item, 'deleted');
+		if(deleted == 1)
+			row.customClasses += ' strikethrough';
+	}
+	configvariablegrid.focus.styleRow(row);
+	configvariablegrid.edit.styleRow(row);
+}
+
+function addStrikethrough() {
+	var node = configvariablegrid.views.views[0].getCellNode(configvariablegrid.selection.selectedIndex, 0);
+	dojo.addClass(node, 'strikethrough');
+}
+
+function serializeConfigVars() {
+	var cfgvars = [];
+	var tmp = configvariablegrid.store._getItemsArray();
+	for(var i = 0; i < tmp.length; i++) {
+		if(tmp[i]['deleted'] == 1 && tmp[i]['id'] > 15000000)
+			continue;
+		var myvar = '';
+		myvar  = '"' + tmp[i]['id'];
+		myvar += '":{"id":"' + tmp[i]['id'];
+		myvar += '","name":"' + tmp[i]['name'];
+		myvar += '","identifier":"' + tmp[i]['identifier'];
+		myvar += '","datatypeid":"' + tmp[i]['datatypeid'];
+		var datatype = getCfgVarType(tmp[i]['datatypeid']);
+		if(datatype == 'text')
+			myvar += '","defaultvalue":"' + tmp[i]['defaultvalue'][0].replace(/\n/g, '\\n');
+		else
+			myvar += '","defaultvalue":"' + tmp[i]['defaultvalue'];
+		myvar += '","required":"' + tmp[i]['required'];
+		myvar += '","ask":"' + tmp[i]['ask'];
+		myvar += '","deleted":"' + tmp[i]['deleted'];
+		myvar += '"}';
+		cfgvars.push(myvar);
+	}
+	var all = cfgvars.join(',');
+	return '{"items":{' + all + '}}';
+}
+
+function serializeConfigSubimages() {
+	var subimages = [];
+	var tmp = subimagegrid.store._getItemsArray();
+	if(tmp.length == 0)
+		return '';
+	for(var i = 0; i < tmp.length; i++) {
+		if(tmp[i]['deleted'] == 1 && tmp[i]['id'] > 15000000)
+			continue;
+		var myvar = '';
+		myvar  = '"' + tmp[i]['id'];
+		myvar += '":{"id":"' + tmp[i]['id'];
+		myvar += '","imageid":"' + tmp[i]['imageid'];
+		myvar += '","min":"' + tmp[i]['min'];
+		myvar += '","max":"' + tmp[i]['max'];
+		myvar += '","deleted":"' + tmp[i]['deleted'];
+		myvar += '"}';
+		subimages.push(myvar);
+	}
+	var all = subimages.join(',');
+	return '{"items":{' + all + '}}';
+}
+
+function getCfgVarType(id) {
+	var options = dijit.byId('cfgvartype').options;
+	for(var i = 0; i < options.length; i++) {
+		if(options[i].value == id)
+			return options[i].label;
+	}
+}
+
+function configSetType() {
+	var type = dijit.byId('type').get('displayedValue');
+	dojo.removeClass('configdatadiv', 'hidden');
+	dojo.removeClass('configvariables', 'hidden');
+	dojo.addClass('subimageextradiv', 'hidden');
+	dojo.addClass('vlanextradiv', 'hidden');
+	dojo.byId('datalabel').innerHTML = type;
+	if(type == 'Cluster') { // TODO - might need to be updated
+		dojo.addClass('configdatadiv', 'hidden');
+		dojo.addClass('configvariables', 'hidden');
+		dojo.removeClass('subimageextradiv', 'hidden');
+		dojo.addClass('vlanextradiv', 'hidden');
+	}
+	else if(type == 'VLAN') {
+		dojo.addClass('configdatadiv', 'hidden');
+		dojo.addClass('configvariables', 'hidden');
+		dojo.addClass('subimageextradiv', 'hidden');
+		dojo.removeClass('vlanextradiv', 'hidden');
+	}
+	recenterDijitDialog('addeditdlg');
+}
+
+function fmtConfigMapDeleteBtn(configmapid, rowIndex) {
+	var btn = new dijit.form.Button({
+		label: 'Delete',
+		onClick: function() {
+			deleteConfigMapping(configmapid);
+		}
+	});
+	btn._destroyOnRemove = true;
+	return btn;
+}
+
+function fmtConfigMapEditBtn(configmapid, rowIndex) {
+	var btn = new dijit.form.Button({
+		label: 'Edit',
+		onClick: function() {
+			editConfigMapping(configmapid);
+		}
+	});
+	btn._destroyOnRemove = true;
+	return btn;
+}
+
+function deleteConfigMapping(configmapid) {
+	var data = {configmapid: configmapid,
+	            continuation: dojo.byId('deletecfgmapcont').value};
+	RPCwrapper(data, deleteConfigMappingCB, 1);
+}
+
+function deleteConfigMappingCB(data, ioArgs) {
+	// TODO handle errors
+	if(data.items.status == 'success') {
+		dojo.byId('delcfgmapdlgcontent').innerHTML = data.items.html;
+		dojo.byId('submitdeletecfgmapcont').value = data.items.cont;
+		dijit.byId('delcfgmapdlg').show();
+	}
+	else if(data.items.status == 'notfound') {
+		alert("Error occurred: Config mapping not found");
+	}
+}
+
+function submitDeleteConfigMapping() {
+	var data = {continuation: dojo.byId('submitdeletecfgmapcont').value};
+	RPCwrapper(data, submitDeleteConfigMappingCB, 1);
+}
+
+function submitDeleteConfigMappingCB(data, ioArgs) {
+	// TODO handle errors
+	if(data.items.status == 'success') {
+		dijit.byId('delcfgmapdlg').hide();
+		dojo.byId('delcfgmapdlgcontent').innerHTML = '';
+		dojo.byId('submitdeletecfgmapcont').value = '';
+		configmapgrid.store.fetch({
+			query: {id: data.items.configmapid},
+			onItem: function(item) {
+				configmapgrid.store.deleteItem(item);
+			}
+		});
+	}
+}
+
+function editConfigMapping(configmapid) {
+	dojo.byId('editcfgmapid').value = configmapid;
+	var data = {configmapid: configmapid,
+	            continuation: dojo.byId('editcfgmapcont').value};
+	RPCwrapper(data, editConfigMappingCB, 1);
+}
+
+function editConfigMappingCB(data, ioArgs) {
+	dojo.byId('savecfgmapcont').value = data.items.cont;
+	dijit.byId('addeditcfgmapdlg').set('title', 'Edit Config Mapping');
+	dijit.byId('addeditcfgmapbtn').set('label', 'Save Changes');
+	dijit.byId('config')._lastValueReported = data.items.data.configid;
+	dijit.byId('config').set('value', data.items.data.configid, false);
+	if(data.items.data.configtype == 'Cluster')
+		dijit.byId('maptype').setStore(maptypestore, '', {query: {clusterok: '1'}});
+	else
+		dijit.byId('maptype').setStore(maptypestore, '', {query: {id: '*'}});
+	dijit.byId('maptype').set('value', data.items.data.configmaptypeid);
+	dijit.byId('affil').set('value', data.items.data.affiliationid);
+	dijit.byId('stage').set('value', data.items.data.stageid);
+	if(data.items.data.prettyconfigmaptype == 'Image')
+		dijit.byId('image').set('value', data.items.data.subid);
+	else if(data.items.data.prettyconfigmaptype == 'OS Type')
+		dijit.byId('ostype').set('value', data.items.data.subid);
+	else if(data.items.data.prettyconfigmaptype == 'OS')
+		dijit.byId('os').set('value', data.items.data.subid);
+	else if(data.items.data.prettyconfigmaptype == 'Config')
+		dijit.byId('mapconfig').set('value', data.items.data.subid);
+	else if(data.items.data.prettyconfigmaptype == 'Subimage')
+		dijit.byId('configsubimage').set('value', data.items.data.subid);
+	else if(data.items.data.prettyconfigmaptype == 'Management Node')
+		dijit.byId('managementnode').set('value', data.items.data.subid);
+	editConfigMapSetMapType();
+	dijit.byId('addeditcfgmapdlg').show();
+}
+
+function configMapSetConfig() {
+	var id = dijit.byId('config').get('value');
+	mapconfigliststore.fetch({
+		query: {id: id},
+		onItem: function(item) {
+			if(item.stage[0] === null)
+				dojo.removeClass('stagediv', 'hidden');
+			else
+				dojo.addClass('stagediv', 'hidden');
+			dojo.byId('mapconfigtype').innerHTML = item.configtype;
+			var queryobj = dijit.byId('maptype').params.query;
+			if(item.configtype == 'Cluster') {
+				//if(typeof queryobj.clusterid === 'undefined')
+					dijit.byId('maptype').setStore(maptypestore, '', {query: {clusterok: '1'}});
+			}
+			else {
+				//if(typeof queryobj.id === 'undefined')
+					dijit.byId('maptype').setStore(maptypestore, '', {query: {id: '*'}});
+			}
+		}
+	});
+}
+
+function editConfigMapSetMapType() {
+	var maptype = dijit.byId('maptype').get('displayedValue');
+	dojo.addClass('imagetypediv', 'hidden');
+	dojo.addClass('ostypediv', 'hidden');
+	dojo.addClass('osdiv', 'hidden');
+	dojo.addClass('configdiv', 'hidden');
+	dojo.addClass('configsubimagediv', 'hidden');
+	dojo.addClass('managementnodediv', 'hidden');
+	if(maptype == 'Image')
+		dojo.removeClass('imagetypediv', 'hidden');
+	else if(maptype == 'OS Type')
+		dojo.removeClass('ostypediv', 'hidden');
+	else if(maptype == 'OS')
+		dojo.removeClass('osdiv', 'hidden');
+	else if(maptype == 'Config')
+		dojo.removeClass('configdiv', 'hidden');
+	else if(maptype == 'Subimage')
+		dojo.removeClass('configsubimagediv', 'hidden');
+	else if(maptype == 'Management Node')
+		dojo.removeClass('managementnodediv', 'hidden');
+}
+
+function addConfigMapping() {
+	dojo.byId('editcfgmapid').value = 0;
+	dijit.byId('addeditcfgmapdlg').set('title', 'Add Config Mapping');
+	dijit.byId('addeditcfgmapbtn').set('label', 'Add Config Mapping');
+	resetConfigMappingFields();
+	editConfigMapSetMapType();
+	dijit.byId('addeditcfgmapdlg').show();
+}
+
+function saveConfigMapping() {
+	var errobj = dojo.byId('addeditcfgmapdlgerrmsg');
+	if(! checkValidatedObj('config', errobj))
+		return;
+	var maptype = dijit.byId('maptype').get('displayedValue');
+	if((maptype == 'Image' && ! checkValidatedObj('image', errobj)) ||
+	   (maptype == 'OS Type' && ! checkValidatedObj('ostype', errobj)) ||
+	   (maptype == 'OS' && ! checkValidatedObj('os', errobj)) ||
+	   (maptype == 'Config' && ! checkValidatedObj('mapconfig', errobj)) ||
+	   (maptype == 'Subimage' && ! checkValidatedObj('configsubimage', errobj)) ||
+	   (maptype == 'Management Node' && ! checkValidatedObj('managementnode', errobj)))
+		return;
+	if(! checkValidatedObj('affil', errobj) ||
+	   ! checkValidatedObj('stage', errobj))
+		return;
+
+	var data = {configmapid: dojo.byId('editcfgmapid').value,
+	            configid: dijit.byId('config').get('value'),
+	            maptypeid: dijit.byId('maptype').get('value'),
+	            affiliationid: dijit.byId('affil').get('value'),
+	            stageid: dijit.byId('stage').get('value')};
+	if(dijit.byId('addeditcfgmapbtn').get('label') == 'Add Config Mapping')
+		data.continuation = dojo.byId('addcfgmapcont').value;
+	else
+		data.continuation = dojo.byId('savecfgmapcont').value;
+	if(maptype == 'Image')
+		data.subid = dijit.byId('image').get('value');
+	else if(maptype == 'OS Type')
+		data.subid = dijit.byId('ostype').get('value');
+	else if(maptype == 'OS')
+		data.subid = dijit.byId('os').get('value');
+	else if(maptype == 'Config')
+		data.subid = dijit.byId('mapconfig').get('value');
+	else if(maptype == 'Subimage')
+		data.subid = dijit.byId('configsubimage').get('value');
+	else if(maptype == 'Management Node')
+		data.subid = dijit.byId('managementnode').get('value');
+	dijit.byId('addeditcfgmapbtn').set('disabled', true);
+	RPCwrapper(data, saveConfigMappingCB, 1);
+}
+
+function saveConfigMappingCB(data, ioArgs) {
+	if(data.items.status == 'error') {
+		dojo.byId('addeditcfgmapdlgerrmsg').innerHTML = data.items.msg;
+		dijit.byId('addeditcfgmapbtn').set('disabled', false);
+	}
+	else if(data.items.status == 'success') {
+		if(data.items.action == 'add') {
+			configmapgrid.store.newItem(data.items.item);
+			configmapgrid.sort();
+		}
+		else {
+			configmapgrid.store.fetch({
+				query: {id: data.items.data.id},
+				onItem: function(item) {
+					for(var key in data.items.data) {
+						if(key == 'id')
+							continue;
+						configmapgrid.store.setValue(item, key, data.items.data[key]);
+					}
+				},
+				onComplete: function(items, result) {
+					// when call resourcegrid.sort directly, the table contents disappear; not sure why
+					setTimeout(function() {configmapgrid.sort();}, 10);
+				}
+			});
+		}
+		dijit.byId('addeditcfgmapdlg').hide();
+		resetConfigMappingFields();
+		setTimeout(function() {dijit.byId('addeditcfgmapbtn').set('disabled', false)}, 250);
+	}
+}
+
+function resetConfigMappingFields() {
+	dijit.byId('config').reset();
+	dijit.byId('maptype').reset();
+	dijit.byId('image').reset();
+	dijit.byId('ostype').reset();
+	dijit.byId('os').reset();
+	dijit.byId('mapconfig').reset();
+	dijit.byId('configsubimage').reset();
+	dijit.byId('managementnode').reset();
+	dijit.byId('affil').reset();
+	dijit.byId('stage').reset();
+	dojo.byId('addeditcfgmapdlgerrmsg').innerHTML = '';
+}