Javascript - Show div only if input value is greater than 999 - javascript

I'm practicing with a script developed by the user #Bibberty, where there are buttons that count clicks, divs are cloned and also sume input values and all run under LocalStorage, and everything works very well, but practicing with JS (I'm novice, level 0), I can not add a new function
My interest is to show a div (#regalo), only if the input #total has a value between 999 and 1,500.
This only works if I place values, but it does not work in auto mode...
SEE LIVE DEMO (jsfiddle, the snippet does not run here)
Any idea...?
Thanks in advance!
//----------------
SCRIPT:
$(document).ready(function(){
if($('#total').val() > 999 ) {
$('#regalo').show();
}
$('#total').on('change',function(){
if($(this).val() > 999 ) {
$('#regalo').show();
}
else{
$('#regalo').hide();
}
})
})

add this
$('.comp-clone').on('click',function(){
if($('#total').val() > 999) {
$('#regalo').show();
}
else{
$('#regalo').hide();
}
})
You arent checking if the input field changes you are checking if you change it
$(document).ready(function(){
if($('#total').val() > 999 ) {
$('#regalo').show();
}
$('#total').on('change',function(){
if($(this).val() > 999 ) {
$('#regalo').show();
}
else{
$('#regalo').hide();
}
})
$('.comp-clone').on('click',function(){
if($('#total').val() > 999) {
$('#regalo').show();
}
else{
$('#regalo').hide();
}
})
})
That should work for you but if you wanted to clean that up a little
$(document).ready(function() {
CheckTotal();
$('#total').on('change', function () {
CheckTotal();
})
$('.comp-clone').on('click', function () {
CheckTotal();
})
})
CheckTotal() {
if ($('#total').val() > 999) {
$('#regalo').show();
}
else {
$('#regalo').hide();
}
}

$(document).ready(function(){
function manageRegalo() {
const total = Number($("#total").val().replace(".",""));
// or:
//const total = suma();
if(total > 999 && total < 1500) {
$('#regalo').show();
}
else{
$('#regalo').hide();
}
}
$(document).on('click', function (event) {
const target = event.target;
if (target.matches('.comp-clone') || target.matches('.bbp')) {
manageRegalo();
}
});
manageRegalo();
});
JSFiddle
There are a couple of changes here:
Don't use display: none to hide it, that way jQuerys show() will not work. Instead call hide() immediately, that's way I call manageRegalo() at the very end directly one time. If the split second that you can see the regalo at the beginning is a problem, add another CSS class to the element which includes display: none and use jQuerys .addClass() and .removeClass() to show and hide the regalo.
$('#total').val() gives you a string value, you need to convert it to a number, but this string value can has dots in it, so the value 1.000 would be converted to 1, that's why we first need to remove all the dots. Another way to get the click would be to use the suma() function which is defined in the other JS-Code (inside the HTML-Window), but that one recalculates the value again.
You checked if the value is greater than 999, but not if it is smaller than 1500.
Don't listen at the total-Element for a click, first you don't click on the total-Element: You click on one of the Clone N Elements or on the red Xs. But don't listen on those directly as well, because the JS code that's already there inside the HTML code is listening on the document itself. If you would listen on the Clone N or Xs element, you would get the click event first, but at that time the total isn't calculated yet, so you would get the value always one click late.

I reviewed the code you posted and you have two major issues.
Never try adding more code without understanding the code already written.
It's a common thing that we start writing some code before even understanding the whole code already written, and this is a big problem since it could cause the other code to not work. I'll give you the example with your issue. Something that is preventing your code to give you the result you are expecting is that in the code previously written, the function that assings the valute to the input with id of total is converting the input to a string with String.toLocaleString() which converts totally the variable type from integer (which is what your are looking for) to a string.
Here is where this happens in the code:
const displaySuma=()=>document.getElementById("total").value=suma().toLocaleString("es-ES");
const suma = function() {
return Array.from(document.querySelectorAll(".derecha div .add-prod"))
.reduce((a, v) => a + parseFloat(v.value), 0);
}
So, to achieve the functionality you want, you need to remove the last function attached to the sum() function. It will be like this:
const displaySuma=()=>document.getElementById("total").value=suma();
Also, there's no need to add extra event listeners to your mini-app. Like I said, just try to give it a little of research before writing more code, if you do this, you'll be writing JavaScript code easily and understand how it works by the time you achieved your goal of modifying an already written piece of code.
There is already an event listening for the value in the code.
Since the script already has an event listening for the #total value change, we can just create a function and check the condition there. Here is the event listening:
document.addEventListener('click', (event) => {
let target = event.target;
// Add
if (target.matches('.comp-clone')) {
addClick();
addToDerecha(event.target.dataset.clone);
verifyCondition(); //We add our own function that we just made to verify the value.
}
// Remove
if (target.matches('.bbp')) {
removeClick();
getParent('.derecha', target).removeChild(target.parentNode);
storeHTML();
displaySuma();
}
});
And now, our function would simply be: (Vanilla JavaScript)
const verifyCondition = () =>{
let total = Number(document.querySelector("#total").value);
//We convert the value to integer anyways to prevent any kind of errors.
if( 999 < total && total < 1200 ){//Check if value is between 999 and 1200
document.getElementById("regalo").style="display:block;";
}else{
document.getElementById("regalo").style="display:none;";
}
}
And that's it! Here is a fiddle with the new working code, try to give it a check and make sure to search for what you don't understand. That's how any Senior Developer started.
https://jsfiddle.net/ax0L12j7/

Related

Jquery issue with val not working as expected

I have a couple of forms on a site. On the first form I used the code below to add a border color if the input field is not blank and remove it if it is blank. This works just fine no issues. But I've found that when I try to use the same method on other forms, to do something else using the same logic, it does not work.
I have read through many forums and what I'm seeing is that the code is only read on page load. But I have forms that run the function after the page is far past loading. Can someone give some light to this? I'm really trying to understand the way this works fully.
Code that works on form:
var checkErrorIn;
jQuery(document).ready(function ($) {
checkErrorIn = setInterval(CheckErrorInput, 0);
});
function CheckErrorInput() {
if (jQuery('body').is('.page-id-6334')) {
// First Name, Last Name validation colors
var pasdFName = jQuery('#first_name').val();
var pasdLName = jQuery('#last_name').val();
if (pasdFName != '') {
jQuery('#first_name').addClass('formConfirm_cc');
} else {
jQuery('#first_name').removeClass('formConfirm_cc');
}
if (pasdLName != '') {
jQuery('#last_name').addClass('formConfirm_cc');
} else {
jQuery('#last_name').removeClass('formConfirm_cc');
}
if (pasdFName != '' & pasdLName == '') {
jQuery('#last_name').addClass('formError_cc');
} else {
jQuery('#last_name').removeClass('formError_cc');
}
if (pasdFName == '' & pasdLName != '') {
jQuery('#first_name').addClass('formError_cc');
} else {
jQuery('#first_name').removeClass('formError_cc');
}
}
}
Code that is not working:
if (jQuery('body').is('.woocommerce-page')) {
var checkActiveName = jQuery('.woo_login_form > form > #username').val();
jQuery('.woo_login_form').on('input', function(){
jQuery('.woo_login_form').addClass('cdc_keep_active');
});
if (checkActiveName =='') {
jQuery('.woo_login_form').removeClass('cdc_keep_active');
}
}
What I am trying to do is fix an issue with a form becoming hidden if not hovered over even when the input has characters. Based on my research I figured I'd do the .on to get the class added when the input got characters. That works but the removal of the characters isn't removing the class. The logic looks right to me. What am I missing?
Thank you in advance for your help and insight.
Update:
Ok so I ended up doing this:
jQuery('.woo_login_form').on('click', function () {
jQuery('.woo_login_form').addClass('cdc_keep_active');
});
jQuery('.custom-login-box > a').on('click', function () {
jQuery('.woo_login_form').toggle();
});
For some reason my class would not add with any of the methods suggested individually so I combined the logic. The first part adds the class that makes the form visible but then the form won't close if clicked out of regardless of the 'removeClass'. So I added a toggle (thank you commenters) method to the "hovered link" to allow users to close the box if not needed.
Would still like to understand why the first method worked in one instance but not the other. Any and all insight appreciated. Thank you.
In your current code example you immediately check for the value of the username field.
var checkActiveName = jQuery('.woo_login_form > form > #username').val();
The thing with this is that checkActiveName will never change, unless it is reassigned elsewhere in the code.
What you need to do is to check the current value after every input of the user. That means moving that line of reading the value of the input inside the input event listener.
if (jQuery('body').is('.woocommerce-page')) {
var $wooLoginForm = jQuery('.woo_login_form');
var $userName = jQuery('#username'); // This ID should only exist once, so no need for complex selectors.
$wooLoginForm.on('input', function() {
var checkActiveName = $userName.val();
if (checkActiveName =='') {
$wooLoginForm.removeClass('cdc_keep_active');
} else {
$wooLoginForm.addClass('cdc_keep_active');
}
});
}
On a sidenote: using setInterval to validate your form is a bad practice. This would basically run infinitely. It doesn't have to. You only have to check if a form is valid after the user enters a value.
Apply the same technique with the event listener like in your second code snippet.
var $document = jQuery(document);
$document.ready(function ($) {
/**
* It might even be better to listen for the input event on the form
* that has to be validated, but I didn't see it in your code.
* Right now it listens for input on the entire page.
*/
$document.on('input', CheckErrorInput);
});

Make JavaScript Detect Buttons That Are Pressed In a Certain Order

I am trying to make a number keypad from 0 to 9 and when certain numbers get pressed in a certain order an event will happen.
So something like this
if ( button1 gets pressed then button2 then button3 )
alert('You did the code!')
}
else {
alert('You did not do the code')
}
No jQuery please
Thanks!
//sequence is 358
//SOLUTION
sequence = {
check : function(e){
sequence.value += this.textContent;
if (sequence.value == sequence.sequence)
{
alert(1);
sequence.value = "";
}
else
{
if (sequence.timer)
{
clearTimeout(sequence.timer);
}
sequence.timer = setTimeout("sequence.value=''", 1000);
}
},
value : "",
sequence : "358"
}
//THIS CODE ATTACHES CLICK HANDLERS TO THE BUTTON, NOT PART OF THE SOLUTION
Array.prototype.map.call(document.querySelectorAll("button"), function(element){
element.addEventListener("click", sequence.check, false);
});
//end
<button>7</button><button>8</button><button>9</button><br/>
<button>4</button><button>5</button><button>6</button><br/>
<button>1</button><button>2</button><button>3</button><br/>
<button>0</button>
How does this work. I don't want to pollute the global scope with values so I used an object to store the variables and the check method in.
The object is called sequence.
It has three properties
check, the method that checks the input when a button is clicked.
value, that holds the sequence value until the correct sequence is found.
sequence, the property that holds the correct value.
Each button on the page is assigned with a click handler. When clicked it fires sequence.check. Via the this keyword (referring to the button) we extract the number (via textContent). We add that number to the value string. Then we check if the value matches the sequence. If so execute some code (in this case an alert) and reset the value.
There is a timer set. If the user doesn't enter a new number within a second the timer will reset the value. setTimeout does this. The 1000 stands for 1000 milliseconds = 1 second.
I would achieve this by monitoring the keydown event, and if the key is a number, add in to an array. At the same time, check the array contents to see if they are in a certain defined order. If they are, fire whatever you need to do, if not, do nothing but add the key to the array. Once your sequence has been completed, clear the array to make way for a new sequence.
You could get complicated with things like, clearing the array after a certain interval of not completing the sequence etc.
Here is a simple system that does part of what you are looking for:
var buttons = document.querySelectorAll('button'),
i;
for (i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', function() {
var pressed = document.getElementById('pressed');
pressed.value += this.value + "|";
if (pressed.value === '1|2|3|') {
alert('You unlocked it!');
}
if (pressed.value.length >= 6) {
//Start over
pressed.value = "";
}
}, false);
}
<input id='pressed' type='text' />
<button value='1'>One</button>
<button value='2'>Two</button>
<button value='3'>Three</button>

Have a better way to hide and show divs with radio checked?

I created this code a few days, but I believe it is possible to improve it, someone could help me create a smarter way?
// Hide registered or customized field if not checked.
function checkUserType(value) {
if (value == 2) {
$('#registered').hide();
$('#customized').show();
} else if (value == 1) {
$('#registered').show();
$('#customized').hide();
}
}
checkUserType($('input:radio[name="jform[place_type]"]:checked').val());
$('#jform_place_type').on('click', function () {
checkUserType($('input:radio[name="jform[place_type]"]:checked').val());
});
Demo: http://jsbin.com/emisat/3
// Hide registered or customized field if not checked.
function checkUserType(value) {
}
var t = function () {
var value = $('input:radio[name="jform[place_type]"]:checked').val();
if (value == 2) {
$('#registered').hide();
$('#customized').show();
} else if (value == 1) {
$('#registered').show();
$('#customized').hide();
}
};
$('#jform_place_type').on('click', t);
You can improve the Jquery (for the performance) by storing the DOM element and cache the rest. This is the maximum stuff you can reach I guess.
function checkUserType(value) {
var r = $("#registered");
var c = $("#customized");
if (value == 2) {
r.hide();
c.show();
} else if (value == 1) {
r.show();
c.hide();
}
}
var func = function () {
checkUserType($('input:radio[name="jform[place_type]"]:checked').val());
};
$('#jform_place_type').on('click', func);
For any further reading check this JQuery Performance
In particular read the third paragraph of the document
Cache jQuery Objects
Get in the habit of saving your jQuery objects to a variable (much like our examples above). For example, never (eeeehhhhver) do this:
$('#traffic_light input.on').bind('click', function(){...});
$('#traffic_light input.on').css('border', '3px dashed yellow');
$('#traffic_light input.on').css('background-color', 'orange');
$('#traffic_light input.on').fadeIn('slow');
Instead, first save the object to a local variable, and continue your operations:
var $active_light = $('#traffic_light input.on');
$active_light.bind('click', function(){...});
$active_light.css('border', '3px dashed yellow');
$active_light.css('background-color', 'orange');
$active_light.fadeIn('slow');
Tip: Since we want to remember that our local variable is a jQuery wrapped set, we are using $ as a prefix. Remember, never repeat a jQuery selection operation more than once in your application.
http://api.jquery.com/toggle/
$('#jform_place_type').on('click', function () {
//show is true if the val() of your jquery selector equals 1
// false if it's not
var show= ($('input:radio[name="jform[place_type]"]:checked')
.val()==1);
//set both divs to visible invisible / show !show(=not show)
// (not show) means that if show=true then !show would be false
$('#registered').toggle(show);
$('#customized').toggle(!show);
});
If you need a selector more than once then cache it I think it's called object caching as Claudio allready mentioned, thats why you see a lot of:
$this=$(this);
$myDivs=$("some selector");
The convention for a variable holding results of jquery function (jquery objects) is that they start with $ but as it is only a variable name you can call it anything you like, the following would work just as well:
me=$(this);
myDivs=$("some selector");

Trouble using .change to verify answer

I'm having some trouble using a .change on a text input field. It's supposed to use a library (artisan), if said answer is right (in this case equal to 1), to draw text on a canvas but it's not doing so.
Here's the javascript
$('#atomnum').change(function(){
ans = $('#atomnum').val();
});
if(ans == 1){
artisan.drawText('canvas', 200, 300, 'Correto!', '#FFFFFF');
}else{
return false;
}
The input's id is atomnum. Any help?
Edit - Tried bot of those, still not working. Here's the whole function that gets called, maybe that çistener shouldn't be inside that function...
If the drawing action is supposed to happen inside the .change() event, put it inside:
$('#atomnum').change(function(){
ans = $('#atomnum').val();
if(ans == 1){
artisan.drawText('canvas', 200, 300, 'Correto!', '#FFFFFF');
}else{
return false;
}
});
Otherwise, you would have needed an additional function to check the new value of ans and act on it accordingly.
Note - removed an extra closing }
That code cannot work. You execute the checking code right after binding the event a single time instead of running it whenever the element changes.
Try this instead:
$('#atomnum').change(function(e) {
var ans = $('#atomnum').val();
if(ans == '1') {
artisan.drawText('canvas', 200, 300, 'Correto!', '#FFFFFF');
}
else {
e.preventDefault();
}
});

action keyup after the third charecter

Hi could someone help me figure out how to stop a function running until a specific number of characters are pressed?
currently using the following function:
$('input#q').keyup
this works as soon as you press any key...
Something like this should start firing code after 3 letters have been added:
Live Example
JavaScript
$('input#q').keyup( function() {
if( this.value.length < 4 ) return;
/* code to run below */
$('#output').val(this.value);
});
HTML
<input id="q" />
<br /><br />
<input id="output"/>
you could do :
$('input#q').keyup(function(){
if($(this).val().length > 3)
{
//do something
}
});
You could store the characters in a string variable each time a key is pressed and then run a conditional statement to check the length of the variable. If it's equal to three, run whatever function
Well you'll probably need to take into account the way focus changes. Do you want to clear the counter when the field is newly focused or not? You should also decide whether you're counting characters actually added to the field, or instead if you want to could actual discrete key presses - a "shift" key press, for example, won't add any characters, but it's a key being pressed.
Anyway it'd probably be something like this:
$(function() {
var keyCount = 0;
$('#q').keyup(function() { // "keypress" to count characters
if (++keyCount === 3) {
// do the thing
}
})
.focus(function() {
keyCount = 0; // if this is what you want
});
});
If you're counting the "keypress" event instead of "keyup", you might want to count the actual length of the text field value rather than trying to count events.
How's about:
var c = 0;
('input#q').keyup( function() {
c++;
if (c >= 3) {
startGame();
}
} );

Categories