Show alert after all requirements have been met - javascript

I have a form where the user can 1.) check one option and be done. or 2.) check the other option and fill out a text field.
Whole thing is, after all is said and done I'd like for my alert to show, but it doesn't.
$('.know-your-role').show('fast', function() {
var $checkboxes = $('input:checkbox.checkchoice');
if($checkboxes.is(':checked')){
// show this after checked and the input has been filled.
alert('cool');
}else if($checkboxes.is(':checked') & $(".year").va() != "" ){
alert('cool');
}
});
How do I get the alert to show after all requirements (checkboxes and input) have been met?
I've made a fiddle here to show what I'm working with.
Thank you for your help in advance.

As well as the previous correct answers (missing & and misspelled val) there is a more fundamental logical issue here. You seem to have this structure:
if (conditionA) {
// behaviorA
} else if (conditionA && conditionB) {
// behaviorB
}
You will never reach behaviorB with such logic. If conditionA fails then conditionA && conditionB will certainly also fail.
Do you need to reverse the order of your if and else-if blocks?

Missing '&'
$checkboxes.is(':checked') && $(".year").val() != ""

You should use && instead of & for boolean comparisons, and also you appear to have mis-typed val as va.

I would suggest having two events, one on the 'Teacher' check box being checked and one on the year field being completed. Both events can trigger a single function that shows your alert and whatever other logic you want. So there is little duplication.
This helps to separate the events from the logic that shows/hides the year field and more easily allows you to perform different actions for the two events if that's a requirement.

Related

Check values of loop to see if ANY match?

In ruby, I would do something like:
array = [1,2,3]
array.any? {|a| a == 1}
=> true
Although, instead of an array, I am going up against a hash
var shop_products = {"607":607};
I have a checkbox loop and I want to check against all currently checked boxes for when checkboxes are both checked and unchecked to then see if there is a matching value and disable/able and hide/show a button if so.
code: https://jsfiddle.net/mk879vu2/7/
As #Mark Meyer mentioned, some can help but is there a way to use this against a hash or an alt for hashes?
I tried this: https://jsfiddle.net/jq9sgp58/
Maybe I am using this wrong?
My issue right now is when a checkbox is unchecked, it sees that the value is the "correct" one, but it isn't displaying the button when I uncheck. I'm doing something wrong in the conditional somehow.
In the jsfiddle I have all of the inputs but I only want one of the buttons (of the 2) to appear when a record with specific parameters is checked (in the example this is value=607, this can be any amount but in the example I have it as 1 record/input). But when I uncheck and the 607 is left alone as the only checked input, it runs the hide/disable and not the show.
What is wrong with my code?
It sounds like you are looking for #array.some()
let a = [1,2,3]
console.log(a.some(n => n === 1)) // true
console.log(a.some(n => n === 4)) //false
https://jsfiddle.net/2kaegb59/
The .some seemed like the way to get it done but i couldn't get it to work with the hash. I'm sure it's possible. Although, I ended up just checking for an undefined through the hash instead of trying to match up the check value with the hash value and it is likely unnoticeably faster.
for (var check of checked_checkboxes_check) {
if (shop_products[check.value] === undefined) {
print_submit.hide().prop("disabled", true);
break;
} else {
print_submit.show().prop("disabled", false);
}
}

JQuery onChange uses values before change (values after change needed)

I am working on a module, which should select the only possible value of a Multi- or Single selection field, if there is only one valid value and a empty one available.
So far its working fine, until I use ACLs to disable selection values.
For example, I got a single selection field with 3 possible values. Then I disable 2 of them (ACL - if there is a special Queue selected) so theres only one value (+ an empty one) left.
My module wont pick the last value at first, but when I change anything else on the same page (second onchange call) it will pick the last possible value.
The first if condition checks if the Field has only one possible value in it. When I log the 'Change' array it always got the disbaled values still in there even when the 'change' that called the whole function was the ACL disabling those values.
Im still kinda new to javascript and havent found a solution yet.
I would realy appreciate any help.
$('.TableLike').on("change", function () {
var Change = [];
$('.Row').each( function() {
$(this).children().next().children().next().children().each( function(index) {
Change[index] = $(this).text()
} )
if ( (!Change[2] || /.*Field needed.*/i.test(Change[2])) && Change[0] === "-") {
SoleOption = Change[1];
$(this).children().next().children().next().children().each(function() {
if ($(this).text() === "-") {
$(this).removeAttr("selected");
}
if ($(this).text() === SoleOption) {
$(this).attr("selected", "selected");
}
} )
$(this).children().next().children().children().children().val(SoleOption)
}
SoleOption = "";
Change = [];
} )
} )
I managed to fix the issue with the setTimeout() Method.
So the DOM updated before the ACL did the changes.
I opened up the setTimeout Method after the onChange method and inserted all the code thats supposed to run after the change into the setTimeout method.
I hope this will be helpfull for others in the future.

Multiple Selectors on If Statement

So, I'm trying to make sure a button is disabled to prevent a user from saving data from form field entries whenever two conditions are met:
The checkbox is checked
There's nothing inside the form field in question ( #read_return_response_rate_ids )
This is what I have to that end:
$('body').on("change","#tab3 #read_return_response_rate_ids", function(){
if ($(this).is('')) && ($('input:checkbox').is(':checked')) {
$('.create_read_btn').attr('disabled', 'disabled');
} else {
$('.create_read_btn').removeAttr('disabled');
}
});
The error it's giving me in the console is totally useless towards debugging purposes.
Uncaught SyntaxError: Unexpected token /
It's my thought that this is where the problem exists:
if ($(this).is('')) && ($('input:checkbox').is(':checked'))
Basically, I don't think I can have multiple selectors as I have them structured, but I don't know. Does anyone have any thoughts on why this is returning an error? I confirmed that this code block is where the error originates by selectively commenting out other blocks of code and whittling it down to this one.
There are syntax errors (parenthesis chars note required):
Change:
if ($(this).is('')) && ($('input:checkbox').is(':checked')) {
by
if ($(this).is('') && $('input:checkbox').is(':checked')) {
The argument to .is() must be a selector or jQuery collection; it tests whether the specified element matches the selector or is the same set of objects. If you want to test whether an input field is empty, you need to use .val() to get the value.
if ($(this).val() == '' && $('input:checkbox').is(':checked')) {

Javascript taking too long to run

I have a script that is taking too long to run and that is causing me This error on ie : a script on this page is causing internet explorer to run slowly.
I have read other threads concerning this error and have learned that there is a way to by pass it by putting a time out after a certain number of iterations.
Can u help me apply a time out on the following function please ?
Basically each time i find a hidden imput of type submit or radio i want to remove and i have a lot of them . Please do not question why do i have a lots of hidden imputs. I did it bc i needed it just help me put a time out please so i wont have the JS error. Thank you
$('input:hidden').each(function(){
var name = $(this).attr('name');
if($("[name='"+name+"']").length >1){
if($(this).attr('type')!=='radio' && $(this).attr('type')!=='submit'){
$(this).remove();
}
}
});
One of the exemples i found : Bypassing IE's long-running script warning using setTimeout
You may want to add input to your jquery selector to filter out only input tags.
if($("input[name='"+name+"']").length >1){
Here's the same code optimised a bit without (yet) using setTimeout():
var $hidden = $('input:hidden'),
el;
for (var i = 0; i < $hidden.length; i++) {
el = $hidden[i];
if(el.type!=='radio' && el.type!=='submit'
&& $("[name='" + el.name + "']").length >1) {
$(el).remove();
}
}
Notice that now there is a maximum of three function calls per iteration, whereas the original code had up to ten function calls per iteration. There's no need for, say, $(this).attr('type') (two function calls) when you can just say this.type (no function calls).
Also, the .remove() only happens if three conditions are true, the two type tests and check for other elements of the same name. Do the type tests first, because they're quick, and only bother doing the slow check for other elements if the type part passes. (JS's && doesn't evaluate the right-hand operand if the left-hand one is falsy.)
Or with setTimeout():
var $hidden = $('input:hidden'),
i = 0,
el;
function doNext() {
if (i < $hidden.length) {
el = $hidden[i];
if(el.type!=='radio' && el.type!=='submit'
&& $("[name='" + el.name + "']").length >1) {
$(el).remove();
}
i++;
setTimeout(doNext, 0);
}
}
doNext();
You could improve either version by changing $("[name='" + el.name + "']") to specify a specific element type, e.g., if you are only doing inputs use $("input[name='" + el.name + "']"). Also you could limit by some container, e.g., if those inputs are all in a form or something.
It looks like the example you cited is exactly what you need. I think if you take your code and replace the while loop in the example (keep the if statement for checking the batch size), you're basically done. You just need the jQuery version of breaking out of a loop.
To risk stating the obvious; traversing through the DOM looking for matches to these CSS selectors is what's making your code slow. You can cut down the amount of work it's doing with a few simple tricks:
Are these fields inside a specific element? If so you can narrow the search by including that element in the selector.
e.g:
$('#container input:hidden').each(function(){
...
You can also narrow the number of fields that are checked for the name attribute
e.g:
if($("#container input[name='"+name+"']").length >1){
I'm also unclear why you're searching again with $("[name='"+name+"']").length >1once you've found the hidden element. You didn't explain that requirement. If you don't need that then you'll speed this up hugely by taking it out.
$('#container input:hidden').each(function(){
var name = $(this).attr('name');
if($(this).attr('type')!=='radio' && $(this).attr('type')!=='submit'){
$(this).remove();
}
});
If you do need it, and I'd be curious to know why, but the best approach might be to restructure the code so that it only checks the number of inputs for a given name once, and removes them all in one go.
Try this:
$("[type=hidden]").remove(); // at the place of each loop
It will take a short time to delete all hidden fields.
I hope it will help.
JSFiddle example

Disabling Checkboxes after specified amount are selected

I have been working on a page that will allow entry into a certain part of my website if the user selects 8 out of 25 checkboxes in the right sequence.
Here is what I have working so far CLICK HERE TO SEE A LIVE VERSION
My question is, how can I completely disable the rest of the checkboxes after 8 have been chosen, so far I am using javascript to keep count, and I have an alert popup keeping them from selecting any more, but I would like to completely disable the rest of the checkboxes if possible.
I have simplified your code and it's here.
and this will answer your question,
//update checkCount
checkCount = $(':checked').length;
if (checkCount >= maxChecks) {
//alert('you may only choose up to ' + maxChecks + ' options');
$(':checkbox[name=checkbox]').not(':checked').attr('disabled', true);
} else {
$(':checkbox[name=checkbox]:disabled').attr('disabled', false);
}
where you have the alert right now, use this bit of jQuery:
$('input[name=checkbox]:not(:checked)').attr('disabled','disabled');
See a fork of your code with this working: http://jsfiddle.net/fKwEQ/
You can do this by modifying the setChecks method as follows:
function setChecks(obj) {
if(obj.checked) {
checkCount = checkCount + 1;
//note: modify this selector to specify the actual table in question,
//of course. If this is not known beforehand (ie there are multiple
//tables of checkboxes), you can use
// $(this).closest('table').find('input:checkbox:not(:checked)')
//instead.
if(checkCount == 8)
$('table input:checkbox:not(:checked)').attr('disabled', 'disabled');
} else {
if(checkCount == 8)
$('table input:checkbox:not(:checked)').removeAttr('disabled');
checkCount = checkCount - 1;
}
}
Unrelated to the question at hand, but hopefully helpful: I know this is a jsfiddle example and thus probably not indicative of your actual code, but you should consider using consistent formatting, especially with regard to indentation (and to a lesser extent spacing). Also, it's good habit to always use semicolons when writing javascript, even though they are sometimes optional. Readable code is much easier to debug, extend, and definitely easier for others to understand.
Another thing you can do to simplify your code is use stylesheets instead of specifying width and align in every td element, and using unobtrusive javascript instead of the onclick event in every checkbox. Those can all be replaced by a simple jQuery bind statement in your document.ready event:
$('table input:checkbox').click(setChecks);
This would require modifying setChecks to receive an event parameter instead. (Edit) Like so:
function setChecks() {
if(this.checked) {
...
} else { ... }
}
You don't actually need the event parameter because this refers to the current event target, so you can just remove that parameter altogether.

Categories