Reagan
May 24, 2023, 3:02am
#1
Hey all, what would be the best way to make dynamic input calculators? They do not need to be sent back to a DB, I just want some sort of calculated field that automatically updates on user input / slider.
The calculators I’m talking about are mortgage calcs / comparison calculators.
Has anyone tackled this problem already?
Hey @Reagan , you can achieve this use case in Softr. You will need to have a formula/calculator in your database to calculate the sum. On the Softr side, add a form block so that the users can add the numbers to your database and add a Summary block to show the final calculation (both form and summary blocks should be linked to the table/sheet.
hi, In my opinion, the best you can do is to add a custom code block, then you can write your own script code to do this.
Reagan
May 24, 2023, 11:55pm
#4
Okay I have made some headway:
Style:
<style>
.row-heading
{
font-size:1.3rem;
font-weight:bold;
}
.total
{
font-size:2rem;
font-weight:bold;
}
.total-val
{
font-size:2rem;
border:
}
</style>
Script:
<script>
document.addEventListener('DOMContentLoaded', function() {
let unit_price = {
sugar: 22,
butter: 12,
eggs: 2,
vanilla: 43
};
let item_price = {};
function calculatePrice(item, qty) {
return qty * unit_price[item];
}
let qtySugar = document.querySelector('#qty_sugar');
let qtyButter = document.querySelector('#qty_butter');
let qtyEggs = document.querySelector('#qty_eggs');
let qtyVanilla = document.querySelector('#qty_vanilla');
let priceSugar = document.querySelector('#price_sugar');
let priceButter = document.querySelector('#price_butter');
let priceEggs = document.querySelector('#price_eggs');
let priceVanilla = document.querySelector('#price_vanilla');
let totalValue = document.querySelector('#total_value');
function calculateTotal() {
item_price.sugar = calculatePrice('sugar', qtySugar.value);
priceSugar.value = item_price.sugar;
item_price.butter = calculatePrice('butter', qtyButter.value);
priceButter.value = item_price.butter;
item_price.eggs = calculatePrice('eggs', qtyEggs.value);
priceEggs.value = item_price.eggs;
item_price.vanilla = calculatePrice('vanilla', qtyVanilla.value);
priceVanilla.value = item_price.vanilla;
let total = item_price.sugar + item_price.butter + item_price.eggs + item_price.vanilla;
totalValue.textContent = total;
}
let qtyInputs = document.querySelectorAll('.qty');
qtyInputs.forEach(function(input) {
input.addEventListener('change', calculateTotal);
input.addEventListener('keyup', calculateTotal);
});
});
</script>
Code:
<div class="container mt-4">
<div class="row">
<div class="col-6 row-heading">
Item
</div>
<div class="col-3 row-heading">
Quantity
</div>
<div class="col-2 row-heading">
Price
</div>
</div>
<div class="row">
<div class="col-6">
1. Powdered white sugar (cups)
</div>
<div class="col-3">
<input type="number" value="0" class="qty" id="qty_sugar"/>
</div>
<div class="col-2">
<input type="number" readonly value="0" id="price_sugar"/>
</div>
</div>
<div class="row my-3">
<div class="col-6">
2. Butter salted (grams)
</div>
<div class="col-3">
<input type="number" value="0" class="qty" id="qty_butter"/>
</div>
<div class="col-2">
<input type="number" readonly value="0" id="price_butter"/>
</div>
</div>
<div class="row my-3">
<div class="col-6">
3. Eggs (count)
</div>
<div class="col-3">
<input type="number" class="qty" value="0" id="qty_eggs"/>
</div>
<div class="col-2">
<input type="number" readonly value="0" id="price_eggs"/>
</div>
</div>
<div class="row my-3">
<div class="col-6">
4. Vanilla extract (ml)
</div>
<div class="col-3">
<input type="number" class="qty" value="0" id="qty_vanilla"/>
</div>
<div class="col-2">
<input type="number" readonly value="0" id="price_vanilla"/>
</div>
</div>
<div class="row my-4">
<div class="col-9 text-right total">
Total
</div>
<div class="col-2 total-val">
<span id="total_value">0</span
</div>
</div>
</div>
The code works which is good.
I think the style / body is okay but I think the script could improve. Any thoughts?
1 Like
Reagan
May 25, 2023, 4:53am
#5
To add, I just came across your generator tools. They are awesome!
ie SVG Shape Generator – Create SVG shapes for your designs
It would be awesome if this could become a block
@Reagan thanks a lot for the provided codes
Regarding the SVG Shape Generator tool, do you mean that you want those shapes added to our block colors?
Reagan
May 25, 2023, 10:30am
#7
Its more so the concept of having a generator block itself. The other cool thing about your generator is that it has a slider & it generates the content in real time.
Do you know whether these were created using softr blocks / blocks enhanced with some code?
I guess something like this could be achieved by allowing summary blocks to pull content directly from a form block on the same page in real time?
I’d imagine it would have to be at the source level so instead of looking at a data source it’d pull content from the form.
Reagan
June 2, 2023, 3:51am
#8
Here is a generic calculated form calculator. You will need to update your code for your calculation needs.; Just chuck in the custom code block and go from there.
<style>
body {
font-family: Arial, sans-serif;
background-color: #f7f7f7;
margin: 0;
padding: 20px;
}
h1 {
text-align: center;
}
form {
background-color: #fff;
border-radius: 5px;
padding: 20px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
fieldset {
margin-bottom: 20px;
border: none;
}
legend {
font-weight: bold;
margin-bottom: 10px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
input[type="number"],
input[type="range"] {
width: 100%;
padding: 10px;
border-radius: 3px;
border: 1px solid #ccc;
transition: border-color 0.3s ease;
}
input[type="number"]:focus,
input[type="range"]:focus {
outline: none;
border-color: #007bff;
box-shadow: 0 0 5px rgba(0, 123, 255, 0.5);
}
input[type="number"].error,
input[type="range"].error {
border-color: red;
}
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type="range"] {
-webkit-appearance: none;
width: 100%;
height: 10px;
margin-top: 5px;
margin-bottom: 10px;
background-color: #f2f2f2;
transition: background-color 0.3s ease;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #007bff;
cursor: pointer;
transition: background-color 0.3s ease;
}
input[type="range"]:hover::-webkit-slider-thumb {
background-color: #0056b3;
}
button[type="submit"],
button[type="reset"] {
display: block;
width: 100%;
padding: 10px;
margin-top: 10px;
background-color: #007bff;
color: #fff;
border: none;
border-radius: 3px;
cursor: pointer;
transition: background-color 0.3s ease;
}
button[type="submit"]:hover,
button[type="reset"]:hover {
background-color: #0056b3;
}
#output {
margin-top: 20px;
padding: 20px;
background-color: #f2f2f2;
border-radius: 5px;
}
#output h2 {
margin-bottom: 10px;
}
#calculationResult {
font-size: 24px;
font-weight: bold;
}
</style>
<h1>Calculated Column Form</h1>
<form>
<fieldset>
<legend>Section 1</legend>
<label for="input1">Input 1:</label>
<input type="number" id="input1" name="input1" required>
<label for="input2">Input 2:</label>
<input type="number" id="input2" name="input2" required>
</fieldset>
<fieldset>
<legend>Section 2</legend>
<label for="input3">Input 3:</label>
<input type="number" id="input3" name="input3" required>
<label for="slider">Slider:</label>
<input type="range" id="slider" name="slider" min="0" max="100" step="1">
<span id="sliderValue">50</span>
</fieldset>
</form>
<div id="output">
<h2>Calculated Column Output:</h2>
<p id="calculationResult">-</p>
</div>
<script>
// JavaScript code for slider value display and automatic output update
var input1 = document.getElementById("input1");
var input2 = document.getElementById("input2");
var input3 = document.getElementById("input3");
var slider = document.getElementById("slider");
var sliderValue = document.getElementById("sliderValue");
var calculationResult = document.getElementById("calculationResult");
function updateOutput() {
var result = parseInt(input1.value) + parseInt(input2.value) + parseInt(input3.value) + parseInt(slider.value);
calculationResult.textContent = result;
}
input1.addEventListener("input", updateOutput);
input2.addEventListener("input", updateOutput);
input3.addEventListener("input", updateOutput);
slider.addEventListener("input", function() {
sliderValue.innerHTML = this.value;
updateOutput();
});
</script>