HOLY COW !!! My eyes just jumping out when i look @ this code
(well my beginnings looked the same, even worse!)
Ok, i even do not know where to start.
We will start with smal things step by step…
- First of all → eleminate all those →
#dropdown15
#dropdown22
#dropdown4312
#dropdown999999
and so on…
This is not how a coder would work!!!
Instead make your code as readable as possible and as less redundant as possible!
You have over 300-codelines, for something what could be written by 50% less of used codelines!
-
The more clean you generate your code → the better for you, because the more you will work on it → the more complexe it will get and the less readable it will become! But if you already start like this, you won’t be able to understand your code after few code lines.
-
You have a big bunch of → HARD-CODINGS <–, this is not a good way to code! It works, but your code needs a lot of maintanance and is not flexible.
In some codeparts i saw some RETURN-FUNCTIONS → well done!!!
Well, let me reduce it a little bit, since your code is really badly readable, i think Dan will agree with me… PRE-VERSION—>
// Product configuration map------------------------------
const productConfig = {
brownies: {
label: "Brownies",
quantityDropdown: '#dropdown1',
flavorDropdowns: ['#dropdown21', '#dropdown28'],
},
cakepops: {
label: "CakePops",
quantityDropdown: '#dropdown9',
flavorDropdowns: ['#dropdown22', '#dropdown29'],
},
cookiesCustom: {
label: "Cookies - Custom",
quantityDropdown: '#dropdown11',
flavorDropdowns: ['#dropdown23', '#dropdown30'],
},
cookiesBakery: {
label: "Cookies - Bakery",
quantityDropdown: '#dropdown13',
flavorDropdowns: ['#dropdown24', '#dropdown31'],
},
macarons: {
label: "Macarons",
quantityDropdown: '#dropdown17',
flavorDropdowns: ['#dropdown26', '#dropdown33'],
},
truffles: {
label: "Truffles",
quantityDropdown: '#dropdown19',
flavorDropdowns: ['#dropdown27', '#dropdown34'],
},
cupcakes: {
label: "Cupcakes",
quantityDropdown: '#dropdown15',
flavorDropdowns: ['#dropdown25', '#dropdown32'],
extraFlavorDropdowns: ['#dropdown42', '#dropdown36', '#dropdown39', '#dropdown43', '#dropdown37', '#dropdown40']
},
cake: {
label: "Cake",
quantityDropdown: '#dropdown45',
flavorDropdowns: ['#dropdown60', '#dropdown61'],
extraFlavorDropdowns: ['#dropdown47', '#dropdown50', '#dropdown53', '#dropdown56', '#dropdown48', '#dropdown51', '#dropdown54', '#dropdown57']
}
};
//Main-CODE---------------------------
$w.onReady(function () {
// Hide all dropdowns initially
hideAllDropdownBoxes();
// Handle checkbox selection changes
$w('#checkboxGroup1').onChange(() => {
console.log("Checkbox values:", $w('#checkboxGroup1').value);
updateProductBoxes();
});
// Automatically update visibility based on pre-checked options
updateProductBoxes();
// Listen to quantity dropdown changes for all products
Object.keys(productConfig).forEach(product => {
const dropdownId = productConfig[product].quantityDropdown;
$w(dropdownId).onChange(() => updateFlavorBoxes(product));
});
});
// FUNCTIONS and more------------------------------------
function updateProductBoxes() {// Update which product boxes to show/hide
const selectedValues = $w('#checkboxGroup1').value || [];
Object.entries(productConfig).forEach(([key, config]) => {
if (selectedValues.includes(config.label)) {
showProductBoxes(key);
updateFlavorBoxes(key);
} else {hideProductBoxes(key);}
});
}
// Show boxes for selected product
function showProductBoxes(product) {
const config = productConfig[product];
$w(config.quantityDropdown).show();
// Show any extra fields
if (product === 'cupcakes') {
$w('#dropdown16').show();
$w('#dropdown41').show();
$w('#dropdown35').show();
$w('#dropdown38').show();
}
if (product === 'cake') {
$w('#dropdown59').show();
$w('#dropdown58').show();
$w('#dropdown46').show();
$w('#dropdown49').show();
$w('#dropdown52').show();
$w('#dropdown55').show();
}
}
// Hide boxes for unselected product
function hideProductBoxes(product) {
const config = productConfig[product];
$w(config.quantityDropdown).hide();
config.flavorDropdowns.forEach(id => $w(id).hide());
if (config.extraFlavorDropdowns) {config.extraFlavorDropdowns.forEach(id => $w(id).hide());}
if (product === 'cupcakes') {['#dropdown16', '#dropdown41', '#dropdown35', '#dropdown38'].forEach(id => $w(id).hide());}
if (product === 'cake') {['#dropdown59', '#dropdown58', '#dropdown46', '#dropdown49', '#dropdown52', '#dropdown55'].forEach(id => $w(id).hide());}
}
// Hide everything on page load
function hideAllDropdownBoxes() {Object.keys(productConfig).forEach(hideProductBoxes);}
// Show flavor dropdowns based on quantity
function updateFlavorBoxes(product) {
const config = productConfig[product];
const quantity = parseInt($w(config.quantityDropdown).value || "0");
// Hide all flavor boxes first
config.flavorDropdowns.forEach(id => $w(id).hide());
if (config.extraFlavorDropdowns) {config.extraFlavorDropdowns.forEach(id => $w(id).hide());}
// Logic for cupcakes and cake (special case)
if (product === 'cupcakes') {
if (quantity >= 2) {$w(config.flavorDropdowns[0]).show(); config.extraFlavorDropdowns.slice(0, 3).forEach(id => $w(id).show());}
if (quantity >= 3) { $w(config.flavorDropdowns[1]).show(); config.extraFlavorDropdowns.forEach(id => $w(id).show());}
} else if (product === 'cake') {if (quantity >= 2) {$w(config.flavorDropdowns[0]).show(); config.extraFlavorDropdowns.slice(0, 4).forEach(id => $w(id).show());}
if (quantity >= 3) {$w(config.flavorDropdowns[1]).show(); config.extraFlavorDropdowns.forEach(id => $w(id).show());}
} else {// Normal product logic
if (quantity === 2) {$w(config.flavorDropdowns[0]).show();}
if (quantity >= 3) {
$w(config.flavorDropdowns[0]).show();
$w(config.flavorDropdowns[1]).show();
}
}
}
So, this one already looks better, but this is only → STEP-1 !!!
In meanwhile do yourself a favour and rename all elements of this example!
a) give all used dropdown-elements (which are initially hidden) appropirate namings and a prefix, like…
- ddnQtyBrownie
- ddnQtyCakePop
- ddnQtyTruffles
…and so on…
a) ddn = stands for DROPDOWN —> making sure you immediatelly recognize the
element inside your code, without having to do unneccessary and timeconsuming
checkings for chosen element-type.
b) Qty = surely will be the QUALITY (additional info like type)
c) Brownie / CakePop / Truffles and so on .. = the PROPERTY itself !!!
So your initial code -----------> 320-Code-Lines
First PRE-VERSION of CN → about 135-Code-lines
You already can feel the difference?
Another question → Why do you HARD-CODE all of your SETUP ?
→ Why not generating this inside a DATABASE (collection) ???
And in one of Dan’s answers it was already mentioned to use…
So next step would be to implement it into code aswell, since just connecting your SUBMIT-BUTTON to your dataset and assuming that the DATASET will know automatically what you have coded → THIS WILL NOT WORK!
A → DATASET ← has it’s own internal PROCESS-FLOW, it will neither listen nor wait for your generated code, as long as you do not connect is also programmatically, like already mentioned!
Further steps would be…
-
.. to reduce and clean up your code one more time, maybe reaching a code-length of max. 100-CODE-LINES
-
..to remove all hardcodings and use a flexible DATABASE instead (again removing unneccessary STATIC-CODING!
Dan will do the rest 
EDIT: And code-blocks like…
if (product === 'cake') {
$w('#dropdown59').show();
$w('#dropdown58').show();
$w('#dropdown46').show();
$w('#dropdown49').show();
$w('#dropdown52').show();
$w('#dropdown55').show();
}
… can be reduced by a loop like…
if (product === 'cake') {
[
'#dropdown59',
'#dropdown58',
'#dropdown46',
'#dropdown49',
'#dropdown52',
'#dropdown55'
].forEach(id => $w(id).show());
}