Service portal - how to refresh webpage on ng-click

Woz
Tera Contributor

I have some code that displays a list of tasks a user needs to complete (A bit like the announcements widget)

 

How do I update data.hideCss from the HTML ng-Click and then make it so the change to css is seen by the user

 

user clicks button>controller updates server script - value now "" so no hide child elements css is now applied > Changes are now seen by user.

 

Does anyone have a simple example how how sending data form HTML> Controller > ServiceNow Script  and back works?

 

 

HTML

<div>
<ul class="{{::c.data.hideCss}} transparent list-group hide-x-overflow" >
<li ng-if="c.data.list.length > 0" ng-repeat="item in c.data.list track by item.sys_id" class="list-group-item">
<h2>Goto TASK</h2>
<a class="btn btn-default darkButtomStyle" ng-click="c.onClick()" href="javascript:void(0)" ><fa name="{{::c.options.glyph}}" /> Goto intranet to do task</a>
<button type="button" class="btn btn-default" ng-click="c.cancel()" href="javascript:void(0)" ><fa name="fas fa-times" /> Show All</button>
</li>
</ul>
</div>

CSS

 

.list-group-item {
background-color: $ubs-grey;
border: 0px solid red

}

.darkButtomStyle {
background-color: $dark-blue;
color:white;
}

.hide-css > li:not(:first-child) {
display: none;
}

 

 

client

 

function () {
var c = this;


this.onClick = function() {
window.open('http://www.cnn.com/', '_blank');
};

this.cancel = function() {
c.data.hideCss = "";
c.server.update()
}

 

Server Script

 

(function () {
/* populate the 'data' object */
/* e.g., data.table = $sp.getValue('table'); */

options.table = "" ||$sp.getParameter('t') || options.table;
var gr = new GlideRecordSecure('u_shouts'); // does ACL checking for us
data.isValid = true;
options.glyph = "fas fa-angle-double-right";

//this is what lids all but the first css item
// see css hide-css
data.hideCss = "hide-css";


// grTemp is used to check isValidField since using GlideRecordSecure fails for date/time fields
var grTemp = new GlideRecord(options.table);


options.display_field = gr.getDisplayName();
options.order_by = options.display_field;

gr.orderBy(options.order_by);
gr.query();

data.count = gr.getRowCount();
data.list = [];

var recordIdx = 0;

while (gr.next()) {

var record = {};
record.sys_id = gr.getValue('sys_id');
record.display_field = getField(gr, options.display_field);
record.url = options.url;

data.list.push(record);
recordIdx++;
}

function getField(gr, name) {
var f = {};
f.display_value = gr.getDisplayValue(name);
f.value = gr.getValue(name);
var ge = gr.getElement(name);
if (ge == null)
return f;

f.type = ge.getED().getInternalType()
f.label = ge.getLabel();
return f;
}

function getActions() {
var rl = GlideRecord("sp_vlist_action");
rl.addQuery("sp_rectangle_vlist",$sp.getValue("sys_id"));
rl.query();
var actions = [];
while(rl.next()) {
var action = {};
$sp.getRecordValues(action, rl, "name,glyph,hint,url,color");
actions.push(action);
}
return actions;
}

1 ACCEPTED SOLUTION

ChrisBurks
Mega Sage

The part that you are missing to update the server side is checking the input object in the server side.

When you use .server.update(), it sends the current data object in scope back to the server as input.

For example in the client script when the cancel() function is kicked off I see that c.data.hideCss is now set to an empty string. When c.server.update() is kicked off this send c.data.hideCss back to the server on the input object with the same property name: input = {hideCss: ''}. 

Thus, in the server side you would set a condition to look for an input:
if(input) {
     data.hideCss = input.hideCss;
}

That said, if the only reason why you're refreshing the page is to change the view or in this case just toggle a css class/style why go back to the server? You should really only have to do this client side since it just deals with the view and not the data.

Also note that Bootstrap already has a helper class to show/hide elements. Basically you could use a variable on $scope just to toggle the visibility of the element. 

Ie. 
HTML:
<ul class="transparent list-group hide-x-overflow"  ng-class="{'hide': hideMe}">
...

Clien:
$scope.hideMe = false;

$scope.someFunction = function(){
     $scope.hideMe = true;
}

In this example ngClass is used to toggle the classname "hide". Initially $scope.hideMe is set false and the ul element displays. If the someFunction is kicked off it will set $scope.hideMe to true and that will trigger ngClass to add the classname "hide" to the ul's class attribute. And the ul element should then disappear from the view.

 

View solution in original post

2 REPLIES 2

ChrisBurks
Mega Sage

The part that you are missing to update the server side is checking the input object in the server side.

When you use .server.update(), it sends the current data object in scope back to the server as input.

For example in the client script when the cancel() function is kicked off I see that c.data.hideCss is now set to an empty string. When c.server.update() is kicked off this send c.data.hideCss back to the server on the input object with the same property name: input = {hideCss: ''}. 

Thus, in the server side you would set a condition to look for an input:
if(input) {
     data.hideCss = input.hideCss;
}

That said, if the only reason why you're refreshing the page is to change the view or in this case just toggle a css class/style why go back to the server? You should really only have to do this client side since it just deals with the view and not the data.

Also note that Bootstrap already has a helper class to show/hide elements. Basically you could use a variable on $scope just to toggle the visibility of the element. 

Ie. 
HTML:
<ul class="transparent list-group hide-x-overflow"  ng-class="{'hide': hideMe}">
...

Clien:
$scope.hideMe = false;

$scope.someFunction = function(){
     $scope.hideMe = true;
}

In this example ngClass is used to toggle the classname "hide". Initially $scope.hideMe is set false and the ul element displays. If the someFunction is kicked off it will set $scope.hideMe to true and that will trigger ngClass to add the classname "hide" to the ul's class attribute. And the ul element should then disappear from the view.

 

Woz
Tera Contributor

Thanks for the help!

 

Im very new to Service Portal and the end goal is re-create the announcements widget with a some tweaks and new functions so I will need to do a server call at some point.

 

I'll give the above another read and do some further research - thought I might have this all working today ... looks like there might be some spill over haha

 

Thanks again for help on a Sunday