Normally in my backbone validation, I have a crazy amount of if() statements, as I've seen in many other code samples as well. Validation is pretty much a crap shoot in backbone; however, the if() way seems to work. I want to clean up the code a bit and wrote some code that does return error which should stop backbone from saving the attribute, but it doesn't!
OLD Code that works
validate : function(attr){
if(attr.firstName){
var defaultValue = 'first name',
value = attr.firstName.toLowerCase();
if(value == defaultValue){
return 'error';
}
}
}
NEW code that doesn't work
//My default strings from another place
MyApp.strings.defaults = {
firstName : 'first name'
}
//Model Validate function
validate : function(attr){
jQuery.each(attr, function(key, value){
var defaultValue = MyApp.strings.defaults[key];
if(defaultValue){
defaultValue = jQuery.trim(defaultValue.toLowerCase());
if(value == defaultValue){
console.log(value, defaultValue); //fires, and outputs both as being the same
return 'error';
}
}
});
}
Are you not allowed to loop over the attributes in Backbone validation?
You are not returning any value from the validate method, you were returning 'error' from the each() callback method, not from validate
//My default strings from another place
MyApp.strings.defaults = {
firstName : 'first name'
}
//Model Validate function
validate : function(attr){
var error;
jQuery.each(attr, function(key, value){
var defaultValue = MyApp.strings.defaults[key];
if(defaultValue){
defaultValue = jQuery.trim(defaultValue.toLowerCase());
if(value.toLowerCase() == defaultValue){
console.log(value, defaultValue); //fires, and outputs both as being the same
error = 'error';
return false;
}
}
});
return error;
}
Related
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
I am writing a search function at the moment for my Backbone application, the idea is that a user can enter a string and the app will search for and return any matching models where the string appears in any of its attributes. So far I have the following,
view function run on keyup,
this.results = this.collection.search(letters);
This runs the following code located in the collection,
search: function( filterValue ) {
filterValue = filterValue.toLowerCase();
var filterThroughValue = function(data) {
return _.some(_.values(data.toJSON()), function(value) {
console.log(value);
if(value != undefined) {
value = (!isNaN(value) ? value.toString() : value);
return value.toLowerCase().indexOf(filterValue) >= 0;
}
});
};
return App.Collections.filterCollection = this.filter(filterThroughValue);
}
However running this I get the following error,
Uncaught TypeError: undefined is not a function
this error is shown as being the line return value.toLowerCase().indexOf(filterValue) >= 0; and this error gets returned whether or not I use a string I know exists in a model of the collection.
Is there a fix for this, or a better way of searching and returning only models that have models that contain the search string?
Since you just want a string representation of value, you can probably just check if value has a toString method. Note that String also has a toString method, so this will work if value is a String.
return _.some(_.values(data.toJSON()), function(value) {
if(value && value.toString) {
return value.toString().toLowerCase().indexOf(filterValue) >= 0;
}
return false;
}
I have the following function in jQuery:
function vali(id) {
$(id).bind("jqv.field.result", function(event, field, errorFound, prompText) {
$(id).removeClass('validationError');
if(errorFound) {
$(id).addClass('validationError');
return false;
};
return true;
});
}
I am adding a validation class to inputs in a complex form to style it appropriately when an input is invalid. I would also like to return a true or false value based on this. The 'validationError' class is being added correctly to inputs but I cannot return the boolean value as I suspect that I am calling a function within a function here and therefore need to return the value to the higher order function? Something like "return.return false;" Obviously this doesn't work but you get what I'm thinking on this. Maybe I am way off?
If I reference a specific input say for eg:
console.log( vali('#cause-name') );
the validationError styling works but I get 'undefined' in the console. Thanks
This should work:
function vali(id) {
var valid = true;
$(id).bind("jqv.field.result", function(event, field, errorFound, prompText) {
$(id).removeClass('validationError');
if(errorFound) {
$(id).addClass('validationError');
valid = false;
};
valid = true;
});
return valid;
}
I am trying to make a function for java script that evaluates the text within a form and updates a label next to the form with either Valid entry or Invalid entry.
I have the code working here so far
function validateText(form) {
if(form.value == '') {
document.getElementById("reasonLabel").innerHTML = "Invalid Entry";
return false;
}
else{document.getElementById("reasonLabel").innerHTML = "Invalid Entry";}
var re = /^[\w ]+$/;
if(!re.test(form.value)) {
document.getElementById("reasonLabel").innerHTML = "Invalid Entry";
return false;
}
document.getElementById("reasonLabel").innerHTML = "Valid Entry";
return true; }
However I want to use this function and apply it to all forms inside my html each form has a corresponding label next to it.
My question is how do I pass in a label and edit its value without using .getElementByID()
Sorry if this is an obvious question I am very new to javascript.
If you have the label (which had to have been gotten using document.getElementById() or something similar in the first place), you can use it as a normal variable, like in the following:
function validateText(form, label) {
if(form.value == '') {
label.innerHTML = "Invalid Entry";
return false;
}
else{
label.innerHTML = "Invalid Entry";
}
var re = /^[\w ]+$/;
if(!re.test(form.value)) {
label.innerHTML = "Invalid Entry";
return false;
}
label.innerHTML = "Valid Entry";
return true;
}
Then label could be gotten by passing something like document.getElementById("reasonLabel") into the function.
You can pass the label's DOM object (returned from getElementByID) as a parameter, just like any other value.
I'm using below code to check some form fields and render datatable table on a button click. My intention is to stop the table from being rendered if any of the fields are empty. Apparently return false inside the loop is not working.
Is this the correct way to accomplish? any better ways?
$('#advance_search').click(function(){
var ds = $('.advance_search .filter_field');
$.each(ds, function(index, value){ //this loop checks for series of fields
if ($(this).val().length === 0) {
alert('Please fill in '+$(this).data('label'));
return false;
}
});
dt.fnDraw(); //shouldn't be called if either one of the field is empty
});
If you look carefully, your return false is inside the $.each callback function, so it returns false for the caller of that function, not the "main function" you are in.
Try this:
$('#advance_search').click(function(){
var ds = $('.advance_search .filter_field'), valid = true;
$.each(ds, function(index, value){ //this loop checks for series of fields
if($(this).val().length === 0) {
alert('Please fill in '+$(this).data('label'));
return (valid = false); //return false and also assign false to valid
}
});
if( !valid ) return false;
dt.fnDraw(); //shouldn't be called if either one of the field is empty
});
You could add a control variable to prevent the dt.fnDraw() from being called:
$('#advance_search').click(function(e){
e.preventDefault();
var check = 0, // Control variable
ds = $('.advance_search .filter_field');
$.each(ds, function(index, value){ //this loop checks for series of fields
if($(this).val().length === 0) {
check++; // error found, increment control variable
alert('Please fill in '+$(this).data('label'));
}
});
if (check==0) { // Enter only if the control variable is still 0
dt.fnDraw(); //shouldn't be called if either one of the field is empty
}
});