Need help with creating a Typeahead search box on Custom Widget

DPrasna
Tera Contributor

Hello All,

I have a custom widget with rows and columns as below that displays list of users

DPrasna_0-1672842023004.png

HTML

<div class="container-fluid" style="background-color:#e6f7ff;">
<div class="panel panel-default" style="background-color:#none;border: none;">
<h3>
All Users
</h3>

<div class="panel-body">

<div class="row">
<div class="col-md-12 text-right">
<button type="button" class="btn btn-primary" style="font-size: 12px;">Active</button>
<button type="button" class="btn btn-default" style="font-size: 12px;">Inactive</button>
</div>
</div>

<table class="table table-striped">
<tr>
<th>User Name</th>
<th>Active</th>
<th>Locked out</th>
<th>Development</th>
<th>Production</th>
<th class="actions"></th>
</tr>
<tbody>
<tr ng-repeat="user in data.users">
<td>{{user.username}}</td>
<td>{{user.active}}</td>
<td>{{user.lockedout}}</td>
<td>{{user.devrole.join(', ')}}</td>
<td>{{user.prodrole.join(', ')}}</td>
<td>
<div class="btn-group">
<button type="button" data-toggle="dropdown" class="btn btn-secondary dropdown-toggle">Action <span class="caret"></span></button>
<ul class="dropdown-menu">
<li><a href="javascript&colon;void(0);" ng-click="c.deactivateUser(user.sys_id)">Deactivate User</a></li>
<li><a href="javascript&colon;void(0);" ng-click="c.openUpdaterole(user)">Update User</a></li>
<!-- <li><a href="javascript&colon;void(0);">Third Link</a></li> -->
</ul>
</div> 
</td> 

</tr>
</tbody>
</table>  
</div>
</div>
</div>

I want a Typeahead search inside the container or below username column to allow users to search the name of the users that is displayed from the result returned from the server script

 

Reference image for expected column

DPrasna_1-1672842202524.png

 

TIA

@jaheerhattiwale @RaghavSh @Community Alums @Mike_R 

7 REPLIES 7

DPrasna
Tera Contributor

Server Script

var grUserrel = new GlideRecord('cmdb_rel_person');
grUserrel.addQuery('ci','IN',Ci_id);
//grUserrel.addQuery('user.active','true');
grUserrel.query();	
while(grUserrel.next()){

var user = {};
user.username = grUserrel.getDisplayValue('user');
user.sys_id = grUserrel.getDisplayValue('user.sys_id');
user.active = grUserrel.getDisplayValue('user.active');
user.lockedout = grUserrel.getDisplayValue('user.locked_out');
user.environment1 = [grUserrel.getDisplayValue('ci.used_for')];
user.environment = grUserrel.getDisplayValue('ci.used_for');

 

Help much appreciated, Thanks

@Mark Roethof @Ankur Bawiskar @Saurav11 

jaheerhattiwale
Mega Sage
Mega Sage

@DPrasna Tried and tested 100% working solution.

 

HTML script:

<div>
<div class="search-icon">
<input ng-model="c.keyword" type="text" placeholder="Search..">
<button type="button" ng-click="c.keywordSearch()"><i class="fa fa-search"></i></button>
</div>

<table class="table">
<tr>
<th>Number</th>
<th>Short Description</th>
</tr>
<tr ng-repeat="inc in data.incidents">
<td>{{inc.number}}</td>
<td>{{inc.short_description}}</td>
</tr>
</table>
</div>

 

Client script:

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

c.keywordSearch = function(){
c.data.action = "keyword_search";
c.data.keyword = c.keyword;
c.server.update().then(function(resp){

})
}
};

 

Server Script:

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


data.incidents = [];
var inc = new GlideRecord("incident");
if(input && input.action=="keyword_search"){
inc.addQuery('123TEXTQUERY321', input.keyword);
}
inc.query();

while(inc.next()){
data.incidents.push({
"number": inc.number.toString(),
"short_description": inc.short_description.toString()
})
}
})();

 

 

Result:

Without search:

jaheerhattiwale_0-1672847215344.png

 

With search:

jaheerhattiwale_1-1672847244439.png

 

 

Note:

Replace the server side with your table and query

 

Please mark as correct answer if this solves your issue.

 

Please mark the answer as correct or helpful based on impact
ServiceNow Community Rising Star, Class of 2023

Hi Thanks for the reply..

I already have a query but without client side script or input action as below. How do I use that query in HTML to achieve the same

Server script

var grUserrel = new GlideRecord('cmdb_rel_person');
grUserrel.addQuery('ci','IN',Ci_id);
//grUserrel.addQuery('user.active','true');
grUserrel.query();	
while(grUserrel.next()){

var user = {};
user.username = grUserrel.getDisplayValue('user');
user.sys_id = grUserrel.getDisplayValue('user.sys_id');
user.active = grUserrel.getDisplayValue('user.active');
user.lockedout = grUserrel.getDisplayValue('user.locked_out');
user.environment1 = [grUserrel.getDisplayValue('ci.used_for')];
user.environment = grUserrel.getDisplayValue('ci.used_for');		
user.role = ['AC'];
user.prodrole = (user.environment1 == 'Production') ? ['AC'] :[];
user.devrole = (user.environment1 == 'Development') ? ['AC'] :[];
user.envsysid = grUserrel.getDisplayValue('ci.used_for')+'_'+grUserrel.ci.sys_id;
data.existUserid1.push(user.sys_id);
data.existUserid += data.existUserid1.join(',');
reltable.push(user);
if(data.users.length > 0 )
{
pos = data.users.map(function(input) { return input.username; }).indexOf(user.username);
if(pos < 0){

data.users.push(user);
}

else
{
//data.users[pos].sys_id=data.users[pos].sys_id+","+user.sys_id;
data.users[pos].environment=data.users[pos].environment+","+user.environment;
data.users[pos].envsysid=data.users[pos].envsysid+","+user.envsysid;
if(data.users[pos].role.indexOf('AC') < 0){
	data.users[pos].role.push('AC');
}

if(data.users[pos].prodrole.indexOf('AC') < 0 && user.environment1 == 'Production'){
	data.users[pos].prodrole.push('AC');
}

if(data.users[pos].devrole.indexOf('AC') < 0 && user.environment1 == 'Development'){
	data.users[pos].devrole.push('AC');
}

if(data.users[pos].environment1.indexOf(user.environment1[0]) < 0){
	data.users[pos].environment1.push(user.environment1[0]);
}

}

}
else
{			
data.users.push(user);

}
}

So in the existing html I just pass the value from server as below

<div class="panel-body">
<div class="search-icon">
<input ng-model="c.keyword" type="text" placeholder="Search..">
<button type="button" ng-click="c.keywordSearch()"><i class="fa fa-search"></i></button>
</div>

<table class="table table-striped">
<tr>
<th>User Name</th>
<th>Active</th>
<th>Locked out</th>
<th>Development</th>
<th>Production</th>
<th class="actions"></th>
</tr>
<tbody>
<tr ng-repeat="user in data.users">
<td>{{user.username}}</td>
<td>{{user.active}}</td>
<td>{{user.lockedout}}</td>
<td>{{user.devrole.join(', ')}}</td>
<td>{{user.prodrole.join(', ')}}</td>
<td>

What should I use for the below code in this case?

 

<input ng-model="c.keyword" type="text" placeholder="Search..">
<button type="button" ng-click="c.keywordSearch()"><i class="fa fa-search"></i></button>
</div>

 

TIA.

@DPrasna Is this server and html code printing the output?

Please mark the answer as correct or helpful based on impact
ServiceNow Community Rising Star, Class of 2023