Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
<script>
jQuery(document).ready(function($) {
"use strict";
/* this script demonstrates a prototype integration for
* to display dynamic ChartJS graphs from Formidable Forms data.
*/
function masterminds_calc_fv( deposit_value, interest_rate, monthly_contribution ) {
const values = [deposit_value];
var chart_years = 30,
future_val = 0;
/* loop through chart years and calculate future value for years 1 through 30 */
for ( var i = 1; i <= chart_years; i++) {
future_val = Math.ceil( deposit_value*(1+interest_rate/12)**(i*12)+monthly_contribution*(((1+interest_rate/12)**(i*12)-1)/(interest_rate/12)) );
values.push(future_val);
}
return values;
}
function masterminds_init_chart() {
/* get values to calculate future value */
var deposit_value = parseInt( $('input#field_icpfrm_initial_deposit').val() ),
selected_rate = $('select#field_icpfrm_interest_rate :selected').val(),
interest_rate = (selected_rate !== "" ) ? parseFloat( selected_rate ) : parseFloat('0'),
monthly_contribution = parseInt( $('input#field_icpfrm_monthly_contribution_amt').val() );
return masterminds_calc_fv( deposit_value, interest_rate, monthly_contribution );
}
function masterminds_set_select_color() {
var selected_rate = $('select#field_icpfrm_interest_rate').prop('selectedIndex'),
interest_rate_class = "";
switch (selected_rate) {
case 1:
interest_rate_class = 'r1_int';
break;
case 2:
interest_rate_class = 'r2_int';
break;
case 3:
interest_rate_class = 'r3_int';
break;
case 4:
interest_rate_class = 'r4_int';
break;
case 5:
interest_rate_class = 'r5_int';
break;
default:
interest_rate_class = "r0_int";
}
$('select#field_icpfrm_interest_rate').addClass('auto_width').addClass( interest_rate_class );
}
masterminds_set_select_color();
/* chart setup */
var selectedbackgroundColor = [$("select#field_icpfrm_interest_rate").css('color')],
selectedlabel = $("select#field_icpfrm_interest_rate :selected").text().trim();
const data = {
labels: ['Today', '', '', '', '', 'Year 5', '', '', '', '', 'Year 10', '', '', '', '', 'Year 15', '', '', '', '', 'Year 20', '', '', '', '', 'Year 25', '', '', '', '', 'Year 30'],
datasets: [{
label: selectedlabel,
data: masterminds_init_chart(),
backgroundColor: selectedbackgroundColor,
}]
};
/* callbacks */
const tooltiptitle = (tooltipItem) => {
return "$" + tooltipItem[0]['formattedValue'] + "*";
};
const labelColor = (tooltipItem) => {
return'rgb(26,32,44)';
};
const tooltiplabel = (tooltipItem) => {
var item_index = tooltipItem.dataIndex,
newlabel = "Today";
if ( item_index == 1 ) {
newlabel = "Accumulated in " + item_index + " year.";
} else if (tooltipItem.dataIndex > 1) {
newlabel = "Accumulated in " + item_index + " years.";
}
return newlabel;
};
const grid = {
color: 'rgb(26,32,44)',
borderColor: 'rgb(26,32,44)',
tickColor: 'rgb(26,32,44)',
};
const ticks = {
color: 'rgb(26,32,44)',
callback: (value, index, values) => {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
maximumFractionDigits: 0,
}).format(value);
},
};
/* chart config */
const config = {
type: 'bar',
data,
options: {
locale: 'en-US',
scales: {
y: {
beginAtZero: true,
grid,
ticks,
},
x: {
grid,
ticks: {
color: 'rgb(26,32,44)',
},
},
},
plugins: {
tooltip: {
yAlign: 'bottom',
backgroundColor: 'rgb(253,254,255)',
titleColor: 'rgb(24,151,178)',
displayColors: false,
titleFont: {
weight: 'bold',
size: 18,
},
bodyFont: {
size: 16,
},
titleAlign: 'center',
footerAlign: 'center',
bodyAlign: 'center',
borderColor: 'rgb(24,151,178)',
borderWidth: 1,
callbacks: {
title: tooltiptitle,
labelTextColor: labelColor,
label: tooltiplabel,
},
}
}
}
};
/* chart render init */
const ibcpBarChart = new Chart(
$('#ibcpBarChart'),
config,
);
function masterminds_refresh_chart() {
/* initialize the new data array */
var selectedlabel = $("select#field_icpfrm_interest_rate :selected").text().trim(),
newvalues = masterminds_init_chart(),
selectedbackgroundColor = [$("select#field_icpfrm_interest_rate").css('color')];
/* feed the new array to the chart and update the display */
ibcpBarChart.data.datasets[0].label = selectedlabel;
ibcpBarChart.data.datasets[0].data = newvalues;
ibcpBarChart.data.datasets[0].backgroundColor = selectedbackgroundColor;
ibcpBarChart.update();
}
/* Formidable field functions follow */
$('input#field_icpfrm_initial_deposit, input#field_icpfrm_monthly_contribution_amt, select#field_icpfrm_interest_rate').on("change", function() {
if ( $(this).attr('id') == 'field_icpfrm_interest_rate' ) {
/* clear the current class if any */
$(this).removeAttr('class');
masterminds_set_select_color();
} else {
var formatted_html = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
maximumFractionDigits: 0,
}).format( $(this).val() );
$(this).siblings('.frm_range_value' ).html(formatted_html);
}
masterminds_refresh_chart();
});
/* this code is a multi-selector variation of the example found
* in Formidable's knowledge base article: https://formidableforms.com/knowledgebase/javascript-examples/#kb-format-a-slider-field-value-as-a-currency
*/
$("#field_icpfrm_initial_deposit ~ .frm_range_value, #field_icpfrm_monthly_contribution_amt ~ .frm_range_value").on('DOMSubtreeModified' , function() {
var field_id = $(this)[0].previousSibling.id,
target_elem = '#' + field_id,
target_span = target_elem + '_display',
formatted_html = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
maximumFractionDigits: 0,
}).format( $(target_elem).val() );
$(target_span)[0].innerText = formatted_html; // add the currency symbol
var event = new Event("change");
$(target_span)[0].dispatchEvent(event);
});
});
</script>
<?php
/*
* add_action loads the ChartJs script from CDN
* you can wrap the echo function in a WordPress
* conditional to granularize page load target(s)
*
* if CDN performance is an issue, retrieve file from
* https://github.com/chartjs/Chart.js/releases/latest
* and load from server directory */
add_action( 'wp_head', function () {
/* to restrict where scripts are loaded, populate array with page ids */
$pages_to_load_scripts = array();
if ( is_page( $pages_to_load_scripts ) ) {
echo '<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.0/chart.min.js" integrity="sha512-sW/w8s4RWTdFFSduOTGtk4isV1+190E/GghVffMA9XczdJ2MDzSzLEubKAs5h0wzgSJOQTRYyaz73L3d6RtJSg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>' . PHP_EOL;
echo masterminds_render_ibcpbarchart_css();
}
});
add_filter('frm_setup_new_fields_vars', 'masterminds_populate_interest_rate_lookup', 20, 3);
function masterminds_populate_interest_rate_lookup( $values, $field, $args ) {
if ( $values['field_key'] == 'icpfrm_interest_rate' ) {
$lu_results = masterminds_icpfrm_config();
$newoptions = array( 0 => array('label' => 'Select a rate:', 'value' => '') );
foreach ( $lu_results as $lu_entry ) {
$newoptions[] = array('label' => $lu_entry->dropdown_label, 'value' => $lu_entry->interest_rate);
}
$values['options'] = $newoptions;
}
return $values;
}
function masterminds_icpfrm_config() {
global $wpdb;
/* create the variables for the formidable tables */
$wpdb_prefix = $wpdb->prefix;
$frm_items_table = $wpdb_prefix . 'frm_items';
$frm_item_metas_table = $wpdb_prefix . 'frm_item_metas';
/* get target field IDs */
$rate_id = FrmField::get_id_by_key('irclu_interest_rate_id');
$dropdown_label = FrmField::get_id_by_key('irclu_dropdown_label');
$interest_rate = FrmField::get_id_by_key('irclu_interest_rate');
$display_color_hex = FrmField::get_id_by_key('irclu_display_color_hex');
/* create SQL SELECT
* if you have many configuration fields, you can also use a SQL View
*/
$sql = "SELECT t1.meta_value AS rate_id, t2.meta_value AS dropdown_label, t3.meta_value AS interest_rate, t4.meta_value AS display_color_hex FROM `{$frm_item_metas_table}` t1 LEFT JOIN `{$frm_item_metas_table}` t2 ON t2.item_id = t1.item_id LEFT JOIN `{$frm_item_metas_table}` t3 ON t3.item_id = t1.item_id LEFT JOIN `{$frm_item_metas_table}` t4 ON t4.item_id = t1.item_id WHERE t1.field_id = '{$rate_id}' AND t2.field_id = '{$dropdown_label}' AND t3.field_id = '{$interest_rate}' AND t4.field_id = '{$display_color_hex}' ORDER BY t1.meta_value;";
return $wpdb->get_results($sql);
}
/* this creates the inline CSS for the page the form is on */
function masterminds_render_ibcpbarchart_css() {
$lu_results = masterminds_icpfrm_config();
$chart_css = "<style>" . PHP_EOL;
$chart_css .= ':root {' . PHP_EOL . '--icpfrm-chart-background-color: rgba(247, 247, 247, 0.76);' . PHP_EOL . '--icpfrm-chart-label-default: rgb(45,55,72);' . PHP_EOL . '--icpfrm-chart-dark-gray: rgb(81,81,81);' . PHP_EOL . '--icpfrm-chart-light-gray: rgb(223,223,223);' . PHP_EOL . '--icpfrm-chart-text-color: rgb(26,32,44);' . PHP_EOL . '--icpfrm-chart-accent-color: rgb(24,151,178);' . PHP_EOL . '--icpfrm-chart-white: rgb(253,254,255);' . PHP_EOL . '}' . PHP_EOL;
$chart_css .= 'body {' . PHP_EOL . 'color: var(--icpfrm-chart-text-color);' . PHP_EOL . 'background-color: var(--icpfrm-chart-white);' . PHP_EOL . '}' . PHP_EOL;
$chart_css .= '.r0_int { color: var(--icpfrm-chart-label-default); }' . PHP_EOL;
foreach ( $lu_results as $lu_entry ) {
$chart_css .= '.' . $lu_entry->rate_id . ' { color: ' . $lu_entry->display_color_hex . ' !important; }' . PHP_EOL;
}
$chart_css .= '.chart-background-color {' . PHP_EOL . 'background-color: var(--icpfrm-chart-background-color);' . PHP_EOL . 'border: solid 1px var(--icpfrm-chart-text-color);' . PHP_EOL . 'padding: 1rem;' . PHP_EOL . '}' . PHP_EOL;
$chart_css .= '/* add styling for slider currencies */' . PHP_EOL . '.frm_range_value_currency {' . PHP_EOL . 'text-align: center;' . PHP_EOL . 'font-size: 16px;' . PHP_EOL . 'display:block;' . PHP_EOL . '}' . PHP_EOL;
$chart_css .= '/* hide the default span */' . PHP_EOL . '#field_icpfrm_initial_deposit ~ .frm_range_value, #field_icpfrm_monthly_contribution_amt ~ .frm_range_value {' . PHP_EOL . 'display:none !important;' . PHP_EOL . '}' . PHP_EOL;
$chart_css .= '.frm_style_formidable-style.with_frm_style input[type="range"]::-moz-range-progress {' . PHP_EOL . 'background-color: var(--icpfrm-chart-dark-gray) !important;' . PHP_EOL . '}' . PHP_EOL;
$chart_css .= '.with_frm_style input[type="range"]::-moz-range-track {' . PHP_EOL . 'background-color: var(--icpfrm-chart-light-gray) !important;' . PHP_EOL . '}' . PHP_EOL;
$chart_css .= '.chart_risk_background {' . PHP_EOL . 'background-color: var(--icpfrm-chart-text-color);' . PHP_EOL . 'padding: 1rem;' . PHP_EOL . 'border: solid 1px var(--icpfrm-chart-text-color);' . PHP_EOL . 'border-top-left-radius: 14px;' . PHP_EOL . 'border-top-right-radius: 14px;' . PHP_EOL . 'position: relative;' . PHP_EOL . 'top: 14px;' . PHP_EOL . 'margin-bottom: 0 !important;' . PHP_EOL . '}' . PHP_EOL;
$chart_css .= "</style>" . PHP_EOL;
return $chart_css;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment