I have a small web app where I need to populate a dropdown list after selecting another right before.
For example this is the URL of the Ajax request http://localhost:8080/ajax/dropdown_model?brandId=0 and the JSON code looks like this:
[{"id":0,"name":"Z-400","brand":{"id":0,"name":"Lenovo"}}]
The code I used is this one:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
var html = '';
$('select#brand').change(
function() {
$.getJSON("http://localhost:8080/ajax/dropdown_model", {
brandId : $(this).val(),
ajax : 'true'
}, function(data) {
html = '<option disabled="disabled" value="">Seleccionar modelo:</option>';
var len = data.length;
for ( var i = 0; i < len; i++) {
html += '<option value="' + data[i].id + '">'
data[i].id + ' : ' + data[i].name + '</option>';
}
html += '</option>';
$('select#model').html(html);
});
}); </script>
It should replace the content of the 2nd select tag adding into it the content of the JSON string.
Also this is the relevant part of the form (I'm using Spring and Thymeleaf):
<div class="brand" th:object="${lbra}">
<select name="brand" id="brand" >
<option value="">Seleccionar marca:</option>
<option th:each="brand : ${lbra}"
th:value="${brand.getId()}"
th:text="${brand.getId()}+' : '+${brand.getName()}"></option>
</select> </div>
<div class="model" id="modellist">
<select name="model" id="model">
<option value="" disabled="disabled" selected="selected">Seleccionar modelo:</option>
<option></option>
</select> </div>
I've removed some of the Spring variables for the sake of creating an example. You were missing a "+" after your dynamic option that is added to the HTML string (after html += '<option value="' + data[i].id + '">')..
var html = '';
$('select#brand').change(
function() {
$.getJSON("https://api.myjson.com/bins/ugf4v", {
brandId: $(this).val(),
ajax: 'true'
}, function(data) {
html = '<option disabled="disabled" value="">Seleccionar modelo:</option>';
var len = data.length;
for (var i = 0; i < len; i++) {
html += '<option value="' + data[i].id + '">' +
data[i].id + ' : ' + data[i].name + '</option>';
}
html += '</option>';
$('select#model').html(html);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="brand">
<select name="brand" id="brand">
<option value="">Seleccionar marca:</option>
<option>Test Change</option>
</select>
</div>
<div class="model" id="modellist">
<select name="model" id="model">
<option value="" disabled="disabled" selected="selected">Seleccionar modelo:</option>
<option></option>
</select>
</div>
Related
I have a button that allows the user to add another row to add different types of returned equipment. I am posting this data to another page to print out. If I try and retrieve the data from the post array, I can only get the last in the entry
I've tried setting the name to name="device[]" then adding a value of "key" but since I'm using a drop down select, I can't do that.
<select name="device-type[]">
<option value="" disabled selected hidden>Select Equipment Type</option>
<option value="dvr">DVR</option>
<option value="modem">Modem</option>
<option value="router">Router</option>
<option value="other">Other</option>
</select>
I have a button that calls a JS function to just add another select element identical to that.
JS code:
function addBox(){
$("#devices").append('<select name="device-type" class="focus:outline-none plain-field">\n' +
' <option>Select Equipment Type</option>\n' +
' <option value="dvr">DVR</option>\n' +
' <option value="modem">Modem</option>\n' +
' <option value="router">Router</option>\n' +
' <option value="other">Other</option>\n' +
' </select>\n' +
' <input class="focus:outline-none plain-field" name="device-number" type="text" placeholder="CMAC/SN">\n' +
' <input type="checkbox" name="power-cord" class="">Power Cord?\n' +
' <input type="checkbox" name="remote" class="">Remote?\n' +
' <br>');
return false;
PHP to retrieve the information from that:
<p><?php echo $_POST['device-type']?></p>
<p><?php echo $_POST['device-number']?></p>
My question is, how can I retrieve the device type and number in the post array?
Simply make your HTML select tag accept multiple values. E.g:
<select name="device_type[]" class="focus:outline-none plain-field" multiple>
....
</select>
You can get the selected values on the PHP end using $_POST['device_type']
Refer to store multiple select option into a PHP array for more information
It looks like you need to add [] brackets to your field names to make them a multi array for $_POST to handle processing. Also, if you want to identify each row by an index, on clicking the ADD button, you can count the amount of select boxes generated to create a count and use that as the key index for each array. If you run the following below in a PHP file, click the ADD button to add some select boxes, and then click SUBMIT, you will see your data echo'd out as a multi-dimensional array. I also gave your initial select box an index of 0 for the multi array.
<?php
if(isset($_POST) && !empty($_POST)) {
echo "<pre>";
print_r($_POST);
foreach($_POST['device-type'] as $key => $type) {
echo "<b>Type:</b> " . $type . " ";
echo (isset($_POST['device-number']) && isset($_POST['device-number'][$key]) && !empty($_POST['device-number'][$key])) ? "<b>Number:</b> " .$_POST['device-number'][$key] . " " : "";
echo (isset($_POST['power-cord']) && isset($_POST['power-cord'][$key]) && !empty($_POST['power-cord'][$key])) ? "<b>Power Cord:</b> " .$_POST['power-cord'][$key] . " " : "";
echo (isset($_POST['remote']) && isset($_POST['remote'][$key]) && !empty($_POST['remote'][$key])) ? "<b>Remote:</b> " .$_POST['remote'][$key] . " " : "";
echo "<br/>";
}
echo "</pre>";
}
?>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
function addBox() {
//console.log($('select.plain-field').length + 1);
var rowCount = $('select.plain-field').length + 1;
$("#devices").append('<br/><select name="device-type[' + rowCount + ']" class="focus:outline-none plain-field">\n' +
' <option value="">Select Equipment Type</option>\n' +
' <option value="dvr">DVR</option>\n' +
' <option value="modem">Modem</option>\n' +
' <option value="router">Router</option>\n' +
' <option value="other">Other</option>\n' +
' </select>\n' +
' <input class="focus:outline-none plain-field" name="device-number[' + rowCount + ']" type="text" placeholder="CMAC/SN">\n' +
' <input type="checkbox" name="power-cord[' + rowCount + ']" class="">Power Cord?\n' +
' <input type="checkbox" name="remote[' + rowCount + ']" class="">Remote?\n' +
' ');
return false;
}
</script>
<form action="" method="post">
<div id="devices">
<select name="device-type[0]">
<option value="">Select Equipment Type</option>
<option value="dvr">DVR</option>
<option value="modem">Modem</option>
<option value="router">Router</option>
<option value="other">Other</option>
</select>
</div>
<input type="button" onclick="addBox();" value="Add [+]" />
<br/>
<br/>
<input type="submit" value="Submit" />
</form>
I'm having an issue with an assignment.
My for loop doesn't seem to run and I'm not sure what I've done wrong.
The variable dailyText prints "Weather Forecast" in a table but doesn't seem to enter the for loop. I'm not sure if this is a scoping issue or what's happening.
The script is supposed to take a number from a form option and create a table with that many rows.
Any help would be greatly appreciated!
function dailyInfo() {
var dailyText = "";
var numberDays = document.getElementById("numberDays").value; //https://stackoverflow.com/questions/23982774/turn-html-form-input-into-javascript-variable
dailyText += "<table class='table'><tr><th>Weather Forecast</th></tr>";
for (var i = 0; i < numberDays; i++) {
dailyText += "<tr><td>Day: " + (i + 1) + "</td>";
dailyText += "<td>" + dailyJsonObject.list[i].temp.min + "℃</td>";
dailyText += "<td>" + dailyJsonObject.list[i].temp.max + "℃</td>";
dailyText += "<td>" + dailyJsonObject.list[i].weather[0].description + "<img src ='http://openweathermap.org/img/w/'" + dailyJsonObject.list[i].weather[0].icon + ".png' /></td>";
}
document.getElementById("demo").innerHTML = dailyText;
dailyText += "</tr></table>";
}
<form id="numberDay">
<label id='numberDays'>Number of days requested</label>
<select name='numberDays'>
<option value='1'>1</option>
<option value='2'>2</option>
<option value='3'>3</option>
<option value='4'>4</option>
<option value='5'>5</option>
</select>
<button type="button" onclick="dailyInfo()">Submit</button>
</form>
</div>
<div id='demo'>
<table id="tableDaily"></table>
</div>
You have named the label with the id required for the numberDays. This means the loop was using the label value not the actual input as expected.
See below for alteration:
<form id="numberDay">
<label id='numberDays_label'>Number of days requested</label>
<!-- the select needs the id so the JS code can grab it!-->
<select name='numberDays' id="numberDays">
<option value='1'>1</option>
<option value='2'>2</option>
<option value='3'>3</option>
<option value='4'>4</option>
<option value='5'>5</option>
</select>
<button type="button" onclick="dailyInfo()">Submit</button>
</form></div>
<div id='demo'>
<table id="tableDaily"></table></div>
You say:
var numberDays = document.getElementById("numberDays").value;
But actually the element you are getting is the label:
<label id='numberDays'>
So numberDays has actually the value undefined then.
Instead, you should do:
<label for='numberDays'>
and then:
<select name='numberDays' id='numberDays'>
That should actually at least start the loop. And then the label > select relationships is actually working, for example you can click now also the label to focus on the select.
Access a selected option:
HTML
<select name="" id="mySelect">
<option value="option1">Option 1</option>
<option value="option2">Option 2</option>
<option value="option3">Option 3</option>
<option value="option4">Option 4</option>
</select>
JavaScript
var select = document.getElementById("mySelect"),
selectedOption = select.options[select.selectedIndex].text;
Get selected option text with JavaScript
In total (commented stuff)
function dailyInfo() {
var dailyText = "";
var numberDays = document.getElementById("numberDays");
numberDays = numberDays.options[numberDays.selectedIndex].text;
dailyText += "<table class='table'><tr><th>Weather Forecast</th></tr>";
for (var i = 0; i < numberDays; i++) {
dailyText += "<tr><td>Day: " + (i + 1) + "</td>";
dailyText += "<td>" + /*dailyJsonObject.list[i].temp.min +*/ "℃</td>";
dailyText += "<td>" + /*dailyJsonObject.list[i].temp.max +*/ "℃</td>";
dailyText += "<td>" + /*dailyJsonObject.list[i].weather[0].description*/ +"<img src ='http://openweathermap.org/img/w/'" + /*dailyJsonObject.list[i].weather[0].icon +*/ ".png' /></td>";
}
document.getElementById("demo").innerHTML = dailyText;
dailyText += "</tr></table>";
}
<form id="numberDay">
<label>Number of days requested</label>
<select id='numberDays' name='numberDays'>
<option value='1'>1</option>
<option value='2'>2</option>
<option value='3'>3</option>
<option value='4'>4</option>
<option value='5'>5</option>
</select>
<button type="button" onclick="dailyInfo()">Submit</button>
</form>
<div id='demo'>
<table id="tableDaily"></table>
</div>
I am looking to change the input type of a number selector to a dropdown if the value is less than 10. For values greater than 9 (10+) the input type should change back to a number selector.
Amazon and Sears.com are doing this style of quantity selectors in their shopping carts for some desktop users (subject to AB testing).
My issue is that it will change input type once, but not back again.
Additionally what is the best practice to retain the value between input types? I've considered either using a variable or copying to a hidden input which is the actual field submitted.
HTML:
<label class="mylabel">Quantity:</label>
<input style="display: inline;" maxlength="3" min="1" pattern="\d+" autocomplete="off" name="quantityBox" class="qty-input" aria-label="Quantity" type="number">
<input type="submit" name="btnAddToCart" value="Add To Cart" id="btnAddToCart" class="">
jQuery:
$(".qty-input").change(function(){
if (parseInt(this.value) < 10){
$(".qty-input").replaceWith(
'<select id="txtQuantity" name="txtQuantity" class="qty-input">' +
'<option value="1">1</option>' +
'<option value="2">2</option>' +
'<option value="3">3</option>' +
'<option value="4">4</option>' +
'<option value="5">5</option>' +
'<option value="6">6</option>' +
'<option value="7">7</option>' +
'<option value="8">8</option>' +
'<option value="9">9</option>' +
'<option value="10">10+</option>' +
'</select>'
);
}
if (parseInt(this.value) > 9){
$(".qty-input").replaceWith(
'<input style="display: inline;" maxlength="3" min="1" pattern="\d+" autocomplete="off" name="quantityBox" class="qty-input" aria-label="Quantity" type="number">'
);
}
});
There is no need to render and re-render the fields each time they should switch. It is easier to simply hide them.
A very basic solution, error handling and styling is up to you:
var high = $('#high')
var low = $('#low')
function onChange() {
if (low.is(':visible')) {
var value = low.val();
high.val(value);
if (parseInt(value) > 9) toggleInputs();
} else {
var value = high.val();
low.val(value);
if (parseInt(value) <= 9) toggleInputs();
}
}
function toggleInputs() {
$('#low').toggle();
$('#high').toggle();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>Quantity:</label>
<input onchange='onChange()' id='high' style='display: none' />
<select onchange='onChange()' id='low'>
<option value='0'>0</option>
<option value='1'>1</option>
<option value='2'>2</option>
<option value='3'>3</option>
<option value='4'>4</option>
<option value='5'>5</option>
<option value='6'>6</option>
<option value='7'>7</option>
<option value='8'>8</option>
<option value='9'>9</option>
<option value='10'>10+</option>
</select>
You can do it with two particular different selectors one for dropdown other for text to take getter than ten.selecting 10+ will change the select control name and it will be point to your textbox name or if want to switch back then restore the old name of select box and remove text box name.
Using jquery toggle method and prop attribute you can handle or modify name prop of the controls you are using.I think you got it.
Your server side code can catch the post data easily with this logic.
If not getting, can ask for sample code i can show you.
Although there are better ways of doing this I'm posting this to answer why your version is not working. Basically you're binding to an element that doesn't exist yet i.e. dynamic content.
Jquery handles this using the on method.
You can get it to work by adding a static ancestor and binding to that instead. For a better understanding of how event bubbling and delegation works check out this link. http://api.jquery.com/on/
Something like this
HTML
<label class="mylabel">Quantity:</label>
<div id="staticAncestor">
<input style="display: inline;" maxlength="3" min="1" pattern="\d+" autocomplete="off" name="quantityBox" class="qty-input" aria-label="Quantity" type="number">
</div>
JS
$("#staticAncestor").on("change",'.qty-input',function(){
if (parseInt(this.value) < 10 && !$( "#txtQuantity" ).length){
$(".qty-input").replaceWith(
'<select id="txtQuantity" name="txtQuantity" class="qty-input">' +
'<option value="1">1</option>' +
'<option value="2">2</option>' +
'<option value="3">3</option>' +
'<option value="4">4</option>' +
'<option value="5">5</option>' +
'<option value="6">6</option>' +
'<option value="7">7</option>' +
'<option value="8">8</option>' +
'<option value="9">9</option>' +
'<option value="10">10+</option>' +
'</select>'
);
}
if (parseInt(this.value) > 9){
$(".qty-input").replaceWith(
'<input style="display: inline;" maxlength="3" min="1" pattern="\d+" autocomplete="off" name="quantityBox" class="qty-input" aria-label="Quantity" type="number">'
);
}
});
Here is the pen http://codepen.io/anon/pen/jAQogj
Cheers and happy coding!
The problem is this...
once you remove the object from the DOM you are also removing the event handler if you still want to take the replace approach you would have to re-bind the event handler something like
$(document).ready(function() {
function test(){
if (parseInt(this.value) < 10) {
$(".container ").html(
'<select id="txtQuantity" name="txtQuantity" class="qty-input">' +
'<option value="1">1</option>' +
'<option value="2">2</option>' +
'<option value="3">3</option>' +
'<option value="4">4</option>' +
'<option value="5">5</option>' +
'<option value="6">6</option>' +
'<option value="7">7</option>' +
'<option value="8">8</option>' +
'<option value="9">9</option>' +
'<option value="10">10+</option>' +
'</select>'
);
} else {
$(".container").html(
'<input style="display: inline;" maxlength="3" min="1" pattern="\d+" autocomplete="off" name="quantityBox" class="qty-input" aria-label="Quantity" type="number">'
);
}
$(".qty-input").on('change', test);
}
$(".qty-input").on('change', test);
});
https://jsfiddle.net/happymacarts/pn1qeyg9/1/
This will work. Your example doesn't work since when you replace the DOM node/element, it no longer has the change event handled so function is bonded nor executed.
$(".qty-input").change(updateControl);
function updateControl(evt) {
var template;
if (parseInt(this.value) < 10 && this.tagName.toLowerCase() === "input") {
template =
'<select id="txtQuantity" name="txtQuantity" class="qty-input">' +
'<option value="1">1</option>' +
'<option value="2">2</option>' +
'<option value="3">3</option>' +
'<option value="4">4</option>' +
'<option value="5">5</option>' +
'<option value="6">6</option>' +
'<option value="7">7</option>' +
'<option value="8">8</option>' +
'<option value="9">9</option>' +
'<option value="10">10+</option>' +
'</select>';
} else if (parseInt(this.value) > 9 && this.tagName.toLowerCase() === "select") {
template =
'<input style="display: inline;" maxlength="3" min="1" pattern="\d+" autocomplete="off" name="quantityBox" class="qty-input" aria-label="Quantity" type="number" value="'+this.value+'">';
}
if (template) {
$(this).replaceWith(template);
$('.qty-input option[value='+this.value+']').attr('selected', true);
$('.qty-input').change(updateControl);
}
}
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<select id="txtQuantity" name="txtQuantity" class="qty-input">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10+</option>
</select>
check this out what I am telling Fiddle Demo
$(".select").on('click',function(){
if(isNaN($(this).val())){
$(this).addClass("hide");
$(".more").removeClass("hide");
$(this).removeAttr("name","quantity");
$(".more").attr("name","quantity");
} });
You may refine code to your purpose.
How can i auto generate multiple select lists from a select list like this example :
My code :
HTML:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="multiple.js"></script>
<div class="container">
<div id="selected_form_code">
<select id="select_btn">
<option value="0">--How many rooms ?--</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
</div>
<div id="form_submit">
<!-- Dynamic Registration Form Fields Creates Here -->
</div>
</div>
JS:
$(document).ready(function() {
$('select#select_btn').change(
function() {
var sel_value = $('option:selected').val();
$("#form_submit").empty(); //Resetting Form
// Below Function Creates Input Fields Dynamically
create(sel_value);
// Appending Submit Button To Form
}
);
function create(sel_value) {
for (var i = 1; i <= sel_value; i++) {
$("div#form1").append($("#form_submit"
).append($("<div/>", {id: 'head' }
).append($("<b>").text("Chambre " + i)),
$("<input/>",
{ type: 'text', placeholder: 'Chambre ' + i, name: 'Chambre-' + i } ) ))
}
}
});
This code only create text inputs. But, i need to display multiple rooms (chambre) by selecting the number from select option. After that, if il select N kids (enfants), N select should appears to choose their ages.
I hope it's clear :)
sorry, i'm not a big jquery fan, but as nobody answers, i try.
so fist, i would made some function get_chambre_html(cn) that will generate some Chambre html block, to append it in 'for' loop in your create().
then, next line after append() in create() function we may add change() event listeners for each new block, like you do it for chambres.
to add additional fields for each child we will append them to $('#ages'+chambre_index)[0]
<html><body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="container">
<div id="selected_form_code">
<select id="select_btn">
<option value="0">--How many rooms ?--</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
</select>
</div>
<div id="form_submit">
<!-- Dynamic Registration Form Fields Creates Here -->
</div>
</div>
<script>
function get_chambre_html(cn)
{
return "<div>"
+ "<b>Chambre " + cn + ":</b> "
+ "Adultes: <select id='adultes" + cn + "'>"
+ "<option value='0'>--How many adults ?--</option>"
+ "<option value='1'>1</option>"
+ "<option value='2'>2</option></select>"
+ "<br/>Enfants: <select id='enfants" + cn + "'>"
+ "<option value='0'>--How many enfants ?--</option>"
+ "<option value='1'>1</option>"
+ "<option value='2'>2</option></select>"
+ "<div id='ages" + cn + "'></div>" // empty block for further usage
+"</div>";
}
$(document).ready(function()
{
$('select#select_btn').change(function()
{
var sel_value = $('option:selected').val();
$("#form_submit").empty(); //Resetting Form
// Below Function Creates Input Fields Dynamically
create(sel_value);
// Appending Submit Button To Form
});
function create(sel_value)
{
for (var i = 1; i <= sel_value; i++)
{
$("div#form1").append($("#form_submit").append(get_chambre_html(i)));
$("div#form1").append($("#form_submit").append("<div id='ages"+i+"'/>"));
$('select#enfants'+i).change(function(){
var infants = this.value;
var i=this.id.substr(7); // 7 = strlen of 'enfants'
for(var j=0; j<infants; j++)
$('#ages'+i).append(':[input age block '+i+']: ');
});
}
};
});
</script>
i need help. I would like to create dynamically selects with options depending the data i get from my REST API. The data is a JSONObject. How can i inject dynamically those selects into my html. Here is an example:
My JSON i get from REST API:
{
"Projects":[
"Project A",
"Project B",
"Project C"
],
"Variant":[
"Variant A",
"Variant B"
],
"Information":[
"Info 1",
"Info 2"
],
"Links":[
"Link 1",
"Link 2"]
}
Thats my template:
<div class="ui-field-contain" id="project-names">
</div>
Now i want to use jquery or angularjs to generate the selects Project, Variant, Information and Links, with their options.
It should be something like that:
<div class="ui-field-contain" id="project-names">
<label for="project">Project:</label>
<select name="project" id="project" data-native-menu="false">
<option value="Project A">Project A</option>
<option value="Project B">Project B</option>
<option value="Project C">Project C</option>
</select>
<label for="variant">Variant:</label>
<select name="variant" id="variant" data-native-menu="false">
<option value="Variant A">Variant A</option>
<option value="Variant B">Variant B</option>
</select>
<label for="Information">Information:</label>
<select name="Information" id="Information" data-native-menu="false">
<option value="Info A">Info A</option>
<option value="Info B">Info B</option>
</select>
<label for="select-1">Link:</label>
<select name="Link" id="Link" data-native-menu="false">
<option value="Link A">Link A</option>
<option value="Link B">Link B</option>
</select>
</div>
Is this possible?
Thanks.
EDIT My code so far:
var $htmlProjectNames = $("#project-names");
$btnGetProjects.on('click', function() {
$.ajax({
type : 'GET',
url: '/RestFulApi/api/v1/mcd/get-projects',
datatype : "json",
success : function(data) {
$.each(data, function(prefix, project) {
$htmlProjectNames.append(
'<label for' + perfix +'>' + prefix +'</label>\n'+
'<select name="'+prefix+ 'id="' + prefix +'"' + 'data-native-menu="false">'
);
});
}
});
});
Try:
$.ajax({
type : 'GET',
url: '/RestFulApi/api/v1/mcd/get-projects',
datatype : "json",
success : function(data) {
$.each(data, function (key, values) {
var template = '<label for="' + key.toLowerCase() + '">' + key + ':</label>' +
'<select name="' + key.toLowerCase() + '" id="' + key + '" data-native-menu="false">';
for(var i=0; i<values.length; i++){
template = template + '<option value="' + values[i] + '">' + values[i] + '</option>';
}
template = template + '</select>';
$("div#project-names").append(template);
});
}
});