Trigger required field check without saving

  • 3
  • Question
  • Updated 1 year ago
  • Answered
Is there a way to trigger a required field check without invoking a model save/cancel?

Here's the use case - Custom button with action sequence that contains a "validate" snippet that performs checks on data on the models to be saved.  If validation occurs, a save models is performed.  The save models, prior to save, runs through the required field checks and only saves if all required fields contain a value.  What I'd like to be able to do is perform the required field check first, then the custom validate snippet and then the save.  This ensures that all fields have a value when the custom validate snippet runs.  Without this, the validate snippet needs to account for fields that don't have values but are marked as required.

Thank you!
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,076 Points 10k badge 2x thumb

Posted 4 years ago

  • 3
Photo of Moshe Karmel

Moshe Karmel, Champion

  • 8,646 Points 5k badge 2x thumb
I'm not sure if your asking declaratively or via Javascript, declaratively I don't think so. Javascript though, you can just create a javascript function that you call at the beginning of your snippet which checks for missing values. If you find any missing values just alert them to the user, and call "return;" which will stop the rest of the snippet from executing. Or return a boolean value to decide if you should continue. We use something like this:

function checkForMissingFields(currentName, salesSupport, opportunityModelCampaign, campaignName, campaignContactId, contLastName){    if(currentName != "" && salesSupport != "null" && salesSupport != '' && 
    ((opportunityModelCampaign != '' && opportunityModelCampaign != "null") || (campaignName != "" && 
            ((campaignContactId != "null" && campaignContactId != '') || contLastName != "")))){
    
        return true;            
    }
    else{
        if(currentName == "")
            alert('Opportunity needs a name.');
        else if(salesSupport == "null" || salesSupport == '')
            alert('Opportunity needs a Sales Support Representative.');
        else if(opportunityModelCampaign == "null" || opportunityModelCampaign == ''){
            if(campaignName == "")
                alert('Opportunity needs either an existing Campaign or a user-entered Campaign that includes a Name');
            else if((campaignContactId == "null" || campaignContactId == '') && contLastName == "")
                alert('Created Campaigns need either an existing Contact or a created Contact with a Last Name');
        }
        return false;
    }
and you can just check the boolean to see if you should continue. I might be missing your question here, but this would work.
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,076 Points 10k badge 2x thumb
Hey Moshe -

Thanks for the reply and thoughts regarding potential approach. 

The paradigm and example you provided would definitely yield the desired outcome, however in our situation it's not quite as scalable or dynamic as I'm goaling towards unfortunately.  In our case, we have rows in multiple objects all within their own field editors, tables, etc.  When you use the stock "save" functionality, skuid goes through all components and ensures that "requireness" is satisfied and if any fields do not satisfy, they are aggregated in messages that appear in the page title messages area.

I think I could achieve the same result by iterating the models and their registered lists and checking for requiredness and field value but what I'm hoping for is that there is a mechanism that can invoke (possibly via a single skuid api call) the behavior that the "save" button would trigger just without the actual "save."  This would allow fields to be added to components and not have to maintain a snippet to ensure that each field goes through an explicit check.

Sorry for not sharing more details in my OP, was kind of in a rush this morning when I posted it :)

Thanks again for insight!
Photo of Zach McElrath

Zach McElrath, Employee

  • 49,056 Points 20k badge 2x thumb
Hi Barry,

This can be done by calling skuid.ui.List.prototype.validateRequiredFields() on all registeredLists of the Models you want to check.

The tutorial on Wizard Step Button Actions shows an example of doing this, and you can also read the documentation on the skuid.ui.List object.

Zach
Photo of Lauren Ake

Lauren Ake

  • 368 Points 250 badge 2x thumb
Okay...please forgive my very non-JS savviness...but I can only get this to work on the first step of my wizard. If I add it to the other buttons, the first step throws an error for a field that is required on a different step.

I've combed through the code here trying to find where it's checking which set of fields and can't find where I need to adjust something.
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,076 Points 10k badge 2x thumb
Hey Zach - That'll teach me to rush through my analysis and not take a thorough look at the docs first.  Exactly what I was looking for, thank you!  
Photo of Chris

Chris

  • 1,632 Points 1k badge 2x thumb
This reply was created from a merged topic originally titled Can I cause a form/model validation without saving?.

I would like to be able to call some JS method to cause a Field Editor in a popup to be validated, without actually saving it.  This is so that a snippet that I'm running, from a multi-step action on a popup button, can verify that the page is valid before it goes and update a series of other fields on the model prior to the save.  

Is there such a method or technique to cause validation to run on-demand, including updating the page to show the validation error and letting my JS know that the validation failed?

Thanks,

- Chris
Photo of Zach McElrath

Zach McElrath, Employee

  • 49,056 Points 20k badge 2x thumb
Chris, I merged your question with Barry's previous question --- see my post above about skuid.ui.List.prototype.validateRequiredFields, and the tutorial on Wizard Step Button actions for an example of this in use.
Photo of Chris

Chris

  • 1,632 Points 1k badge 2x thumb
Thanks - this is exactly the hint I needed.

For others trying to use this outside of a wizard, the only real trick is finding your editor (stepEditor in the sample code in the link provided by Zach).  In a simple page (non-wizard) this can be easily located by putting an ID on your Page TItle control and then using:

var stepEditor = $('#My_page_title').data('object').editor;

Thanks as always, Zach!

- Chris
Photo of Chris

Chris

  • 1,632 Points 1k badge 2x thumb
For others, here is a simple variation of this code that can be used to validate a set of models.  Place this as an "inline" snippet and eliminate all default code that Skuidify provides and replace it with this.  Then, in other snippets, you can simply call "validateModels([model1, model2, model3], '#myPageTitle')" and check for true/false if the validate succeeds or fails.

/* 
 * validateModel: Validates all fields on a specified set of models
 *
 * models: array of models to validate ([model1, model2, ...])
 * editorId: ID of a control (such as Page Title, e.g. '#myPageTitle') to use to find the editor, to place the validation messages. 
 *
 * Returns: true if all validate, false if there are validation errors
 */
function validateModels(models, editorId) {
    var $ = skuid.$;
    var editor = $(editorId).data('object').editor;
    // Clear our list of messages
    editor.clearMessages();
    var messages = [];
    $.each(models,function(i,model){
       $.each(model.registeredLists,function(j,list){
           var listMessages = list.validateRequiredFields();
           if(listMessages && listMessages.length) {
               $.each(listMessages,function(){
                  messages.push(this); 
               });
           }
       });
    });
    // If we have warning messages, do NOT proceed
    if (messages.length) {
        // Have our step's editor handle the messages
        editor.handleMessages(messages);
        return false;
    }
    // Otherwise proceed!
    return true;
}
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 42,714 Points 20k badge 2x thumb
So, with this, one can essentially run the validation rules associated to the fields of each list of each model specified in the array passed into the function and choose which editor (component) to display the message above without saving the record.

Would it be used like this?

if (validateModels([model1,model2],'myPageTitle') {
    Proceed code here
} else {
    Do not proceed code here
}
Photo of Chris

Chris

  • 1,632 Points 1k badge 2x thumb
Yes, except add a '#' (or whatever your jQuery selector is) to the 'myPageTitle', as in '#myPageTitle'.  It's simply used as $('#myPageTitle').data('object').editor to find the editor (to display the error messages on a failed validation).