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

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>

Related

make diffrence between objects that created with clone() in java script

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');

Is there a way to disable a dropdown to users while still being able to submit a form with the disabled dropdown?

I have a dropdown that is disabled to the user. I want for the user to be able to press a button that changes the selected item to a different one. For example: from the 4th item in the dropdown to the 7th.
I've tried disabling the dropdown, but when I do that and submit the form, I get a PHP error saying Undefined index: id.
HTML:
<form>
<select id='id' name='id' autocomplete='none' disabled required>
<option value='2'>apple</option>
<option value='6'>banana</option>
<option value='10'>orange</option>
</select>
<button type='submit'>Submit</button>
</form>
JavaScript:
const dropdown = document.getElementById('dropdown');
const options = dropdown.options;
for (let i = 0; i < options.length; ++i) {
if (options[i].value === id) {
dropdown.selectedIndex = i;
break;
}
}
PHP (This line seems to be the one breaking):
$id = $_POST['id'];
It seems you haven't defined method and action in your form tag. By default, I think, the method is set to 'GET', so when checking 'POST' you'll run into your error.
Therefore, set "method='post'" (and best also an action, e.g. "action='/yourPageName.php') and see if that helps.
I figured out a solution that suits my needs. It was kind of simple. I just enabled the dropdown when I submitted the form, and instantly disabled it again.
id.removeAttribute('disabled');
const data = new FormData(document.getElementById('form'));
id.setAttribute('disabled', '');
request.send(data);
Thanks for the help though :)
A disabled input field will be ignored when you submit the form. I would suggest creating a hidden input field of name="id" if you want the user to view the dropdown but not select it.
<form>
<select id='id' autocomplete='none' disabled required>
<option value='2'>apple</option>
<option value='6'>banana</option>
<option value='10'>orange</option>
</select>
<input type="hidden" name='id' value="6" />
<button type='submit'>Submit</button>
</form>
You can make an hidden input with the id="id" and change the select id to "temp_id". Then, since you are making the request from javascript, you can just update the hidden field before making the request.
<select id='temp_id' autocomplete='none' disabled required>
<option value='2'>apple</option>
<option value='6'>banana</option>
<option value='10>orange</option>
</select>
<input type="hidden" name="id" id="id" value="">
Then, on your javascript, just before you make the request, run the code:
document.getElementById("id").value = document.getElementById("temp_id").value;

Serialize not returning value for select dropdown

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.

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.

Select from multiple HTML fields then add total to another list

I have 3 HTML fields: a textbox and two select lists.
What I'm trying to do is let the user enter something in the text field and choose options from the other two lists and then click an "Add" button which adds his total selection to another list. This final list is the one to be submitted and received by the CGI script.
So for example a user types in "Toyota" and selects Sedan from one list and 2004 from a second list and clicks add. Then, "Toyota Sedan 2004" would be added to an empty list. The user can add multiple selections to the list or remove from the list. And this list is the one that is submitted when the form is submitted. It is preferable if I do this in Javascript only so no JQuery. Can anyone point me in the right direction?
What you need is, when the "add" button is clicked, a simple javascript function is called that retrieves: the text, selection1 & selection2 => build a new option with these information the append it to the result list.
Key javascript functions:
- document.getElementById
- document.createElement
- appendChild
In your html the form/submit button must be around your result list only.
Example (jsfiddle link):
<html>
<head>
<script>
function add() {
var txt = document.getElementById("txt").value;
var sel1 = document.getElementById("sel1").value;
var sel2 = document.getElementById("sel2").value;
var result = txt + " " + sel1 + " " + sel2;
var resultOption = document.createElement("option");
resultOption.value = result;
resultOption.text = result;
document.getElementById("selResult").appendChild(resultOption);
}
</script>
</head>
<body>
<input id="txt" type="text" />
<select id="sel1">
<option value="value11">value11</option>
<option value="value12">value12</option>
<option value="value13">value13</option>
</select>
<select id="sel2">
<option value="value21">value21</option>
<option value="value22">value22</option>
<option value="value23">value23</option>
</select>
<input type="button" value="add" onClick="javascript:add()"/>
<br/>
result:
<form action ="." method="post">
<select id="selResult"></select>
<input type="submit" value="submit"/>
</form>
</body>
</html>
Use need to user this jquery plugins:
Jquery Forms
Jquery Auto Tab
Jquery UI
And some jquery functions that can be useful for you:
.ajax()
prepend()
.on()

Categories

Resources