I want to know whether a control is valid or not in JavaScript. Is there a direct client side API available in Asp.Net which can tell me whether a control is valid or not?
Eg. If I have 2 validators attached to a textbox, I need a function that can tell me whether the textbox is valid or not. If even 1 validator is not valid then it should return false.
I can't seem to find a function that can give me this. Here is a little helper that I wrote which does the job but is inefficient:
function isControlValid(control) {
for (i = 0; i < Page_Validators.length; i++) {
var validator = Page_Validators[i];
var controlId = validator.controltovalidate;
if ($(control).attr('id') == controlId && validator.isvalid == false) {
return false;
}
}
return true;
}
Anybody has any better alternatives?
The below code should work.
function isControlValid(control) {
var validators = $(control).Validators;
var isValid = true;
Array.forEach(validtors, function(item) {
isValid = isValid && (item.isvalid === true);
});
return isValid;
}
UPDATE
This is better than the one you proposed because the entire page validators is not iterated. Only the ones associated with the control is used for iteration. $(control).Validators is used to retrieve the validators associated with the control.
Related
I'm very new to JQuery and Javascript in general, and I'm working on a project for school. While I can get everything to work without defining any functions, I want to reduce redundant code.
Here's a bit of what I'm trying to do:
function firstNameChanged() {
var x = document.getElementById("firstName").value;
if (x == null || x == "") {
$("#firstNameError").html(" First name can't be blank!");
}
else {
$("#firstNameError").html("");
}
}
$(document).ready(function(){
$("#firstName").blur(firstNameChange());
}
Yes I'm positive all IDs exist, because the code works when I pass it as:
$("#firstName").blur(function(){
var x = document.getElementById("firstName").value;
if (x == null || x == "") {
$("#firstNameError").html(" First name can't be blank!");
}
else {
$("#firstNameError").html("");
}
})
I've looked up plenty of documentation on Javascript and JQuery syntax, debugged in Chrome, I can't figure it out.
blur expects a function reference as a parameter. firstNameChange() is calling the function immediately. Remove the ()
$("#firstName").blur(firstNameChange);
I am getting an error while setting global variable flag inside function.
Global variable declaration
var flag = false;
Function to validate textbox
//To validate Product Name field
function Name() {
var pName = document.getElementById('addPName').value;
if (pName == "") {
$('#productNameError').text('Product Name is required');
flag = false;
}
else {
$('#productNameError').text('');
flag = true;
}
}
Function to validate quantity
//To validate Product Quantity Field
function Quantity() {
var pQty = document.getElementById('addPQty').value;
if (pQty != "") {
var regex = /^[1-9]\d*(((,\d{3}){1})?(\.\d{0,2})?)$/;
if (regex.test(pQty)) {
$('#productQtyError').text('');
flag = true;
}
else {
$('#productQtyError').text('Enter Quantity of the Product');
flag = false;
}
}
else {
$('#productQtyError').text('Quantity is required');
flag = false;
}
}
//Validation Summary
function validate() {
if (flag == true) {
$('#validationSummary').text('');
return true;
}
else {
$('#validationSummary').text('Please fill out required fields.');
return false;
}
}
I am calling first two functions on onfocusout event of textbox and calling validate() function on button click. The problem which I am facing is: inside the Quantity() flag is not getting set to false. Although the field remains blank,record gets inserted.
if you are getting flag=true in validate() then you may be calling Quantity() first ,it will set flag false then Name() which will set flag to true so It bypassed validate() function.
This is not the correct way, you are trying to achive validation. Consider scenario, when user have entered the correct value in first filed, flag will be set to true with the fact that second field is empty amd form will be submitted and hold true vice versa.
If want to achive by this way, keep as many flag variables as the number of fields amd chech all those variable inside validate.
Or, use '.each' to iterate each element and validate it and keep appending validation mesages to dom object.
Thanks
Don't use Global Variables
You're going to have a bad time if you use global variables, you can use the revealing module pattern to encapsulate some of the messiness
Would suggest something like this :
var app = app || {};
app.product = app.product || {};
app.product.validate = app.product.validate || {};
app.product.validate.isValid = false;
app.product.validate.name = function(){
var pName = document.getElementById('addPName').value;
if (pName == "") {
$('#productNameError').text('Product Name is required');
app.product.validation.flag = false;
} else {
$('#productNameError').text('');
app.product.validation.flag = true;
}
}
app.product.validate.quantity = function() {
var pQty = document.getElementById('addPQty').value;
if (pQty != "") {
var regex = /^[1-9]\d*(((,\d{3}){1})?(\.\d{0,2})?)$/;
if (regex.test(pQty)) {
$('#productQtyError').text('');
app.product.validate.flag = true;
} else {
$('#productQtyError').text('Enter Quantity of the Product');
app.product.validate.flag = false;
}
} else {
$('#productQtyError').text('Quantity is required');
app.product.validate.flag = false;
}
}
console.log is Your Friend
Try putting a console.log inside some of those methods, what I am guessing your issue is is that something is being called out of the order you expect and setting the flag to a value you aren't expecting.
Can do console.log statement like this console.log if you open up your developer console should show you the output from the console
So, I have this little code in my js file:
window.onload = function Equal() {
var a = 'b1'
var b = 'box1'
var bookstorname = localStorage.getItem(a)
if (bookstorname == 1) {
document.getElementById(b).setAttribute('checked','checked');
}
if (bookstorname == 0) {
document.getElementById(b).removeAttribute('checked','checked');
}
var a = 'b2'
var b = 'box2'
var bookstorname = localStorage.getItem(a)
if (bookstorname == 1) {
document.getElementById(b).setAttribute('checked','checked');
}
if (bookstorname == 0) {
document.getElementById(b).removeAttribute('checked','checked');
}
}
The function itself is not important (it equals checkboxvalues set in the localstorage), but I execute it 2 times. First time with var a & b set to 'b1' & 'box1'. Then I run the script again (same script), but with var a & b set to 'b2' & 'box2'. Now, this code works, but my question is if there is a shorter way to write this? I can imagine some sort of array with a loop, but I could not get it to work for some reason. The 2 variables are pairs, and I know this might be a dumb question, but I can't find the answer anywhere.
You can use a second function which will accept the local storage key and the checkbox id like
window.onload = function Equal() {
setCheckboxState('box1', 'b1');
setCheckboxState('box2', 'b2');
}
function setCheckboxState(id, key) {
document.getElementById(id).checked = 1 == localStorage.getItem(key);
}
You might separate common logic into another function
window.onload = function Equal() {
function extractFromStorage(a, b) {
var bookstorname = localStorage.getItem(a)
if (bookstorname == 1) {
document.getElementById(b).setAttribute('checked','checked');
}
if (bookstorname == 0) {
document.getElementById(b).removeAttribute('checked','checked');
}
}
extractFromStorage('b1', 'box1');
extractFromStorage('b2', 'box2');
}
function doTheStuff(a, b) {
var bookstorname = localStorage.getItem(a)
if (bookstorname == 1) {
document.getElementById(b).setAttribute('checked','checked');
}
if (bookstorname == 0) {
document.getElementById(b).removeAttribute('checked','checked');
}
}
window.onload = function Equal() {
doTheStuff('b1', 'box1');
doTheStuff('b2', 'box2');
}
?
This is how I would do it.
There are several problems with your code.
You do not check that the element you are stetting an attribute to
exists. You do not check if the localStorage item you get is
defined.
You pollute the global name space with the function name Equal.
That function should not be named with a capital as it is not a Object generator.
There is no need to use setAttribute and removeAttribute, in
fact removeAttribute makes no sense in this case as you can not
remove the checked attribute from the element. BTW why use setAttribute here and not for window.onload?
The checked attribute is either true or false, it does not use the
string "checked"
Binding the load event via the onload attribute is not safe as you may
block 3rd party code, or worse 3rd party code may block you.
There is no error checking. DOM pages are dynamic environments, pages
have adverts and content from many places that can interfer with your
code. Always code with this in mind. Check for possible errors and deal with them in a friendly way for the end user. In this case I used an alert, not friendly for a normal user but for you the coder.
My solution.
// add an event listener rather than replace the event listener
window.addEventListener(
"load", // for the load event
function(){
// the update function that is called for each item;
var update = function(item){
// the right hand side equates to true if the localstorage
// is equal to "1". LocalStorage allways returns a string or
// undefined if the key is not defined.
item.element.checked = localStorage[item.storageName] === "1";
}
// safe element getter
var getElement = function(eId){
var e = document.getElementById(eId); // try and get the element
if(e === null){ // does it exist?
throw "Missing element:"+eId; // no then we can not continue
// the program stops here unless
// you catch the error and deal with
// it gracefully.
}
return e; //ok return the element.
}
// Item creator. This creates a new item.
// sName is the local storage name
// eId id the element ID
var item = function(sName, eId){
return {
storageName: sName, // set the loaclStorage name
element:getElement(eId); // get the element and check its safe
};
}
// make it all safe
try{
// create an array of items.
var items = [
item("b1","box1"),
item("b2","box2")
];
// for each item update the element status
items.forEach(update);
}catch(e){
alert("Could not update page?");
}
}
);
I came across this in some code I am reworking and am curious if there is any reason for doing it this way besides personal preference. It seems unnecessarily obfuscated to me, considering how easy it would be to use several small functions with descriptive names. The purpose of the code is to validate a number of variables to ensure the data is properly formatted and within acceptable ranges while generating business data reports. The report is mainly just a tool to bring attention to scheduling issues.
There is a single function that gets passed several values, runs a test on each one, then passes all the results back as a boolean array.
function testAll(test1, ..., test10) {
var results = [false, ..., false];
if (test1 condition == true) {
results[0] = true;
}
...
if (test10 condition == true) {
results[9] = true;
}
return results;
}
That function is then called and used like this.
var tblData = getCurrentData(); // function that gets database info through AJAX
for (i = 0; i < tblData.Rows.Count; i++) {
// some code to append table element
var results = testAll(strStartDate, ..., strTotalHours);
if (results[0] == true) {
$('#startDate' + i.toString()).css('background-color', 'red');
}
...
if (results[9] == true) {
$('#projectTime' + i.toString()).css('background-color', 'red');
}
}
The original writer is gone and did not comment his code
While this may not technically address the question I posed, it is the solution to cleaning up the code in this case.
After further review it made more sense to use a non value returning function that performs the css formatting because of how simple the the tasks after evaluation are.
-Modified function
function verifyData(startDate, ..., timeSpent) {
if (startDate isValid != true) {
$('#startDate' + i.toString()).css('background-color', 'red');
}
...
if (timeSpent isValid != true) {
$('#projectTime' + i.toString()).css('background-color', 'red');
}
}
-New method of calling and using
var tblData = getCurrentData(); // function that gets database info through AJAX
for (i = 0; i < tblData.Rows.Count; i++) {
// some code to append table element
verifyData(strStartDate, ..., strTotalHours, i);
}
I'm having problems with this function I've made, the first part is called fine but after the first if statements nothing else is being called. I've used JSfiddle, but it doesn't indentify a serious problem.
I usually work with PHP not JS so I'm wondering if there is something simple I am missing here?
function validatequestion(form){
var e = document.getElementById("chooseqtype");
var strQtype = e.options[e.selectedIndex].value;
if(strQtype == "default"){
alert("Please select a question type");
return false;
}
if(strQtype == "textquestion"){
fail = validatetextq(form.textquestiondesc.value)
if(fail == "") return true
else {
alert(fail);
return false;
}
}
if(strQtype == "videoquestion"){
fail = validatevideoq(form.videoquestiondesc.value)
if(fail == "") return true;
else {
alert(fail);
return false;
}
}
//everything above works, after this point nothing seems to get called
var a = document.getElementById("chooseatype");
var strAtype = a.options[a.selectedIndex].value;
if(strAtype == "textanswer"){
//get the value of the number of text answers select box
var t = document.getElementById("choosetextnumber");
//put the value in variable strQtype
var strTextno = t.options[t.selectedIndex].value;
if(strTextno == "2tanswers"){
fail = validatetexta1(form.textanswer1.value)
fail += validatetexta2(form.textanswer2.value)
if(fail == "") return true;
else {
alert(fail);
return false;
}
}
}
}
If strQtype can only be one of the 3 values you are testing for then there is no way you can ever get to the second part of your code because you always return from each of those if statements.
EDIT:
What you need to do is not return when fail == "". Since you're just returning true I assume you don't need to return a value, just verify that the validation was successful. What you should do then is only test for failure, e.g. if (! fail=="" ) (syntax is prob wrong, javascript is not my first lang.) and in that case do your alert.
Or you could always just write 3 different functions, one to test each menu item, which is what I would probably do.