Change input type based on value - javascript

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.

Related

how i can disable the appending option when it is selected once in javascript

function populate() {
$('#select_items :selected').each(function() {
let html = '';
html += '<div>';
html +='<label> Quantity:'+$(this).text()+' </label>';
html += '<input type="text" name="quantity[]" class="form-control" ID="txtName" placeholder="Enter Quantity" required="" val='+$(this).val()+' />';
html += '</div>'
$('#selected-quantity').append(html)
})
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form method="POST" style="width:60%;margin-left:200px">
<div class="form-group">
<label>Choose Product:</label>
<select name="product_id" class="form-control" class="select" id="select_items" multiple onchange="populate()">
<option disabled selected>-- Select Product --</option>
<option value="foo1">foo1</option>
<option value="foo2">foo2</option>
<option value="foo3">foo3</option>
<option value="foo4">foo4</option>
<option value="foo5">foo5</option>
</select>
<div id="selected-quantity">
</div>
</div>
<form>
i want to disable the selected option when it is already selected.i have tried with the but this didnt work.this is the code where it is appending the dynamically
function populate() {
$('#select_items :selected').each(function() {
let html = '';
html += '<div>';
html +='<label> '+$(this).text()+' </label>';
html += '<input type="text" name="quantity[]" class="form-control" ID="txtName" placeholder="Enter Quantity" required="" val='+$(this).val()+' />';
html += '</div>'
$('#selected-quantity').append(html)
});
}
here is the code where i tried to disable the selected option
$(document).on('click', 'select.select_items', function () {
$('select[name*="product_id[]"] option').attr('disabled',false);
$('select[name*="product_id[]"]').each(function(){
var $this = $(this);
$('select[name*="product_id[]"]').not($this).find('option').each(function(){
if($(this).attr('value') == $this.val())
$(this).attr('disabled',true);
});
});
});
the CDN use for this is given below
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
function populate() {
$('#select_items :selected').each(function() {
var seldrop = $("#select_items :selected").val();
if ($("#selectedbox_" + seldrop).length == 0) {
let html = '';
html += '<div id="selectedbox_' + seldrop + '">';
html += '<label> Quantity:' + $(this).text() + ' </label>';
html += '<input type="text" name="quantity[]" class="form-control" ID="txtName" placeholder="Enter Quantity" required="" val=' + $(this).val() + ' />';
html += '</div>'
$('#selected-quantity').append(html)
} else {
alert("Already Added");
}
});
}
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"> </script>
Check Append Div length exists or not
$("#selectedbox_" + seldrop).length == 0
<form method="POST" style="width:60%;margin-left:200px">
<div class="form-group">
<label>Choose Product:</label>
<select name="product_id" class="form-control" class="select" id="select_items" multiple onchange="populate()">
<option value="0" disabled selected>-- Select Product --</option>
<option value="foo1">foo1</option>
<option value="foo2">foo2</option>
<option value="foo3">foo3</option>
<option value="foo4">foo4</option>
<option value="foo5">foo5</option>
</select>
<div id="selected-quantity">
</div>
</div>
<form>
Try this code.
You are using select_items as class. But it is id.
Added working fiddle link also.
Working fiddle link
var selectedVal = [];
$(document).on('click', '#select_items option:selected', function () {
$("select option[value='"+$(this).val()+"']").attr('disabled', true);
});
function populate() {
$('#select_items :selected').each(function() {
let html = '';
html += '<div>';
html +='<label> '+$(this).text()+' </label>';
html += '<input type="text" name="quantity[]" class="form-control" ID="txtName" placeholder="Enter Quantity" required="" val='+$(this).val()+' />';
html += '</div>'
$('#selected-quantity').append(html)
});
}

PHP post with dynamic entries created in JS

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>

How to retrieve data from array using $.getJSON?

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>

For loop ending unexpectedly

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 + "&#8451</td>";
dailyText += "<td>" + dailyJsonObject.list[i].temp.max + "&#8451</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 +*/ "&#8451</td>";
dailyText += "<td>" + /*dailyJsonObject.list[i].temp.max +*/ "&#8451</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 want to submit the form when last option of dropdown is selected options are generated dynamically

For example I am adding field after selecting the Parent then insert child field , I want to submit a form when select list is ended or select is on last child how to submit after I added all fields and if I have no child of select then submit
<script type="text/javascript">
var children = $H(<?php echo json_encode($tree['children']) ?>);
function showCat(obj, level) {
var catId = obj.value;
level += 1
if ($('cat_container_' + level)) {
$('cat_container_' + level).remove();
}
if (children.get(catId)) {
var options = children.get(catId);
var html = '<select id="cat_' + catId + '" onchange="showCat(this, ' + level + ')">';
for (var i = 0; i < options.length; i++) {
html += '<option value="' + options[i].entity_id + '">' + options[i].name + '</option>';
}
html += '</select>';
html = '<div id="cat_container_' + level + '">' + html + '</div>';
$('sub_cat').insert(html);
}
}
Here is my form i m using onchange="this.form.submit()"
<form id="search_mini_form" action="<?php echo $catalogSearchHelper->getResultUrl() ?>" method="get">
<select id="first_cat" name="<?php echo $catalogSearchHelper->getQueryParamName() ?>" value="<?php echo $catalogSearchHelper->getEscapedQueryText() ?>" onchange="showCat(this,2);this.form.submit()">
<?php foreach ($tree['first'] as $cat): ?>
<option value="<?php echo $cat->getId() ?>"><?php echo $cat->getName() ?> </option>
<?php endforeach ?>
</select>
<button type="submit" title="<?php echo $this->__('Search') ?>" class="button"><span><span><?php echo $this->__('Search') ?></span></span></button>
This code is adding field but it submit on first select i have a tree of select and i want to submit when its on last select
var strLastOptionSelected = $("select option:last-child").val();
$("select").change(function() {
if ($(this).children("option:selected").val() === strLastOptionSelected) {
alert("You have selected the last option");
//Submit code
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
<option value="4">Option 4</option>
</select>

Categories