Hide datalist options when user starts typing - javascript

I've created a datalist that shows the saved data of the user when he/she closed the program. I wanted the datalist to only show when the user clicks on the dropdown arrow (or the input box) and hides when the user starts typing. I've tried:
Creating an oninput event in the hopes that the datalist will hide when user starts typing.
Hiding datalist by using datalist.style.display = none;
Trying the codes written here: Avoid filtering of datalist items in an input element (Although it does not work in my case because I need to use pure JS)
Help is appreciated, thanks.
Edit:
Here is my code:
<div style="top:60px;position:absolute;z-index:2" id="speechBox">
<input id ="userText" name="userText" type="text" list = 'talk-list' oninput = "hideList()"></input>
<span class = "dropdown" title = "Saved Talk"><datalist id = 'talk-list'></datalist></span>
<button id="speakText" class="toolbutton" title="Speak"></button>
<hr>
</div>
<script>
function hideList() {
var hiddenList = document.getElementById("talk-list");
hiddenList.style.display = none;
}
</script>
Note: The datalist is not empty. I have an external script that adds infinite amount of options to datalist.

One way you can do this is to chage the datalist id when there is a value in input. If there is no value then change the id back so that they can choose the options in the datalist rather than type a new one.
function hideList(input) {
var datalist = document.querySelector("datalist");
if (input.value) {
datalist.id = "";
} else {
datalist.id = "talk-list";
}
}
<input id ="userText" name="userText" type="text" list = 'talk-list' oninput="hideList(this)"></input>
<span class = "dropdown" title = "Saved Talk"><datalist id = 'talk-list'><option>Apple</option><option>Ball</option><option>Calculator</option><option>Donkey</option></datalist></span>
<button id="speakText" class="toolbutton" title="Speak">Speak</button>

I doubt you can replace how the <datalist> element behaves. If I were you, I'd just make my own datalist made out of divitis. The sample below still has ways to go, but this should get you started in case you want to go this path.
The 3rd solution you mentioned in your post is not really a direct solution to your datalist problem. Instead it suggests a separate library that can render a datalist-like ui element, which turns out to be something from jQuery. What I'm suggesting is exactly like that, except you're gonna write your own.
function hideList() {
const list = document.querySelector("#talk-list");
list.style.display = "none";
}
function showList(){
const list = document.querySelector("#talk-list");
list.style.display = "block";
}
#talk-list{ border: 1px solid #ccc; display: none; }
button{display: block}
<div style="top:60px;position:absolute;z-index:2" id="speechBox">
<input id ="userText" name="userText" type="text" list = 'talk-list' oninput = "hideList()" onclick="showList()"></input>
<div id = 'talk-list'>
<div value="foo">foo</div>
<div value="bar">bar</div>
</div>
<button id="speakText" class="toolbutton" title="Speak">Submit</button>
</div>

Related

How to set required to a custom select option?

I want to show message required when user don't set a choice.
This is my code:
var options = document.querySelectorAll('.myOptions');
var selecText = document.querySelector('.selectFeld>p');
var mylist = document.querySelector('.list_contrat');
//var iconSelect = document.querySelector(".icon_typeCont_rota");
var valueTypeContra = document.querySelector('#typecontrat');
for(option of options) {
option.onclick = function() {
mylist.classList.toggle('myhide');
//iconSelect.classList.toggle('myRotate');
selecText.innerHTML = this.textContent;
valueTypeContra.value = this.getAttribute('data-value'); // get value select option
}
}
<div class="selectFeld" title="Type de contrat">
<input type="text" name="typeContrat" id="typecontrat" class="d-none" required>
<p>Type de contrat</p>
<img src="icon_form/Icon_contrat_deroulant.png" alt="" class="icon_select">
</div>
<ul class="container-optionSelec list_contrat myhide">
<li class="myOptions" data-value="redaction"><p>Redaction</p></li>
<li class="myOptions" data-value="assistance"><p>Assistance</p></li>
</ul>
It's a custom select option, the code set the value for the input displayed none
Since you're not using a standard form element you're not able to use the standard required attribute, and therefore don't have the standard help features that goes along with it. And adding required to your input field does not present the built-in help message because you are hiding it.
You need to use Javascript to program a custom "required" message to go along with your custom form input mechanism. Naturally there are a number of ways to accomplish this, and present an error message to your user. What do you suppose works best for your users?
Upon first glance...
Remove the ineffective required attribute from the input element. Change the input to a hidden type, to avoid using css to hide it. And add a note to the instructions letting your users know ahead of time the selection is necessary to proceed.
Add a submit event handler to the form to capture submission and have an opportunity to validate the form. In the handler check the (now hidden) input field for an empty string indicating the custom selection mechanism has not been used. If the input value is empty, emphasize the instructions, and provide the user an error message.
For example:
var options = document.querySelectorAll('.myOptions');
var selecText = document.querySelector('.selectFeld>p');
var mylist = document.querySelector('.list_contrat');
var valueTypeContra = document.querySelector('#typecontrat');
for (option of options) {
option.onclick = function() {
selecText.style.color = 'black'; // restore black color to instruction
selecText.innerHTML = this.textContent;
valueTypeContra.value = this.getAttribute('data-value');
}
}
// GET FORM AND ADD SUBMIT EVENT HANDLER
document.querySelector('form').onsubmit = function () {
// check if "typeContrat" is equal to an empty string
if ( "" === this.elements['typeContrat'].value ) {
// emphasize the instruction label
selecText.style.color = 'red';
// provide the user and alert message
alert('Veuillez sélectionner type de contrat');
// prevent the form from being submitted
return false;
}
// if "typeContrat" is not an empty string submit the form
else { return true; }
}
<form>
<div class="selectFeld" title="Type de contrat">
<input type="hidden" name="typeContrat" id="typecontrat" class="d-none" value="">
<p>Type de contrat (required)</p>
</div>
<ul class="container-optionSelec list_contrat myhide">
<li class="myOptions" data-value="redaction">
<p>Redaction</p>
</li>
<li class="myOptions" data-value="assistance">
<p>Assistance</p>
</li>
</ul>
<input type="submit">
</form>
However, there are many user interface approaches and programming mechanisms to accomplish this, so first determine what works best for your users, supports your application purpose, goals, and look, meets your security needs—and do that.

How to make divs which are created when a form is submitted, remain in place when the form is resubmitted

I am making a webpage where the user can use a form to search for a string and then divs will appear showing rows with matching info from a database. Then when a checkbox is clicked on a row it will move up to another div. I would like for the rows which have been selected via the checkbox to remain where they are when the form is resubmitted but still disappear when the checkbox is unclicked.
I have taken this video to show how it is currently working, which should hopefully make my question make sense.
https://imgur.com/a/DmkP0ut
This is the code for my form
<form action = "" method = "POST">
<div class = "searchcontainer">
<input id = "search" type="search" name = "search" class = "textbox" placeholder
= "Type the students name and press Enter to search...">
<input type = "submit" style="display:none" id = "submitsearch"/>
</div>
</form>
Then when the form is submitted this code will run to create the divs that appear (This is just a really short version, let me know if you need to see all of it)
<?php
if(isset($_POST['search'])){
$input = $_POST['search'];
$result = $conn->query("select * from logins");
let r<?php echo $studentid ?> = document.createElement("div");
r<?php echo $studentid ?>.id = "r<?php echo $studentid ?>";
r<?php echo $studentid ?>.className = "rowcontainer";
document.getElementById("tablecontainer").appendChild(r<?php echo $studentid ?
>);
Then this is the Javascript code which moves the rows to the 'selected' container when the checkbox is ticked and back to the 'tablecontainer' when unckecked.
<script>
const main = document.querySelector(".tablecontainer");
const selected = document.querySelector(".selected");
main.addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.classList.contains("move")) {
const rowContainer = tgt.closest(".rowcontainer");
if (tgt.checked) {
selected.append(rowContainer);
}
}
})
selected.addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.classList.contains("move")) {
const rowContainer = tgt.closest(".rowcontainer");
main.append(rowContainer)
}
})
</script>
From what I found online it looks like I will need to se session variables to keep the rows in place once they have been selected, but I dont really know how to do this, so help would be appreciated.
Thanks
Edit: I have a had a look through these answers but as a beginner they do not make much sense to me. I have found that I can use
var rowsselected = document.getElementById("selected").children;
to get a list of all the children divs in my selected div, so is there a way I can save this list so it persists when the form is resubmitted and take the children from this list and append them to selected again. If you could show examples that would be good. Also I should have mentioned this in the main post but I would also like to carry over info from the rows which have been selected to the next page so if I could make the ids of these rows into session variables or something like that that would be good.

Possible to leave out ID[] from url?

I have alot of data, that i can check, useing checkbox. when I 'Submit', and want to see all the data i checked, i get redirected to the result page. But lets say i choose to only check 1 element the URL is: http://XXX.xxx/Test/TestResults?ID%5B%5D=2728
this is okay, but lets say i choose to see 10 elements the URL is LONG:
http://XXX.xxx/Test/TestResults?ID%5B%5D=2728&ID%5B%5D=2726&ID%5B%5D=2727&ID%5B%5D=2725&ID%5B%5D=2724&ID%5B%5D=2723&ID%5B%5D=2722&ID%5B%5D=2721&ID%5B%5D=2720&ID%5B%5D=2719
and the problem is that if i choose to see 100 elements, the URL will become so long that the site can alert me with: 'Submitted URI too large!'
is there any way only to show the id number, and not the ID[] (ID%5B%5D)?
The ID[] is the ID%5B%5D part, and then the id number will be added to it.
echo "<input type = 'checkbox' name = 'ID[]' class = 'checkbox' value = '".$testjobids[$count]."'/>";
/*this is in another .php file where i get the ID*/
$SelectedTestjobids = $_GET['ID'];
Link is shorter
After useing _POST, i got this: http://XXX.xxx/Test/TestResults
Problem
The only problem i have now is that i can't link this site to anyone, because there isn't attached anything else but the site in the URL. Is there a way to make a uniqe number after the http://XXX.xxx/Test/TestResults, so it's possible to share the link and it stills shows the same data?
If you can't use a post request for some reason, you could copy the values you want and submit them as a more compact string, either manually or by adding the string to another form element before submitting.
Of course, your server code would have to know what to do with the comma-separated string when it receives it.
This example uses a hidden <textarea> element to hold the values:
// Identifies HTML elements
const
boxes = document.querySelectorAll(".box"),
area1 = document.getElementById("area1"),
btn1 = document.getElementById("btn1"),
div1 = document.getElementById("div1");
// Calls `submitCheckboxValuesAsText` when the button is clicked
btn1.addEventListener("click", submitCheckboxValuesAsText);
// Defines `submitCheckboxValuesAsText`
function submitCheckboxValuesAsText(){
// Puts checked values in the textarea
updateTextarea();
// Copies the text from the textarea
const text = area1.value;
// Clears the demo div
div1.innerHTML = "";
// Formats the copied text within the demo div
if(text){
div1.innerHTML = "Imagine this gets sent to your server:<br /><br />" +
"<span class='grey'>" + text + "</span>";
}
}
// Defines `updateTextarea`
function updateTextarea(){
area1.value = [...boxes] // `[...boxes]` converts `boxes` to a proper Array
.filter(box => box.checked) // Makes a new Array of just the checked boxes
.map(box => box.value) // Makes a new Array with the values of those boxes
.join(","); // Makes a string from the array, separated by commas
}
label{ margin-right: 15px; }
#btn1{ margin: 20px 5px; }
.grey{ background-color: #DDDDDD; padding: 2px 5px; }
<label><input type="checkbox" class="box" value="val1" /><span>box1</span></label>
<label><input type="checkbox" class="box" value="val2" /><span>box2</span></label>
<label><input type="checkbox" class="box" value="val3" /><span>box3</span></label>
<textarea id="area1" hidden></textarea>
<div><button id="btn1">Submit</button></div>
<div id="div1"></div>
(If you wanted to avoid submitting manually, you should probably populate the hidden field before the user clicks Submit, such as by using document.addEventListener("change", updateTextarea);.
You would also want to change the button to <input type="submit" />.)

Manipulating Text with JavaScript Based on Checkbox State

I'm trying to create a simple HTML page that presents a user with several options via checkboxes. I need to generate a string, stored in a variable that I can use on the page when a button is clicked, which will vary based on which boxes are checked.
The string will be a URL ("http://example.com/index.htm&term=") and will need to have additional text appended to it for each checkbox that is checked.
For example, if only a single box, say box1, is checked the string "box1" should be appended to the URL variable to look like "http://example.com/index.htm&term=box1"
If, however more than one box is checked, say box2 and box3 are checked, then the string "box2%20OR%20box3" should be appended to the URL string.
I'm pretty sure this can be done with JavaScript but I have no experience with it and would appreciate some guidance/examples.
Instead of storing it in a variable, I would recommend calling a function that builds the link when the button is pressed. If you really wanted to put it in a variable though, you would set up an event listener for the change event for each checkbox, and call the function to update the variable each time one of the checkboxes is checked or unchecked.
function checkboxUrl(checkboxes) {
const
url = `http://example.com/index.html`,
checkedArray = [];
for (let checkbox of checkboxes) {
if (checkbox.checked) checkedArray.push(checkbox);
};
const checkboxString = checkedArray.map(checkbox => checkbox.value).join(`%20OR%20`);
return url + (checkboxString ? `?term=` + checkboxString : ``);
}
let checkboxes = document.querySelectorAll(`input[type='checkbox']`);
label {
display: block;
}
<label><input type='checkbox' value='box1'>box1</label>
<label><input type='checkbox' value='box2'>box2</label>
<label><input type='checkbox' value='box3'>box3</label>
<button onclick='console.log(checkboxUrl(checkboxes))'>Get URL</button>
If you use Jquery you can do something like this:
<input type="checkbox" id="box1">
<input type="checkbox" id="box2">
<button type="button" id="myButton">Submit</button>
<script>
$(document).ready(function(){
$('#myButton').click(function(){
var url = 'www.myurl.com/index.html&term=';
var checkboxList = [];
var params = '';
$(':checkbox:checked').each(function(){
checkboxList.push($(this).attr('id'));
});
params = checkboxList.join('%'); //will output "box1%box2"
url += params //www.myurl.com/index.html&term=box1%box2
window.location.href = url;
});
});
</script>

Getting text from input to replace label text in another form

reposting for simplicity. i want to have the text users enter into an input to replace the label text of another form's input. Additionally, the form is a plugin which doesn't let me attach an id to the specific label tag of the text i want to change. how can i do this, in vanilla javascript please.
the input users put text into:
<input class="charInput" id="name1" type="text" onKeyUp="change1(this)" >
the form label i want to change the text in (p.s: cant use the class(not unique to this label), cant add id):
<div id="frm_field_53_container" class="frm_form_field form-field frm_top_container">
<label class="frm_primary_label" for="field_inputactor1">
TEXT TO REPLACE
<span class="frm_required"></span>
</label></div>
Maybe it is not the best solution, but it is a solution that works in Firefox and Chrome (not tested under IE)
findLabelToChange = function() {
var div = document.getElementById("frm_field_53_container");
return div.querySelector("label");
};
customizeText = function(text) {
return text + ' <span class="frm_required"></span>';
};
change1 = function() {
var label = findLabelToChange();
var text = document.getElementById("name1").value;
label.innerHTML = customizeText(text);
};
you can see a example in this feedle
http://jsfiddle.net/HAK5X/1/
Here is a fiddle.
It is one line of code.
http://jsfiddle.net/te3jv/6/
function change1(myInput){
document.getElementById('frm_field_53_container').querySelector("label").innerHTML =myInput.value;
}
Alternatively add <span class="frm_required"></span> to the end of HTML reassignment to keep your empty (but required?) span.

Categories