- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-23-2022 02:28 PM
Hi Community,
I am very new to this. I am trying to create a widget. This is the basic structure.
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!
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() {
}
};
Solved! Go to Solution.
- Labels:
-
Service Portal Development
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-24-2022 10:12 AM
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 🙂
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-23-2022 02:47 PM
You should wire the view (HTML) to the mode using ng-model: make both the select synchronize itself with a property of the scope using ngModel directive. Make the table create its rows from another property of the scope using the ngRepeat directive. Once that is done, when someone clicks the button all you have to do is transfer data from the 1st property into the 2nd one.
But I have a question to you: let's assume someone would like to help you by modifying your code and adding the missing pieces. What should that person do: retype the whole thing (as opposed to copying it from your posting)? Wouldn't posting code in place of pictures be better?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-23-2022 03:38 PM
Hi,
Thanks a lot for your quick response. I'm very new to Angular, I'll look into using ngModel as you mentioned.
And yeah posting code does make sense! My bad. I've added the snippets now.
Could you help me out with the client script?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-24-2022 10:12 AM
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 🙂
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-25-2022 05:14 AM
Hi János,
This is working and your code makes a lot of sense to me even when im not that familiar with Angular!
I understand that data.host_arr ideally would populate from server script. However for my use case, Im planning to populate it from an API call on load of the widget.
Again,
Thanks a lot this was very helpful!