Important Update: Some Community URL Redirects are Under Maintenance. Learn More. .

cancel
Showing results for 
Search instead for 
Did you mean: 

Custom Object - Required Fields with Calculated Helper

JenniferClark
Archer Employee
Archer Employee

Hello,

 

I have a requirement to make certain fields required, if a date field is past 18 months.  I have a DATEDIF helper calculated field to determine the logic for the date field; however, the record needs to be saved in order to calculate the helper field.  Due to this, the fields won't become required initially.  Has anyone developed a custom object for this scenario? 

 

Thank you!

 

David Petty

20 REPLIES 20

BJJohnson
Archer Employee
Archer Employee

Might start with: https://community.rsa.com/thread/85285

Should help until Mr. Petty can point you to another.

 

There's a whole custom object section at https://community.rsa.com/community/products/archer-grc/archer-customer-partner-community/custom-objects

DavidPetty
Archer Employee
Archer Employee

Jennifer it can be done by a custom object.  Probably easier to have the custom object set a date field to the appropriate date and let the DDE take over for making the field required.

 

Can you post the logic that you were going to use for the calculated date field?

 Advisory Consultant

Hi David,

 

My helper field is DATEDIF(TODAY(),[Date to be retired],DAY)

 

I have it as a numeric field to determine days from 'Date to be retired' the user will enter.  If it is greater than 548 Days (18 Months), the other two fields would be required. 

 

I appreciate your help  

DavidPetty
Archer Employee
Archer Employee

Jennifer, see how this work.

 

You just have to adjust lines 14 and 15 with the correct field names.  Then a normal DDE can take over when the numeric field is greater than 548 [days].

 

<script type='text/javascript'>
var dateToBeRetiredFieldId, numberOfDaysId;

// For todays date;
Date.prototype.today = function () {
return (((this.getMonth()+1) < 10)?"0":"") + (this.getMonth()+1) +"/"+ ((this.getDate() < 10)?"0":"") + this.getDate() + "/" + this.getFullYear();
}
var currentDate = new Date();
var dateTime = currentDate.today();
var currentDateTime = new Date(dateTime);;
var dateToBeRetired;

Sys.Application.add_load(function() {
dateToBeRetiredFieldId = lookupFieldId('Date'); // Enter field name
numberOfDaysId = lookupFieldId('Numeric'); // Enter field name

// Watch if the date field changes
$('div[id$="f' + dateToBeRetiredFieldId + 'cdp"]').change(function(){
dateDifference()
});
dateDifference()
});

function dateDifference() {
dateToBeRetired = new Date(String($CM.getFieldValue(dateToBeRetiredFieldId, false)));
var differenceInTime = currentDateTime - dateToBeRetired;
var differenceInDays = differenceInTime / (1000 * 3600 * 24);

setTextNumericField(numberOfDaysId,differenceInDays);
}

function setTextNumericField(f,v) {
var textFieldAttributes = new Array();
field = ArcherTech.UI.ClientContentManager.GetInstance().getFieldById(f);

textFieldAttributes.push({
enabled: true,
emptyMessage: '',
validationText: v,
valueAsString: v,
minValue: '-9999999999999',
maxValue:'9999999999999',
lastSetTextBoxValue: v});

var textFieldAttributesSerialised = Sys.Serialization.JavaScriptSerializer.serialize(textFieldAttributes[0]);

$('#'+field.clientId).trigger('focus');

$('input[id*="'+ f +'c"]').val(v);
$('input[id*="'+ f +'c_ClientState"]').val(textFieldAttributesSerialised);

//Check to see if the field is read-only
if($('input[id*="'+ f +'c"]').parent().parent().find('.readOnly')) $('input[id*="'+ f +'c"]').parent().parent().find('.readOnly').text(v);

//Trigger if there any rules for the field
$('#'+field.clientId).trigger('blur');
}

function lookupFieldId(fldName){
var goFindId = null;
var fldText;
try{
$('.FieldLabel').each(function(){
fldText = $(this).text();

if(fldText.replace(new RegExp(' ', 'g'), '') === fldName.replace(new RegExp(' ', 'g'), '') + ':') {
goFindId = $(this).find("span")[0].id;
return false;
}
});
} catch (err) {}
try {if (!goFindId) goFindId = $('.SectionLabel:findField("' + fldName + '")')[0].id;} catch (err) {}
try {if (!goFindId) goFindId = $('.SubSectionLabel:findField("' + fldName + '")')[0].id;} catch (err) {}

return goFindId ? $LM._layoutItems[goFindId.replace( /^\D+/g, '')].fieldId : 0;
}

$.expr[':'].findField = $.expr.createPseudo(function(arg) {
return function( elem ) {
return $(elem).text().replaceAll(' ','').match("^" + arg + "$");
};
});
</script>

 Advisory Consultant

Hi David,

 

Here is what I tried below.  The record just froze when I tried to open.  I also tried to create a new record, but it also froze.  

 

 

<script type='text/javascript'>
     var dateToBeRetiredFieldId, numberOfDaysId;

     // For todays date;
     Date.prototype.today = function () {
          return (((this.getMonth()+1) < 10)?"0":"") + (this.getMonth()+1) +"/"+ ((this.getDate() < 10)?"0":"") + this.getDate() + "/" + this.getFullYear();
     }
     var currentDate = new Date();
     var dateTime = currentDate.today();
     var currentDateTime = new Date(dateTime);;
     var dateToBeRetired;

     Sys.Application.add_load(function() {
          dateToBeRetiredFieldId = lookupFieldId('Date to be retired');  // Enter field name
          numberOfDaysId = lookupFieldId('Helper Count of Days to be Retired');       // Enter field name

          // Watch if the date field changes
          $('div[id$="f' + dateToBeRetiredFieldId + 'cdp"]').change(function(){
               dateDifference()
          });
          dateDifference()
     });

     function dateDifference() {
          dateToBeRetired = new Date(String($CM.getFieldValue(dateToBeRetiredFieldId, false)));
          var differenceInTime = currentDateTime - dateToBeRetired;
          var differenceInDays = differenceInTime / (1000 * 3600 * 24);

          setTextNumericField(numberOfDaysId,differenceInDays);
     }

     function setTextNumericField(f,v) {
          var textFieldAttributes = new Array();
          field = ArcherTech.UI.ClientContentManager.GetInstance().getFieldById(f);

          textFieldAttributes.push({
               enabled: true,
               emptyMessage: '',
               validationText: v,
               valueAsString: v,
               minValue: '-9999999999999',
               maxValue:'9999999999999',
               lastSetTextBoxValue: v});

          var textFieldAttributesSerialised = Sys.Serialization.JavaScriptSerializer.serialize(textFieldAttributes[0]);

          $('#'+field.clientId).trigger('focus');

          $('input[id*="'+ f +'c"]').val(v);
          $('input[id*="'+ f +'c_ClientState"]').val(textFieldAttributesSerialised);

          //Check to see if the field is read-only
          if($('input[id*="'+ f +'c"]').parent().parent().find('.readOnly')) $('input[id*="'+ f +'c"]').parent().parent().find('.readOnly').text(v);

          //Trigger if there any rules for the field
          $('#'+field.clientId).trigger('blur');
     }

     function lookupFieldId(fldName){
          var goFindId = null;
          var fldText;
          try{
               $('.FieldLabel').each(function(){
                    fldText = $(this).text();

                    if(fldText.replace(new RegExp(' ', 'g'), '') === fldName.replace(new RegExp(' ', 'g'), '') + ':') {
                         goFindId = $(this).find("span")[0].id;
                         return false;
                    }
               });
          } catch (err) {}
          try {if (!goFindId) goFindId = $('.SectionLabel:findField("' + fldName + '")')[0].id;} catch (err) {}
          try {if (!goFindId) goFindId = $('.SubSectionLabel:findField("' + fldName + '")')[0].id;} catch (err) {}

          return goFindId ? $LM._layoutItems[goFindId.replace( /^\D+/g, '')].fieldId : 0;
     }

     $.expr[':'].findField = $.expr.createPseudo(function(arg) {
          return function( elem ) {
               return $(elem).text().replaceAll(' ','').match("^" + arg + "$");
          };
     });
</script>

Open the browser developer tools and display the Console then create a record and see if any errors are being thrown.  Also set the Display option of the custom object to Edit Only instead of both.

 Advisory Consultant

Hi David,

 

I ran it in the Console and have the error SCRIPT5022:  Sys.InvalidOperationException:  Cannot serialize non finite numbers.

 

pastedImage_3.png

 

Apparently it is looking for a numeric value in the calculated field before the record is saved.  I also changed to Edit Only instead of both. 

 

Thank you again for your assistance. 

Oh, you'll need to make the numeric field non-calculated for this to work and the field has to be on the layout.

 Advisory Consultant

Hi David,


I made it non-calculated and on layout; however, 'Helper Count of Days to be Retired' is calculating to a negative number.  

 

pastedImage_1.png

 

I am also still getting the same error message in the console related to this.  

 

pastedImage_3.png

 

Thank you!