Skip to content

Commit 14e2f56

Browse files
authored
Location hierarchy (#1065)
* Location hierarchy widget Creates a simple location hierarchy picker to be used in the service catalog. Requires another variable to save chosen location into. Allows selection of multiple existing locations or creation of new at multiple levels. * Update and rename client controller.txt to client controller.js Updated formatting * Update and rename css.txt to css.css * Update and rename html.txt to html.html * Update and rename server script.txt to server script.js * Create README.md
1 parent 690dba9 commit 14e2f56

File tree

5 files changed

+181
-0
lines changed

5 files changed

+181
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
This widget allows you to hierarchically choose a location for the catalog item variable.
2+
3+
With small additional setup you can adjust it to your own structure. You also need a variable (preferably multi line text) to save the output of this widget.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
api.controller=function($scope, spModal) {
2+
var c = this;
3+
c.newLocations = [];
4+
5+
c.server.get({
6+
action: 'getChildren',
7+
type: 'city',
8+
parent: null
9+
}).then((res) => {
10+
c.locations = res.data.locations;
11+
$scope.locations = res.data.locations.selected;
12+
$scope.locations.room = '';
13+
});
14+
15+
c.changeCity = (newSysId) => {
16+
$scope.locations.city = c.locations.available.city.filter((city) => city.sys_id === newSysId)[0];
17+
$scope.locations['building/structure'] = c.locations.default['building/structure'];
18+
$scope.locations.floor = c.locations.default.floor;
19+
$scope.locations.zone = c.locations.default.zone;
20+
21+
c.getChildren('building/structure', newSysId);
22+
}
23+
24+
c.changeBuilding = (newSysId) => {
25+
$scope.locations['building/structure'] = c.locations.available['building/structure'].filter((building) => building.sys_id === newSysId)[0];
26+
$scope.locations.floor = c.locations.default.floor;
27+
$scope.locations.zone = c.locations.default.zone;
28+
29+
c.getChildren('floor', newSysId);
30+
}
31+
32+
c.changeFloor = (newSysId) => {
33+
$scope.locations.floor = c.locations.available.floor.filter((floor) => floor.sys_id === newSysId)[0];
34+
$scope.locations.zone = c.locations.default.zone;
35+
36+
c.getChildren('zone', newSysId);
37+
}
38+
39+
c.changeZone = (newSysId) => {
40+
$scope.locations.zone = c.locations.available.zone.filter((zone) => zone.sys_id === newSysId)[0];
41+
}
42+
43+
c.changeRoom = () => {
44+
//c.newLocations.push($scope.locations.zone.name + $scope.locations.room);
45+
}
46+
47+
c.addNewLocation = () => {
48+
c.newLocations.push('City: ' + $scope.locations.city.name + ', building: ' + $scope.locations['building/structure'].name + ', floor: ' + $scope.locations.floor.name + ', corridor: ' + $scope.locations.zone.name + ', room: * ' + $scope.locations.room);
49+
if ($scope.page.g_form) {
50+
$scope.page.g_form.setValue('locks_locations_new_locations_added', c.newLocations.join('\n'));
51+
}
52+
$scope.locations.room = '';
53+
}
54+
55+
c.notListedModal = (type) => {
56+
spModal.prompt('Please enter missing value for the ' + type)
57+
.then(value => {
58+
$scope.locations[type] = {name: '* ' + value, sys_id: '-2'};
59+
});
60+
}
61+
62+
c.getChildren = (type, parent) => {
63+
c.server.get({
64+
action: 'getChildren',
65+
type: type,
66+
parent: parent
67+
}).then((res) => {
68+
c.locations.available[type] = res.data.locations.available[type];
69+
});
70+
}
71+
72+
c.allSelected = () => {
73+
return $scope.locations &&
74+
$scope.locations.city.sys_id !== '-1' &&
75+
$scope.locations['building/structure'].sys_id !== '-1' &&
76+
$scope.locations.floor.sys_id !== '-1' &&
77+
$scope.locations.zone.sys_id !== '-1'
78+
}
79+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.location-picker-input {
2+
padding: 6px 12px;
3+
color: #555555;
4+
border: 1px solid #939393;
5+
border-radius: 4px;
6+
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
7+
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
8+
-webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
9+
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
10+
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<h3>
2+
Describe the new location
3+
</h3>
4+
<div class="form-group">
5+
<div class="btn-group" uib-dropdown>
6+
<button id="cityRef" type="button" class="btn btn-info" uib-dropdown-toggle>
7+
{{locations.city.name}}&nbsp;<span class="caret"></span>
8+
</button>
9+
<ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="cityRef">
10+
<li ng-repeat="city in c.locations.available.city" role="menuitem" ng-click="c.changeCity(city.sys_id)"><a href="#">{{city.name}}</a></li>
11+
<li class="divider"></li>
12+
<li role="menuitem" ng-click="c.notListedModal('city')"><a href="#">City not listed</a></li>
13+
</ul>
14+
</div>
15+
<div class="btn-group" uib-dropdown>
16+
<button id="buildingRef" type="button" class="btn btn-info" uib-dropdown-toggle ng-disabled="locations.city.sys_id === '-1'">
17+
{{locations['building/structure'].name}}&nbsp;<span class="caret"></span>
18+
</button>
19+
<ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="buildingRef">
20+
<li ng-repeat="building in c.locations.available['building/structure']" role="menuitem" ng-click="c.changeBuilding(building.sys_id)"><a href="#">{{building.name}}</a></li>
21+
<li class="divider"></li>
22+
<li role="menuitem" ng-click="c.notListedModal('building/structure')"><a href="#">Building not listed</a></li>
23+
</ul>
24+
</div>
25+
<div class="btn-group" uib-dropdown>
26+
<button id="floorRef" type="button" class="btn btn-info" uib-dropdown-toggle ng-disabled="locations['building/structure'].sys_id === '-1'">
27+
{{locations.floor.name}}&nbsp;<span class="caret"></span>
28+
</button>
29+
<ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="floorRef">
30+
<li ng-repeat="floor in c.locations.available.floor" role="menuitem" ng-click="c.changeFloor(floor.sys_id)"><a href="#">{{floor.name}}</a></li>
31+
<li class="divider"></li>
32+
<li role="menuitem" ng-click="c.notListedModal('floor')"><a href="#">Floor not listed</a></li>
33+
</ul>
34+
</div>
35+
<div class="btn-group" uib-dropdown>
36+
<button id="zoneRef" type="button" class="btn btn-info" uib-dropdown-toggle ng-disabled="locations.floor.sys_id === '-1'">
37+
{{locations.zone.name}}&nbsp;<span class="caret"></span>
38+
</button>
39+
<ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="zoneRef">
40+
<li ng-repeat="zone in c.locations.available.zone" role="menuitem" ng-click="c.changeZone(zone.sys_id)"><a href="#">{{zone.name}}</a></li>
41+
<li class="divider"></li>
42+
<li role="menuitem" ng-click="c.notListedModal('zone')"><a href="#">Corridor not listed</a></li>
43+
</ul>
44+
</div>
45+
<input id="roomRef" class="location-picker-input" type="text" placeholder="Room name" ng-disabled="!c.allSelected()" ng-model="locations.room" ng-blur="c.changeRoom()"/>
46+
<button type="button" class="btn btn-success" ng-click="c.addNewLocation()" ng-disabled="locations.room === ''">Add to the list</button>
47+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
(function() {
2+
data.locations = {
3+
available: {
4+
city: [],
5+
'building/structure': [],
6+
floor: [],
7+
zone: []
8+
},
9+
default: {
10+
city: {name: 'Pick a city', sys_id: '-1'},
11+
'building/structure': {name: 'Pick a building', sys_id: '-1'},
12+
floor: {name: 'Pick a floor', sys_id: '-1'},
13+
zone: {name: 'Pick a corridor', sys_id: '-1'}
14+
}
15+
};
16+
17+
data.locations.selected = data.locations.default;
18+
19+
if (input && input.action === 'getChildren' && input.type) {
20+
data.locations.available[input.type] = getData(input.type, input.parent);
21+
}
22+
23+
function getData(locationType, parent) {
24+
let ret = [];
25+
let gq = new global.GlideQuery('cmn_location').where('cmn_location_type', locationType);
26+
27+
if (!gs.nil(parent))
28+
gq = gq.where('parent', parent);
29+
30+
gq
31+
.orderBy('name')
32+
.select('name')
33+
.forEach(function(childLocation){
34+
ret.push({
35+
sys_id: childLocation.sys_id,
36+
name: childLocation.name
37+
});
38+
});
39+
return ret;
40+
}
41+
})();

0 commit comments

Comments
 (0)