Service Portal Widget: Client Side Script to add items from <select> to <table>

Mudit4
Kilo Expert

Hi Community,

I am very new to this. I am trying to create a widget. This is the basic structure.

find_real_file.png

Now,

When I click on Add Button, the hosts selected should be added to the table in a new row. I cant figure out the code. I neeeed help!

find_real_file.png

Also is there a way to populate the list of host options dynamically?

 

Adding Code Snippets here:

<style>
table, th, td {
  border:1px solid black;
}
</style>
<div class="panel panel-primary">
 <div class="panel-heading">Request OS Account</div>
 <div class="panel-body">
   <form>
     <label for="cname">Customer Name: </label>
     <input type="text" id="cname" name="justification"><br><br>
     <label for="servicetype">Service Type: </label>
     <input type="text" id="servicetype" name="servicetype"><br><br>
     <label for="envname">Environment name: </label>
     <input type="text" id="envname" name="envname"><br><br>
     <label for="hosts">List of Hosts </label>
     <select name="hosts" id="hosts" multiple>
  			<option value="host1">host1</option>
  			<option value="host2">host2</option>
  			<option value="host3">host3</option>
  			<option value="host4">host4</option>
		 </select>
     <button type="button" ng-click="c.addStuff()">Add</button><br><br>
     <table style="width:100%">
       <tr>
         <th>Name</th>
         <th>col2</th>
         <th>col3</th>
       </tr>
       <tr id="select">
         
       </tr>
     </table>
     <br><br>
     <input type="submit" value="Submit" ng-click="c.submitForm()">
   </form> 
  </div>
</div>

Client Side-

api.controller = function($http) {
    /* widget controller */
    var c = this;

    c.addStuff = function() {
    
    }
};
1 ACCEPTED SOLUTION

Here's how one could do it:

- controller:

api.controller = function ($scope, $http) {
	var c = this;

	c.data.host_arr = [
		{
			'id': 1,
			'value': 'host_1',
			'label': 'Host 1',
			'col2': '1 asdfasdfasdf',
			'col3': '1 asdfasdfasdf'
		},
		{
			'id': 2,
			'value': 'host_2',
			'label': 'Host 2',
			'col2': '2 asfdasdfasdf',
			'col3': '2 asdfasdfasdf'
		},
		{
			'id': 3,
			'value': 'host_3',
			'label': 'Host 3',
			'col2': '3 asdfasdf',
			'col3': '3 asdfasdfasdf'
		},
		{
			'id': 4,
			'value': 'host_4',
			'label': 'Host 4',
			'col2': '4 dfgsdf',
			'col3': '4 sdfgsdfg'
		}
	];

	$scope.row_arr = [];
	$scope.selectedHost_arr = [];

	c.addStuff = function addStuff () {
		return $scope.selectedHost_arr
			.filter(retainNotEmptyString)
			.map(convertIntoIndexIn(c.data.host_arr))
			.filter(retainValidIndex)
			.map(convertIntoHostFrom(c.data.host_arr))
			.map(insertAsRowInto($scope.row_arr));
	};

	function convertIntoIndexIn (host_arr) {
		return function convertIntoIndex (value) {
			return host_arr.findIndex(hasValue(value));
		};
	}

	function convertIntoHostFrom (host_arr) {
		return function convertIntoHost (index) {
			return host_arr[index];
		};
	}

	function hasValue (value) {
		return function has (host) {
			return host.value == value;
		};
	}

	function insertAsRowInto (row_arr) {
		return function insertAsRow (host) {
			row_arr.push({
				'id': row_arr.length,
				'name': host.label,
				'col2': host.col2,
				'col3': host.col3
			});
		};
	}

	function retainNotEmptyString (value) {
		return value != '';
	}

	function retainValidIndex (index) {
		return index != -1;
	}

};

- the Body HTML template:

<div class="panel panel-primary">
  <div class="panel-heading">Request OS Account</div>
  <div class="panel-body">
    <form>
      <label for="cname">Customer Name: </label>
      <input type="text" id="cname" name="justification"><br><br>
      <label for="servicetype">Service Type: </label>
      <input type="text" id="servicetype" name="servicetype"><br><br>
      <label for="envname">Environment name: </label>
      <input type="text" id="envname" name="envname"><br><br>
      <label for="hosts">List of Hosts </label>
      <select name="hosts" x-id="hosts" multiple ng-model="selectedHost_arr">
        <option ng-repeat="host in c.data.host_arr track by host.id" value="{{ host.value }}">{{ host.label }}</option>
      </select>
      <button type="button" ng-click="c.addStuff()">Add</button><br><br>
      <table style="width:100%">
        <tr>
          <th>Name</th>
          <th>col2</th>
          <th>col3</th>
        </tr>
        <tr ng-repeat="row in row_arr track by row.id">
          <td>{{ row.name }}</td>
          <td>{{ row.col2 }}</td>
          <td>{{ row.col3 }}</td>
        </tr>
      </table>
      <br><br>
      <button type="button" value="Submit" ng-click="c.submitForm()">Submit</button>
    </form> 
  </div>
</div>

Of course in a normal situation data.host_arr would be loaded in the Server script. The main things here are c.data.host_arr, $scope.row_arr and $scope.selectedHost_arr which hold the list of hosts to display, the list of rows created and the currently selected values in the select box.

The 1st one provides the list of hosts - this is newly introduced enhancement, the 2nd one is "generated"/filled when clicking the "Add" button and provides the data for the table rows and the last one is "the model" for values selected in the select box. Transferring the options to the select box is handled by AngularJS because of the ng-repeat directive on the sole "template" option element. Transferring the selected options from the select box to the scope property selectedHost_arr is handled by AngularJS because of the ng-model directive on the select element. Transferring the data from the row_arr scope property as table rows is again handled by AngularJs because of the ng-repeat directive applied to the sole tr element.

All in all you need to switch to an AngularJS (MVC) mindset and let the framework do the heave lifting everywhere possible - being that you are using it anyway.

And hope this all helps 🙂

View solution in original post

5 REPLIES 5

Indeed it is perfectly fine to fetch the data from the client side. Especially if it is not "static".

And you're most welcome and I am glad it helped 🙂