So, why did I write this post? The Portal Web API is awesome and it’s fast. You can empower users to create records, upload files, provide feedback in record time with very little friction. However, it works behind the scenes which can leave the user asking Did that actually do anything? Was it successful? Is it still doing it? Am I safe to navigate away from the page now?

I came across this on my Spotify clone project and again with my editable grid project and thought I’d share with you awesome people.

Providing visual feedback isn’t much additional effort. It’ll answer all the above questions and tends to give the impression that the whole thing is even faster than it is (although no actual difference!)

Visual examples

Here’s how that looks for my like button:

Here’s how that looks for my profile image upload

Here’s how that looks for a row in my editable grid

Note – I’ve also added some CSS to highlight which of the fields are ‘dirty’ as a way of reminding the user to save their changes

We’ll do this in 2 stages:

  1. Once when the Portal Web API operation begins
  2. Again, once the operation has completed

This is actually really simple to do. A single line of jQuery should do the trick (well, a single line for the ‘in progress’ message, and another single line for the ‘succeeded’ message). Here’s what we need to:

  • Select the element we wish to update
  • Either
    • Provide some text or HTML to override that element’s content with OR
    • Add an additional HTML element to the page

Selecting elements

Note – if you’re already comfortable with jQuery selectors, skip ahead to the next heading 🙂

We’ll usually select an element using an id or a class. Here are examples of each:

Select an element e.g. an anchor tag (link) by id:


Select all elements e.g. anchor tags (links) by class:


Bonus: select a table cell <td> by data attribute:


So what do we do with those elements now we can select them?…

Provide visual feedback by interactively amending the HTML of those elements

My usual approach for providing visual feedback is to use jQuery’s .html() to change the content of a HTML element e.g. the label on a button. It’s simply a matter of providing the HTML in quotes, like so:


Another approach for providing the visual feedback is to append additional HTML to the page using jQuery’s append(). You can see an example of that in the profile photo upload above. As well as changing the text on the upload button for In Progress, I use the append function to add the uploaded photo to the page. This one’s a little more complicated as you need to know some HTML but I think the result is well worth it.

$(‘div#showOnSuccess’).append(‘<img class=”img-responsive” src=”data:image/jpeg;base64,’ + profilePhotoContents + ‘” />’);

Where to place the jQuery to provide visual feedback for your Portal Web API operation

Seems simple enough, right? Now it’s just a matter of where that jQuery goes.

For the ‘In Progress’ message, I place the jQuery just above the Portal Web API request. If you’re not sure what this is, just look for the line starting with

Here’s an example of that (Don’t worry, I’ll share the full web templates at the end)…

function createLike(itemGUID,itemName) {

var dataObject={

        “musdyn_name”:{{ user.firstname }} liked ” + itemName,

        “musdyn_ListenerGeneratedPlaylist@odata.bind”:“musdyn_playlists(“ + itemGUID + “)”,

        “musdyn_Customer@odata.bind”:“contacts({{ }})




    type: “POST”,

    url: “/_api/musdyn_likes”,

For the ‘Succeeded’ message, the jQuery should go withing the success function which is towards the end of that webapi.safeAjax function

Here’s an example of that:


    type: “POST”,

    url: “/_api/musdyn_likes”,


    data: JSON.stringify(dataObject),

    success: function(res, status, xhr) {

$(“.like-button”).html(‘<span class=”glyphicon glyphicon-ok” aria-hidden=”true”></span>’);



Code examples

Here’s the HTML and jQuery for each of the visual examples provided in the introduction…

Like button

Original HTML

class=“btn btn-primary like-button”
item-name=”{{ playlist.musdyn_name }}” item-guid=”{{ playlist.musdyn_playlistid }}” item-entity=“musdyn_playlist” href=“#”>Like</a>

jQuery to provide ‘In Progress‘ visual feedback


jQuery to provide ‘Succeeded‘ visual feedback

$(“.like-button”).html(‘<span class=”glyphicon glyphicon-ok” aria-hidden=”true”></span>’);

Image upload

Note – I’ve taken a slightly different approach for the visual feedback on success. Instead of changing an existing element’s HTML, I’m appending a new <img> element to an existing <div>

Original HTML

class=“btn btn-default”

jQuery to provide ‘In Progress‘ visual feedback


jQuery to provide ‘Succeeded‘ visual feedback

$(‘div#showOnSuccess’).append(‘<img class=”img-responsive” src=”data:image/jpeg;base64,’ + profilePhotoContents + ‘” />’);

Editable grid

I’ve used these same methods but I’m providing visual feedback for the record as a whole. Because I’m saving multiple records at once, the selector is a little more complicated. I don’t have a unique class or id to rely on so I’m using a combination of jQuery looping, $this and a data attribute to identify the required column to place the tick in (you can read more about this in my editable grid tutorial)… however the key point is that the visual feedback is provided in exactly the same way.

Original HTML

class=“btn btn-primary save-editable-grid pull-right”
style=“margin: 2em 0;”>Save Changes</a>

jQuery to provide ‘In Progress‘ visual feedback


jQuery to provide ‘Succeeded‘ visual feedback

$(‘tr[data-id=”‘ + updatedRecordGUID + ‘”]’).find(‘td[data-attribute=”change-status”]’).html(‘<span class=”glyphicon glyphicon-ok” style=”color: #1ed760;” aria-hidden=”true”></span>’);

$(‘tr[data-id=”‘ + updatedRecordGUID + ‘”]’).find(‘.dirty’).removeClass(‘dirty’);

The above examples are all quite different in appearance but all using a very similar approach and usually a single line of code to provide the feedback

I hope you’ve found that useful and I’d be most excited to see you take these ideas to the next level and build something awesome!

Franco Musso

You may also like

Leave a reply

Your email address will not be published. Required fields are marked *