I've been spending the past couple of days researching on W3C and SO (this being the closest issue I found to mine), to dynamically load a "static" JSON into a dynamically created datalist.
More details on what I'm trying to achieve - I'm trying to create a form to add records to a database; default form allows to add one record, but there's a button to dynamically add another set of empty fields to submit multiple records at once. Once all form is filled in, this is sent to PHP for processing. I'm using bootstrap for the frontend (though I'll try to clean the code for readability).
Load page for the first time, save the JSON into a "HTML variable". Note the page has already one datalist.
Should the user click on the button to add another set of fields, these appear (including an additional datalist)
Objective: this newly created datalist should be populated with the JSON saved in the HTML Variable in point no. 1
Two questions:
Is this doable? As in, do HTML vars have a persistent scope even if I change the DOM?
If so, what am I doing wrong in the code below?
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>?do=addnewstructure" enctype="multipart/form-data">
<input list="datalistOptions" id="datalisttype1" name="deftype_ent[]" placeholder="Type to search..." onFocus="populate_datalist(types_json);">
<datalist id="datalistOptions">
<option value="first">First persistent option</option>
</datalist>
</div>
<div>
<label for="value_ent">Name</label>
<input type="text" name="defvalue_ent[]" id="value_ent">
</div>
<div>
<label for="relevance_ent">Relevance</label>
<select id="relevance_ent" name="relevance_ent">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</div>
<script>
var types_json = document.createElement("list_of_types");
var dataList = document.getElementById("datalisttype1");
var types_json = [<?php
echo json_encode($results_json); // This is coming from backend, it is valid JSON
?>];
// Loop over the JSON array.
function populate_datalist(which_dl)
{
which_dl.forEach(function(item) {
var option = document.createElement('option');
option.value = item.type_id;
option.text = item.name;
dataList.appendChild(option);
});
}
</script>
<button type="submit">Add</button>
</form>
I know this may be a noob question as I just started with js, only did BE languages so far. Thanks for your help! :)
For anyone stumbling upon this code in the future - I got it work and there are a variety of reasons why it wasn't working previously.
In brief:
function appendChild wasn't attaching options to the datalist but to the input
the JSON, although valid, didn't have single quotes
some of the variables weren't initialised, and failed when called for a function
the function was declared after the datalist (e.g. called before it was declared)
some others
TLDR; do not rely on the code above, even as an inspiration :)
Wondering if it is possible that when a checkbox is clicked it changes the select box to a textbox with the same id "Wine_name"
Not really clued up when it comes to javascript, so any help will be greatly appreciated.
The reason I need this, when a user is filling out a form, if the selectbox does not have the option they want to select, they can click the check box which will then allow them to manually type in the text they want.
Well.. you can do it.. just keep in min that you have to disable the hidden input so that it wont be processed when the form is submited.
Have a look at the code that i've come up to do it.
I'm not sure it you really need the same 'id' attribute, if you're just sending a form and processing the result on the server side, you can 'name' the submitted parameters with the 'name' attribute. So that you can freely use different ids on the view side without changing the backend to conditionally verify it.
var checkbox = document.querySelector("#custom_value");
var select = document.querySelector("#selection");
var altSelect = document.querySelector("#selection_alt");
checkbox.addEventListener('change', function(event) {
select.classList.toggle('hidden');
select.disabled = !select.disabled;
altSelect.classList.toggle('hidden');
altSelect.disabled = !altSelect.disabled;
});
.hidden {
display: none;
}
<input type="checkbox" id="custom_value"> Alternative
<br>
<select id="selection" name="selection">
<option value="1">1</option>
<option value="1">2</option>
<option value="1">3</option>
<option value="1">4</option>
<option value="1">5</option>
</select>
<input type="text" disabled class="hidden" name="selection" id="selection_alt" placeholder="Custom value..">
i have the first select options
<form id="infform" method="post">
<select id="infmenu" name ="infmenu" size="1" class="select" >
<option value="0" >Please Select your article</option>
<option value="3" selected='selected' > value 1</option>
<option value="2" > value 2</option>
<option value="18" > value 3</option>
<option value="16" > value 4</option>
</select>
<input type="hidden" name="hiddenselect" value="3" />
</form>
and the second is
<form action="" method="POST" id="form0">
<input type="text" name="date0" class="tcal" value="" readonly="readonly" /><br />
<input type="image" src="../submit.png"/>
<input type="hidden" name="submit0" />
</form>
this my javascript
function displayv() {
var singleValues = $("select option:selected").text();
$("#hiddenselect").val(singleValues);
$("select > option:first").prop("disabled", "disabled")
}
$(document).ready(function(){
$("select").change(function() {
displayv();
});
displayv();
$("select#infmenu").change(function() {
$("#infform").submit();
});
});
now when i select the first option the page refresh and i get the value selected.
and when i submit the second submit the page refreshes and the first select option returns empty Please Select your article.
so how should this be fixed please .
EDIT :
this the php how i handle between them.
if (isset($_POST['infmenu'])){
$infmenu = $_POST['infmenu'];
// some sql of updating here
}
if (isset($_POST['submit0'])){
//some updating sql here
}
It's not really clear to me what your question really is.
If you're saying you're not seeing your select item value when you submit the second form, then that is normal and expected. You have two independent forms so when you submit the second form, the data from the first form will not be sent to the server.
The submit button /image only sends data for the inputs within it's own form, not data from any other forms within your html body tag.
Edited to add: you could:
have a single form tag instead of two
modify your jquery so that it puts the select value into the hidden field of the second form s well as the hidden field of the first. Then when second form is submitted, have your PHP script read the hidden field value and use that when rendering the HTML to decide which option has the selected attribute.
use cookies with some JavaScript to set the cookie when the value of select changesuse Ajax to do a partial submit - assuming server doesn't need to know value of select item when dealing with second form
There is no action="" assigned to the first button.
You have two forms.
When you click the submit in the second form, of course the data of the first form is not submitted.
Also, the submit button in the second form has no name, so you perhaps cannot evaluate in PHP if the button is clicked. But that's a different story
You should make the two forms one.
If they are too far apart on your page. You should save the value of the select box in the hidden field in the second form with php
I have html form, where it is possible that:
(1) user input's nothing, for ex., in case with text input field;
<input type="text" class="input-xlarge" id="first-name" name="first-name">
(2) user leaves default empty value, like with select:
<select id="prof-area" class="input-xlarge">
<option value="0" selected="selected"></option>
(3) user leaves empty value, like with multiple options select:
<select multiple="multiple" id="reason" name="reason" class="input-xlarge">
<option value="001">reason001</option>
<option value="002">reason002</option>
In each case on GAE side I should understand that this is empty value.
first_name = None
if self.request.get('first-name'):
first_name = self.request.get('first-name')
works well with case (1).
prof_area = None
if self.request.get('prof-area') and self.request.get('prof-area') !='0':
prof_area = self.request.get('prof-area')
should work for case (2), but doesn't look well. Is there any better way to handle the same?
You don't need all this work unless you have added the required=True argument. If you put an entity missing some property, GAE create or update the entity with the property missed empty. See this docs
You do not have a name parameter for your prof-area field which is prob why you are't seeing data at the server.
Anyways, try this ...
At the client, just put an empty string in your empty select option, like this:
<select id="prof-area" name="prof-area" class="input-xlarge">
<option value="" selected="selected"> -- select -- </option>
</select
then at the server, first grab all the values into local variables - makes it easier for others to see whats going on ...
first_name = self.request.get('first_name')
prof_area = self.request.get('prof-area')
reason = self.request.get('reason')
you can then check each param in turn ...
if first_name:
# do something with first_name
if prof_area:
# do something with prof_area
if reason:
# do something with reason
I have a select form field that I want to mark as "readonly", as in the user cannot modify the value, but the value is still submitted with the form. Using the disabled attribute prevents the user from changing the value, but does not submit the value with the form.
The readonly attribute is only available for input and textarea fields, but that's basically what I want. Is there any way to get that working?
Two possibilities I'm considering include:
Instead of disabling the select, disable all of the options and use CSS to gray out the select so it looks like its disabled.
Add a click event handler to the submit button so that it enables all of the disabled dropdown menus before submitting the form.
Disable the fields and then enable them before the form is submitted:
jQuery code:
jQuery(function ($) {
$('form').bind('submit', function () {
$(this).find(':input').prop('disabled', false);
});
});
<select disabled="disabled">
....
</select>
<input type="hidden" name="select_name" value="selected value" />
Where select_name is the name that you would normally give the <select>.
Another option.
<select name="myselect" disabled="disabled">
<option value="myselectedvalue" selected="selected">My Value</option>
....
</select>
<input type="hidden" name="myselect" value="myselectedvalue" />
Now with this one, I have noticed that depending on what webserver you are using, you may have to put the hidden input either before, or after the <select>.
If my memory serves me correctly, with IIS, you put it before, with Apache you put it after. As always, testing is key.
I`ve been looking for a solution for this, and since i didnt find a solution in this thread i did my own.
// With jQuery
$('#selectbox').focus(function(e) {
$(this).blur();
});
Simple, you just blur the field when you focus on it, something like disabling it, but you actually send its data.
I faced a slightly different scenario, in which I only wanted to not allow the user to change the selected value based on an earlier selectbox. What I ended up doing was just disabling all the other non-selected options in the selectbox using
$('#toSelect').find(':not(:selected)').prop('disabled',true);
it dows not work with the :input selector for select fields, use this:
jQuery(function() {
jQuery('form').bind('submit', function() {
jQuery(this).find(':disabled').removeAttr('disabled');
});
});
Same solution suggested by Tres without using jQuery
<form onsubmit="document.getElementById('mysel').disabled = false;" action="..." method="GET">
<select id="mysel" disabled="disabled">....</select>
<input name="submit" id="submit" type="submit" value="SEND FORM">
</form>
This might help someone understand more, but obviously is less flexible than the jQuery one.
The easiest way i found was to create a tiny javascript function tied to your form :
function enablePath() {
document.getElementById('select_name').disabled= "";
}
and you call it in your form here :
<form action="act.php" method="POST" name="form_name" onSubmit="enablePath();">
Or you can call it in the function you use to check your form :)
I use next code for disable options in selections
<select class="sel big" id="form_code" name="code" readonly="readonly">
<option value="user_played_game" selected="true">1 Game</option>
<option value="coins" disabled="">2 Object</option>
<option value="event" disabled="">3 Object</option>
<option value="level" disabled="">4 Object</option>
<option value="game" disabled="">5 Object</option>
</select>
// Disable selection for options
$('select option:not(:selected)').each(function(){
$(this).attr('disabled', 'disabled');
});
Just add a line before submit.
$("#XYZ").removeAttr("disabled");
Or use some JavaScript to change the name of the select and set it to disabled. This way the select is still submitted, but using a name you aren't checking.
I whipped up a quick (Jquery only) plugin, that saves the value in a data field while an input is disabled.
This just means as long as the field is being disabled programmaticly through jquery using .prop() or .attr()... then accessing the value by .val(), .serialize() or .serializeArra() will always return the value even if disabled :)
Shameless plug: https://github.com/Jezternz/jq-disabled-inputs
Based on the solution of the Jordan, I created a function that automatically creates a hidden input with the same name and same value of the select you want to become invalid. The first parameter can be an id or a jquery element; the second is a Boolean optional parameter where "true" disables and "false" enables the input. If omitted, the second parameter switches the select between "enabled" and "disabled".
function changeSelectUserManipulation(obj, disable){
var $obj = ( typeof obj === 'string' )? $('#'+obj) : obj;
disable = disable? !!disable : !$obj.is(':disabled');
if(disable){
$obj.prop('disabled', true)
.after("<input type='hidden' id='select_user_manipulation_hidden_"+$obj.attr('id')+"' name='"+$obj.attr('name')+"' value='"+$obj.val()+"'>");
}else{
$obj.prop('disabled', false)
.next("#select_user_manipulation_hidden_"+$obj.attr('id')).remove();
}
}
changeSelectUserManipulation("select_id");
I found a workable solution: remove all the elements except the selected one. You can then change the style to something that looks disabled as well.
Using jQuery:
jQuery(function($) {
$('form').submit(function(){
$('select option:not(:selected)', this).remove();
});
});
<select id="example">
<option value="">please select</option>
<option value="0" >one</option>
<option value="1">two</option>
</select>
if (condition){
//you can't select
$("#example").find("option").css("display","none");
}else{
//you can select
$("#example").find("option").css("display","block");
}
Another option is to use the readonly attribute.
<select readonly="readonly">
....
</select>
With readonly the value is still submitted, the input field is grayed out and the user cannot edit it.
Edit:
Quoted from http://www.w3.org/TR/html401/interact/forms.html#adef-readonly:
Read-only elements receive focus but cannot be modified by the user.
Read-only elements are included in tabbing navigation.
Read-only elements may be successful.
When it says the element may be succesful, it means it may be submitted, as stated here: http://www.w3.org/TR/html401/interact/forms.html#successful-controls