Display message notifications in Skuid

Can Skuid display message notifications, like a notification bar at the top of the page, for messages to users, or errors and contain a link that they can click on.

Also if possible, can you close this notification and append further messages to it if needed
Thanks

Check out this, specifically the section about handleMessages : Page Not Found — Skuid v15.1.6 Documentation

Yes you can: 


The red is with the message error and the orange are message warning (with the handle messages Moshe linked)

Hi,  

Very timely question and replies.  There seems to be a caveat with the handleMessages functionality and Multiple Actions.

In the screenshot below, I have a Row Action implemented using the Action Framework.  Here’s the workflow:

1. Show a message and block the UI
2. Run a snippet
    a. Invoke a 3rd party web service
    b. All Async
    c. Use handleMessages when error encountered 
    d. Return a promise
3. Save Models
4. Unblock the UI




Here’s the snippet:

<br>// Define variable to access snippet's arguments var $ = skuid.$;<br>var item = arguments[0].item;<br>var list = arguments[0].list;<br>var model = arguments[0].model;<br>var row = item.row; <br>// Create jQuery Deferred&nbsp;<br>var deferred = $.Deferred(); // Handle error messages<br>var displayMessage = function (message, severity) {<br>&nbsp; &nbsp; var topPanel = $('#topPanel');<br>&nbsp; &nbsp; var editor = topPanel.data('object').editor;<br>&nbsp; &nbsp; editor.handleMessages([<br>&nbsp; &nbsp; &nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; message: message,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; severity: severity.toUpperCase()<br>&nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; ]);<br>} <br>var onSuccess = function (response) {<br>&nbsp; &nbsp; console.log('onSuccess: ' + response); <br>&nbsp; &nbsp; var rowsToUpdate = {};<br>&nbsp; &nbsp; var respObj = $.parseJSON(response);<br>&nbsp; &nbsp;&nbsp;<br>&nbsp; &nbsp; if (respObj.Error) {<br>&nbsp; &nbsp; &nbsp; &nbsp; displayMessage(respObj.Error.Description, 'ERROR');<br>&nbsp; &nbsp; } <br>&nbsp; &nbsp; $(respObj.EvaluationError).each(function (i, er) {<br>&nbsp; &nbsp; &nbsp; &nbsp; ...<br>&nbsp; &nbsp; &nbsp; &nbsp; displayMessage(rowToUpdate.Evaluation_Error__c, 'ERROR');<br>&nbsp; &nbsp; }); <br>&nbsp; &nbsp; $(respObj.EvaluationResult).each(function (i, er) {<br>&nbsp; &nbsp; &nbsp; &nbsp; ...<br>&nbsp; &nbsp; }); <br>&nbsp; &nbsp; model.updateRows(rowsToUpdate);<br><br>}; <br>var onFailure = function (data) {<br>&nbsp; &nbsp; console.log('onFailure: ' + data);<br>&nbsp; &nbsp; displayMessage(data, 'ERROR');<br>}; <br>// Add success and failure handlers<br>deferred.then(onSuccess, onFailure); <br>// Assemble JSON request<br>function buildRequest(row) {<br>&nbsp; &nbsp; var request = {<br>&nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; };<br>&nbsp; &nbsp; return request;<br>} <br>// Perform web callout<br>function doWebCallout(request) {<br>&nbsp; &nbsp; <br>&nbsp; &nbsp; sforce.connection.remoteFunction({<br>&nbsp; &nbsp; &nbsp; &nbsp; url: "<a href="https://nebula-dev.pros.com:8090/Message/PPSS/get/price&quot;" title="Link: https://nebula-dev.pros.com:8090/Message/PPSS/get/price&quot;">..."</a>,<br>&nbsp; &nbsp; &nbsp; &nbsp; requestHeaders: {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "Content-Type": "application/json",<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //"Connection": "Keep-Alive",<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "Authorization": autToken,<br>&nbsp; &nbsp; &nbsp; &nbsp; },<br>&nbsp; &nbsp; &nbsp; &nbsp; requestData: JSON.stringify(request),<br>&nbsp; &nbsp; &nbsp; &nbsp; method: 'POST',<br>&nbsp; &nbsp; &nbsp; &nbsp; onSuccess: function (response) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log('onSuccess');<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; deferred.resolve(response);<br>&nbsp; &nbsp; &nbsp; &nbsp; },<br>&nbsp; &nbsp; &nbsp; &nbsp; onFailure: function (response) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log('onSuccess');<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; deferred.reject(response);<br>&nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; });<br>} <br>// Assemble the request and perform the callout<br>doWebCallout(buildRequest(row)); <br>// Return a Promise object<br>return deferred.promise();



The issue is that the message is never shown and I believe this be due to the async nature of the workflow.

Irvin

Irvin, are you sure that displayMessage is being called? I’d throw in some console.logs into your code right before the points where displayMessage is being called to ensure that your code is getting there — perhaps the problem is not with handleMessages() , but that handleMessages never gets called.

Irvin, are you sure that displayMessage is being called? I’d throw in some console.logs into your code right before the points where displayMessage is being called to ensure that your code is getting there — perhaps the problem is not with handleMessages() , but that handleMessages never gets called.

Will confirm shortly.  Thanks for the reply.

Hi, Yes, my function is being invoked.





<br>
<br>var displayMessage = function (message, severity) {&nbsp; &nbsp;<br>&nbsp;console.log('displayMessage: ' + message + ' ' + severity);<br>&nbsp; &nbsp; var qliTable = $('#qliTable');<br>&nbsp; &nbsp; var editor = qliTable.data('object').editor;<br>&nbsp; &nbsp; editor.handleMessages([<br>&nbsp; &nbsp; &nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; message: message,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; severity: severity.toUpperCase()<br>&nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; ]);<br>}




Zach,

I think I know this cause of the problem: Save Models action.  

If I remove this action, the messages are shown as expected.

Thoughts?

Regards, Irvin

Aha, that makes sense — after the “Save Models” action runs, the Model notifies all of its registered Editors of any error messages that happened during the save, if any, and the registered Editors replace their messages with what the Model hands them — which has the effect here of removing your manually-added messages. 

So what you probably need to do is this: if there are error messages that result from your call to sforce.connection.remoteFunction(), then you need to force the Action Sequence to stop, thereby preventing the Save Models action from being run. To stop the Action Sequence, call deferred.reject() if there are any error messages encountered, like this:

var displayMessages = function (messages) {   
    console.log(‘displaying ’ + messages.length + ’ messages’);
    var qliTable = $(‘#qliTable’);
    var editor = qliTable.data(‘object’).editor;
    editor.handleMessages(messages);
}

var onSuccess = function (response) {
    console.log('onSuccess: ’ + response);
    var rowsToUpdate = {};
    var respObj = $.parseJSON(response);
    var messages = ;

   var addMessage = function(message,severity){
      messages.push({
        message: message,
         severity: severity.toUpperCase()
      });
    };

    if (respObj.Error) {
        addMessage(respObj.Error.Description, ‘ERROR’);
    }
    $(respObj.EvaluationError).each(function (i, er) {
        …
        addMessage(rowToUpdate.Evaluation_Error__c, ‘ERROR’);
    });
    $(respObj.EvaluationResult).each(function (i, er) {
        …
    });

    // If we have any messages, display them,
    // and stop our Action Sequence from proceeding
    if (messages.length) {
        displayMessages(messages);
       deferred.reject();
    }

    model.updateRows(rowsToUpdate);

};

Zach,

Thanks for the timely replies - they keep me moving.

Makes sense.  In my case, the web service could return a response with both successful and unsuccessful results e.g. call out to get a price for 4 products, get back 3 prices and one product not found.

So what I did was set up a model save callback handler that added the messages to the page.  This seems to work.

var quoteModel = skuid.model.getModel('Quote');&nbsp; &nbsp; skuid.model.save([model, quoteModel], {<br>&nbsp; &nbsp; &nbsp; &nbsp; callback: function(result) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (messages.length &gt; 0) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; displayMessages(messages);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; });

Glad to hear that helped — you approach makes sense.