How to add additional variables on the walk-up appointment scheduling widget?

Raskill1
Giga Contributor

Hi Experts,

I have a requirement to customise the walk-up appointment scheduling widget - 'Online check-in experience'. Currently it has just one single variable dropdown, where we can select the reason for visiting. We need to gather more information from the user like phone, existing request reference, etc. I have created a variable set that hosts these questions and added it to the record producer associated with the appointment location but it does not show up in the widget. So i went about digging deeper into the providers and the angular templates, and I found the code in the 'walkUpAppointmentPanel' template,

<div>
<div class="wu_header">
<h4 class="form-header">{{c.headerMsg}}</h4>
<p class="reason-msg" ng-if="!c.hasAppointment">{{c.reasonMsg}}</p>
<p class="reason-msg apt-msg" ng-if="c.hasAppointment">{{c.rescheduleMsg}}</p>
</div>

<!-- Child element of directive -->
<div ng-transclude="reasonSelect" ng-if="!c.hasAppointment"></div>

<br/>

<!-- Catalog Item Variables -->
<div class="" ng-class="{'b-b wrapper-md': !data.no_fields}">
<sp-cat-item item="::data.sc_cat_item"></sp-cat-item>
<form>
<sp-model form-model="::data.sc_cat_item" mandatory="c.mandatory"></sp-model>
</form>
</div>

<br/>

<!-- Select appointment widget -->
<div ng-if="!c.hasAppointment">
<div id="appt-select-widget" class="appointment-wrapper">
<sp-widget widget="c.appointmentSelect"></sp-widget>
</div>
<br/>
</div>

<!-- Reselect appointment widget -->
<div id="appt-reselect-widget" ng-if="c.hasAppointment">
<sp-widget widget="c.appointmentReselect"></sp-widget>

<!-- Child element of directive -->
<div class="reason-text" ng-transclude="reasonText"></div>
</div>

<div ng-if="!c.hasAppointment" class="wu-submit">
<button ng-aria-label="{{c.buttonMsg}}" type="button" class="btn btn-primary appt-btn" ng-click="c.submitAppointment()" ng-disabled="c.isDisabled()">
{{c.buttonMsg}}
</button>
</div>
</div>

If you see under the 'Catalog Item Variables' section, sp-cat-item and sp-model directives are being used to render the variables I add on the record producer,  The data.sc_cat_item is populated with the object data in the server side, but for some reason it doesn't seem to render the html.

I have spent hours trying to figure this out, any help with this regard is greatly appreciated!

Thanks!

 

1 ACCEPTED SOLUTION

Janel
Kilo Sage

This was the exact reason I needed to clone that widget in the first place!  😄

This is what I did.  I tried using that built in catalog form method, but it'd never displayed correctly so I gave up on that immediately. 

I can add certain variable types from the associated appointment record producer and use the record producer to do any mapping/update/lookups/whatever based on the values.  I'm getting the variables directly and I have no clue how to get it to follow any UI policies or client scripts or just pull in the record producer (in a way that works).  Also, I'm ignoring variable sets because I don't want the extra questions to repeat the questions from the appointment variables.

There is some trouble with mandatory questions (which I'm sure you could easily work in), but it suits our basic needs.  Hopefully this helps!

 

Updating the ng-templates

I added a 9th ng-template called "walkUpAdditionalInformationPanel" to render the variables on the page.  Right now it is only doing references and strings, so you'll need to add more variable types as needed.  It just dawned on me you MIGHT be able to use this to display the actual record producer, but I'm not sure how well submitting will work.

<br />
<div>
  <div ng-repeat="item in c.catalogQuestions track by item.sys_id">
      {{item.question}}

    <div ng-if="item.type == 8">
      <sn-record-picker ng-change="c.itemChanges(item.value, item)" class="catalog-questions"
                        field="item.value"
                        table="item.reference"
                        display-field="'name'"
                        page-size="25"
                        search-field="'name, user_name'"
                        value-field="'sys_id'"
                        default-query="item.reference_qual"
                        sn-required="true" 
                        aria-required="true">
      </sn-record-picker>
    </div>
    <br />
    <div ng-if="item.type == 6">
      <input type="text" class="form-control catalog-questions" ng-model="item.value" ng-change="c.itemChanges(item.value, item)"  id="{{item.name}}" ng-model-options="{debounce: 1000}" aria-required="true" required />
    </div>
  </div>
  <p/>

</div>

 

On the "walkUpOnbehalfAppointmentPanelCustom" ng-include, under this line near the top,

  <!-- Child element of directive -->
  <div ng-transclude="reasonSelect" ng-if="!c.hasAppointment"></div>

Add an ng-include to the new ng-template:

div ng-include="'walkUpAdditionalInformationPanel'" ng-if="!c.hasAppointment && c.catalogQuestions"></div>

 

And then also add it to the "walkUpOnbehalfAppointmentPanelCustom" ng-include in the same spot.

 

Updating Directives

Hopefully you added customized directives already.  Open the "walkUpAppointmentCustom" directive.  The c.createAppointment function needs to be updated to check for extra questions that were included and to send those over to the main widget.  Within the c.createAppointment function, send your catalog questions back with the picked snAppointment.  Around line 70ish?

catQuestions: c.catQuestions

c.createAppointment({
					snAppointment: c.selectedDate,
					catQuestions: c.catQuestions,
					callback: function(success) {

 

Updating the Server Script

The server script will be responsible for looking up the catalog variables and making them available for use.  At the end of the "if (input.action === a.getConfig) {" and before the "return", add the question lookup (somewhere around line 155).  Remember, we're not looking for variable set questions so we don't duplicate the the appointment questions.

if (data.catalogID) {
				if(options.extra_questions == 'true'){
					data.extraCatQuestions = getExtraVariables(data.catalogID);				
				}else{
					data.extraCatQuestions = undefined;
				}

				data.currentUser = gs.getUserID();
				data.apptmnt = AppointmentFacade.fetchTaskRecord(data.currentUser, queueId);

				data.appointmentSelect = getApptSelectWidget(data.catalogID, config.locationId, data.currentUser);
				setApptmntReselectState(data.apptmnt, data.catalogID);
				data.userOnBehalfEligibility = WalkUpUtil.checkEligibility(gs.getUser(), queueId);

				data.hasAppointmentBooking = true;
			} else {
				data.hasAppointmentBooking = false;
			}

 

Updating the main Client Controller

I think lastly, is updating the client controller to accept the extra questions as part of the payload that is submitted. 

In the c.createAppointment function in the main client controller, update the function to include the catQuestions as the second parameter.

c.createAppointment = function(snAppointment, catQuestions, callback) {

And then, just have the payload JSON object is created, add your catQuestions into it.  Somewhere around line 246.

		//Add the addtional questions to the payload if there are any
		if(catQuestions != undefined){
			for(var k in catQuestions){
				if(catQuestions[k] != ''){
					payload[k] = catQuestions[k];
				}
			}
		}

In the record producer itself you'll need to use the Script field to do any question mapping or update whatever it is you need to with the extra information.

View solution in original post

12 REPLIES 12

Janel
Kilo Sage

Oh!  I left out the getExtraVariables function.  It is probably what you can guess it is, just a lookup on item_option_new for the catalog item to get the values. 

I can't edit the original post so here it is.  I put this function around line 177, just outside of the "if (input.action === a.getConfig)".  As you can see, I'm only getting variables with the type of String or Reference.  Just cramming them into a new JSON object to call on later.

		/* Ask additional questions if the record producer has any.
		* Only looks at the producer.  Ignores variable sets. */
		function getExtraVariables(catalogID){
			var extraInfos = [];
			var itemOpts = new GlideRecord('item_option_new');
			itemOpts.addQuery('cat_item', catalogID);
			itemOpts.addQuery('active', true);
			itemOpts.addQuery('type', 6).addOrCondition('type', 8); //String and reference
			itemOpts.query();

			while(itemOpts.next()){
				var infoz = {
					sys_id: itemOpts.getValue('sys_id'),
					name: itemOpts.getValue('name'),
					type: itemOpts.getValue('type'),
					question: itemOpts.getValue('question_text'),
					reference: itemOpts.getValue('reference'),
					reference_qual: itemOpts.getValue('reference_qual')
				};
				extraInfos.push(infoz);
			}
			return extraInfos;
		} //End of function

Thanks Janel, this helped validate the direction I was going with constructing the function.

I have confirmed I am retrieving the additional variables from the record producer and that the function is being called once I select the location.

What I am still having some trouble with is actually rendering the variables on the page.  I am not able to get the panel to display unless I remove 'c.catalogQuestions' form the ng=if statement in the appointmentpanel templates.  If I remove, I see where the panel is rendered but no variables within are displayed.

Did you experience anything similar as you worked through this solution or have any thoughts on why this might be?

 

Thank you also for the speedy response and wealth of information on this topic!

I did not run into that.

Silly question, but does the record producer have a string or reference variable that *is not* part of a variable set on it?

I'm assuming you mean this line in walkUpAppointmentPanelCustom (I noticed the div above is missing the < )

<div ng-include="'walkUpAdditionalInformationPanel'" ng-if="!c.hasAppointment && c.catalogQuestions"></div>

 

Did you create a new ng-template for the additional information?

Check to see if c.catalogQuestions has a value.  Maybe it is coming back undefined and just blowing up.

SergioPita
Tera Contributor

Hi Justin,

 

In Rome version we have the same problem, we can not see the variables in the portal. Any updates about your issue? Could you fix it?

Thanks

Sergio

 

Hi Janel, thank you for your work here.

I think the problem is that the value "c.catalogQuestions" is never defined/used within the whole widget.

Can you please have a look in your configuration?

Thank you!!!

 

Regards

Roland