I am doing length validation with java script. If input is short in length I shows an alert and after that I want to set focus back in the text field. It is working in IE but not working in FF. I have searched a lot on google but no solution could work plz guide and help me.
function IsLengthOK(_title,_control,_length)
{
if(_control.value.length < _length)
{
alert("'"+ _title +"'" + " must be minimum "+_length+" characters in length");
document.getElementById('txtUserName').focus();
return(false);
}
}
I am calling this function here on textbox's blur event:
if(IsLengthOK("Registration Username",this,6))
{
// do something next.
}
HTML of my textbox is:
<input id="txtUserName" type="text" tabindex="1" name="txtUserName" style="background: none repeat scroll 0% 0% white;">
function IsLengthOK(_title,_control,_length) {
if(_control.value.length < _length) {
alert("'" + _title + "'" + " must be minimum " + _length + " characters in length");
setTimeout(function() {
document.getElementById('txtUserName').focus();
}, 0);
return false;
}
}
This's working in my Firefox. It will have the focus on object#txtUserName after the setTimeout called.
It works fine for me in Firefox 4.
jsFiddle.
Here is a suggested rewrite of your function...
function IsLengthOK(_title, _control, _length) {
if (_control.value.length < _length) {
alert("'" + _title + "'" + " must be minimum " + _length + " characters in length");
_control.focus();
return false;
}
return true;
}
jsFiddle.
You are passing a reference to your element but then selecting it again. There is no reason to do that. It will only make maintenance more difficult. It will also bind that function to your one element when it could easily be more flexible.
You return false in parenthesis. That is not necessary. Also, if the condition is true, it returns false, so it would stand to reason otherwise it should return true (instead of undefined).
If you have a bunch of validation utility functions like this, it may be a good idea to namespace them as methods of a Validator object, for example.
Why do you prefix your variables with _? You should drop them.
Instead of using document.getElementById, like you are here:
document.getElementById('txtUserName').focus();
Use a jquery selector and then extract the raw element, like so.
$('#txtUserName')[0].focus();
Related
The function in question:
function toggleElementClass(element, className) {
if (element.className.indexOf(className) > -1) {
element.className = element.className.replace(new RegExp(className, 'g'), '');
} else {
element.className += " " + className;
}}
I'm trying to identify issues with this code. I've had experience with jQuery and JavaScript here and there, but I cannot seem to come to a solid conclusion with what I've seen so far. I've seen a lot of examples using the current .toggleClass() function from jQuery but none that help me analyze the code above.
One problem I think I can identify is that it never seems to remove a class. Only adds more but I've had problems attempting to test this on plunker. Any help would be appreciated. What problems can you identify with this method?
Want to make an edit: This questions is purely for my own understanding. I'm not intending to use this or re-write a tool that already exists in jQuery! Thanks for all who have submitted answers so far!
Edit: For anyone who may be interested. This isn't a perfect solution (adds spaces between classes the more you toggle). It seems to get around the false positive the original code would cause!
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
</head>
<body>
<h1 class="football">Hello Plunker!</h1>
<script>
function toggleElementClass(element, className) {
var regex = new RegExp('\\b' + className + '\\b', 'g');
if (regex.test(element.className)) {
element.className = element.className.replace(regex, '');
} else {
element.className += " " + className;
};
};
$("h1").click(function() {
toggleElementClass(this, "test")
})
</script>
</body>
</html>
The logic is fine for most circumstances, although will get false positives when searching for foo and a football class is available.
The specific issue with your code is with how you are attaching the click event to the h1. Currently you're setting the result of the function call to the event handler, not the function reference. This means the function is called immediately on load and the scope is not what you're expecting (it's the window instead of the h1) hence the 'undefined' error you receive.
To fix this you need to wrap the click event handler in an anonymous function:
function toggleElementClass(element, className) {
if (element.className.indexOf(className) > -1) {
element.className = element.className.replace(new RegExp(className, 'g'), '');
} else {
element.className += " " + className;
};
};
$("h1").click(function() {
toggleElementClass(this, "a")
})
.a {
color: #c00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1 class="a">Hello Plunker!</h1>
That being said the function is completely redundant, as you can use either jQuery's toggleClass():
$("h1").click(function() {
$(this).toggleClass('a')
})
.a {
color: #c00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1 class="a">Hello Plunker!</h1>
Or alternatively you can use classList.toggle():
document.querySelector('h1').addEventListener('click', function() {
this.classList.toggle('a');
});
.a {
color: #c00;
}
<h1 class="a">Hello Plunker!</h1>
Here are some problems:
You'll get false positives for a partial class name match (searching for foo, will match foobar). If you fix this problem, be careful how you do it, since you must allow for more than one kind of space separator.
The replacement will leave extra spaces, which isn't huge, but can add up.
You're using a regular expression with the assumption that the class name will not contain any special regex characters. You already are getting the index, so why not use that? You'll need a loop to make sure they all get removed, but it's going to be safer.
I'm looking for an easy way an end user can generate "pseudo-code" on how to generate a final string. I think it would be easier if I gave an example.
I have the following variables:
Round
Game
Wins
Losses
Player
Opponent
Rating
In the back end of my application, I'm doing this all manually.
echo Player + " is currently playing " + Opponent + ". Round: " + Round + ", Game: " + Game;
if ( Wins > Losses ) {
echo " (Up a Game)";
} else if ( Wins < Losses ) {
echo " (Down a game)";
}
What I'd like to ultimately do is give control to the end user of how this string is being displayed. I'd like them to add variables where they want, as well as add if/else statements.
I looked a bit into selectize and select2, and they seem to be on the right track of what I'm looking for, but doesn't really contain any if/else functionality I need. Something I have used in the past is Blockly which does contain if/else logic, but this can be a bit complex to the end user. Does anyone have any other recommendations of javascript/jQuery plugins/scripts I can use to accomplish this?
You can still use selectize and add some nice css features. E.g. you could use the data-value selector
[data-value="if"] {
background-color: red;
}
to distinguish if/else tags from other tags. Next you could use the adjacent sibling css selector (http://www.w3.org/TR/CSS2/selector.html#adjacent-selectors) to find the next tag after an if statement to mark this aswell
[data-value="if"] + div {
background-color: anything;
}
Moreover you can also distinguish variables using the same technique. Later, a parser could parse the if/else statements using regexp or whatever suits you best.
Someone could then write something like
[Player][" is currently playing "][Opponent][". Round: "][Round]
[", Game: "][Game][if][Wins>Losses][" (Up a Game)"][else][" (Down a game)"]
where the brackets indicate "tags". Your parser then should tread tags with quotations "" as string.
Assuming you use php to look for key words in a string and replace them with the stuff you actually want!
$s="Player is currently playing Opponent [ROUND], Game: Game";
$s = str_replace("[ROUND]", "Round: $Round", $s );
For example look for [ROUND] and replace it with your desired content.
Then with out reloading the page, use ajax to call the php file to do the work for you!
If you are looking for a custom client side parsing of text, maybe this will help you.
var keywords = {
Round: 'red',
Game: 'green',
if: 'blue',
else: 'blue',
then: 'blue'
}
$('#input').keyup(function(){
var parsedInputTags = $(this).val().split(/[\[\]]/);
$('#output').html('');
parsedInputTags.forEach(function(text){
if(text in keywords){
$('#output').append('<span data-tag="' + text + '" class="tag-' + keywords[text] + '">' + text + '</span>');
}
else $('#output').append('<span>' + text + '</span>');
});
});
.tag-red {
color: red;
}
.tag-green {
color: green;
}
[data-tag="if"] + span {
color: cyan;
}
.tag-blue {
color: blue;
}
textarea {
width: 200px;
height: 200px;
}
#output { display: inline-block; vertical-align: top; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="input" placeholder="Type this: This is game [Game] in round [Round]. [if] something > smth [then] type this [else] type that"></textarea>
<div id="output"></div>
I'm trying to make a variable equal the value of the text box. I have the text box value being set to a variable and returned as an alert (for now) but I can't figure out how to call that variable from other functions.
$('#max_char').keyup(function () {
var max_char = $(this).val();
alert(max_char + ' Handler for .keyup() called.');
});
var count_options = {
'maxCharacterSize': max_char,
'originalStyle': 'originalDisplayInfo',
'warningStyle': 'warningDisplayInfo',
'warningNumber': 40,
'displayFormat': '#input Characters | #left Characters Left | #words Words'
};
$('#textinput').textareaCount(count_options);
});
HTML
<textarea cols="68" rows="21" name="textinput" id="textinput"></textarea><br/>
<input type="textbox" id="max_char" name="max_char" value="-1" /> Max Characters <br/>
Any help would be great. Trying to add the var max_char to the maxCharacterSize of count_options
All you need to do is declare max_char in a higher scope, i.e. outside of the keyup function:
var max_char;
$('#max_char').keyup(function () {
max_char = +$(this).val();
alert(max_char + ' Handler for .keyup() called.');
});
Also note that I put a + in front of $(this).val() to convert it from a string into a number, since "1" + 1 == "11".
Update:
The reason the textareaCount plugin isn't working is because it is initialised once, on document ready. At this time, max_char is nothing because the user hasn't typed anything yet.
You'd have to either reconfigure or re-initialise the plugin on every keyup to get the effect you're after. Unfortunately the plugin doesn't document an easy way to do this. After digging through the plugin's source code, I think there are only 3 events it binds that you need to revert, before you can simply re-initialize it again. Try this out:
var count_options = {
'maxCharacterSize': 100, // Just some default value
'originalStyle': 'originalDisplayInfo',
'warningStyle': 'warningDisplayInfo',
'warningNumber': 40,
'displayFormat': '#input Characters | #left Characters Left | #words Words'
};
// Initialise the plugin on document ready
$('#textinput').textareaCount(count_options);
$('#max_char').keyup(function () {
var max_char = +$(this).val();
count_options.maxCharacterSize = max_char;
// Unbind the 3 events the plugin uses before initialising it
$('#textinput')
.next('.charleft').remove().end()
.unbind('keyup').unbind('mouseover').unbind('paste')
.textareaCount(count_options);
});
If I understand you correctly, if you declare the var within the global scope of javascript
Or if you directly access the input with
$("#max_char").val()
parseInt($('#max_char').val())
I've been writing JS (mainly jQuery) for quite a few months now, but today I decided to make my first abstraction as a jQuery method. I already have working code but I feel/know that I'm not doing it the right way, so I come here for some enlightenment.
Note: Please do not reply that there's already something out there that does the trick as I already know that. My interest in this matter is rather educational.
What my code is intended to do (and does):
Limit the characters of a textfield and change the color of the counter when the user is approaching the end.
And here's what I have:
$(function(){
$('#bio textarea').keyup(function(){
$(this).char_length_validation({
maxlength: 500,
warning: 50,
validationSelector: '#bio .note'
})
})
$('#bio textarea').trigger('keyup');
})
jQuery.fn.char_length_validation = function(opts){
chars_left = opts.maxlength - this.val().length;
if(chars_left >= 0){
$(opts.validationSelector + ' .value').text(chars_left);
if(chars_left < opts.warning){
$(opts.validationSelector).addClass('invalid');
}
else{
$(opts.validationSelector).removeClass('invalid');
}
}
else{
this.value = this.value.substring(0, opts.maxlength);
}
}
In the HTML:
<div id="bio">
<textarea>Some text</textarea>
<p class="note>
<span class="value">XX</span>
<span> characters left</span>
</p>
</div>
Particularly I feel really uncomfortable binding the event each on each keyup instead of binding once and calling a method later.
Also, (and hence the title) I need to call the method initially (when the page renders) and then every time the user inputs a character.
Thanks in advance for your time :)
chars_left is a global variable which is not good at all. Here is a better (slightly changed) version:
jQuery.fn.char_length_validation = function(opts) {
this.each(function() {
var chars_left = opts.maxlength - $(this).val().length;
$(this).keyup(function() {
chars_left = opts.maxlength - $(this).val().length;
if (chars_left >= 0) {
$(opts.validationSelector).text(chars_left);
if (chars_left < opts.warning) {
$(opts.validationSelector).addClass('invalid');
}
else {
$(opts.validationSelector).removeClass('invalid');
}
}
else {
$(this).val($(this).val().substring(0, opts.maxlength));
}
});
});
this.keyup(); // makes the "initial" execution
return this;
};
See a DEMO.
Some explanation:
In a jQuery plugin in function, this refers to the elements selected by the selector. You should use this.each() to loop over all of these and set up every element accordingly.
In this example, every element gets its on chars_left variable. The event handler passed to keyup() has access to it as it is a closure. Update: It is already very late here ;) It is not necessary to declare it here as you recompute the value every time anyway. Still, it should give you an idea how to have private variables that persist over time.
You should always return this to support chaining.
Further thoughts:
You might want to think about how you could make it work for several textareas (i.e. you have to think about the validation selector). Don't tie it to a specific structure.
You should have default options.
Update: Of course you can make your plugin work with only one textarea (like some jQuery functions work).
You can do the binding and initial triggering in the method:
jQuery.fn.charLengthValidation = function(opts) {
return this.keyup(function() {
var charsLeft = opts.maxLength - $(this).val().length;
if (charsLeft >= 0) {
$(opts.validationSelector + ' .value').text(charsLeft);
$(opts.validationSelector).toggleClass('invalid', charsLeft < opts.warning);
} else {
$(this).val($(this).val().substring(0, opts.maxLength));
}
}).trigger('keyup');
}
$(function() {
$('#bio textarea').charLengthValidation({
maxLength: 25,
warning: 10,
validationSelector: '#bio .note'
});
});
This code loads via jQuery a page based onclick events of checkboxes.
function product_analysis(address, box) {
if (box.checked) {
$('#product_' + box.alt).load(address);
} else {
$('#product_' + box.alt).load('http://www.divethegap.com/update/blank2.html');
}
document.getElementById('product_quantity_PRI_' + box.alt).value = box.value;
};
With the onclick event looking as follows onclick="product_analysis('http://www.samedomain.blahblahblah', this)
What I need is that for all checkboxes that are already ticked on page load to have this function applied to them all. I am reasonably confident with javaScript but when it comes to objects and arrays I get lost.
Many Thanks,
You can use this code to find all the checkboxes that are currently checked:
$(':checkbox:checked')
If you then want to do something to all of them, you can use the each function like this:
$(':checkbox:checked').each(function() {
// alerts the checkbox for example
// "this" referes to the checkbox, one after the other
alert(this);
})
Or to do what you asked for ("for all checkboxes that are already ticked on page load to have this function applied to them all"):
$(':checkbox:checked').each(function() {
product_analysis("someaddress", this);
})
EDIT: To address the second issue (not a part of the original question, but to the comments below):
I will assume that you have fields like this in your markup. Use some meaningful IDs rather than my stupid examples of course.
<input type="checkbox" id="foo" />
<input type="checkbox" id="bar" />
<input type="checkbox" id="baz" />
Then you'll put the following in your JS:
var addresses = {
foo: 'some_address',
bar: 'some_other_address',
baz: 'yet_another_one'
};
$(':checkbox:checked').each(function() {
product_analysis(addresses[this.id], this);
})
That will invoke product_analysis with the address that corresponds to the ID of the checkbox.
EDIT (again):
There is actually a way to add meta-data directly to the html-tags that I wasn't aware of. You can add attributes prefixed by "data-" to your tag, like this:
<input type="checkbox" data-address="someaddress" data-foo="something else" data-bar="more data!" />
You can read more about it on John Resigs blog.
this is required script
$().ready(function(){
var box, address;
$(":checkbox").each(function(){
box = this;
if (box.checked) {
address = ""; //you can set address either in hidden fields or in metadata
$('#product_' + box.alt).load(address);
}
else {
$('#product_' + box.alt).load('http://www.divethegap.com/update/blank2.html');
}
document.getElementById('product_quantity_PRI_' + box.alt).value = box.value;
});
});
You need to check how many number of check is checked and then invoke your code.
var checkLength = checkObj.length;
for(var i = 0; i < checkLength ; i++) {
if(radioObj[i].checked) {
}
// here your code base on check box status
}
If you have a class called as "selected" when the check box are checked, you could do something like this
$('.selected').function(element){product_analysis(address, element)};
Thanks chaps for all your help here is I I got it. Jakob will probably consider this a hack but it is a data driven site and based on my limited technical knowledge can't be tasked with modifying a JS file every time we add a new product.
function product_analysis_global() {
$(':checkbox:checked').each(function() {
$('#product_' + this.alt).load(this.title);
});
}
function product_analysis(box) {
if (box.checked) {
$('#product_' + box.alt).load(box.title);
}
else {
$('#product_' + box.alt).load('http://www.divethegap.com/update/blank2.html');
}
document.getElementById('product_quantity_PRI_' + box.alt).value = box.value;
};