I have the following code that hides a div when there is anything typed in a textbox.
<script type="text/javascript" charset="utf-8">
$('#email').change(function () {
var len = $('#email').val().length;
if (len > 0) {
$("#user_accounts").fadeOut(1)
} else {
$("#user_accounts").fadeIn(1)
}
});
</script>
This is working but it only works after you click away from the textbox and not when you start typing. I wanted to see if there is a way to execute this code when you start typing and not just when there is text in the field and you click away.
It's quite easy, here's the code:
document.getElementById('myInput').addEventListener('keyup', () => {
if (document.getElementById('myInput').value.length > 0) {
document.getElementById('myDiv').style.display = 'none';
} else {
document.getElementById('myDiv').style.display = 'block';
}
})
#myInput {
width: 200px;
height: 35px;
padding: 0 10px;
background: #333;
color: #fff;
border: 0;
outline: 0;
font-family: arial;
}
#myInput::placeholder {
color: #ccc;
}
#myDiv {
width: 220px;
height: 70px;
margin-top: 20px;
line-height: 70px;
text-align: center;
font-family: arial;
background: red;
color: #fff;
}
<html>
<body>
<input id='myInput' type="text" placeholder="Type here!">
<div id='myDiv'>Can you see me?</div>
</body>
</html>
Basically using
document.getElementById('myInput').addEventListener('keyup', () => { // your function }
you're calling a function everytime someone types inside the input (actually the function is called only when you realese a key)
and then you just check for the input's value length inside of the function and hide or not the div based on the length.
Hope It's what you're looking for, if you have any question let me know.
According to the documentation, for <input type="text">, the change event only triggers after the element loses its focus (e.g. clicking away).
Unlike change event, input event is fired every time the value of the element changes. Therefore, it fits better to your usecase.
Your code will look like this:
$('#email').on('input', function() {
var len = $('#email').val().length;
if (len > 0) {
$("#user_accounts").fadeOut(1)
} else {
$("#user_accounts").fadeIn(1)
}
});
for cleaner code, I would recommend using inline HTML and instead of onchange, I would actually use onkeyup (as other commentators noted) this event would call a named function which would be binded to the event.
as follows:
HTML
<element onkeyup="handleInputKeyup">...</element>
JS
const handleInputKeyup = (event) => {//do something with the event here};
Related
I have a form that I'm using for orders. I'm using the same form for every order but I want to replace the last word in the text string of the header (in this case "Food") to show what the customer is ordering based on the button they clicked. For this example, I've just made a simple layout with three buttons that are each assigned a value inside their button tags. The same button style is going to be used all throughout, it's just going to have a different name and value assigned to it for the form. I've also made a close button to simulate the user closing the form and forcing the last word in the header back to its default Food just in case they manage to open the form without actually clicking a button so they don't see something like "Order Your null". So ideally, the user would click their choice of food and the header title would change to "Order Your [Food Value]"
The problem I'm having is that I can't figure out how to collect the values and change the innerHTML based on what was clicked using javascript. If it were only three buttons I could write three separate expressions but on my project, I've got about 40 items and buttons total so I'd rather label 40 buttons with values and use one script to power them all as opposed to writing an expression for every button (completely possible but not very efficient for myself or the user's browser I would imagine...).
The script runs but returns an "undefined" value. I've tried changing the let food = document. attribute to just about anything I could find on Google and nothing is returning a value (or an error for that matter).
https://jsfiddle.net/astombaugh/kf2vgq0p/550/
<body>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="foodHeader">Order Your<div id="foodHeader">Food</div>
</div>
<div class="btnContainer">
<a class="orderBtn" name="foodItem" value="Cheeseburger">Order Your Cheeseburger</a>
<a class="orderBtn" name="foodItem" value="Salad" style="background-color: green">Order Your Salad</a>
<a class="orderBtn" name="foodItem" value="Sub" style="background-color: blue">Order Your Sub</a>
</div>
<div class="closeBtnContainer">
<a class="closeBtn">
X
</a>
</div>
</body>
.foodHeader {
display: block;
font-family: Helvetica Neue, Helvetica, Arial;
font-weight: 700;
text-align: center;
color: black;
font-size: 3rem;
margin: 0 auto;
}
.btnContainer {
display: flex;
flex-direction: row;
}
.orderBtn {
display: block;
font-family: Helvetica Neue, Helvetica, Arial;
font-weight: 700;
text-align: center;
color: white;
width: 200px;
height: 50px;
margin: 0 auto;
background-color: red;
font-size: 1rem;
padding: 10px 10px;
line-height: 3rem;
outline: 1px solid black;
}
.closeBtnContainer {
display: block;
margin: 20px auto;
text-align: center;
}
.closeBtn{
background-color: black;
color: white;
width: 20px;
height: 20px;
margin: 0px auto;
padding: 10px;
text-align: center;
cursor: pointer;
}
let food = document.querySelectorAll('foodItem').value;
let foodHeaderText = document.getElementById('foodHeader');
const orderBtn = document.getElementsByClassName('orderBtn');
const closeBtn = document.getElementsByClassName('closeBtn');
for (let order = 0; order < orderBtn.length; order++) {
orderBtn[order].addEventListener('click', function() {
foodHeaderText.innerHTML = food;
})
}
for (let close = 0; close < closeBtn.length; close++) {
closeBtn[close].addEventListener('click', function() {
foodHeaderText.innerHTML = "Food";
})
}
The function you pass to the event listeners accepts a parameter, that is the event object. You can find more here. Given that, you can arrange a solution like the following:
let foodHeaderText = document.getElementById('foodHeader');
const orderBtn = document.getElementsByClassName('orderBtn');
const closeBtn = document.getElementsByClassName('closeBtn');
for (let order = 0; order < orderBtn.length; order++) {
orderBtn[order].addEventListener('click', function(event) {
foodHeaderText.innerHTML = event.target.attributes["value"]["value"];
})
}
for (let close = 0; close < closeBtn.length; close++) {
closeBtn[close].addEventListener('click', function(event) {
foodHeaderText.innerHTML = "Food";
})
}
Reason why you are getting undefined is because
let food = document.querySelectorAll('foodItem').value;
definitely is undefined: querySelectorAll return a collection, and has no property value. Besides, you want to dynamically get the value at each click, not once for all.
Replace code buy:
function(e) {
foodHeaderText.innerHTML = e.target.getAttribute("value") || "food";
I believe your issue is in this line:
let food = document.querySelectorAll('foodItem').value;
You could try this:
let food = Array.from(document.querySelectorAll('[name="foodItem"]')).map(el => el.getAttribute('value'))
Hope this helps.
food isn't defined as a string. In fact, it's undefined because you're trying to retrieve all foodItem elements at once before they're even clicked. As others have said - that's a NodeList and won't have a value property.
You code can be updated to:
for (let order = 0; order < orderBtn.length; order++) {
orderBtn[order].addEventListener('click', function(e) {
foodHeaderText.innerHTML = e.target.value;
});
}
Or, to be a little more modern:
document.getElementsByClassName("orderBtn").forEach(orderBtn => {
orderBtn.addEventListener("click", e => {
foodHeaderText.textContent = e.target.value;
});
});
Or, even better, don't use tons of listeners - just add one to the parent container:
document.querySelector(".btnContainer").addEventListener("click", e => {
if (e.target.matches(".orderBtn")) {
foodHeaderText.textContent = e.target.value;
}
}
your code should work
// just change this line
foodHeaderText.innerHTML = food;
// with this one
foodHeaderText.innerHTML = this.innerHTML;
// or with this one
foodHeaderText.innerHTML = orderBtn[order].innerHTML;
and get rid of that food variable
It's not correct, and you don't have any foodItem classes in your html file, even though you've already selected them as orderBtn.
My aim is for the users to click the button multiple times and on each click it changes the color and the wording on the button. I got the word and the color to change on the first and second click but it doesn't change when I click again. What am I doing wrong?
You can find my code below:
$(document).ready(function() {
$("button").click(function() {
$("#partyButton").text("Party Over!");
$(this).addClass("click").one("click", function() {
$("#partyButton").text("Party Time!");
$(this).removeClass();
});
});
});
button {
color: white;
font-family: 'Bungee';
background-color: #222;
border: none;
border-radius: 5px;
width: 25%;
padding: 20px;
cursor: pointer;
}
.click {
background-color: #0A8DAB;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="partyButton" type="button"> party time!</button>
You can achieve this By using toggleClass and check with .hasClass()
//button
$(document).ready(function (){
$("button").click(function (){
$(this).toggleClass("click").text($(this).hasClass('click') ? "Party Time":"Party Over!");
});
});
button{
color: white;
font-family: 'Bungee';
background-color:#222;
border: none;
border-radius: 5px;
width: 25%;
padding: 20px;
cursor: pointer;
}
.click{
background-color:#0A8DAB;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id = "partyButton" type = "button"> party time!</button>
Code Explanation:
$(this).toggleClass("click") this will toggle between class on each click
$(this).hasClass('click') check if this element has a class it return true/false .. you can also use it like if($(this).hasClass('click')){}else{}
() ? : ; shorthand if statment
Also Take care when you use removeClass() without assign any class it will remove all the classes for this element
The problem is you are registering an one time click event for the button while the button is clicked for the first time, which will detach the event once clicked. This is the reason you are not getting the event further. It is unnecessary and confusing
You just need the below implementation
$("#partyButton").click(function(){
if($(this).hasClass('click'))//check whether it party time or not
{
$(this).text("Party Time!").toggleClass('click');
}
else
{
$(this).text("Party Over!").toggleClass('click');
}
})
https://jsfiddle.net/n5hdg7tv/
For example:
$(function() {
$('#partyButton').on('click', function () {
var $button = $(this);
if($button.hasClass('click')) {
$button.removeClass('click').text('Party Time !');
} else {
$button.addClass('click').text('Party Over !');
}
})
});
I am creating a minesweeper game and am trying to create an event where if the user holds down the shift key and left clicks their mouse simultaneously then the button (background-color is black) that I created for the field will turn yellow to indicate a button that is flagged. Here is what I have so far. The attribute ('data-value', 0) means that that button does not have a mine or number label that will indicate how far it is from the mine.
JS:
$('button').getAttribute('data-value', 0).getAttribute('data-x', j).getAttribute('data-y', i).getAttribute('data-visible', false).getAttribute('data-mine', false).click(function (e) {
if (e.shiftKey) {
$('button').addClass('flag');
}
});
CSS:
table td button {
background-color: black;
color: white;
width: 2em;
height: 2em;
}
.flag {
background-color: yellow;
}
Thank you for your help.
If you are not able to detect the key combination you can use the following script to do that, see below code try pressing SHIFT+ mouse left click to detect it.
let ShiftOn = false;
$(document).ready(function() {
$(document).keydown(function(e) {
let isShiftOn = e.which == "16";
(isShiftOn) && (ShiftOn = true);
}).keyup(function() {
ShiftOn = false;
});
$("#detectable-area").on('click', function() {
(ShiftOn) && console.log('SHIFT +LEFT Click');
});
});
div#detectable-area {
width: 100%;
height: 250px;
background: #c8c8c8;
vertical-align: middle;
text-align: center;
line-height: 250px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="detectable-area">Press SHIFT + click anywhere in the div to detect.</div>
I have a textarea and send button on my webpage.
How can I change the style of the send button (to a particular CSS class) while I'm typing and then after some time of not-typing to another CSS class.
Also, when the message is deleted, the style of the send button must change back to the original CSS class.
Here is the code I tried:
function isTyping(val) {
if (val == 'true') {
document.getElementsByClassName('send')[0].innerHTML = "Class1";
} else {
document.getElementsByClassName('send')[0].innerHTML = "Class2";
}
}
.type-message:focus + .send {
background-color: red;
}
.class1 {
display: block;
width: 50px;
height: 20px;
background-color: red;
}
.class2 {
display: block;
width: 50px;
height: 20px;
background-color: yellow;
}
<textarea class="type-message" onkeypress="isTyping('true'); timer=5;" onkeyup="isTyping('false')" name="textarea" cols="45" rows="5">
</textarea>
<div class="send">Class2</div>
But it doesn't works. What is wrong?
Solution:
Run CODE snippet below & type as the textarea appears.
See if this is what you wanted to do:
var delay = 3000; // that's 3 seconds of not typing
var timer = null;
function isTyping() {
clearTimeout(timer);
var value = document.getElementById('text').value;
if( value ) {
document.getElementById('send').innerHTML = "Typing";
document.getElementById("send").className = "typing";
timer = setTimeout(notTyping, delay);
}
else {
notTyping();
}
}
function notTyping() {
document.getElementById('send').innerHTML = "Not Typing";
document.getElementById("send").className = "not-typing";
}
#send {
display: block;
width: 200px;
height: 20px;
}
.not-typing {
background-color: yellow;
}
.typing {
background-color: red;
}
<textarea class="type-message" oninput="isTyping()" id="text" name="textarea" cols="45" rows="5"></textarea>
<div id="send" class="not-typing">Not Typing</div>
Problem in your CODE:
The reason your CODE doesn't work is because:
You changed class on the event onkeypress & then immediately on the event onkeyup.
onkeypress means as you press any key & onkeyup means when you release the same key. So as you typed onkeypress, onkeyup, onkeypress, onkeyup ... kept on happening and class kept on changing.
Instead what I did was:
Used only one oninput event - that detects any change in input.
Inside event handler used a timer using setTimeout function. This only fires after 3 seconds of inactivity or if the textarea is empty.
I'm pretty new with Javascript and jQuery, and can't seem to indentify the reason why my code acts like it does.
I have created two seemingly identical functions to change the background color of an input field.
Their goal is to turn the background color of the given input field to the color #00FF7F if anything is typed in the field. And if not, the field should be transparent.
Code JS:
$(document).ready(function () {
var $input1 = $("#logindata1");
var $input2 = $("#logindata2");
function onChangeInput1() {
$input1.css("background-color", "#00FF7F");
var value = $.trim($(".form-control").val());
if (value.length === 0) {
$input1.css("background-color", "transparent");
}
}
function onChangeInput2() {
$input2.css("background-color", "#00FF7F");
var value = $.trim($(".form-control").val());
if (value.length === 0) {
$input2.css("#background-color", "transparent");
}
}
$input1.on("keyup", onChangeInput1);
$input2.on("keyup", onChangeInput2);
});
css:
#loginbox {
width: 400px;
height: 200px;
margin-left: auto;
margin-right: auto;
margin-top: 25%;
}
.logindata {
margin-left: auto;
margin-right: auto;
margin-top: 20px;
height: 60px;
width: 290px;
transition: 0.25s ease;
}
.form-control {
margin-left: auto;
margin-right: auto;
height: 55px;
width: 288px;
border-style: none;
background-color: transparent;
text-align: center;
border: solid 2px #00FF7F;
transition: 0.25s ease;
font-size: 25px;
font-family: "Trebuchet MS";
}
.form-control:hover {
box-shadow: 0px 0px 30px #2E8B57;
}
::-webkit-input-placeholder {
color: #00FF7F;
}
Simple HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Test</title>
<!-- Stylesheet link -->
<link rel="stylesheet" type="text/css" href="assets/style.css">
<!-- jQuery link -->
<script type="text/javascript" src="assets/vendor/jquery-3.1.0.min.js"></script>
</head>
<body>
<div id="loginbox">
<div class="logindata" id="logindata1">
<input type="text" class="form-control" placeholder="Username">
</div>
<div class="logindata" id="logindata2">
<input type="password" class="form-control" placeholder="Password">
</div>
</div>
<!-- Javascript link-->
<script type="text/javascript" src="assets/js/javascript.js"></script>
</body>
On the jsbin above, try typing in both the Username and Password field to see how they react differently.
Images of what happens. Didn't want to include all images here:
http://imgur.com/a/qgubP
I realize there probably is a way to compromise my js/jquery into 1 function that each input field calls instead of have a function for each.
If both of these fields are required, here's a much simpler solution using CSS only.
Add the attribute required to your <input> tags and then use the pseudo-class :valid.
.form-control:valid {
background-color: #00FF7F;
}
Code snippet:
#loginbox {
width: 400px;
height: 200px;
margin-left: auto;
margin-right: auto;
margin-top: 25%;
}
.logindata {
margin-left: auto;
margin-right: auto;
margin-top: 20px;
height: 60px;
width: 290px;
transition: 0.25s ease;
}
.form-control {
margin-left: auto;
margin-right: auto;
height: 55px;
width: 288px;
border-style: none;
background-color: transparent;
text-align: center;
border: solid 2px #00FF7F;
transition: 0.25s ease;
font-size: 25px;
font-family: "Trebuchet MS";
}
.form-control:hover {
box-shadow: 0px 0px 30px #2E8B57;
}
::-webkit-input-placeholder {
color: #00FF7F;
}
.form-control:valid {
background-color: #00FF7F;
}
<div id="loginbox">
<div class="logindata" id="logindata1">
<input type="text" class="form-control" placeholder="Username" required>
</div>
<div class="logindata" id="logindata2">
<input type="password" class="form-control" placeholder="Password" required>
</div>
</div>
jsFiddle : https://jsfiddle.net/7vzjz2u5/3/
jQuery
$(document).ready(function() {
$('.change-background').on('change', function() {
var $this = $(this);
var value = $.trim($this.val());
// toggleClass can be provided a bool value,
// If we provide true we add class, if false we remove class
$this.toggleClass('filled-background', value.length !== 0);
}).change();
// We also want to call a 'change' event on
// all inputs with the change-background class just incase the page has
// pre-filled in values
});
Instead of listening for the keyup event and then running a function, just create a listener on the change event, also if we just apply one class to all inputs we want the background colour to change on, we can just create one listener which will do it for any input with the class change-background.
Html
<div id="loginbox">
<div class="logindata" id="logindata1">
<input type="text" class="change-background form-control" placeholder="Username">
</div>
<div class="logindata" id="logindata2">
<input type="password" class="change-background form-control" placeholder="Password">
</div>
</div>
Css (the extra class for background color)
.filled-background {
background-color: #00FF7F;
}
Also side note
listening for keyup is back, someone may want to copy and paste their username and password and if they do this it won't trigger an keyup event if they use right click and paste.
Your code clears the background color when the length is 0. The way it checks the length is with this snippet of code:
var value = $.trim($(".form-control").val());
The selector $(".form-control") will select all elements with the CSS class of .form-control. This is a problem because there is more than one of them; in this case, it will always return the value from the first element found.
You should change the code to check for the specific control by searching by ID, like so:
var value = $.trim($("#logindata1 input").val()); //get user ID
var value = $.trim($("#logindata2 input").val()); //get password
You have some minor mistakes, but no worry. We can fix it.
First Problem
Other answers are pointing something important: you are trying to get the value selecting all elements with form-control class.
var value = $.trim($(".form-control").val());
You can do it, replacing your selector by your already declared variables $input1 and $input2. This way:
var value = $.trim($input1.val());
var value = $.trim($input2.val());
Second
Ok. First problem solved. The second problem is in your second function. You trying to set an invalid css: $input2.css("#background-color", "transparent");
When should be: $input2.css("background-color", "transparent"); (without #).
Next One
Nice. Next one. The id's you are setting logindata1 and logindata2 are on your divs. So, you are wrongly trying to get the value of the div instead the value of the input. you can fix your selector by appending input, this way:
var $input1 = $("#logindata1 input");
var $input2 = $("#logindata2 input");
Finally
So, finally, it should work:
$(document).ready(function () {
var $input1 = $("#logindata1 input");
var $input2 = $("#logindata2 input");
function onChangeInput1() {
$input1.css("background-color", "#00007F");
var value = $.trim($input1.val());
if (value.length === 0) {
$input1.css("background-color", "transparent");
}
}
function onChangeInput2() {
$input2.css("background-color", "#00007F");
var value = $.trim($input2.val());
if (value.length === 0) {
$input2.css("background-color", "transparent");
}
}
$input1.on("keyup", onChangeInput1);
$input2.on("keyup", onChangeInput2);
});
Your value check is not right. With your jQuery, you are checking the value of both inputs every time.
Try checking the single inputs that you are interested in instead.
$(document).ready(function () {
var $input1 = $("#logindata1");
var $input2 = $("#logindata2");
function onChangeInput1() {
$input1.css("background-color", "#00FF7F");
var value = $.trim($input1.val());
if (value.length === 0) {
$input1.css("background-color", "transparent");
}
}
function onChangeInput2() {
$input2.css("background-color", "#00FF7F");
var value = $.trim($input2.val());
if (value.length === 0) {
$input2.css("#background-color", "transparent");
}
}
$input1.on("keyup", onChangeInput1);
$input2.on("keyup", onChangeInput2);
});