Home › Forums › Backend Issues (wp-admin) › Calculated values while completing fields
Howdy!
First, I’d like to say I’m a long-time user of ACF Pro and love the product.
Task: Our client’s business is hired to do reporting for brands and agencies. They have developed their own scoring mechanism for how they score and build these reports, which we are digitizing.
Problem: One part of their process involves entering numbers for the scores, but then displaying an average of numbers entered, somewhere else on the edit/admin page, before it is saved.
Question: Is it possible to calculate the average of two(or more) ACF fields, as they are being completed, and display them within the ACF page/edit form? How might you approach something like this, if it is possible?
Design:
This is one portion of the layout I designed for their process, blurred for their privacy. The average of the 6 fields would show where the dash/hyphen is shown, next to “Average Score.” This would be present two or more times on their report pages.
Thanks! This client ask was a bit beyond anything I have done before, so I thought this would be a good place to start as I’m getting into the project. I have tentatively told them I would, “Look into it.”
The only way to do this is to add custom JavaScript to ACF and using the ACF JS API. This can be used to either modify the value of another field or to alter the HTML of the page to insert the calculated value.
@hube2, thanks for the links. I had looked over those links, before posting this, but your suggestion confirmed my choice of approach.
I was able to figure it out after a few hours.
For those trying something similar, I ended up included this in the theme functions.php file, but be sure to load it correctly in your script stack:
function my_admin_enqueue_scripts() {
wp_enqueue_script( 'katalyst-admin-js', get_template_directory_uri() . '/js/admin.js', array(), '1.0.0', true );
}
My admin.js file looked like this:
// Scoring Averages, on Load
acf.add_action('ready', function( $el ){
// $el will be equivalent to $('body')
// Relevancy Calculation
// Selects all Relevancy input fields (html node list)
const relevancyElements = [...document.querySelectorAll('.relevancy-data input')];
// Function to calculate Relevancy
function relevancyCalc() {
// Creates an array of values from the selected input field html (usable values)
var relevancyScores = relevancyElements.map(function (obj) {
return obj.value;
});
// Function to remove values outside of the 1-5 range also which removes null and undefined
function hasValue(value) {
return Number(value >= 1 && value <= 5);
}
// Filters values based on the above function (1-5, no null or undefined)
var relevancyFiltered = relevancyScores.filter(hasValue);
// Calculating total of comlpeted values (number)
var relevancyTotal = 0;
for(var i = 0; i < relevancyFiltered.length; i++) {
relevancyTotal = relevancyTotal + Number(relevancyFiltered[i]);
}
// Calculating the average of completed values (number)
var relevancyAverage = relevancyTotal / relevancyFiltered.length;
// Removing all but two decimals
var relevancyAverageDecimals = relevancyAverage.toFixed(2);
// Updates the average field
document.querySelector('#relevancy-average p').innerHTML = relevancyAverageDecimals;
// Show values in console
console.log(relevancyScores);
console.log(relevancyFiltered);
console.log(relevancyAverageDecimals);
}
// Run the function on Load
relevancyCalc();
// Adding event listeners to each element, on Load, to run the function again when a value is updated
for (var i = 0 ; i < relevancyElements.length; i++) {
relevancyElements[i].addEventListener('input' , relevancyCalc , false ) ;
}
});
Essentially, the code checks over each number field, per scoring section (ex: ‘.relevancy-data input’), maps the values into an array, filters out any results outside of the scoring range (1-5, which also removes NAN and undefined to better calculate the average as the fields are completed), averages the values, trims them to 2 decimals, and updates a message field with the average as inputs are entered.
Definitely a lot of work, but a good exercise for a designer-dev like myself.
Thanks again for the help, John.
Cheers,
Matt
You must be logged in to reply to this topic.
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Privacy Policy. If you continue to use this site, you consent to our use of cookies.