Remove An Element When One Exists - javascript

I'm back with my nooby Javascript questions. I'm working on form validation and I'm adding text to check if a name was inputted. The problem I'm running into is if I don't put a name but then I do, the message for not putting a name shows up with the other element and vice versa but im looking for a way to make it dissapear when another element is chosen. Is there some sort of way of preventing an element from showing when one is present? I appreciate you guys/girls taking time out of your day to help a noob out haha. :)
Code:
var complete = document.getElementById('button');
complete.addEventListener('click', validate);
function validate() {
var textBox = document.getElementById('name');
var red = document.getElementById('nah');
var green = document.getElementById('yah');
if (textBox.value === '') {
red.style.display = 'block';
} else {
green.style.display = 'block';
}
}
#nah {
display: none;
color: red;
}
#yah {
color: green;
display: none;
}
button {
display: block;
margin-top: 50px;
border: 0.1px solid red;
background: red;
color: white;
font-size: 30px;
padding: 10px;
cursor: pointer;
}
<input type="text" id="name">
<p id="nah">Please Enter Name!</p>
<p id="yah">Thank you!</p>
<button id="button">Complete Form</button>

When you show one message you need to hide the other one.
var complete = document.getElementById('button');
complete.addEventListener('click', validate);
function validate() {
var textBox = document.getElementById('name');
var red = document.getElementById('nah');
var green = document.getElementById('yah');
if (textBox.value === '') {
red.style.display = 'block';
green.style.display = 'none';
} else {
green.style.display = 'block';
red.style.display = 'none';
}
}
#nah {
display: none;
color: red;
}
#yah {
color: green;
display: none;
}
button {
display: block;
margin-top: 50px;
border: 0.1px solid red;
background: red;
color: white;
font-size: 30px;
padding: 10px;
cursor: pointer;
}
<input type="text" id="name">
<p id="nah">Please Enter Name!</p>
<p id="yah">Thank you!</p>
<button id="button">Complete Form</button>

Simplest way is to just hide the other messages during validation:
function validate() {
var textBox = document.getElementById('name');
var red = document.getElementById('nah');
var green = document.getElementById('yah');
if (textBox.value === '') {
red.style.display = 'block';
green.style.display = 'none'; //hide the other element
} else {
green.style.display = 'block';
red.style.display = 'none'; //hide the other element
}
}
You could do it in a more sophisticated way using data attributes to control visibility, but this is probably a good start.

Related

A message box won't appear when using an onclick event

I am trying to show a message box for password validation when clicking on an input type password field. i want the message box to show as soon as i click on the password field.
So far, if i run the page and click on the password input field, i would have to click in, click out then click in again just for the message box to appear. I can't really pinpoint the error here since im fairly new to Javascript and HTML.
I am using visual studio code for the IDE and it doesnt appear to show any errors when i run so it has to be an internal issue.
my code is :
function getPassword() {
var myInput = document.getElementById("psw");
var number = document.getElementById("number");
var length = document.getElementById("length");
// When the user clicks on the password field, show the message box
myInput.onfocus = function() {
document.getElementById("message").style.display = "block";
}
// Validate numbers
var numbers = /[0-9]/g;
if(myInput.value.match(numbers)) {
number.classList.remove("invalid");
number.classList.add("valid");
} else {
number.classList.remove("valid");
number.classList.add("invalid");
}
// Validate length
if(myInput.value.length >= 8) {
length.classList.remove("invalid");
length.classList.add("valid");
} else {
length.classList.remove("valid");
length.classList.add("invalid");
}
}
the input type code is as follows:
<label for="psw"><b>Password:</b></label> <br>
<input id = "psw" name="psw" type="password" onblur=" getPassword();"/> <br>
<input type="button" value="check password" class="checkpsw">
My CSS code is :
input {
width: 50%;
padding: 6px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
margin-top: 6px;
margin-bottom: 16px;
}
input[type=radio]{
position:absolute;
line-height: 2px;
}
input[type=checkbox]{
position:absolute;
line-height: 2px;
}
/* Style the button */
input[type=button] {
background-color: #04AA6D;
color: white;
}
.checkpsw {
background-color: #0fabb6;
color: white;
}
/* Style the container for inputs */
.container {
background-color: #f1f1f1;
padding: 20px;
}
/* The message box is shown when the user clicks on the password field */
#message {
display:none;
background: #f8f8f8;
color: #000;
position: relative;
padding: 15px;
margin-top: 10px;
width:50%;
}
#message p {
padding: 10px 35px;
font-size: 18px;
}
/* Add a green text color and a checkmark when the requirements are right */
.valid {
color: green;
}
.valid:before {
position: relative;
left: -35px;
content: "\2714";
}
/* Add a red text color and an "x" icon when the requirements are wrong */
.invalid {
color: red;
}
.invalid:before {
position: relative;
left: -35px;
content: "\2716";
}
Use the myInput.onfocus = function() outside of the getPassword function block.
You need to modify your code in this way. It will solve your problem. Basically, when you go to the password field it will be focus So anything you want to do at that time. You can do like if you want to change the border color on the focus you can do it as well.
// When the user clicks on the password field, show the message box
myInput.onfocus = function() {
document.getElementById("message").style.display = "block";
}
function getPassword() {
var myInput = document.getElementById("psw");
var number = document.getElementById("number");
var length = document.getElementById("length");
// Validate numbers
var numbers = /[0-9]/g;
if(myInput.value.match(numbers)) {
number.classList.remove("invalid");
number.classList.add("valid");
} else {
number.classList.remove("valid");
number.classList.add("invalid");
}
// Validate length
if(myInput.value.length >= 8) {
length.classList.remove("invalid");
length.classList.add("valid");
} else {
length.classList.remove("valid");
length.classList.add("invalid");
}
}

How to style array elements separately

I have recently taken up programming and my first task is to create a queue at the post office. The code kind of works and does everything I need, except, I need the input array elements to be displayed with some style, more like separate squares with names (similarly to the way the buttons are styled), not only in line separated by commas - see the demo below please.
var guests = new Array();
for (var i=0;i<10;i++){
guests[i] = prompt("Enter your name");
if (guests[0] == null) {
alert("No guests in a queue");
break;
} else if (guests[i] == null) {
break;
} else {
document.getElementById("queue").innerHTML=guests;
}
}
function removePeople() {
guests.shift();
document.getElementById("queue").innerHTML=guests;
}
function reversePeople() {
guests.reverse();
document.getElementById("queue").innerHTML=guests;
}
button:hover {
background-color:beige;
color:black;
}
.button {
background-color: green;
border: 2px solid black;
border-radius:4px;
color: white;
padding: 5px 15px;
text-align: center;
font-size: 16px;
margin: 4px 2px;
}
<body>
<p id="queue"></p>
<button class="button" onclick ="removePeople()">Next</button>
<button class="button" onclick ="reversePeople()">Reverse</button>
</body>
I tried hard to find some hints here but everything seems too complicated for my level of understanding. So, if there is no easy way, I would rather ask for some specific materials where I could find how to deal with it. I am learning through W3Schools and also reading Eloquent Javascript publication, but coulnd't find anything concerning my problem. I hope my question makes sense.
Also, if you have any idea how to logically improve the code, I am open to any discussion.
I've tried to keep your code mostly the same.
To be able to change the css of a single queue item you need to wrap that item in something (in this example i've used a span)
I've created a function createQueueItemsHtml() that returns the array items wrapped in a span now you can use the following css selector to add css to each item #queue span
var guests = new Array();
for (var i = 0; i < 3; i++) {
var guestInput = prompt("Enter your name");
if(guestInput != "") {
guests[i] = guestInput;
}
if (guests[0] == null) {
alert("No guests in a queue");
break;
} else if (guests[i] == null) {
break;
} else {
document.getElementById("queue").innerHTML = createQueueItemsHtml();
}
}
function removePeople() {
guests.shift();
document.getElementById("queue").innerHTML = createQueueItemsHtml();
}
function reversePeople() {
guests.reverse();
document.getElementById("queue").innerHTML = createQueueItemsHtml();
}
function createQueueItemsHtml() {
let queueString = "";
for (var ii = 0; ii < guests.length; ii++) {
queueString += "<span>" + guests[ii] + "</span>";
}
return queueString;
}
button:hover {
background-color: beige;
color: black;
}
.button {
background-color: green;
border: 2px solid black;
border-radius: 4px;
color: white;
padding: 5px 15px;
text-align: center;
font-size: 16px;
margin: 4px 2px;
}
#queue span {
background-color: green;
border: 2px solid black;
border-radius: 4px;
color: white;
padding: 5px 15px;
}
<p id="queue"></p>
<button class="button" onclick ="removePeople()">Next</button>
<button class="button" onclick ="reversePeople()">Reverse</button>
You can make your guests into <div> elements and then style those in any way you want or need. (I haven't touched the rest of your code, only the part that was needed for this particular thing)
Just change this bit
else {
document.getElementById("queue").innerHTML=guests;
}
To this:
} else {
var guest = document.createElement('div');
guest.classList.add('guest');
guest.innerHTML = guests[i];
document.getElementById("queue").appendChild(guest);
}
What it does is create a <div> element for each item in your guests array, add class="guest" to the element and add the name from your prompt to it. Then it appends this element to the #queue.
Your HTML would then look like this:
<p id="queue">
<div class="guest">john</div>
<div class="guest">doe</div>
</p>
I would suggest changing the <p> to <section> or something like that, just for the sake of semantics.
You can then style these elements like this:
.guest {
}
var guests = new Array();
for (var i=0;i<10;i++){
guests[i] = prompt("Enter your name");
if (guests[0] == null) {
alert("No guests in a queue");
break;
} else if (guests[i] == null) {
break;
} else {
var guest = document.createElement('div');
guest.classList.add('guest');
guest.innerHTML = guests[i];
document.getElementById("queue").appendChild(guest);
}
}
guest:hover {
background-color:beige;
color:black;
}
.guest {
background-color: green;
border: 2px solid black;
border-radius:4px;
color: white;
padding: 5px 15px;
text-align: center;
font-size: 16px;
margin: 4px 2px;
display: inline-block
}
<!DOCTYPE html>
<html>
<head>
<style>
</style>
</head>
<body>
<p id="queue"></p>
</body>
</html>

Why the onclick only works if you click twice?

I was searching for autocomplete examples in pure javascript, and I found a pretty good example on JSFiddle, but it has a Bug that I'm trying to figure it out how to fix.
The autocomplete only autocompletes the text if you click at the paragraph twice
Code:
var db = [
"drawLine",
"drawCircle",
"drawCircleMore",
"fillLine",
"fillCircle",
"fillCircleMore"
];
function popupClearAndHide() {
autocomplete_result.innerHTML = "";
autocomplete_result.style.display = "none";
}
function updPopup() {
if (!autocomplete.value) {
popupClearAndHide();
return;
}
var a = new RegExp("^" + autocomplete.value, "i");
for (var x = 0, b = document.createDocumentFragment(), c = false; x < db.length; x++) {
if (a.test(db[x])) {
c = true;
var d = document.createElement("p");
d.innerText = db[x];
d.setAttribute("onclick", "autocomplete.value=this.innerText;autocomplete_result.innerHTML='';autocomplete_result.style.display='none';");
b.appendChild(d);
}
}
if (c == true) {
autocomplete_result.innerHTML = "";
autocomplete_result.style.display = "block";
autocomplete_result.appendChild(b);
return;
}
popupClearAndHide();
}
autocomplete.addEventListener("keyup", updPopup);
autocomplete.addEventListener("change", updPopup);
autocomplete.addEventListener("focus", updPopup);
#autocomplete {
border: 1px solid silver;
outline: none;
margin: 0;
background: #fff;
}
#autocomplete_result {
border: 1px solid silver;
border-top: 0;
position: absolute;
overflow: auto;
max-height: 93px;
background: #fff;
}
#autocomplete,
#autocomplete_result {
width: 200px;
box-sizing: border-box;
}
#autocomplete,
#autocomplete_result p {
padding: 4px;
margin: 0;
color: #000;
}
#autocomplete_result p:nth-child(2n+1) {
background: #f6f6f6;
}
#autocomplete_result p:hover {
background: #e5e5e5;
}
<input id="autocomplete" type="text" />
<div id="autocomplete_result" style="display: none;"></div>
On change event is trigger before the click event can complete
Removing the on change call would fix the issue. Great suggestion from the comment below by 'imvain2' to replace "keyup" event listener with "input" event listener. This would trigger on any input, not only "keyup".
Demo: https://jsfiddle.net/hexzero/qrwgh7pj/
autocomplete.addEventListener("input", updPopup);
autocomplete.addEventListener("focus", updPopup);

Why Append in JQuery does repeat in span? i want no repeat for tags

i want to no repeat the tags that i will writing in field i try but the console appears the span value repeat like this in image how can i fix that to not repeat the tags. i used JQuery
s://i.stack.imgur.com/dIVP1.jpg
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<input class="add-tags" type="text" placeholder="Type Your Tags">
<div class="tags"></div>
</div>
<script>
$('.add-tags').on('keyup', function(e) {
var tagsKey = e.keyCode || e.which;
if (tagsKey === 188) {
var thisValue = $(this).val().slice(0, -1); //remove last letter
$('.tags').append('<span class="tags-span"><i class="fa fa-times"></i>' + thisValue + '</span>');
var spanvalue = $('.tags-span').text();
console.log(spanvalue);
if (thisValue === spanvalue) {
console.log('good');
} else {
console.log('bad');
}
$(this).val('');
}
$('.tags').on('click', '.tags-span i', function() {
$(this).parent('.tags-span').remove();
});
});
</script>
Voila!
I have a gift for you, but first I would like to point out, that next time you should invest more time into the preparation of your question. Don't cry, don't beg, start from doing your homework first and get as much information as you can. Stackoverflow is not a place were people will do you job for you.
Right now, one can only guess what you are really trying to achieve.
After some harsh treatment let's go to the good parts:
In the following example (https://jsfiddle.net/mkbctrlll/xb6ar2n1/95/)
I have made a simple input that creates a tag on a SPACE key hit. Each tag could be easily removable if X is clicked.
HTML:
<form class="wrapper">
<label for="test">
<span id="tags">
Tags:
</span>
<input id="test" type="text" >
</label>
</form>
JS:
var tagsCollection = []
document.body.onkeyup = function(e){
if(e.keyCode == 32){
var content = getContent('#test')
console.log(tagsCollection.indexOf(content))
if(tagsCollection.indexOf(content) === -1) {
console.log('Spacebar hit! Creating tag')
createTag(content)
tagsCollection.push(content)
console.log(tagsCollection)
} else {
console.log('We already have this one sir!')
displayError('Whoops! Looks like this tag already exists... )')
}
}
}
$('.wrapper').on('click', function(event) {
$(event.target).closest('.tag').remove()
})
function displayError(content) {
var error = document.createElement('p')
error.classList.add('error')
error.innerHTML = content
document.querySelector('.wrapper').append(error)
}
function getContent(target) {
var value = $(target).val().replace(/\W/g, '')
$(target).val("")
return value
}
function createTag(content) {
var $tags = $('#tags')
var tag = document.createElement('span')
var closeIcon = '×'
var iconHTML = document.createElement('span')
iconHTML.classList.add('remove')
iconHTML.innerHTML = closeIcon
tag.classList.add('tag')
tag.append(iconHTML)
tag.append(content)
$tags.append(tag)
}
function removeTag(target) {
target.remove()
}
CSS:
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
.wrapper {
background: #fff;
border-radius: 4px;
padding: 20px;
font-size: 25px;
transition: all 0.2s;
margin: 0 auto;
width: 300px;
}
#tags {
display: block;
margin-bottom: 10px;
font-size: 14px;
}
#test {
display: block;
width: 100%;
}
.tag {
border-radius: 16px;
background-color: #ccc;
color: white;
font-size: 12px;
padding: 4px 6px 4px 16px;
position: relative;
}
.tag:not(:last-child) {
margin-right: 4px;
}
.remove {
font-weight: 600;
position: absolute;
top: 50%;
left: 6px;
cursor: pointer;
transform: translateY(-50%);
}
.remove:hover {
color: red;
}
It is just a quick and dirty example, not a production lvl code.

getElementById().style.display does not work

I made some js code for <div> to appear or disappear.
[src.js]
openSearch = () => {
var con = document.getElementById("search-bar");
if(con.style.display == 'none') {
con.style.display = 'block';
} else {
con.style.display = 'none';
}
}
[style.css]
#search-bar {
position: absolute;
height: 4em;
width: 20em;
background-color: white;
border: 1px solid black;
padding: 1.5rem;
right: 0;
display: none;
}
and add onclick="openSearch()" to <a> tag.
When I click the <a> tag first time, it doesn't work anything.
But click again, it works properly.
So I tried to console.log(document.getElementById("search-bar").style.display, it throws ""(blank).
I wonder that I defined display: none to search-bar but why initial style.display of search-bar is blank value?
And how can I fix it?
Alternatively, you can move the display style to another class and can toggle class.
openSearch = () => {
var con = document.getElementById("search-bar");
con.classList.toggle("hidden");
}
#search-bar {
position: absolute;
height: 4em;
width: 20em;
background-color: white;
border: 1px solid black;
padding: 1.5rem;
right: 0;
}
.hidden {
display: none;
}
<a onclick="openSearch()">Toggle</a>
<div id="search-bar" class="hidden">Some text here</div>
function openSearch()
{
var div = document.getElementById("search-bar");
if (div.style.display !== "none") {
div.style.display = "none";
}
else {
div.style.display = "block";
}
}
You could try initializing the style via js to none:
document.getElementById("search-bar").style.display = 'none';
When the page loads. My guess is that'll work.
[SOLVED]
First I add display: none to css file.
But after style="display: none" to a tag, it works properly.
Maybe I think there is loading priority, But I don't know why exactly.
when you set the display:none in css it innisial like display="". and not display=none. the result is the same, but if you check display='none' he will return false.. you can try it like this:
openSearch = () => {
var con = document.getElementById("search-bar");
if(con.style.display == '') {
con.style.display = 'block';
} else {
con.style.display = '';
}
}
and it will work fine
Use this line code:
if(con.style.display == 'none' || con.style.display == '') {
openSearch = () => {
var con = document.getElementById("search-bar");
if(con.style.display == 'none' || con.style.display == '') {
con.style.display = 'block';
} else {
con.style.display = 'none';
}
}
#search-bar {
position: absolute;
height: 4em;
width: 20em;
background-color: white;
border: 1px solid black;
padding: 1.5rem;
right: 0;
display: none;
}
<div id="search-bar">My Div</div>
<a onclick="openSearch()" href="#">Click</a>

Categories