I am developing this code for a storytelling type game and I need to change the dropbox options after the user or player is done selecting their option. I am trying to make the options in the dropbox relevant to what is happening in the game at the given moment. I was told to do research on a possible change of element(with different options in the dropbox) every time the user has chosen their option.
I have tried some jquery, but only moved the dropbox on click. I could not find any type of operator that could help me with changing it. The append bit in my code is submitting the input and getting an outcome
<div id="actions">
<select id="chosen_action">
<option value="You have entered the dungeon...">Yes</option>
<option value="You turned and left THE END">No</option>
<option value="You attempted to communicate with the enemy...">Talk</option>
</select>
<button onclick="append_to_history()">Go!</button>
</div>
You can do this really easily with .innerHTML:
$("#chosen_action").innerHTML = `
<option>You turn away from the castle</option>
<option>You take a closer look at the old drawbridge</option>
<option>You decide to consult your map</option>
`;
.innerHTML simply changes the HTML content of a given element. The backtick operators (`) form a template string, which is capable of spanning multiple lines, making it easier to lay out your new options. You could use a regular string here instead if you'd like (and of course can generate this value with a loop, array, etc).
const choice = document.getElementById('chosen_action');
const opt1 = document.getElementById('option1');
const opt2 = document.getElementById('option2');
const opt3 = document.getElementById('option3');
const go = document.getElementById('goButton');
go.addEventListener('click',(e) => {
if(choice.value !== ""){
if(choice.value === opt1.value){
opt1.value = ... //change the value of this element
opt2.value = ...
opt3.value = ...
//if need to change value of text shown to user for selection you can:
opt1.textContent = ...//change the text of this element
opt2.textContent = ...
opt3.textContent = ...
} else if(choice.value === opt2.value){
...
...
...
} else{
...
...
...
}
} else {
alert("You must make a choice to continue!")
}
})
<div id="actions">
<select id="chosen_action">
<option id="option1" value="You have entered the dungeon...">Yes</option>
<option id="option2" value="You turned and left THE END">No</option>
<option id="option3" value="You attempted to communicate with the enemy...">Talk</option>
</select>
<button id="goButton" onclick="append_to_history()">Go!</button>
</div>
I can't comment to gather more information, so, without knowing more about what you are asking, or where your game is going, or what "append_to_history()" does, or how many possible combinations there are, etc., this is one way of doing what you need to do.
In the end, I would guess you will have to make a giant object, or a great deal of smaller objects, and come up with a naming system that you can programmatically grab the proper values from when it comes time. Probably a tracker to count the number of choices (each button click) and then name your objects accordingly, so that you can use the tracker value and the option number to call the correct value. You will have to figure out, at some point, every single possible value and then programmatically call them for each new value depending on the value chosen at time of click.
Would be interested to know if anyone else has any different perspective on this, though!
Related
for example - a profile page - users want to change some values in select tags
you cannot say - <select id='lorem' value='ipsum'>
you must go to javascript - $('#lorem').val('ipsum')
is this really true ?
is there any better practice - if you have a lot of select tags ?
btw - why html developers made this like this - there must be some strong reason
Your "question" really embodies multiple questions, hence I divided my answer into multiple sections.
<select> and <option>
To select an <option> of <select> initially, add the selected-attribute to <option>. Selecting an <option> makes the <select> have the value of the selected option.
var select = document.querySelector('select');
var code = document.querySelector('code');
select.addEventListener('change', () => code.textContent = select.value);
code.textContent = select.value;
body {display:flex;align-items:center;gap:0.5rem}
code {padding:0 0.2rem;background:lightgray}
<select>
<option value="first">First option</option>
<option value="second" selected>Second option, initially selected</option>
<option value="third">Third option</option>
</select>
<span>Select's 'value': <code></code></span>
Giving <select> a value-attribute will be ignored by the browser-engine, since HTML5 doesn't specify the <select>-tag to have a value-attribute.
Note: The HTML-attribute value and the JavaScript property .value are not necessarily related to each other.
See this example for reference:
var select = document.querySelector('select');
var code = document.querySelector('span > code');
select.addEventListener('change', evt => {
code.textContent = evt.target.value;
});
code.textContent = select.value;
body {display:flex;flex-flow:column;align-items:flex-start;gap:0.5rem}
code {padding:0 0.1rem;background:lightgray}
<div>
<code><select></code> has the attribute <code>value="from-select"</code>.
</div>
<select value="from-select">
<option value="from-opt1">Opt1</option>
<option value="from-opt2">Opt2</option>
</select>
<span>Select's 'value': <code></code></span>
To change the value of an <option> dynamically, you would have to use JavaScript.
var input = document.querySelector('input');
var option = document.querySelector('option');
var code = document.querySelector('code');
// Ignore; update 'pre.textContent' when changing 'value'
option.setAttribute = function(name, value) {
HTMLElement.prototype.setAttribute.call(this, name, value);
if (name === 'value') code.textContent = value;
};
// How to change the 'value'-attribute using JS
document.querySelector('button').addEventListener('click', () => {
option.setAttribute('value', input.value);
input.value = '';
});
body {display:flex;flex-flow:column;align-items:flex-start;gap:0.5rem}
code {padding:0.1rem 0.2rem;background:lightgray}
<span>
<input>
<button>Change value of 'Option'</button>
</span>
<select>
<option value="initial-value">Option</option>
</select>
<span>Option's value: <code>initial-value</code></span>
Regarding "why html developers made this like this"
Paraphrased: Why can't HTML change its markup on its own?
Reason is, HTML was initially created for scientific documents served via the internet.
Since the internet is by nature a web of interconnected, potentially completely different devices, HTML had to be as unspecific and "device-agnostic" as possible, to allow rendering it on virtually any device that has a display.
For that reason, any further resource (e.g. stylesheets, scripts, images) should only be optional for the rendering of the HTML, as the HTML should be renderable "as is".
HTML should also be backwards-compatible, meaning that future changes to the HTML specification should in no way hinder the serving of the HTML. That means, any unknown... thing, basically, will be ignored by the rendering engine (todays browsers) so that all the then-existing features can still work as intended.
Initially, HTML was not intended to have any further functionality than serving static content. However, over the last few decades, the internet has had its "boom" of technological advancement, and now, JavaScript is de facto part of any browser-engine and website, enabling them to have advanced functionality and be interactive.
The internet is in a state of ongoing development, and always will be. Neglecting the new state of the internet and its specification (e.g. for the browser-engines, etc.) would mean that one is not moving with the times, withholding new, modern and current information and knowledge from oneself, essentially leaving one behind.
"Tradition" is difficult to find in any technical field, as new advancements and discoveries are simply spoken part of them.
To learn more about the roots of the internet (even though the video is thematically about CSS) I recommend watching MDN's video about why CSS is weird (and how HTML came to be).
Regarding your "question" ...
as you have further explained in the comments:
I have some data about each user in database. Those data are from
registration form. That form has select tags. Now, user want to change
some data on his profile. Tha data need to be presented on select
tags. It would be normal to do that using value attribute, like in any
other input - without javascript
You could do it two ways:
Create a <form> with one field for each user-data. With this, you have two more options:
Prepare the fields to hold their current data. The user can then submit his changes easily.
Leave the fields empty. If a field is empty after submission, ignore the proposed "change".
Let the user select what data to change one at a time. Again, two more options to achieve this:
Fetch the current data for that field. The user can change it and then submit it easily, again.
Let the user enter the new data anew, then submit it.
Here is a simple example of how the HTML for option 2.2 could look when implemented:
Note: I changed the <button>'s default type from type="submit" to type="button" for demonstration-purposes.
var select = document.querySelector('select');
var input = document.querySelector('input');
document.querySelector('button').addEventListener('click', () => {
console.log(`Would change user-data '${select.value}' to the value '${input.value}'.`);
});
<form>
<select>
<option value="name">Name</option>
<option value="address">Address</option>
<option value="email">E-Mail</option>
</select>
<input>
<button type="button">Submit</button>
</form>
I have some web pages which display a number of (up to several dozen) work items.
Each work item is a form consisting of several fields, two of which are large selects (one about 350 items and the other about 650 options) which are always identical other than the initially selected item.
The page can be pretty slow to load. Some of this may be due to the 24KB + 52KB of html for each copy of those selects, and I'm betting a fair amount of it is the time for the browser to build what is essentially the same huge chunk of (mostly of no interest) DOM over and over again.
What I'm thinking might be better is to just keep a master copy of the options for each in an array and just start each select out with only a single option (the initially selected value), For example:
<form ...>
<input ...>
<select class='dept_select' id='dept' name='dept' size='1'>
<option value='12345' selected>Department of Banking and Finance
</select>
<select class='approver_select' id='approver' name='approver' size='1'>
<option value='jpflat' selected>J. Pierpont Flathead
</select>
</form>
and then when the user clicks on the one selectbox they are interested in, build the rest of it from the array. Is this at all sensible, and if it might be, is there some clever and succinct way to do this in jQuery or am I going to have to invent it from whole cloth and raw JavaScript? FWIW, there's no real correlation between the selects (e.g., like selecting a state limits the valid choices for selecting a city).
I'm not going to post code so far. I recommend to re-build your concept a bit to get to a simpler structure:
A user can only edit one item at a time. There's no need to generate "a couple of dozen forms", as long as no edit action is taken.
render the items as a simple two-dimensional array with rows and fields, preferable in a JSON
built the table of items dynamically in the client by use of jQuery
if the user wants to edit an item, open a div layer, render a form into it by the use of the above array. Of course with just one single set of these dropdowns.
consider to load these dropdowns on request by AJAX or use some "combo box" features like in jQuery ui (below).
on "save" submit the form and close the div layer
There are certain containers and dialogs ready-to-use in jQuery ui to achieve this. The result will be
more generic code
less html overhead
better usability even
Well, turns out it wasn't as hard as I was imagining it...
<form ...>
<select id="ts" name="ts" size="1" class="tsc">
<option value="12345" selected>This is the initial value</option>
</select>
</form>
and:
var arr = [
{V:'alpha',T:'One'},
{V:'bravo',T:'Two'},
{V:'charlie',T:'Three'}
];
$(function() {
$( '.tsc' ).mousedown(function() {
var sel = $(this);
sel.unbind('mousedown');
$(arr).each(function() {
sel.append($('<option>')
.attr('value', this.V)
.text(this.T));
});
});
});
jQuery rocks.
I need to display a specific option inside a select based on certain values of the zip code.
So far I've managed to do the opposite, hide it based on values of the zip, but that is too easy to game.
<script type="text/javascript">
$(function(){
var $location = $('#ShippingOptions');
$location.data('options', $location.find('option')); //cache the options first up when DOM loads
$('#zip').on('change', function () { //on change event
$location.html($location.data('options')); //populate the options
if ($(this).val() == "12345" ) { //check for condition
$location.find("option[value='300305']").remove(); //remove unwanted option
}
if ($(this).val() == "54321" ) { //check for condition
$location.find("option[value='300305']").remove(); //remove unwanted option
}
});
});
</script>
<!--Zip-->
<div class="zip-field">
<label for="zip">Zip Code</label>
<input type="number" id="zip" name="zip" />
</div>
<!--Location-->
<div class="location-field">
<label for="location">Location</label>
<select class="shippingDropDown" id="ShippingOptions" name="ShippingOptions"><option value="-1">Choose Shipping Option</option>
<option value="300305">Free Shipping $0.00</option></select>
</div>
I do no have access to add classes to the options, they are dynamically generated by a rendering engine. I can however target values which stay fixed.
The plan was to have it hidden by default, then adding conditions in which to show it. This is not about setting a value to an option but showing/hiding an option with a certain value
A little background story: the system I work with gives me the option to add various types of shipping some free some paid. However, because there is no way to discern/filter between them, especially by zip, I am left in the hilarious position of letting the users choose either free shipping or paid shipping which, as human nature goes, it's pretty much pointless. So my idea was to have the user enter their zip and show the free option, which can only be identified by value, only to those that have a specific zip (full number) and not to anybody else. I am aware of the security issues and willing to live with them.
Is there a way to add/show that option instead of removing it? Is there a way to set it selected?
<select class="zip-list">
<option value="26598">New York</option>
<option value="19356">Mexico</option>
<option value="26825">Artic Ocean</option>
<option value="93583">A Village</option>
</select>
<p><input type="text" class="zip-filter" /></p>
var $zipList = $('.zip-list');
var $zipOptions = $('option', $zipList);
var $zipOptionsAll = $zipOptions.clone();
$('.zip-filter').on('change', function () {
var filterText = $(this).val();
var $filteredOptions = $zipOptionsAll.filter(function(e) {
return $zipOptions.eq(e).val().indexOf(filterText) === 0;
});
if ($filteredOptions) {
$zipList.empty().append($filteredOptions);
} else {
$zipList.empty().append($zipOptionsAll);
}
});
Fiddle: http://jsfiddle.net/ekEY4/
Should be pretty self explanatory. Note that since you are listening to the change event you have to loose focus on the text by clicking/tabbing out or pressing return before it updates.
I am also doing a "begins with" string check (indexOf) as I figure with something like postcode/zipcode you will want to show all results that begin with a certain area code before narrowing down. That means if you had "26598" and "26825" in the list and they searched for "26" both would come up.
"When the filter changes loop through and filter all the options that begin with the query. If something is found set those options, otherwise reset back to all options as nothing was found."
Edit:
Oh you want the inverse - easy. Simply change indexOf(filterText) === 0 to indexOf(filterText) !== 0.
Fiddle: http://jsfiddle.net/v3ZDE/
I know this has been asked before, however I cannot find a solution to my problem.
I have a select box with three options and three values, these values are used to perform some calculations using JS so I cannot change these to match the option text. This is to work out the amount of V.A.T.
My select looks like this:
<select name="tax" id="tax" class="select">
<option value="20">Standard 20%</option>
<option value="0">Zero 0%</option>
<option value="0">Exempt 0%</option>
</select>
Which is fine, however I need to insert the text into the database and not the values, as it needs to be viewed in the backend. I have tried a javascript function to add a hidden input to the select box targeting the option that is selected but that was a bit buggy, and didn't seem right. i was thinking of displaying the text next to the value when it is retrieved from the database, however I wouldn't be able to distinguish from the two 0 amounts.
Could someone please offer some further solutions, best approaches to this.
Many Thanks
You can get the text of the selected option with jQuery as follows:
$("#tax option:selected").text();
You could easily use this within your AJAX request to send the correct value to the database, just assign it to a variable:
var the_text = $("#tax option:selected").text();
Failing that, why not just do the lookup in the JS calculations - it'd make your life so much easier:
<select name="tax" id="tax" class="select">
<option value="standard">Standard 20%</option>
<option value="zero">Zero 0%</option>
<option value="exempt">Exempt 0%</option>
</select>
And your JS could look something like this:
var vat_amount = ($('#tax').val() == 'standard') ? 20 : 0;
You can retrieve the text by JS using the html() function. Or, if you are just using a POST to send the data to the server, try adding both values to the value attribute of the option and split it server side to get the right data.
I am building a calculator form to allow people to calculate the cost of running electrical appliances. They can select an appliance, as an example, from a dropdown list and this should prepopulate the text fields with the figures necessary for the calculation. Here is the form:
<form action = "<?php echo $_SERVER['PHP_SELF']; ?>" method = "POST">
<label>Appliance</label>
<select id="list" >
<option value="select">Select</option>
<option value="dishwasher">Dishwasher</option>
<option value="iron">Iron</option>
</select>
<label>Watts</label> <input name="watts" /><br>
<label>Hours</label> <input name="hours" /> <br>
<label>Price</label> <input name="price" /> <br>
<label>Number</label> <input name="number" /> <br>
<label>Total</label> <input name="total" value="" id="total"></input>
</form>
When a user selects an appliance I want the input fields to be filled something like this:
case 'dishwasher':
$('input[name="watts"]').val('1200');
$('input[name="hours"]').val('20');
$('input[name="price"]').val('10');
$('input[name="number"]').val('1');
Then do some calculation on the figures:
kilowatts = watts / 1000;
kwhours = kilowatts * hours;
costpounds = kwhours * price / 100;
total = costpounds * number
and put the total into the total field in the form, the idea is to also allow the user to change the figures, or even just add their own, in the form and the total updates accordingly. I can get all the individual bits to work, but don't know jquery well enough to put it all together. Help would be greatly appreciated. Thanks!
Here is some javascript / jquery to get you started. There are more efficient ways, but those are very confusing for someone just learning.
//when the document is finished being rendered, this fires
$(document).ready(function(){
//if the user changes the value in the select dd, this fires.
$('#list').change(function(e){
changeInputValues(this.val());
});
// standard JS function to set the input values with defaults for a given drop down. your idea ;)
function changeInputValues(ddValue){
//put your Case 'dishwasher' code here, one case for each Drop down value
//$('input[name="watts"]').val('1200');
//$('input[name="hours"]').val('20');
//$('input[name="price"]').val('10');
//$('input[name="number"]').val('1');
//recalculate the figures
recalculate();
};
// when someone changes an input, but not the Drop Down, we have that on already.
$('input').not('select').change(function(e){
recalculate();
});
function recalculate(){
// get the current values, then do your math
//var currentWatts = $('input[name="watts"]').val();
//var currentHours = $('input[name="hours"]').val();
//....
//var total = 0;
// do more math... whatever you want
//set the 'visible' value
$('input[name="total"]').val(total)
};
});
So basic structure is 2 functions.
Called when the "appliance" select is changed. Takes all the values of the item selected by grabbing the id like $(this)find('selected').attr('id')*. Once you have the id of the select appliance you can use it to pull the correct values from your appliance arrays and then it's easy to $(this).find('name_of_filed').text("value from the array") with a little for each loop.
called when any other field is onChanged (or you can make an update button in case it's annoying to have it constantly updating while you are making multiple changes). Also called at the end of function 1. Takes all the values from the fields, does calculation, inserts into "total" field.
you can certainly break this down much further to smaller pieces if you want it to be more easily edited in the future and to reuse any of this code but if it's going to be a one of then I wouldn't bother splitting it much more than this.
I can get a lot more specific if need be but I figure it's better for you to try and figure specifics out to learn as you go and we here at SO can answer specific questions as you go.
*may not be actuall correct code. I'm lazy and you will learn more this way! ;)