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');
Related
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="1Title1">Title1</option>
<option value="2Title2">Title2</option>
</datalist>
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();
}
}
}
I have some code that gets a value from unselected options in a select dropdown. This displays in console.log as an array with the correct values. However, serialize(); is not returning any values for this select when i console.log(data);. If I console.log(boxintake); this shows me the correct values being passed.
Options are being added from button click and are working correctly. Assume all names and form names are correct.
I would be grateful if someone could enlighten me as to why this is not working. Many thanks.
html
<div class="form-group">
<label class="labelStyle" for="box_ni">Select Your Box(es)</label><br />
<select disabled id="box_ni" multiple name="box_ni[]" size="15">
<option value="">
</option>
</select>
<div id="nidstrmessage"></div>
<div class="servicesHelp"><lead id="serviceHelp" class="form-text text-muted help">
Read help <img src="/domain/admin/images/qmark.png" width="24px" height="24px" class="helpintk"/>
</lead>
</div>
<div class="noBrtvBoxes" style="color:white;"></div>
</div>
js
$("#USRboxni").submit(function(e) {
e.preventDefault();
var boxintake = $("#box_ni option").map(function(){
return this.value;
}).get();
console.log(boxintake);
var data = $("#USRboxni").serialize();
console.log(data);
});
Couple of issues:
.serialize() will exclude any controls that are disabled
.serialize() on a multi select will only return the selected values
As your select is both disabled and doesn't have anything actually selected, you get no results.
When you add your items, I suggest you also make them selected at that time; this might solve many of your issues.
That's what <select multiple is for - giving the user a number of options and allowing them to select which ones they want. But you're not using it for that, you're using it as a "the user selected these". You might be better off using a hidden input store and a div to show the selected values.
Example snippet with disabled removed and one item selected shows that it only returns that one item:
//$("#USRboxni").submit(function(e) {
//e.preventDefault();
var boxintake = $("#box_ni option").map(function() {
return this.value;
}).get();
console.log(boxintake);
var data = $("#USRboxni").serialize();
console.log(data);
//});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form id='USRboxni'>
<div class="form-group">
<label class="labelStyle" for="box_ni">Select Your Box(es)</label><br />
<select /*disabled*/ id="box_ni" multiple name="box_ni[]" size="15">
<option value="1" selected>one</option>
<option value="2">two</option>
</select>
</div>
</form>
You could remove the 'disabled' just before serialize() then add it back, but you'll still need to select the items.
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...
I have a small form.
Two select box elements and a submit button.
The select box elements collectively when selections are chosen, fire off an ajax request.
What I want to do is, disable the submit button UNTIL user has made selections from the select drop downs.
They must make a selection from BOTH select drop downs, before the Submit button is enabled.
I dont mind if the submit button is hidden until selections made.
Brief Code:
<form id="ad_form" method="post" action="">
<p>
<select id="ad_type" name="ad_type">
<option value="" selected="selected">Select premium ad type</option>
<option value="<?php echo TYPE_USER;?>">Featured Agent</option>
<option value="<?php echo TYPE_LISTING;?>">Featured Listing</option>
</select>
<label for="ad_type" class="labelStrong">Advertising Type</label>
</p>
<p>
<select id="ad_duration" name="ad_duration">
<option value="" selected="selected">Select premium ad duration</option>
<option value="weekly">Weekly</option>
<option value="fortnightly">Fortnightly</option>
<option value="monthly">Monthy</option>
</select>
<label for="ad_duration" class="labelStrong">Advertising Duration</label>
</p>
<p>
<div id="calender">
</div>
</p>
<p>
<input type="submit" name="submit" value="Submit" id="submitorder" />
</p>
</form>
Here's a demo that seems to do what you want:
http://jsfiddle.net/Yr59d/
That javascript code would go in a $(document).ready() block
$(function() {
$("#submitorder").css("visibility", "hidden");
$("#ad_form select").bind("change", function() {
if ($("#ad_type").val().length > 0 && $("#ad_duration").val().length > 0) {
$("#submitorder").css("visibility", "visible");
} else {
$("#submitorder").css("visibility", "hidden");
}
});
});
If you give all your selects a common class name (like 'required') , you can do something like this:
$('select.required').change(function() {
var total = $('select.required').length;
var selected = $('select.required option:selected').length;
$('#submitorder').attr('disabled', (selected == total));
});
This is not tested code. This documentation might help. This jquery discussion might help too.
Gah, I'll have to agree with Kon on this one - fix-now-worry-about-it-later answers have their place but an elegant solution that is simple at the same time has to be the way to go.
My solution: (with credit from a thread at: JQuery Enable / Disable Submit Button in IE7)
$('select.required').change(function() {
var total = = $('select.required').length;
var selected = $('#ad_form').find("select.required option[value!='':selected").length;
$('#submitorder').prop('disabled', (selected != total));
});
Incidentally, thanks ctcherry for demoing the code on the JSFiddle site - I've not seen that before and will make use of it in the future!
Use listeners on both select buttons for change and check whether the other is also set. If set, enable the submit button.