I'm working on a validation function in jQuery and am getting a bit stuck. I've got a working version that is very lengthy and full of hardcoded form values which I'm trying to avoid. Here's what works, currently:
$(document).ready(function(){
var fname = $("#formFName");
var lname = $("#formLName");
fname.blur(validateFName);
lname.blur(validateLName);
function validateFName(){
if(fname.val().length > 0){
fname.removeClass("req_error");
return true;
}
else {
fname.addClass("req_error");
return false;
}
}
function validateLName(){
if(lname.val().length > 0){
lname.removeClass("req_error");
return true;
}
else {
lname.addClass("req_error");
return false;
}
}
});
That part works fine for those two fields but I'd like to encapsulate the whole thing in a function that's a bit easier to maintain. Something like this:
$(document).ready(function(){
$("#first_name").blur(validateField("first_name","text"));
$("#last_name").blur(validateField("last_name","text"));
$("#email_address").blur(validateField("email_address","email"));
function validateField(formfield, type){
var field = $("#" + formfield);
switch(type) {
case "text":
if(field.val().length > 0){
field.removeClass("req_error");
return true;
}
else {
field.addClass("req_error");
return false;
}
break;
case "email":
var filter = /^[a-zA-Z0-9]+[a-zA-Z0-9_.-]+[a-zA-Z0-9_-]+#[a-zA-Z0-9]+[a-zA-Z0-9.-]+[a-zA-Z0-9]+.[a-z]{2,4}$/;
if(filter.test(field.val())) {
field.removeClass("req_error");
return true;
else {
field.addClass("req_error");
return false;
}
break;
}
}
});
However, when I do that I get the following error in Firefox's JS error log:
Error: ((f.event.special[r.origType] || {}).handle || r.handler).apply is not a function
Source File: /scripts/jquery-1.7.1.min.js
Line: 3
A quick Google for that error hasn't yielded anything that means anything to me, unfortunately. I've tried alerts in various spots and doing so has verified that the proper form field names are indeed being passed where there supposed to be, but as I'm fairly new to jQuery (and not great at JavaScript) I'm at a bit of a loss here.
Thanks to anyone who can point me in the right direction. Also, if anyone thinks that I'm going about this in the wrong way, I'm more than happy to change. I tried using the jQuery validation plugin but I'm also using some dynamically created fields and unfortunately the plugin prevents the visitor from submitting the form when hidden required fields are involved.
Sounds like you could simplify this by attaching behavior instead of specific elements:
<input type="text" id="someId" class="validate-text" />
<input type="text" id="someOtherId" class="validate-email" />
$('.validate-text').live('blur', function()
{
$(this).removeClass('req_error');
if($.trim(this.value).length < 1)
$(this).addClass('req_error');
});
$('.validate-email').live('blur', function()
{
// Same thing with the email validation logic
});
This way, you dont need to attach specific event handlers to your elements and instead use those handlers to check the behavior you want. Then you simply mark HTML elements with specific classes to mark the validation mode you want.
Assuming I understood your question correctly.
You can't pass a function invocation expression to .blur(). You can pass an anonymous function constructor:
$("#first_name").blur(function () {validateField("first_name","text");});
Or pass the name of a function:
function validateFirstName() {
validateField("first_name","text");
}
* * *
$("#first_name").blur(validateFirstName));
#Tejs's suggestion to use classes to attach validators is a good one, as well.
Related
I have a notification on PhpStorm that "Duplicate JQuery Selector" for a JQuery if...else conditional based on a value and then updating that value.
$(document).ready(function() {
$('#forgotten').click(function () {
if($('#button').val() === 'Login') {
$('#button').val('Send New Password');
}
else {
$('#button').val('Login');
}
return false;
});
});
PhpStorm tells me
Duplicated jQuery selector
Inspection info: Checks that jQuery selectors are used in an efficient way. It warns about duplicated selectors which could be cached and optionally about attribute and pseudo-selectors usage
Does this really matter? (I suspect not, it's micro-optimisation)
Is there a better way of writing this code (I suspect so)?
What is this better way?
Attempts:
if($('#button').val() === 'Login') {
$(this).val('Send New Password');
}
else {
$(this).val('Login');
}
The above code using this doesn't work; It seems that the JQuery isn't aware of what this is because it's not an invocation.
Attempt two is to use This useful answer:
$('#something')[$(this).val()=='X'?'show':'hide']();
But I can't see the syntax of how to apply this to swapping the value.
$('#button')[$(this).val() === 'Login'?$(this).val('Send New Password'):$(this).val('Login')];
The above attempt does not make the change expected (and does not give any console notices).
So, how do I do it; how do I write the original IF statement without repeating the reference?
Creating a jquery has (some, minor) overhead, so is not the most efficient. Your first code could be written as:
var btn = $("#button");
if (btn.val() === 'Login') {
btn.val('Send New Password');
}
else {
btn.val('Login');
}
while, in this case, it's a micro-optimisation, if you were doing this 1000s of times with very complicated selectors, it can save a lot of time to only run the jquery selection once.
Regarding your other attempts, using this will only make sense if this has relevant context, eg if inside an event:
$("#button").click(function() {
var btn = $(this);
...
In the case of .val() (and many other jquery functions (but not all)) a callback can be provided which is called for each entry in the jquery collection.
https://api.jquery.com/val/#val-function
A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old value as arguments.
In your case, this becomes:
$("#button").val(function(i, v) { return v === "Login" ? "Send new" : "login" });
This will run the callback function on each item in the collection provided by the selector, so very useful if you want to run against multiple items with different results on each, example:
$(".button").val(function(i, v) { return v === "Login" ? "Send new" : "login" });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="button" class="button" value="Login"></input>
<input type="button" class="button" value="Login"></input>
<input type="button" class="button" value="Not Login"></input>
Whenever you call $("#button") jQuery searches the document and gets the corresponding DOM element. So you can try to assign the selection to a variable as followings to avoid the repetition of the search:
var btn = $('#button');
if(btn.val() === 'Login') {
btn.val('Send New Password');
}
else {
btn.val('Login');
}
I am trying to find a way to copy the value of multiple input fields into 1 single input field.
currently I can only copy 1 input field into another one using the following code:
addEvent(document.getElementById('inputName'), 'keyup', function () {
document.getElementById('inputURL').value = this.value.replace(' ', ' ');
$(".sect2 input[#value='']").parents(".secTxt").hide();
});
function addEvent(ele, evnt, funct) {
if (ele.addEventListener) // W3C
return ele.addEventListener(evnt,funct,false);
else if (ele.attachEvent) // IE
return ele.attachEvent("on"+evnt,funct);
}
is it possible to do something like this:
addEvent(document.getElementById('inputName, inputName2, inputName3, inputName4'), 'keyup', function () {
document.getElementById('inputURL').value = this.value.replace(' ', ' ');
$(".sect2 input[#value='']").parents(".secTxt").hide();
});
function addEvent(ele, evnt, funct) {
if (ele.addEventListener) // W3C
return ele.addEventListener(evnt,funct,false);
else if (ele.attachEvent) // IE
return ele.attachEvent("on"+evnt,funct);
}
if not, what is the correct way of doing this?
Thanks in advance.
UPDATE:
None of the examples bellow works and neither they are practical.
I also tried my own solution and that didn't work either.
I can only assume this is not possible using javascript!
Your second example isn't possible, but if you're using jQuery anyway then something like this is probably the simplest solution
UPDATE - Having thought about this, you probably want something like below
$(function(){
$('#inputName, #inputName2, #inputName3, #inputName4').keyup(function(){
var str = "";
$('#inputName, #inputName2, #inputName3, #inputName4').each(function() {
str += $(this).val().replace(' ', '');
});
$('#inputURL').val(str);
});
});
I've added a jsFiddle here of a working example
insetead of document.getElementById() you can use document.querySelector():
document.querySelector('#inputName, #inputName2, #inputName3, #inputName4')
Im trying to validate a form at the point of clicking submit. There are a number of inputs which need validating which are all assigned the class .ipv4val. The issue I have is that I cant seem to add the 'bad' class to the single input element that has failed the validation ?
$("form").submit(function() {
var REGEX = /^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/;
if (REGEX.test($(".ipv4val").val())) {
return true;
}
else {
$(this).addClass("bad");
return false;
}
Any ideas ?
Look out for your use of: $(this).addClass("bad")
$(this) is the form element at the time of its execution. Try using the element ID of the input.
Have you considered the jquery.validate plugin, instead of rolling your own validation?
Try it this way:
$("form").submit(function() {
var REGEX = /^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/;
var ok=true;
$(".ipv4val").each(function(){
if (!REGEX.test($(this).val())) {
$(this).addClass("bad");
ok = false;
}
});
return ok;
};
I am trying to create a Jquery function to add or remove a drop down menu based on the selection of a different drop down menu,
This is my very first time trying to use Java script, and i need a little help to get it going.
here is what i have done up to now, but i cant seem to get it to work can somone tell me where i have gone wrong?
$(document).ready(function(){
$(function remove() {
$("select#name").val();
if (name == "United Kindom") {
$("select.county").show();
} else {
$("select.county").hide(); });
});
<select name="ab" onchange="remove();">
Firstly, what you're using is a mash-up of Javascript and jQuery(A Javascript Library). You must understand this. Just so you know the below is jQuery, and I'll add the pure JS to the end of the post.
Try This:
$(document).ready(function(){
$(".selectWrapper").on("change", "select#ab", function(){
$("select.county").toggle($(this).val() != "United Kindom");
});
});
<div class="selectWrapper">
<select id="ab">
This is also assuming you have
<select class="country">
somewhere in your code.
//---Pure JS ----
document.getElementById("ab").onchange = function(){
var selects = document.getElementsByTagName("select"), countrySelect;
for(var x in selects){
countrySelect = (selects[x].className == "country")? select[x] : "";
}
countrySelect.style.display = (this.value == "United Kindom")? 'none' : 'block';
};
Your code contains a syntax error, undeclared variables and a scope problem.
Your code can be rewritten more efficiently: $(fn) where fn is a function is equivalent to $(document).ready(fn). Also, the .toggle method can be used instead of if-then-show-else-hide.
Fixed code
The inline handler did not work either, because function remove was defined within the $().ready function.
To fix the code itself, bind the event handler using jQuery, instead of using an inline handler:
$(function() {
$('select[name=ab]').change(function() {
var name = $("select#name").val();
$("select.county").toggle(name == "United Kindom");
});
});
//<select name="ab">
Syntax error revealed
After indenting the code properly, the syntax error can be spotted quite easily
$(document).ready(function () {
$(function remove() {
var name = $("select#name").val(); // Prefixed "var name = "
if (name == "United Kindom") {
$("select.county").show();
} else {
$("select.county").hide();
} // <----------- This one is missing!
});
});
and just a quick hint at how to make easier use of jQuery
Remember, it's the "write less, do more" library:
// Easy jquery way to run when doc loaded
$(function() {
// you dont need to include the tag in an id selector
// remember, any way you can select an element in css, you can do in jQuery
$("#Country").change(function() { // here i use the .change event to know when this select box's value has actually changed to a new value
// i'm not sure exactly what you were trying to hide and show,
// i couldn't fllow where vaiable `name` came from, but this is
// how you could easily show or hide somthing based on this select's value
var $value = $(this).val();
// although, if you're gonna have alot of possible ifs,
// i would suggest a switch statement
switch($value) {
case "United Kingdom":
// here you can choose to show a specific select for UK states/countries/ares (i'm not familiar with how it works, i'm sorry)
$("#UKStates").show();
// if you're going to show specific, prefilled select boxes,
// then it would be advised to include a classname on each one
// that you can refer to in order to hide the rest
$(".select-states").hide();
break;
case "United States":
// do work
break;
default:
// do work
}
// otherwise, if you won't have many if statements,
// just use a regular if statment, like so:
// if ($value == "United Kindom") {
// $(".county").show();
// }
// else {
// $(".county").hide();
// }
})
});
notice in my example, there is alot of commented teaching, but not alota of code. Always remember, jQuery does all the work, just do what you need too.
You could start of by reducing your function to just this, making use of the showOrHide overload of .toggle().
function remove() {
$("select[name='ab']").toggle($("select[name='ab']").val() === "United Kingdom");
}
Since you are loading jQuery, you could as well make use of its event-handling as well, instead of using inline onchange="". Something like this:
$(function(){ // Wait for DOM to be ready
$("select[name='ab']").change(remove); // Attach an change-lister
});
So the complete thing would be:
$(function(){
$("select[name='ab']").change(remove);
});
function remove() {
$("select[name='ab']").toggle($("select[name='ab']").val() === "United Kingdom"));
}
I know this seems like a repeat question, but i've read all the others and they arn't quite the same :(
I've got some drop downs, and if they have something other then an option with a value of "0" selected then I want the coresponding Expiry Date field to be required.
I tried putting the rule in the class of the objects, and using the rules('add') function. Here's where i am at right now:
$('[id^=ExpiryDate]').each(function() {
$(this).rules('add',
{ required: function() {
if ($('#q' + id).val() == '0') {
return false;
}
else {
return true;
}
}
}
);
my expiry date fields are id'ed like "ExpiryDate1", "ExpiryDate2" and the corresponding drop downs are ided like "q1" and "q2".
this makes my scripts fail. it doesn't give any errors in the error console or firebug. but it doesn't execute any javascript that occurs after it either.
I have a feeling it's something really obvious and stupid that i am missing. but i've been staring at this code for a couple hours now and can't find it!
Thanks in advance!
Try this:
$('[id^=ExpiryDate]').each(function() {
var id = $(this).attr('id').replace('ExpiryDate','');
$(this).rules('add', {
required: function() {
return $('#q' + id).val() !== '0';
}
}
);
Currently, your id is undefined, so it's just not finding any elements. The rest is just a shorter version.