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.
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();
}
}
}
Good Day Friends. I have a problem... Thanks, if you help me
I have a couple of inputs into a div. I copied that div with Clone function in java script (by click a button) and right now, I have two divs. but my problem:
1- I don't know, How can I get the values of inputs correctly (the input's names are the same)?
2- and I have a select input in div, that some inputs add or remove by choose each option of select input. Now after copied div, choose one option in div2, create changes in div1... and I don't want it !!
<div class="levels">
<div class="add_senario_level">
<span>Level 1</span>
<form>
<select name="condition" onchange="show_div(this,'shop during');">
<option selected="selected" disabled="disabled">choose condition</option>
<option>shop after registration</option>
<option>shop during</option>
</select>
<div id="shop_during" style="display:none;">
<input type="number" id="shop_during_num" name="shop_during_num" placeholder="Enter number">
<select id="shop_during_time" name="shop_during_time">
<option selected="selected">hour after registeration</option>
<option>day after registeration</option>
<option>week after registeration</option>
<option>month after registeration</option>
</select>
</div>
<div>
<button type="button" class="newLevel"> Add New Level </button>
</div>
</form>
</div>
</div>
<script>
$(document).ready(function()
{
$(".newLevel").click(function()
{
$(".add_senario_level").clone().appendTo(".levels");
});
});
function show_div(obj, id)
{
txt = obj.options[obj.selectedIndex].text;
if (txt.match(id))
{
document.getElementById("shop_during").style.display = 'block';
}
else
{
document.getElementById("shop_during").style.display = 'none';
}
}
</script>
You can use jQuery's find function to find a child element and the attr function to get and set attribute values. You will want to do this to change on the id and name attributes for the input and select like below:
HTML
<input type="number" id="shop_during_num0" name="shop_during_num0" class="shop_input" placeholder="Enter number">
JavaScript
$(".newLevel").click(function()
{
const count = $('.add_senario_level').length;
const clone = $(`#add_senario_level${count - 1}`).clone();
const input = clone.find(`#shop_during_num${count - 1}`);
const select = clone.find(`#shop_during_time${count - 1}`);
input.attr('name', `shop_during_num${count}`);
input.attr('id', `shop_during_num${count}`);
select.attr('name', `shop_during_time${count}`);
select.attr('id', `shop_during_time${count}`);
clone.appendTo(".levels");
});
In the show_div method, you can use $(obj) to reference the select that called the function and show or hide the correct element with
$(obj).parent().find('#shop_during').css('display', 'block');
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>
This is my html,When i click option "new-item" it will open input type box , and then i enter value it want to add to select option
<form (submit)="addItem()">
<input type="text" [(ngModel)]="add.name" name="name">
<input type="text" [(ngModel)]="add.price" name="price">
<input type="text" [(ngModel)]="add.description" name="description">
<select [(ngModel)]="add.type" name="room-type">
<option [value]="c">Select</option>
<option>BreakFast</option>
<option>Lunch</option>
<option>Dinner</option>
<option><button (click)="addSelect()">Add-item</button></option>
<input *ngIf='edited' type="text" >
</select>
and my type script is,
addSelect() {
this.edited = true;
}
constructor() {
this.edited = false;
}
You can't add such an event to an <option>.
You can see that the event doesn't fire in all browsers (the only browsers it works in is < ie11 and Firefox):
$("#trig").click((event) => console.log(event));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select>
<option>default</option>
<option id="trig">trigger</option>
</select>
The tag does not propagate down any click events. So any click events you try and allocate inside an option will not work. Your best bet is to look at the value you receive in the onChange() callback and then turn on another component which allows the user to enter data. You could even use a window.prompt() to get such data.
You can instead do this:
<select (change)="onChange($event.target.value)">
onChange(val) {
console.log(val);
this.edited = false;
}
For further information on implementing this approach, see: How can I get new selection in "select" in Angular 2?