To add arguments or to add an array? - javascript

I have this chunk of code [sourced from different user on this site—thanks!] that I need to modify so that I can check multiple fields instead of just one. I'm not sure if I should be adding arguments to the second function or turn the variable checkString to an array.
function getField(fieldType, fieldTitle) {
var docTags = document.getElementsByTagName(fieldType);
for (var i = 0; i < docTags.length; i++) {
if (docTags[i].title == fieldTitle) {
return docTags[i]
}
}
}
function checkField() {
var checkString = getField('input', 'fieldtocheck').value;
if (checkString != "") {
if (/[^A-Za-z\d]/.test(checkString)) {
alert("Please enter only alphanumeric characters for the field fieldtocheck");
return (false);
}
}
}
I think the best option would be to feed "getfield" into the the "checkfield" as arguments but how would I do that?
Any help appreciated.

I would make your function more generic and use a class to identify the fields:
function checkFields(className, regex) {
var inputs = document.getElementsByClassName(className);
for (var i = 0; i < inputs.length; i++) {
if (!regex.match(inputs[i].value)) {
return false;
}
}
return true;
}
function validate() {
if (!checkFields('alphanum', /^[A-Za-z\d]+$/)) {
alert('Please enter only alphanumeric characters');
}
}
And your HTML could look like this:
<input type="text" class="alphanum" />
A much simpler (and better, IMO) approach would be to use the jQuery validation plugin.

Related

IF does not work when using variables

The second if does not work, and the third one does not work if I put a variable instead of "2" I was trying to put if (cont==len) but does not work. Which is the problem?
function alert(Vform){
var i=0;
var cont=0;
var len=Vform.length;
for (i=0;i<=len;i++){
if (Vform.elements[i].checked!=true){
cont=cont+1
}
}
if (cont!=2){
window.alert("Please select date and time");
}
}
Try to do these changes:
function alert(Vform)
{
var cont=0;
var len=Vform.length;
for (var i=0;i<=len;i++)
{
if (Vform.elements[i].checked!=true)
{
cont++;
}
}
if (cont != 2)
{
alert("Please select date and time");
}
}
Your for loop should be like this.
for (i=0;i<len;i++){
//code
}
It should check i<len and not i<=len because array element start with zero based index

Match value from array and return another array from a function

I was given a task to create a object based array of users. Then create a a function which takes in a parameter and returns another array matching the values compared within the first arr
var users = [
{
firstname : "jetlag",
lastname: "son"
},
{
firstname : "becky",
lastname: "love"
},
{
firstname : "just",
lastname: "me"
}
];
function matchName(name) {
for (var i = 0; i < users.length; i++) {
if(users[i].firstname == name) {
return users[i];
} else {
console.log('user does not exist')
}
}
}
console.log(matchName("jetlag"));
I am able to match a specfic username, but what if I just enter jinto the matchName("j"), i would like to return two objects.
Any help on this would be great.
http://jsfiddle.net/dv9aq0m7/
Thanks.
Your current code returns the first complete match. This code:
if(users[i].firstname == name) {
return users[i];
}
checks that the two strings are equal and then the return statement will only return that matched value. The function also stops once it has returned any value.
So you need to make two small changes. First you need to keep track of all users that fit the criteria, and you should use different logic to check that the string starts with another string.
Revised code might look like this:
function matchName(name) {
var validUsers = []; //the array of users that pass the logic
for (var i = 0; i < users.length; i++) {
if(users[i].firstname.lastIndexOf(name) === 0) { //this is "starts with" logic
validUsers.push(users[i]); //add the element if it's valid
}
}
//I moved the logic for no matching users the outside the loop
if (validUsers.length === 0)
console.log('No matching users found')
return validUsers;
}
Note: Based on the text you were printing, I moved the logic for printing that no users were found outside the loop by checking the number of elements in the validUsers array. This will print once only if there are no matching users.
Here's a fork to your fiddle
You can use Array.prototype.filter and return an array of objects that match your criteria. Something like this:
var users = [...];
function matchName(name) {
return users.filter(function (user) {
return user.firstname.indexOf(name) !== -1;
});
}
So you want to compare the prefix, not equality.
You can use
users[i].firstname.indexOf(name) === 0
to test if a user.firstname starts with name.
And use filtering to retrieve matches:
function matchName (name) {
return users.filter(function (user) {
return user.firstname.indexOf(name) === 0;
});
}
This always returns an array, which I think is a better interface.
Use Array.prototype.filter() for this. Your approach will only return the first match as an object.
function matchName(name) {
return users.filter(function (item) {
return item.firstname == name
}
}
Then use length of result to test if matches exist
You could use regular expressions in order to match any part of your name, not just the beggining.
function matchName(name) {
var pattern = new RegEx(name, "i");
for (var i = 0; i < users.length; i++) {
if(users[i].firstname.search(pattern)) {
return users[i];
} else {
console.log('user does not exist')
}
}
}

How i can get value $scope.TobaccoProduct_0 , $scope.TobaccoProduct_1

How i can get value of TobaccoProduct_0 , TobaccoProduct_1, TobaccoProduct_2.
Currently i am trying with this code and its not working
for (var count = 0; count < $scope.ProductCount; count++) {
if ($scope.TobaccoProduct_[count] == true) {
$("#SmokeReview").submit();
} else {
alert("plz chcek atleast one value");
}
}
for (var count = 0 ; count < $scope.ProductCount; count++) {
if ($scope["TobaccoProduct_"+count] == true) {
$("#SmokeReview").submit();
}
else {
alert("plz chcek atleast one value");
}
}
You really shouldn't be doing it this way though. You should surely be using some kind of array to store the Tobacco products rather than numbering the variable name.
Edit: You might actually be doing it that way (otherwise you'd have a really strange ProductCount implementation) and so the above solution won't work, you'll have to use $scope.TobaccoProduct[count]

Find HTML based on partial attribute

Is there a way with javascript (particularly jQuery) to find an element based on a partial attribute name?
I am not looking for any of the selectors that find partial attribute values as referenced in these links:
starts with [name^="value"]
contains prefix [name|="value"]
contains [name*="value"]
contains word [name~="value"]
ends with [name$="value"]
equals [name="value"]
not equal [name!="value"]
starts with [name^="value"]
but more something along the lines of
<div data-api-src="some value"></div>
<div data-api-myattr="foobar"></div>
and
$("[^data-api]").doSomething()
to find any element that has an attribute that starts with "data-api".
This uses .filter() to limit the candidates to those that has data-api-* attributes. Probably not the most efficient approach, but usable if you can first narrow down the search with a relevant selector.
$("div").filter(function() {
var attrs = this.attributes;
for (var i = 0; i < attrs.length; i++) {
if (attrs[i].nodeName.indexOf('data-api-') === 0) return true;
};
return false;
}).css('color', 'red');
Demo: http://jsfiddle.net/r3yPZ/2/
This can also be written as a selector. Here's my novice attempt:
$.expr[':'].hasAttrWithPrefix = function(obj, idx, meta, stack) {
for (var i = 0; i < obj.attributes.length; i++) {
if (obj.attributes[i].nodeName.indexOf(meta[3]) === 0) return true;
};
return false;
};
Usage:
$('div:hasAttrWithPrefix(data-api-)').css('color', 'red');
Demo: http://jsfiddle.net/SuSpe/3/
This selector should work for pre-1.8 versions of jQuery. For 1.8 and beyond, some changes may be required. Here's an attempt at a 1.8-compliant version:
$.expr[':'].hasAttrWithPrefix = $.expr.createPseudo(function(prefix) {
return function(obj) {
for (var i = 0; i < obj.attributes.length; i++) {
if (obj.attributes[i].nodeName.indexOf(prefix) === 0) return true;
};
return false;
};
});
Demo: http://jsfiddle.net/SuSpe/2/
For a more generic solution, here's a selector that takes a regex pattern and selects elements with attributes that match that pattern:
$.expr[':'].hasAttr = $.expr.createPseudo(function(regex) {
var re = new RegExp(regex);
return function(obj) {
var attrs = obj.attributes
for (var i = 0; i < attrs.length; i++) {
if (re.test(attrs[i].nodeName)) return true;
};
return false;
};
});
For your example, something like this should work:
$('div:hasAttr(^data-api-.+$)').css('color', 'red');
Demo: http://jsfiddle.net/Jg5qH/1/
Not sure what it is you're looking for, but just spent a few minutes writing this:
$.fn.filterData = function(set) {
var elems=$([]);
this.each(function(i,e) {
$.each( $(e).data(), function(j,f) {
if (j.substring(0, set.length) == set) {
elems = elems.add($(e));
}
});
});
return elems;
}
To be used like :
$('div').filterData('api').css('color', 'red');
And will match any elements with a data attribute like data-api-*, and you can extend and modify it to include more options etc. but of right now it only searches for data attributes, and only matches 'starts with', but at least it's simple to use ?
FIDDLE

Validating age field

I'm trying to validate an age field in a form but I'm having some problem. First I tried to make sure that the field will not be send empty. I don't know JavaScript so I searched some scripts and adapted them to this:
function isInteger (s)
{
var i;
if (isEmpty(s))
if (isInteger.arguments.length == 1)
return 0;
else
return (isInteger.arguments[1] == true);
for (i = 0; i < s.length; i++)
{
var c = s.charAt(i);
if (!isDigit(c))
return false;
}
return true;
}
function isEmpty(s)
{
return ((s == null) || (s.length == 0))
}
function validate_required(field,alerttxt)
{
with (field)
{
if (value==null||value=="")
{
alert(alerttxt);return false;
}
else
{
return true;
}
}
}
function validate_form(thisform)
{
with (thisform)
{
if ((validate_required(age,"Age must be filled out!")==false) ||
isInteger(age,"Age must be an int number")==false))
{email.focus();return false;}
}
}
//html part
<form action="doador.php" onsubmit="return validate_form(this)" method="post">
It's working fine for empty fields, but if I type any letters or characters in age field, it'll be sent and saved a 0 in my database. Can anyone help me?
Sorry for any mistake in English, and thanks in advance for your help.
You can use isNaN() to determine if an object is a number, for example:
someString="6";
someNumber=5;
someFloat=3.14;
someOtherString="The";
someObject = new Array();
isNaN(someString); // Returns false
isNaN(someNumber); // Returns false
isNaN(someFloat); // Returns false
isNaN(someOtherString); // Returns true
isNaN(someObject); // Returns true
Then you can use parseFloat() or parseInt() to convert a string into a number:
aString = "4";
aNumber = parseInt(aString);
if(aNumber<5)
alert("You're too young to use this website");
See also this other question that vladv pointed out in the comments.

Categories