I am generating the drop down dynamically by script (Smarty).
If the drop down has just one option value, is it possible to display it as a label.
This will display a drop down with 3 values.
<select>
<option> 1 </option>
<option> 2 </option>
<option> 3 </option>
</select>
If it shows just one value then display it as label, is it possible with pure HTML or Jquery or combination of both? I could use smarty to check for the values and throw different different html, but that would make my code long as I have many drop downs.
<select>
<option> 1 </option>
</select>
Any simple logic, which I might be missing?
UPDATE (RESOLVED)
Thank for all the stackoverflow'ers who helped.
I used the code given by #ahren which worked as required.
However I have expanded the code to copy the attributes of one tag to another, in case if someone is looking for
// To replace a <select>, with <label> tag if it has just one value
$('select').each(function(){
if($(this).find('option').length === 1){
// Copy all attributes from a given tag and save it in a variable.
var attributes_from = $(this).prop("attributes");
var attributes_to = '';
$.each(attributes_from, function() {
attributes_to += ' '+this.name+'="'+this.value+'"';
});
// If select then copy its value from option.
attributes_to += ' value="'+$(this).find('option').attr('value')+'"';
// Replace the <tag>
$(this).replaceWith(function(){
return $('<label '+attributes_to+' />').html($(this).text());
});
}
});
$('select').each(function(){
if($(this).find('option').length === 1){
$(this).replaceWith(function(){
return $('<label />').html($(this).text());
});
}
});
After you've generated your dropdowns, you can just run this snippet to check each of the select elements.
DEMO: http://jsfiddle.net/kqunE/
I'd iterate over each of the <select> elements, checking the number of options they have, and make the required DOM changes accordingly:
$('select').each(function(index, select) {
var numOptions = $('option', this).length;
if(numOptions === 1) {
// replace the select element here - something like the below
var label = $('<label>').html(this.value);
$(this).after(label).hide();
}
});
I opted to hide, rather than replace, the <select> element so you still get the value sent back as part of the form. If that's not required then you can remove the element entirely using .remove() in place of .hide().
I have part of a code where it displays a Multi Select box and displays the options depending on the if statement:
$moduleSELECT = '<select name="moduletextarea" id="moduleselect" size="10">'.PHP_EOL;
if($modulenum == 0){
$moduleSELECT .= "<option disabled='disabled' value=''>No Modules currently on this Course</option>";
}else{
while ( $currentmodstmt->fetch() ) {
$moduleSELECT .= sprintf("<option disabled='disabled' value='%s'>%s - %s</option>", $dbModuleId, $dbModuleNo, $dbModuleName) . PHP_EOL;
}
}
$moduleSELECT .= '</select>';
Now from doing some research on the internet I think it is bad practice to include tags inside option tags. So my question is that if the if statement is true where number of records in 0, how can I display the text for "<option disabled='disabled' value=''>No Modules currently on this Course</option>"; in red colour and if the else statement is met how can I display these options sprintf("<option disabled='disabled' value='%s'>%s - %s</option>", $dbModuleId, $dbModuleNo, $dbModuleName) . PHP_EOL; in black colour text?
Thanks
just set a css style to the select (if there are no options), in this case color: red;
you can also have different colors for the options as well, just set different colors on each option. example fiddle here: http://jsfiddle.net/kennypu/CP8Xf/1/
I don't believe you can style individual <option> tags with CSS, but you could style the entire <select> as #kennypu points out.
Another way to achieve the results you want with a better/more intuative UI might be to only output the <select> tag when you actually have data to put inside it. When $modulenum == 0 maybe you should just output some different HTML that you can style properly.
HTML
<div class='no-data'>No Modules currently on this Course</div>
CSS
.no-data{
background-color: #CCC;
color: red;
padding: 5px;
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
display dropdown values based on previous dropdown
I know html pretty well and about forms a little bit, but would like to know, for example:
when clicking on a certain drop down list item, a certain second drop down list appears based on the previous field choice. how would you go about incorporating this, is there a specific website I can go to?
an example of code would be appreciated. I am assuming that you could use javascript for this?
do you retrieve specific values or just use different drop down lists for specific choices
Thanks
of the top of my head.
You would handle your javascript on the page, before you submit your form.
step 1. reference jquery in your header
step 2. on load, hide the second select, put this script beneath you reference jquery
<script type="text/javascript">
$(function () {
$("#secondselect").hide()
$("#firstselect").change(function () {
if($(this).val() != 0){
$("#secondselect").show()
}
else
{
$("#secondselect").hide()
}
});
});
</script>
<select id="firstselect" name="firstselect" >
<option value="0">first</option>
<option value="1">second</option>
<option value="2">third</option>
<option value="3"></option>
</select>
<select id="secondselect" name="secondselect">
<option value="0">first</option>
<option value="1">second</option>
<option value="2">third</option>
<option value="3"></option>
</select>
Of the top of my head... but i'd do it something like that.
Good luck.
Oh... just a quick update.
You could use a switch instead of an if like so, might be a bit tidier...
FROM
if($(this).val() != 0){
$("#secondselect").show()
}
else
{
$("#secondselect").hide()
}
TO
switch($(this).val())
{
case '1':
$("#secondselect").show();
break;
case '1':
//do something else... show a third dropdown instead
//for instance...
// $("#thirdselect").show();
alert('got to case 1');
//or if you use firebug or chrome, right click and inspect an element then click on Console and this log report should show
console.log('got here, showing the log');
break;
default:
$("#secondselect").hide();
}
I assume from your question that you want to dynamically populate the second dropdown based on the selected value of the first one.
To do that you can use jQuery to get the value of the first selected value pass it to a PHP file to get a response of the options that the second drop down needs to have and populate them.
You can use .show() and .hide() also to hide or show the dropdown when is needed.
$('#first').change(function(){
var selected= $('#first').val();
$.getJSON('data.php',{name: selected},function(data){
var results='';
$.each(data, function(i, item) {
results += '<option value="'+item.Description+'">'+item.Description+'</option>"' ;
});
$("select#Second").html(results);
})
});
If the options do not need to dynamically change and you just need to hide and show then you can use the simpsons88 answer!
I have two pages with HTML forms. The first page has a submission form, and the second page has an acknowledgement form. The first form offers a choice of many controls, while the second page displays the data from the submission form again with a confirmation message. On this second form all fields must be static.
From what I can see, some form controls can be readonly and all can be disabled, the difference being that you can still tab to a readonly field.
Rather than doing this field by field is there any way to mark the whole form as readonly/disabled/static such that the user can't alter any of the controls?
Wrap the input fields and other stuff into a <fieldset> and give it the disabled="disabled" attribute.
Example (http://jsfiddle.net/7qGHN/):
<form>
<fieldset disabled="disabled">
<input type="text" name="something" placeholder="enter some text" />
<select>
<option value="0" disabled="disabled" selected="selected">select somethihng</option>
<option value="1">woot</option>
<option value="2">is</option>
<option value="3">this</option>
</select>
</fieldset>
</form>
Not all form elements can be set to readonly, for example:
checkboxes
radio boxes
file upload
...more..
Then the reasonable solution would be to set all form elements' disabled attributes to true, since the OP did not state that the specific "locked" form should be sent to the server (which the disabled attribute does not allow).
Another solution, which is presented in the demo below, is to place a layer on top of the form element which will prevent any interaction with all the elements inside the form element, since that layer is set with a greater z-index value:
DEMO:
var form = document.forms[0], // form element to be "readonly"
btn1 = document.querySelectorAll('button')[0],
btn2 = document.querySelectorAll('button')[1]
btn1.addEventListener('click', lockForm)
btn2.addEventListener('click', lockFormByCSS)
function lockForm(){
btn1.classList.toggle('on');
[].slice.call( form.elements ).forEach(function(item){
item.disabled = !item.disabled;
});
}
function lockFormByCSS(){
btn2.classList.toggle('on');
form.classList.toggle('lock');
}
form{ position:relative; }
form.lock::before{
content:'';
position:absolute;
z-index:999;
top:0;
right:0;
bottom:0;
left:0;
}
button.on{ color:red; }
<button type='button'>Lock / Unlock Form</button>
<button type='button'>Lock / Unlock Form (with CSS)</button>
<br><br>
<form>
<fieldset>
<legend>Some Form</legend>
<input placeholder='text input'>
<br><br>
<input type='file'>
<br><br>
<textarea placeholder='textarea'></textarea>
<br><br>
<label><input type='checkbox'>Checkbox</label>
<br><br>
<label><input type='radio' name='r'>option 1</label>
<label><input type='radio' name='r' checked>option 2</label>
<label><input type='radio' name='r'>option 3</label>
<br><br>
<select>
<option>options 1</option>
<option>options 2</option>
<option selected>options 3</option>
</select>
</fieldset>
</form>
You can use this function to disable the form:
function disableForm(formID){
$('#' + formID).children(':input').attr('disabled', 'disabled');
}
See the working demo here
Note that it uses jQuery.
On the confirmation page, don't put the content in editable controls, just write them to the page.
This is an ideal solution for disabling all inputs, textareas, selects and buttons in a specified element.
For jQuery 1.6 and above:
// To fully disable elements
$('#myForm :input').prop('disabled', true);
Or
// To make elements readonly
$('#myForm :input').prop('readonly', true);
jQuery 1.5 and below:
$('#myForm :input').prop('disabled', 'disabled');
And
$('#myForm :input').prop('readonly', 'readonly');
There is no built-in way that I know of to do this so you will need to come up with a custom solution depending on how complicated your form is. You should read this post:
Convert HTML forms to read-only (Update: broken post link, archived link)
EDIT: Based on your update, why are you so worried about having it read-only? You can do it via client-side but if not you will have to add the required tag to each control or convert the data and display it as raw text with no controls. If you are trying to make it read-only so that the next post will be unmodified then you have a problem because anyone can mess with the post to produce whatever they want so when you do in fact finally receive the data you better be checking it again to make sure it is valid.
There's no fully compliant, official HTML way to do it, but a little javascript can go a long way.
Another problem you'll run into is that disabled fields don't show up in the POST data
<form inert>
This won't change the styling of the form but will stop all the inputs from being focusable and stop any buttons from being clickable.
Have all the form id's numbered and run a for loop in JS.
for(id = 0; id<NUM_ELEMENTS; id++)
document.getElementById(id).disabled = false;
A simple need : display non-editable form (that can become editable later on) with minimum code and headache.
If you can't use the 'disabled' attribut (as it erases the value's input at POST), and noticed that html attribut 'readonly' works only on textarea and some input(text, password, search, as far I've seen), and finally, if you don't want to bother with duplicating all your select, checkbox and radio with hidden input logics,
you might find the following function or any of his inner logics to your liking :
addReadOnlyToFormElements = function (idElement) {
// textarea an input of type (text password search) work with the html readonly
$('#' + idElement + ' textarea, #' + idElement + ' input').prop('readonly',true);
// but you still have to destroy their associated objects, as I.E, datepicker (in our old project, datepicker is appended to input where 'Date' is in name attribut, don't ask why)
$('#' + idElement + ' input[name*="Date"]').datepicker('destroy');
// html readonly don't work on input of type checkbox and radio, neither on select. So, a safe trick is to disable the non-selected items
$('#' + idElement + ' input[type="checkbox"]:not(:checked), #' + idElement + ' input[type="radio"]:not(:checked)').prop('disabled',true);
$('#' + idElement + ' select>option:not([selected])').prop('disabled',true);
// and, on the selected ones, to disable mouse/keyoard events and mimic readOnly appearance
$('#' + idElement + ' input[type="checkbox"]:checked').prop('tabindex','-1').css('pointer-events','none').css('opacity','0.5');
$('#' + idElement + ' input[type="radio"]:checked').css('opacity','0.5');
$('#' + idElement + ' select').css('background-color','#eee');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
And there's nothing easier than to remove these readonly
removeReadOnlyFromFormElements = function (idElement) {
// just remove the html readonly on textarea and input
$('#' + idElement + ' textarea, #' + idElement + ' input').prop('readonly',false);
// and restore their Objects, as I.E, datepicker
$('#' + idElement + ' input[name*="Date"]').datepicker();
// Remove the disabled attribut on non-selected
$('#' + idElement + ' input[type="checkbox"]:not(:checked), #' + idElement + ' input[type="radio"]:not(:checked)').prop('disabled',false);
$('#' + idElement + ' select>option:not([selected])').prop('disabled',false);
// Restore mouse/keyboard events and remove readOnly appearance on selected ones
$('#' + idElement + ' input[type="checkbox"]:checked').prop('tabindex','').css('pointer-events','').css('opacity','');
$('#' + idElement + ' input[type="radio"]:checked').css('opacity','');
$('#' + idElement + ' select').css('background-color','');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I'd rather use jQuery:
$('#'+formID).find(':input').attr('disabled', 'disabled');
find() would go much deeper till nth nested child than children(), which looks for immediate children only.
Another simple way that's supported by all browsers would be:
HTML:
<form class="disabled">
<input type="text" name="name" />
<input type="radio" name="gender" value="male">
<input type="radio" name="gender" value="female">
<input type="checkbox" name="vegetarian">
</form>
CSS:
.disabled {
pointer-events: none;
opacity: .4;
}
But be aware, that the tabbing still works with this approach and the elements with focus can still be manipulated by the user.
Easiest way
$('#yourform .YOUR_CLASS_FOR_INPUTS').prop('readonly', true);
You can use an opaque layer over the form:
Put position: relative on the form
Add the transparent blocking div as a child of this form with position: absolute and top, bottom, left, right equal to 0
You add html invisible layer over the form. For instance
<div class="coverContainer">
<form></form>
</div>
and style:
.coverContainer{
width: 100%;
height: 100%;
z-index: 100;
background: rgba(0,0,0,0);
position: absolute;
}
Ofcourse user can hide this layer in web browser.
To make a whole fieldset disabled conditionally in angular you can do like this:
<fieldset [attr.disabled]="isEditable ? null : 'disabled'">
I have three select boxes.
<div style='float: left; padding-right: 10px;'>
<select size="10" name="company_id">
// a lot of options here
</select>
</div>
<div style='float: left; padding-right: 10px;'>
<select size="10" name="department_id" id="department_id">
// a lot of options here
</select>
</div>
<div style='float: left; padding-right: 10px;'>
<select size="10" name="user_id[]" id="user_id" multiple>
// a lot of options here
</select>
</div>
They are floated next to each other. When you select an item in the 1st one, an ajax query updates the values of the 2nd one.
What happens in Firefox and most other browsers is that it changes in size and pushes the 3rd one away. But in IE (6.0 and 7) the 2nd one changes size but it does not push the 3rd one away.
What i had done is to fix the size of the boxes but i want to fix this correctly, so anyone know how?
Here's the JQuery code i use to add the data to the departments select.
$.get("ajax/fetchDepartment.php?sec=departments&company_id="+company_id,
function(data){
$("#department_id").html(data);
});
data contains the <option>Stuff</option>'s needed
EDIT to add: The select boxes always have some value within them.
Here's a picture of what happens (i had to remove the items in the boxes via photoshop but you get my point)
selcet bug http://cznp.com/select_bug.jpg
IE and select options have certain 'quirks' (some, regarding select boxes and innerHTML are detailed here) about them that I've never really fully understood, but I can at least provide you with a workaround.
The trick is to add the options exlicitly to the select box, not just change the entire html of the select element wholesale. So the following works:
function changeval() {
var option = document.createElement("option");
option.text = 'my long text value to change stuff';
option.value = 'test';
$('#department_id')[0].options.add(option);
}
While this does not:
function changeval() {
var data = '<option value="test">my long test string with wide stuff</option>';
$("#department_id").html(data);
}
You might find this page helpful -apparently he fixed it by just retouching the innerHTML, so that might be a simpler option. Up to you.
The solution from the second link would look like:
function changeval() {
var data = '<option value="test">my long test string with wide stuff</option>';
$("#department_id").html(data);
$("#department_id").parent()[0].innerHTML += '';
}
try putting an option inside the selects on start. I guess u only start filling the second and third select when u selected something from the first.
I've had problems with empty selects in IE so just put an
<option value="-1">-</option>
in the 2nd and third select to start with.