• Jace's Blog
  • Posts
  • Service Portal: Embedding a form widget

Service Portal: Embedding a form widget

So this weekend I had the opportunity to help someone out with an issueon their side project. They had this list they wanted to access froma phone, and wanted the ability to add a new record from a phone.

Simple enough I though. Just make a bootstrap listof sorts and add a button, to open a spModalto the OOB form widget.

That worked, but we ended up with 3 buttons, and 2 headers.

So that didn't work. Sure, I could have removed the buttons, by settingthe buttons array to blank. Also I could have looked into thewidget-form options. I didn't though. Because it was for a ratingsystem and needed to use something that has a star ranking

In case you are not aware, ServiceNow does a few things for you, like loadin a bunch of UI Bootstrap directives.

Enter <uib-rating>

This gets a little fuzzy here, but essentially, if you have a numeric scale;1-10 or less, you can represent it with stars or other icons. You cannot dothis with the OOB widgets you'll need your own input form. That's where thispost really shines for me. I need to remember how I did this.

So we had a Widget already, called "Home" for the list of ratings. Then wewanted a spModal to load a new widget that was the form. One of the fieldsis this UIB Rating thing. Then when the [OK] is pressed, send the data backup to the parent widget, and make a new Rating record, and refresh the list.

When sorting this out, I didn't have that last paragraph. So it took me a bitto find how to pass the data but here's the crucial bits if you find yourselfin a similar situation.

Below is a Home widget which makes the call to spModal.open. That has a promiseto handle the response in the then bit. That's where this magic happens. Itwasn't in the docs. Thankfully this markdown file was still out on Github.

End result was this;

That example shows how to do this for variable, and I wanted to do this for five.

Home Widget

HTML

<div class="list-group"> <a href="#" class="list-group-item" ng-repeat="book in c.data.books"> <span class="badge"></span> </a> </div><button ng-click="c.onWidget() "class="btn btn-default"> Add Rating</button>

Client Script

//Client Scriptfunction(spModal) { /* widget controller */ var c = this; var shared = {}; c.onWidget = function (){ spModal.open({ shared: shared, value: c.response, title: 'titkfadsf', widget: 'rating_form', widgetInput: {} }).then(function () { console.log(shared); c.data.bookrating=shared; c.server.update() }) }}

Server Script

//Server Script(function() { /* populate the 'data' object */ /* e.g., data.table = $sp.getValue('table'); */ if (input) {//if submitted rating console.log(input) var rating=new GlideRecord('x_86691_heardit_ratings') rating.newRecord(); rating.book=input.bookrating.title; rating.stars=input.bookrating.stars; rating.author=input.bookrating.input; rating.genre=input.bookrating.genre; rating.u_comments=input.bookrating.comments; rating.insert() } data.books = []; var countRatings = new GlideAggregate('x_86691_heardit_ratings'); //parm1: COUNT, MIN, MAX, parm2: field countRatings.addAggregate('COUNT', 'book'); countRatings.addAggregate('AVG', 'stars'); countRatings.query(); while (countRatings.next()) { var book = countRatings.getValue('book'); var ratingCount = countRatings.getAggregate('COUNT', 'book'); var averageRating = countRatings.getAggregate('AVG', 'stars'); data.books.push({ name:book, averageRating:averageRating, ratingCount: ratingCount }); }})();

Form Widget

HTML

<form class="form-horizontal" ng-model-options="{getterSetter: true}"><fieldset><!-- Form Name --><legend>Form Name</legend><!-- Text input--><div class="form-group"> <label class="col-md-4 control-label" for="textinput">Title</label> <div class="col-md-4"> <input id="bookTitle" ng-model='c.title' ng-model-options="{getterSetter:true}" name="textinput" type="text" placeholder="placeholder" class="form-control input-md"> </div></div><!-- Text input--><div class="form-group"> <label class="col-md-4 control-label" for="textinput">Author</label> <div class="col-md-4"> <input id="bookAuthor" ng-model='c.author' ng-model-options="{getterSetter:true}" name="textinput" type="text" placeholder="placeholder" class="form-control input-md"> </div></div><!-- Select Basic --><div class="form-group"> <label class="col-md-4 control-label" for="selectbasic">Genre</label> <div class="col-md-4"> <select id="bookGenre" ng-model='c.genre' ng-model-options="{getterSetter:true}" name="selectbasic" class="form-control"> <option value="">Pick One</option> <option value="Action/Adventure">Action/Adventure</option> <option value="Autobiography/Biography/Memoir">Autobiography/Biography/Memoir</option> <option value="Children's Fiction">Children's Fiction</option> <option value="Comedy/Humor">Comedy/Humor</option> <option value="Crime/Mystery">Crime/Mystery</option> <option value="Drama/Romance">Drama/Romance</option> <option value="History/Classic">History/Classic</option> <option value="Horror/Paranormal">Horror/Paranormal</option> <option value="Motivational/Educational/Health & Wellness">Motivational/Educational/Health & Wellness</option> <option value="Mystery/Suspense/Thriller">Mystery/Suspense/Thriller</option> <option value="Poetry">Poetry</option> <option value="Religion/Spirituality">Religion/Spirituality</option> <option value="Sci-Fi/Fantasy">Sci-Fi/Fantasy</option> <option value="Other">Other</option> </select> </div></div><!-- Text input--><div class="form-group"> <label class="col-md-4 control-label" for="textinput">Stars</label> <div class="col-md-4"> <uib-rating ng-model='c.stars' ng-model-options="{getterSetter:true}" max="5" ></uib-rating> </div></div><!-- Textarea --><div class="form-group"> <label class="col-md-4 control-label" for="textarea">Comments</label> <div class="col-md-4"> <textarea ng-model='c.comments' ng-model-options="{getterSetter:true}" class="form-control" id="bookComments" name="bookComments">default text</textarea> </div></div></fieldset></form>

Client Script

//Client Scriptfunction() { /* widget controller */ var c = this; var shared = c.widget.options.shared; c.title = function title(newVal){ return angular.isDefined(newVal) ? (shared.title = newVal) : shared.title; } c.author = function author(newVal){ return angular.isDefined(newVal) ? (shared.author = newVal) : shared.author; } c.genre = function genre(newVal){ return angular.isDefined(newVal) ? (shared.genre = newVal) : shared.genre; } c.stars = function stars(newVal){ return angular.isDefined(newVal) ? (shared.stars = newVal) : shared.stars; } c.comments = function comments(newVal){ return angular.isDefined(newVal) ? (shared.comments = newVal) : shared.comments; }}

Server Script

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

viswam10 thanks for the feedback!

Reply

or to participate.