Content Selector Configuration Editor, Part V

“It takes considerable knowledge just to realize the extent of your own ignorance.”
Thomas Sowell

At the end of our last installment in this series, we had the HTML for the Tables section, but none of the underlying code to make it all work. Now it’s time to create that code by building all of the client-side functions needed to support all of the ng-click attributes sprinkled throughout the HTML. The first one that you come to in this section is the editButton function that passes the button object as an argument. This should pop open a modal editor just like we did with the Perspectives and the States, so this function could be loosely modeled after those other two. Something like this should do the trick:

$scope.editButton = function(button, btnArray) {
	var shared = {};
	if (button != 'new') {
		shared.label = button.label;
		shared.name = button.name;
		shared.heading = button.heading;
		shared.icon = button.icon;
		shared.color = button.color;
		shared.hint = button.hint;
	}
	spModal.open({
		title: 'Button/Icon Editor',
		widget: 'button-icon-editor',
		shared: shared
	}).then(function() {
		if (button == 'new') {
			button = {};
			btnArray.push(button);
		}
		button.label = shared.label;
		button.name = shared.name;
		button.heading = shared.heading;
		button.icon = shared.icon;
		button.color = shared.color;
		button.hint = shared.hint;
	});
};

We had to add a second argument to the function in this case, but only when creating a new Button/Icon. For an existing object, it is already in place in the object tree, but in the case of a new Button/Icon that we create from a new blank object, we need to know where to put it so that it lives with all of its siblings. Other than that one little wrinkle, the rest is pretty much the same as we have built before. The deleteButton function is also a little different in that we do not have a specified index, so we have to spin through the list to determine the index. Once we have that, though, all we need to do is remove the Button/Icon from the list, as there are no other dependent objects that have to be removed, unlike the Perspectives and the States.

$scope.deleteButton = function(button, btnArray) {
	var confirmMsg = '<b>Delete Button/Icon</b>';
	confirmMsg += '<br/>Are you sure you want to delete the ' + button.label + ' Button/Icon?';
	spModal.confirm(confirmMsg).then(function(confirmed) {
		if (confirmed) {
			var a = -1;
			for (var b=0; b<btnArray.length; b++) {
				if (btnArray[b].name == button.name) {
					a = b;
				}
			}
			btnArray.splice(a, 1);
		}
	});
};

That takes care of the Buttons/Icons … now we have to do essentially the same thing for the Reference Pages. Once again, we have a few little wrinkles that make things not quite exactly the same. For one thing, the Button/Icon data is stored in an Array, but the Reference Page data is stored in a Map. Also, both of the properties for a Reference Page (Table and Portal Page) have values that come from a ServiceNow database table, so the pop-up editor can use an sn-record-picker for both fields. That means their values will be stored in objects, not strings, so again, not an exact copy of the other functions. Still, it looks pretty close to all of its cousins:

$scope.editRefMap = function(table, refMap) {
	var shared = {table: {}, page: {}};
	if (table != 'new') {
		shared.table.value = table;
		shared.table.displayValue = table;
		shared.page.value = refMap[table];
		shared.page.displayValue = refMap[table];
	}
	spModal.open({
		title: 'Reference Page Editor',
		widget: 'reference-page-editor',
		shared: shared
	}).then(function() {
		if (table != 'new') {
			if (shared.table.value != table) {
				delete refMap[table];
			}
		}
		refMap[shared.table.value] = shared.page.value;
	});
};

… and because of those differences, the deleteRefMap function turns out to be the most simplest of all:

$scope.deleteRefMap = function(table, refMap) {
		var confirmMsg = '<b>Delete Reference Page</b>';
		confirmMsg += '<br/>Are you sure you want to delete the ' + table + ' table reference page mapping?';
		spModal.confirm(confirmMsg).then(function(confirmed) {
			if (confirmed) {
				delete refMap[table];
			}
		});
	};

So now we are done with all of the client-side functions, but our work is still not finished. Both of the edit functions pop open modal editor widgets, so we are going to need to build those. We already have a couple of different models created for the Perspective and State editors, so it won’t be as if we have to start out with a blank canvas. Still, there is a certain amount of work involved, so that sounds like a good place to start out in our next installment.