Important Update: Community URLs redirect issues are partially resolved. 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

I added some debugging lines to the code.  Send me what's outputted in the console.

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

//Setup console log
if(!window.console || typeof console == "undefined") {
this.console = {
log: function() { },
info: function() { },
error: function() { }
};
}

// 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;
var debugging = true;

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

if (debugging) console.log('dateToBeRetiredFieldId: ' + dateToBeRetiredFieldId);
if (debugging) console.log('numberofDaysId: ' + numberOfDaysId);

// 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);

if (debugging) console.log('dateToBeRetired value: ' + dateToBeRetired);
if (debugging) console.log('differenceInTime: ' + differenceInTime);
if (debugging) console.log('differenceInDays: ' + differenceInDays);
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 = function(a, i, m) {
return $(a).text().replace(/[&\/\\#,+()$~%.'":*?<>{}]/g,'_').match("^" + m[3].replace(/[&\/\\#,+()$~%.'":*?<>{}]/g,'_') + "$");
};
</script>

 Advisory Consultant

Here is what I am getting now in the Console.  

 

Screen Shot 2020-09-23 at 5.05.53 PM.png

 

Thank you, David. 

Thanks.  So is the date always a future date?

 

If so, change line 40 to:

var differenceInTime = dateToBeRetired - currentDateTime‍

 Advisory Consultant

That worked!! 

 

The issue I am running into now is that when the record is new and there is no value in the Date to be retired field, I receive the same 'Cannot serialize non finite numbers' error in the console when I save the record. 

 

pastedImage_3.png

 

I would put a default value in the 'Date to be retired' field, but there should only be a value in that field if the system is to be retired so that won't work. Is it possible to add a default 0 to the 'Helper Count of Days to be Retired' field in the javascript?

 

Thank you!!

syedtahir16
Advocate

I always thought that if Archer calculation refers to TODAY() then such fields will auto calculate everyday.

 

Have you tried doing this:

Create a date field called Test -> Make it calculated with the calculation = TODAY()

Set this calc field to "Always"

 

Then update your original helper calc:

DATEDIF([Test],[Date to be retired],DAY) 

 

Make sure to have the Test  field above your Helper calc in the calc order.

Then Archer should recalc this helper everyday and then you can base your ACL on this helper.

If you do not have scheduled calculation defined in place for the module, TODAY fields will not be calculated every day as well.

That's right. We need to enable the scheduled calc. But if we do enable that then this requirement can be met without a custom object right?

Yes, but initial requirement was to make it available without saving the record. So, I assume it could also be so that such required real time, when some certain date field is set. For that Custom Object is required.

Ah alright! Makes sense thank you.

Sweet

 

Give this update a try,

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

//Setup console log
if(!window.console || typeof console == "undefined") {
this.console = {
log: function() { },
info: function() { },
error: function() { }
};
}

// 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;
var debugging = true;

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

if (debugging) console.log('dateToBeRetiredFieldId: ' + dateToBeRetiredFieldId);
if (debugging) console.log('numberofDaysId: ' + numberOfDaysId);

// 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)));

if(!isNaN(dateToBeRetired)) {
var differenceInTime = dateToBeRetired - currentDateTime;
var differenceInDays = differenceInTime / (1000 * 3600 * 24);

if (debugging) console.log('dateToBeRetired value: ' + dateToBeRetired);
if (debugging) console.log('differenceInTime: ' + differenceInTime);
if (debugging) console.log('differenceInDays: ' + differenceInDays);
} else {
differenceInDays = 0;
}
setTextNumericField(numberOfDaysId,Math.abs(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 = function(a, i, m) {
return $(a).text().replace(/[&\/\\#,+()$~%.'":*?<>{}]/g,'_').match("^" + m[3].replace(/[&\/\\#,+()$~%.'":*?<>{}]/g,'_') + "$");
};
</script>
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

 Advisory Consultant