Summary
In this post, I share how I built a dynamic JavaScript dropdown that pairs prices with readable text, auto-selects single options, and keeps inputs clean and consistent.
When building complex order forms, sometimes you need more than just numbers.
I wanted a way to store both the price and the readable text for each selected option — clean, trimmed, and paired with its corresponding add-on name. Later, this logic evolved into a dynamic dropdown that automatically selects the only available option.
Here’s how I done the whole thing.
Step 1: Retrieving the Price and Text from the Selected Option
It all started with a simple goal:
I can get the price, but I also want the corresponding text.
Initially, my code looked like this:
layersPriceSum += parseInt($(this).find('option:selected').data('price'));
layersPriceSumText += parseInt($(this).find('option:selected'));
That second line obviously didn’t work — parseInt() can’t handle a jQuery object, so it returned NaN.
The fix was simple:
layersPriceSumText += $(this).find('option:selected').text();
This gave me the visible text from the dropdown instead of NaN.
Step 2: Cleaning Up the Text
Raw .text() can often include unwanted whitespace or line breaks.
So I normalized everything with a single, reliable regex:
let priceText = $(this).find('option:selected').text().trim().replace(/\s+/g, ' ');
Now, no matter how messy the HTML was, my output was always clean: Extra chocolate layer
Step 3: Including the Add-on Name
The next step was to make the stored text more descriptive – not just “Extra large”, but “Chocolate coating – Extra large”.
Each add-on had this structure:
<div class="addon" data-template="szalgyertya" data-price="80">
<div class="addon__badge">
<span class="addon__title">Szál gyertya</span>
</div>
<select>…</select>
</div>
So, I extracted the add-on name like this:
let addonName = $addon.find('.addon__title').text().trim().replace(/\s+/g, ' ');
let priceText = addonName + ' – ' + $addon.find('option:selected').text().trim().replace(/\s+/g, ' ');
That produced clean, contextual strings like: “Szál gyertya – Extra large”
Step 4: Writing the Result into a Hidden Field
Since I wanted to pass this data through the form without showing it to the user,
I created a hidden <textarea> field:
<textarea name="price_comment" maxlength="1000" style="display:none;"></textarea>
Then, instead of saving the text to an internal variable, I simply updated the textarea:
$('textarea[name="price_comment"]').val(sumText);
This way, the field stays invisible but still gets submitted with the form – never use disabled, because those values aren’t sent.
Step 5: Dynamic Dropdown with Auto-Select
Next, I built a dynamic <select> that pulls options from a flavors array:
let options = '<option value="">Choose a flavor</option>';
for (const i in flavors) {
const flavor = flavors[i];
const price = flavor.price + topDecorationPrice + waferPrice;
options += '<option data-price="' + price + '" value="' + flavor.variation_id + '">' +
flavor.name + ' (' + CakeOrder.formatPrice(price) + ')</option>';
}
$row.find('select').append(options);
If there was only one flavor, it made sense to auto-select it immediately:
Step 6: Updating and Displaying the Selection
Finally, whenever the user picked something, I updated both the total and the readable text:
$row.find('select').on('change', function() {
const selected = $(this).find('option:selected');
const price = parseInt(selected.data('price'));
const text = selected.text().trim().replace(/\s+/g, ' ');
layersPriceSum += price;
layersPriceSumText += text + '<br>';
});
Everything was clean, readable, and automatic.
What I Learned
- Never parse DOM elements as numbers. .data() is for data, .text() is for humans.
- Whitespace cleanup is gold. A simple regex makes dynamic text perfectly consistent.
- Hidden fields beat disabled inputs. They submit silently without breaking logic.
- Small UX details matter. Auto-selecting the only flavor turns a clunky step into a seamless one.
- Readable data structure = maintainable code. Having both price and text stored together simplified later debugging immensely.
Final Thoughts
This small system turned into a surprisingly powerful and clean workflow — prices, add-on names, and user-readable strings all handled dynamically, safely, and elegantly.
It’s a great example of how improving tiny technical details can make the overall user experience feel polished and professional.
The less the user has to think, the smarter your interface feels.
Buy me a coffee?
If you enjoyed this story, you can buy me a coffee. You don’t have to – but it means a lot and I always turn it into a new adventure.
Buy a coffee for Steve

Linktree
Short introduction