PageSourceSearch

https://ideascale.com/wp-content/plugins/ideascale-roi-calculator/js/ideascale-roi-calculator.js?ver=1.0.2

js ideascale.com collected 2026-10-02 02:12:24 UTC 4,765 bytes, 122 lines download raw bytes

1document.addEventListener('DOMContentLoaded', () => {
2  const calculator = document.getElementById('ideascale-roi-calculator');
3  if (!calculator) return;
4
5  const calculateButton = document.getElementById('calculate-roi');
6  const resetButton = document.getElementById('reset-roi');
7  const inputFields = calculator.querySelectorAll('input[type="text"]');
8
9  function calculateROI() {
10    const audienceSize = parseInput('audience_size', 1500);
11    const employeeSize = parseInput('employees_size', 1000);
12    const participationRate = parseInput('participation_rate', 5.0) / 100;
13    const revenueValue = parseInput('revenue_value', 1000000000);
14    const annualRevenue = parseInput('annual_revenue', 0.5) / 100;
15    const goodIdeas = parseInput('good_ideas', 1);
16    const implementationRate = parseInput('implementation_rate', 10) / 100;
17    const ideascaleCost = 48234;
18    const employeeCost = parseInput('employee_cost', 70000);
19    const turnoverCost = parseInput('turnover_cost', 50) / 100;
20    const turnoverReduction = parseInput('turnover_reduction', 1.5) / 100;
21
22    const engagedCommunity = audienceSize * participationRate;
23    const newIdeas = engagedCommunity * goodIdeas;
24    const implementedIdeas = newIdeas * implementationRate;
25    const ideaValue = revenueValue * annualRevenue;
26    const totalIdeaValue = implementedIdeas * ideaValue;
27    const roi = ideascaleCost > 0 ? ((totalIdeaValue / ideascaleCost - 1) * 100) : 0;
28    const turnoverReductionEmployees = engagedCommunity * turnoverReduction;
29    const turnoverSavings = turnoverReductionEmployees * employeeCost * turnoverCost;
30    const incrementalEngagedEmployees = turnoverReduction * employeeSize;
31    const costPerChurnedEmployee = employeeCost * turnoverCost;
32    const totalCostSavingsEmployees = incrementalEngagedEmployees * costPerChurnedEmployee;
33
34    updateResults(
35      engagedCommunity, newIdeas, implementedIdeas, ideaValue, totalIdeaValue,
36      ideascaleCost, roi, incrementalEngagedEmployees, costPerChurnedEmployee,
37      totalCostSavingsEmployees, turnoverReductionEmployees, turnoverSavings
38    );
39  }
40
41  function resetForm() {
42    inputFields.forEach(input => {
43      input.value = '';
44    });
45    updateResults(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
46    if (calculateButton) calculateButton.disabled = true;
47  }
48
49  function handleInputChange() {
50    if (calculateButton) calculateButton.disabled = false;
51  }
52
53  if (calculateButton) calculateButton.addEventListener('click', calculateROI);
54  if (resetButton) resetButton.addEventListener('click', resetForm);
55  inputFields.forEach(input => {
56    input.addEventListener('input', handleInputChange);
57    input.addEventListener('input', formatInput);
58  });
59
60  calculateROI();
61});
62
63function safeNumber(value) {
64  return (value != null && !isNaN(value)) ? Number(value) : 0;
65}
66
67function parseInput(id, defaultValue = 0) {
68  const el = document.getElementById(id);
69  if (!el || !el.value) return defaultValue;
70  const cleaned = el.value.replace(/[^0-9.-]+/g, "");
71  const parsed = parseFloat(cleaned);
72  return isNaN(parsed) ? defaultValue : parsed;
73}
74
75function formatInput(event) {
76  const input = event.target;
77  let value = input.value.replace(/[^0-9.]/g, '');
78
79  const parts = value.split('.');
80  if (parts.length >= 2) {
81    value = parts[0] + '.' + parts[1].slice(0, 2);
82  }
83
84  if (value) {
85    const [integer, decimal] = value.split('.');
86    const formattedInteger = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
87    input.value = parts.length >= 2 && decimal !== undefined
88      ? formattedInteger + '.' + decimal
89      : formattedInteger;
90  } else {
91    input.value = '';
92  }
93}
94
95function formatNumber(value) {
96  return safeNumber(value).toLocaleString(undefined, {maximumFractionDigits: 0});
97}
98
99function updateResults(
100  engagedCommunity, newIdeas, implementedIdeas, ideaValue, totalIdeaValue,
101  ideascaleCost, roi, incrementalEngagedEmployees, costPerChurnedEmployee,
102  totalCostSavingsEmployees, turnoverReductionEmployees, turnoverSavings
103) {
104  const fmt = (val) => formatNumber(val);
105  const money = (val) => '$' + fmt(val);
106  const percent = (val) => safeNumber(val).toFixed(2) + '%';
107
108  const setText = (id, text) => {
109    const e = document.getElementById(id);
110    if (e) e.innerText = text;
111  };
112
113  setText('numbercommunitymembers', fmt(engagedCommunity));
114  setText('newIdeas', fmt(newIdeas));
115  setText('implementedIdeas', fmt(implementedIdeas));
116  setText('ideaValue', money(ideaValue));
117  setText('totalIdeaValue', money(totalIdeaValue));
118  setText('roiValue', percent(roi));
119  setText('incrementalEngagedEmployees', fmt(incrementalEngagedEmployees));
120  setText('costPerChurnedEmployee', money(costPerChurnedEmployee));
121  setText('totalCostSavingsEmployees', money(totalCostSavingsEmployees));
122}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.