How to POST selected option to controller - javascript

I have created the following dropdown list and also the conditional check that will output the "block" -> details that are associated with the options. See below for e.g:
function val(ddbox) {
//NEW
if ( ddbox.options[ddbox.selectedIndex].value == "Others"){
document.getElementById("extradiv").style.display = "block";
}else{
document.getElementById("extradiv").style.display = "none";
}
if( ddbox.options[ddbox.selectedIndex].value != "Others"){
document.getElementById("NumberChosen").style.display = "block";
}else{
document.getElementById("NumberChosen").style.display = "none";
}
}
<li class="bigfield">
<select name ="ddbox" id="ddbox" onchange = "val(this)">
<option value ="0"> Select Number..</option>
<option value ="Option 1"> 1</option>
<option value ="Option 2"> 2</option>
<option value ="Option 3"> 3</option>
<option value = "Others"> Others</option>
</select>
</li>
<!--when user select "Others"-->
<div id = "extradiv" style ="display:none">
<li class="bigfield"><input placeholder="Enter your Num" type="text" name="OthersNum" id="OthersNum"/></li>
<li class="bigfield"><input placeholder="Number Characteristics" type="text" name="NumberOthersCharacteristics" id="NumberOthersCharacteristics"/></li>
<li class="bigfield"><input placeholder="why do you like this number" type="text" name="NumberOthersLikefactor" id="NumberOthersLikefactor"/></li>
</div>
<!--when user select other options-->
<div id = "NumberChosen" style ="display:none" >
<li class="bigfield"><input value="NumChosen" type="text" name="NumChosen" id="NumChosen" readonly></li>
<li class="bigfield"><input value="Num Chosen Characteristic" type="text" name="NumChosenCharactersitics" id="NumChosenCharactersitics" readonly/></li>
<li class="bigfield"><input value="Num Chosen Likes" type="text" name="NumChoseLikes" id="NumChoseLikes" readonly/></li>
</div>
I have made each chosen option to reference to the details in and when user clicks "Others", it will reference to the input field in . Hence the field form is done within the View of the MVC framework.
To ensure that on submission and the values are POST correctly to the controller code, I have made the following error log within the controller code to check on the values captured from the form. The following error_logs as shown:
error_log(date("Y-m-d H:i:s")."_ipad,Num: ".$_POST['OthersNum']."\n",3,"/var/tmp/*/*.log");
error_log(date("Y-m-d H:i:s")."_-ipad, NumChar: ".$_POST['NumberOthersCharacteristics']."\n",3,"/var/tmp/*/*.log");
error_log(date("Y-m-d H:i:s")."_-ipad, NumLikes: ".$_POST['NumberOthersLikefactor']."\n",3,"/var/tmp/*/*.log");
error_log(date("Y-m-d H:i:s")."_-ipad,NumberChosen: ".$_POST['NumChosen']."\n",3,"/var/tmp/*/*.log");
error_log(date("Y-m-d H:i:s")."_-ipad, NumChosenChar: ".$_POST['NumChosenCharacteristics']."\n",3,"/var/tmp/*/*.log"); error_log(date("Y-m-d H:i:s")."_-ipad, NumChosenLikes: ".$_POST['NumChoseLikes']."\n",3,"/var/tmp/*/*.log");
Now, this is the main issue that I am facing, both the error logs will always show when I run the following terminal command: 'tail -f *.log', for example, if I were to select "Others" in the option list and key in the respective fields, and submit the form, values will POST to the controller code and the error log will not only show the values for "OthersNum", it will also show the details of the NumChosen. That is not the result I want, I am looking at the error log only posting details that have been entered for "Others" option and not display the details associated for the other options as well
Hence, the redundant error_log is shown, from what I understand, all values from the form are POST -ed to the controller. Hence, how am I able to edit the existing code such that only the chosen selected option will be POST-ed over to the controller?

I think your problem is from the if statement, you don't want to use multiple if statement for same conditions, yours if statement should be,
function val(ddbox) {
if ( ddbox.options[ddbox.selectedIndex].value == "Others"){
document.getElementById("extradiv").style.display = "block";
document.getElementById("NumberChosen").style.display = "none";
}else{
document.getElementById("extradiv").style.display = "none";
document.getElementById("NumberChosen").style.display = "block";
}
}
Use single if statement for similar conditions, Hope this works...

Related

Getting selected datalist option value, and innerHTML, without using jQuery

I have a situation where I want to let a user decide titles of books that I have on my db, using an input with a datalist (generated by php), after the user picked a title, he would click a submit button and the form would send the title in another file.
Everything worked fine but I didn't realized that I needed to send the ID of the book that the user selected, because there can be more than one book with the same title.
What I would like to have is the option of the datalist, that no longer has the title of the book inside its "value" attribute, but I want that title inside its innerHTML, so that the title gets displayed, while having the ID inside the "value" attribute. My problem is that if I do that, when the user clicks on the datalist option, the ID gets inside the text input, so the user may not know what book he choose.
summing up: I would like to have the datalist that displays the title, when an option is chosen, that title gets displayed in the text input, when I submit, the Id of the book gets sent in "FindBook.php" inside $_POST.
isIn() checks if the title is inside the array of titles, I would need to change that so that it can check if the ID is inside the array of IDs.
<form onsubmit="alert(document.getElementById('number').value);" action="FindBook.php" target="_blank" method="POST">
<input id="number" list="BooksById">
<input type="submit" value="Find">
</form>
<datalist id="BooksById">
<option value="1">Title1</option>
<option value="2">Title2</option>
<option value="3">Title3</option>
<option value="4">Title4</option>
</datalist>
<br>
<form onsubmit="alert(document.getElementById('string').value);" action="FindBook.php" target="_blank" method="POST">
<input id="string" list="booksByTitle">
<input type="submit" value="Find">
</form>
<datalist id="booksByTitle">
<option value="Title1"></option>
<option value="Title2"></option>
<option value="Title3"></option>
<option value="Title4"></option>
</datalist>
Since I don't understand jQuery I would really prefer a solution that doesn't imply that.
I think that in your case you must use a <select> tag instead of a <datalist> because you do not want the end user to enter new names (or yes?). However you can work with the data attributes like in the code below:
HTML:
<input list="titles" id="title-input" oninput="getBookId()">
<datalist id="titles">
<option data-value="5" value="A book name">
</datalist>
JavaScript:
function getBookId() {
var selectedTitle = document.getElementById("title-input").value;
var value2send = document.querySelector(`#titles option[value='${selectedTitle}']`).dataset.value; // Here now you have the book title id.
console.log("getBookId ~ value2send", value2send)
}
I hope it works for you.
Assuming you can provide distinct title values for each datalist option...
Add a dataset attribute, such as data-id, to your datalist option elements, containing the corresponding id, and add a hidden type input to your form. Then use the onsubmit event handler function to get the selected datalist option's dataset id value and assign it to the value of the hidden input:
function findBook(form) {
form.bookid.value = document.querySelector(`datalist option[value="${form.booktitle.value}"]`).dataset.id;
console.log(form.bookid.value);
return false;
}
<form onsubmit="return findBook(this)">
<input type="hidden" name="bookid">
<input name="booktitle" list="BooksById">
<input type="submit" value="Find">
</form>
<datalist id="BooksById">
<option data-id="1" value="Title1">
<option data-id="2" value="Title2">
<option data-id="3" value="Title3">
<option data-id="4" value="Title4">
</datalist>
Upon form submission, your PHP file will have the variables $_POST['bookid'] and $_POST['booktitle'] available.
Thanks for your suggestions. I prefer to use a datalist, instead of a select tag, because it looks more like a dropdown menu that works like a button. Using datalist allows me to find a book by a random word inside the title of it, while the select only finds the first word of an entry. I can also distinguish different books with the same name by another attribute that states if it's available or if it's taken.
I asked for no JQuery, i appreciate your help but I really don't understand them, even if it's cleaner to use them I would like a solution that doesn't use them.
I ended up using the solution CBroe suggested:
document.getElementById("bookTitle").addEventListener('input', function (evt) {
let data = this.value.split('');
document.getElementById("bookId").value = "";
if(isIn(data,'books')){
document.getElementById("bookId").value = data[0];
document.getElementById("bookTitle").value = data[1];
}
});
function checkForm(id, value, list){
if(isIn([document.getElementById(id).value,document.getElementById(value).value],list)){
alert("Book found");
return true;
}else{
alert("not found")
return false;
}
}
function isIn(value, list) {
switch (list) {
case 'books':
//this was generated by php in my code
if (value[0] == 1 && value[1] == "Title1"){
return true;
}
if (value[0] == 2 && value[1] == "Title2"){
return true;
}
return false;
break;
//I've cut out other cases
}
}
<form onsubmit="checkForm('bookId','bookTitle','books')" action="FindBook.php" target="_blank" method="POST">
<input id="bookTitle" list="booksByTitle" autocomplete="off">
<label>id:</label>
<input id="bookId" <!--type="hidden"-->
<input type="submit" value="Find">
</form>
<datalist id="booksByTitle">
<!-- value was generated by php in my code-->
<option value="1Title1">Title1</option>
<option value="2Title2">Title2</option>
</datalist>

Need to advice applying .disabled in Javascript

I run Woocommerce website and want to disable a specific input on the checkout page.
Woocommerce can set shipping method by country.
I have the default country set as S,Korea, and the shipping options for Korea are displayed.
However, where if i select US, Shipping method will see shipping options according to the US.
So, Shipping method of US is not displayed by default.
And it will only be displayed if visitor select "US" as the shipping country.
Here I want to disable the input field that is only displayed when the shipping country is US.
I can hide this input field using CSS, or even get rid of it.
However, the reason I want to disable it is that the post office is temporarily paralyzed due to Corona.
I want to inform visitor that the shipping method is not only express shipping, there is also free shipping, but it is temporarily unavailable.
My website structure is as follows.
Default (S.korea)
<td data-title="shipping">
<ul id="shipping_method" class="shipping__list woocommerce-shipping-methods>
<li class="shipping_list_item">
<input id="shipping_method_0_free_shipping1">
<label class="shipping_list_label" for="shipping_method_0_free_shipping1">
</li>
</ul>
<td>
If choose shipping country as US
<td data-title="shipping">
<ul id="shipping_method" class="shipping__list woocommerce-shipping-methods>
<li class="shipping_list_item">
<input type="radio" id="shipping_method_0_free_shipping3"> <--- want to disable this
<label class="shipping_list_label" for="shipping_method_0_free_shipping3">
</li>
<li class="shipping_list_item">
<input type="radio" id="shipping_method_0_flat_rate2"
<label class="shipping_list_label" for="shipping_method_0_flat_rate2">
</li>
</ul>
</td>
Country selector
<span class="woocommerce-input-wrapper">
<select name="billing_country">
<option value>Select Country</option>
<option value="US">US</option>
<option value="KR" selected="selected">Korea</option>
<option value="CA">Canada</option>
</select>
And I tried the javascript below.
<script>
const target = document.querySelector('#shipping_method > li:nth-child(1)');
target.disabled = true;
</script>
<script>
const target = document.querySelector('#shipping_method_0_free_shipping3');
target.disabled = true;
</script>
but these code not work.
I'd like to get some advice on which part I should check.
Try this (Updated Answer)
<input id="name" type="text"/>
const myInput = document.getElementById("name")
const inputDisabled = true
if (inputDisabled) {
myInput.setAttribute("disabled", "disabled");
} else {
myInput.removeAttribute("disabled");
}
You can try to do it with css styling, place your inputs inside a div and give the div a disabled class, all you have to do is to assign the disabled class to the div via java script
div.disabled {
opacity: 0.6;
pointer-events: none;
}
html
<div id="#mydiv"> <input name="input-1"/></div>
//jquery code
$("#mydiv").addClass("disabled");
//javascript code
document.getElementById("#myDiv").classList.add('disabled');

Shopify - Debut Theme - Showing A Textbox if Certain Variant is Selected

I'm trying to show my "Embossing" textbox only when the "Style" dropdown option "Embossing" is selected. I've added the below code in my new template, product-customizable-template.liquid, which created the textbox but I want to hide it unless "Embossing" is selected.
<p class="line-item-property__field">
<label for="embossing">Embossing</label>
<input required class="required" id="embossing" type="text" name="properties[Embossing]">
</p>
"Style" Dropdown
The Style textbox has the following code:
<select class="single-option-selector single-option-selector-product-customizable-template product-form__input" id="SingleOptionSelector-0" data-index="option1">
<option value="None" selected="selected">None</option>
<option value="Embossing">Embossing</option>
<option value="Stamp">Stamp</option>
</select>
I am still working on the site, so it is not active right now.
Any help would be greatly appreciated, thank you!
You need to check on-page load and on change of select box using Javascript and you can add and remove custom code to form easily
You can check and try the below snippet for a better idea
// on change test for your condition
document.getElementById('SingleOptionSelector-0').addEventListener('change', function (e) {
_checkAndAppend();
});
// run on page load and check the for value and add if selected value meet condition
_checkAndAppend();
function _checkAndAppend() {
var item = document.getElementById('SingleOptionSelector-0');
var itemValue = document.getElementById('SingleOptionSelector-0').value;
if (itemValue == 'Embossing') {
var input = `<p class="line-item-property__field _embossing">
<label for="embossing">Embossing</label>
<input required class="required" id="embossing" type="text" name="properties[Embossing]">
</p> `;
item.parentNode.insertAdjacentHTML('beforeend',input);
} else {
if(document.querySelector('._embossing')){
document.querySelector('._embossing').remove();
}
}
}

If a user selects a option from the select box, hidden div should appear

so I am trying to display a div if user select a specific option value from a select drop down list. for example, if the user selects "trade" in the select box then the div with the company name should come up while the div containing the "first name and last name" should disappear. and If the user selects the "customer" in the select box then the the opposite should happen. Here is my code
Javascript
var custDetails = document.getElementById('retCustDetails');
var tradeDetails = document.getElementById('tradeCustDetails');
var SelectMenu = document.getElementById('makeBooking');
if (makeBooking.value == trd) {
document.getElementById('tradeDetails').style.display = 'block';
document.getElementById('custDetails').style.display = 'none';
}
else {
document.getElementById('custDetails').style.display = 'block';
}
HTML
<section id="makeBooking">
<h2>Make booking</h2>
Your details
Customer Type:
<select name="customerType">
<option value="">Customer Type?</option>
<option value="ret">Customer</option>
<option value="trd">Trade</option>
</select>
<div id="retCustDetails" class="custDetails">
Forename <input type="text" name="forename">
Surname <input type="text" name="surname">
</div>
<div id="tradeCustDetails" class="custDetails" style="visibility:hidden">
Company Name <input type="text" name="companyName">
</div>
You should be using an if / else if to handle the different values that the user could select - this also allows you to hide all the divs by default, if no valid selection is picked
You can use .addEventListener('change', function ()) on your Select element to call a function every time the value is updated, and then you can use this.value inside the function to access the selected element's value
Also, be sure that you're wrapping strings with ' or " - You were using makeBooking.value == trd, which is checking for a variable called trd, not the String 'trd' as you were aiming for
Finally, You could hide your divs by default using CSS, so that only the correct div is showing when selected
.custDetails {
display: none;
}
var custDetails = document.getElementById('retCustDetails');
var tradeDetails = document.getElementById('tradeCustDetails');
var SelectMenu = document.getElementById('makeBooking');
document.querySelector('select[name="customerType"]').addEventListener('change', function() {
if (this.value == 'trd') {
custDetails.style.display = 'none';
tradeDetails.style.display = 'block';
} else if (this.value == 'ret') {
custDetails.style.display = 'block';
tradeDetails.style.display = 'none';
} else {
custDetails.style.display = 'none';
tradeDetails.style.display = 'none';
}
});
.custDetails {
display: none;
}
<section id="makeBooking">
<h2>Make booking</h2>
Your details Customer Type:
<select name="customerType">
<option value="">Customer Type?</option>
<option value="ret">Customer</option>
<option value="trd">Trade</option>
</select>
<div id="retCustDetails" class="custDetails">
Forename <input type="text" name="forename"> Surname <input type="text" name="surname">
</div>
<div id="tradeCustDetails" class="custDetails">
Company Name <input type="text" name="companyName">
</div>
First, you had different names in your JavaScript than you had as ids in your HTML. You were also trying to work with the section element instead of the select element.
After that, you need to set up an event handling function to handle when the select gets changed.
Also, instead of working with inline styles. It's much simpler to set up a CSS class and then just add or remove it.
Finally, don't use an HTML heading element (h1...h6) because of the formatting applied to it. Formatting is done with CSS. Choose the right heading because it makes sense. You can't have the first heading in a section be an h2 because and h2 is for a subsection of an h1. The first heading in any section should always be h1.
See comments inline:
var custDetails = document.getElementById('retCustDetails');
var tradeDetails = document.getElementById('tradeCustDetails');
// You must get a reference to the <select> element
var selectMenu = document.getElementById('customerType');
// Then, you must configure a JavaScript function to run as a "callback"
// to a specific event that the <select> element could trigger:
selectMenu.addEventListener("change", function(){
// The value of the select will be a string, so you must wrap it in quotes
if (selectMenu.value == "trd") {
// Now, just add or remove the pre-made CSS class as needed.
tradeDetails.classList.remove("hidden");
custDetails.classList.add("hidden");
} else {
tradeDetails.classList.add("hidden")
custDetails.classList.remove("hidden");
}
});
.hidden { display:none; }
<section id="makeBooking">
<h1>Make booking</h1>
Your details<br>
Customer Type:
<select name="customerType" id="customerType">
<option value="">Customer Type?</option>
<option value="ret">Customer</option>
<option value="trd">Trade</option>
</select>
<div id="retCustDetails" class="custDetails hidden">
Forename <input type="text" name="forename">
Surname <input type="text" name="surname">
</div>
<div id="tradeCustDetails" class="custDetails hidden">
Company Name <input type="text" name="companyName">
</div>
</section>

how do i make my onchange function generic?

My Javascript function checks for radio button selection and displays the appropriate drop down box. but this code is not generic, i tried using "this" but it doesn't help.. can this actually be generic?
CODE:
function change(s)
{
if(document.getElementById("viewstate").checked==true)
{
document.getElementById("state").style.display="inline";
document.getElementById("cat").style.display="none";
}
else
{
document.getElementById("state").style.display="none";
if(document.getElementById("viewcat").checked==true)
{
document.getElementById("cat").style.display="inline";
}
else
document.getElementById("cat").style.display="none";
}
}
Front end radio button
<input type="radio" name="viewrecord" value="viewstate" onchange="change('state')" required="" id="viewstate"> View by State
<select name="stat" id="state" style="display:none;">
<option selected disabled>Select State</option>
<input type="radio" name="viewrecord" value="viewcat" required="" onchange="change('cat')" id="viewcat">View By Agency
<select id="cat" name="che" style="display:none" required="">
You can try with this snippet
JS
document.addEventListener('click',function(event){
var tar = event.target.id;
if(tar ==="viewstate"){
document.getElementById("state").style.display="inline";
document.getElementById("cat").style.display="none";
}
else if(tar==="viewcat"){
document.getElementById("state").style.display="none";
document.getElementById("cat").style.display="inline";
}
},false)
WORKING COPY
What else I tried?
My primary idea was to add a class to next select tag. For example if you select radio#viewstate it will add a class to closest select element. Then just loop through all the select tag and whoever dont have this class , hide them.
But since you are using display:none nextSibling will not work.For why nextSibling wont work you can take a look at difference between it visibility:hidden
Also note in the demo that I have used label tag with input
If by generic you mean to make the function to be able to work for any similar selection process without depending on the hard-coded values of the selection inputs, this is one way I thought of doing it :
function change(selectorId, selectorClass) {
// Get all the selector elements you use.
var rS = document.getElementsByClassName( selectorClass );
// Out of the elements you fetched above, make the one with
// id = selectorId visible, rest hidden.
for(var i = 0; i < rS.length; ++i)
rS[i].style.display = (rS[i].id == selectorId) ? "inline" : "none";
}
In the HTML part add a class to every select input you want to use with the radio values:
<input type="radio" name="viewrecord" value="viewstate" onchange="change('state', 'record-selector')" required="" id="viewstate"> View by State
<select class='record-selector' name="stat" id="state" style="display:none;">
<option selected disabled>Select State</option>
<input type="radio" name="viewrecord" value="viewcat" required="" onchange="change('cat', 'record-selector')" id="viewcat">View By Agency
<select class='record-selector' id="cat" name="che" style="display:none" required="">
With this you can use the same function for similar selection process on different forms.

Categories

Resources