Trouble using .change to verify answer - javascript

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();
}
});

Related

Prevent Select from changing selected option if condition is not met

I have a select box. Currently, this select box make an ajax call on change.
Now, I want to make call only when a condition is met.
So, here is my code:
$('#buildingSelect').on('change', function(){
var result = checkDirtyStatus();
//this checkDirtyStatus alert message if there is some changes on the form.
//if cancel return false, if confirm return true.
if(result === false) {
return;
}
//make ajax call
});
This prevents from making ajax call, however, this change the selected option of the select i.e, if option1 is selected at the begining and if I try to select next option then it will change the selected option to option2 then only check the status.
On searching on the internet, I got the option of focusin.
$('#buildingSelect').on('focusin', function(){
// console.log("Saving value " + $(this).val());
var result = checkDirtyStatus();
if(result === false) {
return;
}
}).on('change', function(){
g_building_id = $(this).val();
getAmenitiesDetails(g_building_id);
});
However, using this focusin options makes the alert box to appear everytime no matter either I click cancel or ok. This might be because, it call focusin again whenevr I click Ok or Cancel.
What would be the best option to check this status, and if result is false, I don't want to change the selected option as well.
Update
Answer from marked as duplicate not preventing from changing the selected option. Its making ajax call on click i.e. before checking condition.
CodePen Link
function checkDirtyStatus(){
dirtyStatus = true;
if(dirtyStatus === true){
if (confirm("Changes you made may not be saved.")) {
return true;
}else{
return false;
}
}
}
Finally, by mixing the link from Rory and idea of organizing code from some. I have find a solution for my problem. So, if anyone got stuck on the similar problem here is my solution.
$(function(){
var lastSel;
$('#buildingSelect').on('focusin', function(){
lastSel = $("#buildingSelect option:selected");
}).on('change', function(){
if(!checkDirtyStatus()) {
lastSel.prop("selected", true);
return;
}else{
//made ajax call
//$.ajax({})
}
});
});
function checkDirtyStatus(){
let dirtyStatus = getDirtyStatus();
if(dirtyStatus){
return confirm("Changes you made may not be saved.");
}
return true;
}
Let us look at your function:
function checkDirtyStatus(){
dirtyStatus = true; // I assume this is only for testing
if(dirtyStatus === true){ // This can be simplified.
if (confirm("Changes you made may not be saved.")) {
return true;
}else{
return false;
}
}
}
confirm returns a Boolean that is either true or false, so you can simplify your function like this:
function checkDirtyStatus(){
dirtyStatus = true;
if(dirtyStatus){
return confirm("Changes you made may not be saved.");
}
// Notice that you do not return anything here. That means that
// the function will return undefined.
}
Your other function can be simplified like this:
$('#buildingSelect').on('change', function(){
if(!checkDirtyStatus()){
// Here you probably want to set the value of the select-element to the
// last valid state. I don't know if you have saved it somewhere.
return;
}
//make ajax call
});
I played with your codepen and you have some errors in your selectors. As I get confused by your explanation I will try to explain what you could update and how to use it in your code and I hope this is what you need to solve your problem.
First I would change your js to this:
var lastSel = $("#buildingSelect").val();
$("#buildingSelect").on("change", function(){
if ($(this).val()==="2") {
$(this).val(lastSel);
return false;
}
});
The proper way to get the value of a select box in jquery is with the .val(). In your case you selected the entire selected option element.
I store this value in the lastSel variable. Then in the change function the new value of the select list is $(this).val(). I check against this value and if it equals 2 I revert it to the value stored in the lastSel variable with this $(this).val(lastSel).
Keep in mind that the value of a select list is always a string, if you want to check against a number you must first cast it to a numeric value e.g. by using parseInt.
If you want to use the checkDirtyStatus for the check then you should only call this function in the change and pass as parameters the lastSel and the newSel like this:
$("#buildingSelect").on("change", function(){
checkDirtyStatus(lastSel, $(this).val());
});
Then you can transfer the logic from the change function into the checkDirtyStatus function and do your checks there. In this case if you wish to revert the select value instead of $(this).val(lastSel) you will do a $("#buildingSelect").val(lastSel).
I hope this helps.

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

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/

jQuery return false not working

I have a table and I iterate through each row.
If the row background color is green and its respective checkboxes with class as linebox are not checked I am supposed to display an error message on click of submit.
But the return false is not working and the form is getting submitted.Though the message is getting displayed.
How do I resolve this?
Below is the code.
jQuery(document).on('click', '#add-All-button', function () {
$(".rowb").each(function() {
if($(this).css("background-color") == "rgb(71, 163, 71)") {
var ischk = 0;
var row = $(this);
if (row.find('input[class="linebox"]').is(':checked') ) {
ischk++;
}
if(ischk==0) {
alert('Every green colored row should have one of the checkboxes checked.');
return false;
}
}
});
});
You're not returning false out of your event handler, just out of your $.each callback. If you want to also return false out of your handler, you'll need a return statement in the handler itself.
For instance, perhaps (see the *** lines):
jQuery(document).on('click', '#add-All-button', function() {
var rv; // *** By default it's `undefined`, which has no special meaning, so that's fine
$(".rowb").each(function() {
if ($(this).css("background-color") == "rgb(71, 163, 71)") {
var ischk = 0;
var row = $(this);
if (row.find('input[class="linebox"]').is(':checked')) {
ischk++;
}
if (ischk == 0) {
alert('Every green colored row should have one of the checkboxes checked.');
rv = false; // ***
return false;
}
}
});
return rv; // ***
});
Side note: This comparison is likely to fail in the wild:
$(this).css("background-color") == "rgb(71, 163, 71)"
Different browsers return color information in different formats, and don't return the value in the same format you set it in (necessarily). jQuery doesn't attempt to standardize this. So the value you get back might be "rgb(71, 163, 71)", but it might also be "rgb(71,163,71)" or "rgba(71, 163, 71, 0)" or "rgba(71,163,71,0)" or even "#47A347". Instead of relying on getting back a value in a specific format, you'd probably be better off using a data-* attribute or a value tracked via the jQuery data function instead.
Side note 2: I wouldn't use the click event of a button to hook into the form submission process; I'd use the submit event of the form instead.
You need to return false in the outer function, returning false in .each will only break the loop. The other you may need to use to stop a form submission is event.preventDefault which can be used to stop the browsers default behavior like going to a link or submitting a forming but you'll need to change the event type on your button to match this appropriately. That is to say that the event you should be listening for is submit. Have a look at the fixed up code below for more details.
jQuery(document).on('submit', '#add-All-button', function() {
var out = true;
$(".rowb").each(function() {
if ($(this).css("background-color") == "rgb(71, 163, 71)") {
var ischk = 0;
var row = $(this);
if (row.find('input[class="linebox"]').is(':checked')) {
ischk++;
}
if (ischk == 0) {
alert('Every green colored row should have one of the checkboxes checked.');
out = false;
}
}
});
if (!out) { event.preventDefault(); }
return out;
});

Using Blur and Submit events on the same form

I am still confused about this. Started learning JQuery about a week now and this is what I have:
var IsValidUserName = false;
$(document).ready(function () {
$('#txtUserName').blur(function () {
if ($('#txtUserName').val().match(isNumberLetter) &&
($('#txtUserName').val().length >= 8)) {
$('#userNameError').removeClass("error").addClass("default");
$('#txtUserName').removeClass("alert");
$('#txtUserName + label').removeAttr("id", "lblUserName");
IsValidUserName = true;
}
else {
$('#userNameError').removeClass("default").addClass("error");
$('#txtUserName').addClass("alert");
$('#txtUserName + label').attr("id", "lblUserName");
}
});
});
Lets say I have another function like above, lets say FirstName:
How do I call this on the submit event? The code works as I need it to when the user leaves a field. Not sure how I can also call this code and also use the variable above to prevent submit if the data entered is invalid.
I need to call the validation above if the user clicks the submit button and stop the submission if the IsValidUserName variable is false.
Somethings just need a little push.
Thanks my friends.
Guy
You could always extract it into a function instead of an anonymous function and pass the reference to the object you want to check. This would give you the added benefit of reusing it for other elements.
function validate(ele) {
var valid;
if (ele.val().match(isNumberLetter)) && (ele.val().length >= 8)) {
valid = true;
// update user here.
} else {
valid = false;
// update user here.
}
return valid;
}
$(function(){
$('#firstName').blur(function(){ validate($(this)); });
$('#lastName').blur(function(){ validate($(this)); });
$("yourFrom").submit(function(){
var firstNameIsValid = validate($('#firstName'));
var lastNameIsValid = validate($('#lastName'));
if (!nameIsValid) && (!lastNameIsValid) {
return false;
// User has already been updated
}
});
});
Also, since you are already heavily using javascript for your validation (hope this is convenience and not the only security), you can also disable the submit button entirely until the form meets the proper requirements.

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

Categories