I need some help writing a re-usable function for form checking. I want to call the function on an element of my form and perform a value validation; however I am not sure I have written the function correctly to accept the targeted element.
Here is a fiddle where you can find all the code.
My questions:
By using the element object as a parameter of the function, does this get the specified element when the user types in values in that input element?
And can I write the function in this way and then pass it into addEventListener?
I am trying to adapt the simple function found at this link.
The piece of JS code I am trying to get to work is as follows:
var A = {
invoiced: document.getElementById("invoiced"),
checkValue: function (event, elem) {
if(elem.validity.typeMismatch)
elem.setCustomValidity("Only number(s) and '+' and '-' signs");
else
elem.setCustomValidity("");
}
};
A.invoiced.addEventListener("keyup", A.checkValue, false);
checkValue: function(event) {
var elem = event.target || event.srcElement;
...
Related
I've got a two-part question.
One: can I use the last variable I set to update the value on the line after if (!last) {? i.e., something like last = size;?
var j$ = jQuery.noConflict();
function updateCount() {
var self = j$(this),
last = self.data('last'),
size = self.val().length,
span = j$('.currentCount');
if (!last) {
self.data('last', size);
} else if (last != size) {
span.text(size);
self.data('last', size);
}
}
j$('textarea[id$=textBody]').on('propertychange change click keyup input paste', updateCount);
Secondly, can I chain my .on('propertychange ... line to have updateCount run as soon as the script is loaded?
Question 1:
No, you can not use simply the assignment to the variable because there is no data-binding in jQuery. So updating last variable will never update the data-last of the jQuery object.
Question 2:
This is what I am used to do:
j$('textarea[id$=textBody]').on('propertychange change ...', updateCount).change();
Where change() automatically triggers the function.
For Q1: No you can't. If you want data binding to work, you can try AngularJS where 2 way data binding between UI and model is possible.
Q2: My solution would be something like this using immediate function
$('textarea[id$=textBody]').on('propertychange change click keyup input paste', (function(){
updateCount();
return updateCount;
}()));
The last variable has a copy of the value in self.data('last'), it is not a pointer, so you would have to do something like this:
last = size;
self.data('last', last);
For the second question, you can trigger the event or just call the function:
j$('textarea[id$=textBody]').trigger('propertychange');
// or
j$('textarea[id$=textBody]').each(updateCount);
I'm beginning to learn OOP in Javascript and my instructor is not very good and I'm learning out of a very bad book. (http://www.amazon.com/JavaScript-The-Web-Technologies-Series/dp/0538748877/ref=cm_cr_pr_product_top) However I'm doing my best to use this site and any resource possible to follow along. That said! We're going over OOP and I'm trying to make a simple object oriented form validator but I'm having a problem with passing the input value to the method inside of the object. I apologize if I got the phrasing wrong. Here's my code.
function validate() {
this.isEmpty = function(value) {
if(value == "" || value.length < 1 || value == null) {
// testing alert
alert(value);
return false;
}
}
}
And my HTML
<form action="" method="get">
<label for="name">Name</label>
<input type="text" id="name" name="name">
<input type="submit" value="submit" id="submit">
</form>
Basically what I don't get is how I can pass the input value of the field "name" to the object? And my follow up to that would be how do I pass multiple inputs? For example if I wanted to check if "name" and another field named "email" were empty?
Can anyone shed some light on how I would go about doing this in regular JS? Am I even attempting this in the right way? I have no idea since this is my first time trying anything object oriented.
Well first it's important to know which concepts you are trying to model when doing OO. You were speaking about a "validator" concept, but perhaps it's still not specific enough. What exactly are you validating? Think about it, a "Validator" object suggests that it's actually quite flexible and is an object that could be helpful to validate many disparate models. If this isin't what you have in mind, then be more specific. For instance, you could name your class MyFormValidator (it's just an example).
Here's a very simple example of a specific validator class that takes a form as an argument and implements a public validate method to trigger validation on demand. The example is very simple and not quite flexible. There's a lot of space for improvements, such as removing UI concerns (like the messages), from the validator, but I did not want to make the example too complex.
*Note: _members identifies private members. You can enforce true privacy with the module pattern and/or priviledged functions, but I prefer naming conventions.*
function MyFormValidator(form) {
this.form = form;
this._errors = [];
}
MyFormValidator.prototype = {
constructor: MyFormValidator,
validate: function () {
var errors = this._errors,
name = this._valueOf('name');
//clear previous errors
errors.length = 0;
if (this._isEmpty(name)) {
errors.push('The name is mandatory');
}
return !errors.length;
},
errors: function () { return this._errors.slice() },
_valueOf: function (fieldName) {
return this.form.querySelector('[name="' + fieldName + '"]').value;
},
_isEmpty: function (value) {
return value == "" || value.length < 1 || value == null;
}
};
//Setting up form validation
var form = document.querySelector('form'),
validator = new MyFormValidator(form);
form.addEventListener('submit', function (e) {
if (!validator.validate()) {
e.preventDefault(); //prevent submit
alert(validator.errors());
}
});
DEMO: http://jsfiddle.net/Q2d5c/
When a JavaScript function is invoked inline, "this" points to the containing DOM element.
So if you want to validate the following tag:
<input name="test" onblur="validate();">
Then your validate function can grab its container's value:
function validate(){
alert(this.value); //the value of input field "test"
//to get the name of this input:
alert(this.name);
}
Personally I don't code like this because the code is sensitive to its context. Instead I use this style:
<input name="test" onblur="validate(this);">
function validate(d){
alert(d.value); //value
alert(d.name); //name
}
As you can see, the object is explicitly passed in, and you can see that on the call stack, "this" is placed in the tag directly. Later if you want to use the same function from another location, you can, by manually getting the object, and pass it in:
<input name="test" id="test">
<button onclick="validate(document.getElementById('test'));">Validate</button>
Unless it's an inline callback (closure) function, I avoid using the ambiguous "this" pointer to increase code readability.
I do not recommend to use a framework when learning javascript. After you learn javascript itself, then you should dive into frameworks, not now. So i will not tell anything about vanilla yet.
You can get values of inputs in several ways. The best is to get their value by id:
var name = document.getElementById("name").value
So there you have it, the value of the input assigned to name variable.
After that you can pass that variable to validate function and see the results.
You would also want to catch the form's submit event and do the validation before the form gets submitted. To do so:
var form = document.getElementsByID('form'); //you should assign id 'form' to the form element
form.addEventListener("submit", function(e) {
e.preventDefault(); //do not submit the form
var name = document.getElementById("name").value
validate(name);
});
It is simply done like that:
<script type="text/javascript">
function MsgAlert()
{
var value = document.getElementById('abc').value;
alert(value);
}
</script>
<input id="abc"></input>
<button onClick="MsgAlert();">PassValue</button>
function showHideSoldTo() {
if ($("#radio-text-sold-to").prop("checked")) {
$("#select-sold-to").hide();
$("#text-sold-to").show();
} else if ($("#radio-select-sold-to").prop("checked")) {
$("#text-sold-to").hide();
$("#select-sold-to").show();
}
}
$("#radio-text-sold-to").click(showHideSoldTo());
$("#radio-select-sold-to").click(showHideSoldTo());
All this is inside a document ready wrapper.
Remove the () from the function names in the click call. So..
$("#radio-text-sold-to").click(showHideSoldTo);
...
Remove the () from the function names in the click call
just try like
$("#radio-text-sold-to").click(showHideSoldTo);
$("#radio-select-sold-to").click(showHideSoldTo);
The problem is with the value you pass to the .click() method it's supposed to be a function value but instead you are invoking the function and as a result passing the return value of that function (which is equal to undefined)
the fix is simple you need to remove the () in these two lines
$("#radio-text-sold-to").click(showHideSoldTo());
$("#radio-select-sold-to").click(showHideSoldTo());
So they become
$("#radio-text-sold-to").click(showHideSoldTo);
$("#radio-select-sold-to").click(showHideSoldTo);
in javascript any identifier identifies a value. That value might be a simple value such as an integer or it might be a more complex object and as is the case with the value you pass as a callback or event handler it might be a function value.
These two lines of code are basically the same
function myFoo() {}
var myFoo = function() {}
and in the latter it's explicit that the right hand side is assigned to the left hand side. Ie that the function value is assigned to an identifier.
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
How to pass arguments to an event handler function and still use ‘this’ reference?
I've done a bit of searching but I'm struggling to find a solution to this.
Anyway:
function CreateMe(){
//....
var mycell = row.insertCell(-1);
var myelement3 = document.createmyelement("input");
myelement3.type = "button";
myelement3.value = "Delete";
myelement3.onclick = DeleteMe;
myelement3.name = "Delete[]";
mycell.appendChild(myelement3);
//....
}
function DeleteMe(){
alert(this);
}
I have a form with a button that calls CreateMe which dynamically creates a button. What I'm after is to be able to pass in arguments to the DeleteMe function when this dynamic button is clicked; in particular this:
onclick="DeleteMe(this.parentNode.parentNode.rowIndex)"
from: http://www.java2s.com/Code/JavaScript/HTML/Deletingtablerows.htm
I'm at a bit of a loss on how to proceed here, so if anybody could lend a hand it would be appreciated.
Edit: Just to be clear, what is being asked is how I can pass arguments from the onclick event of the dynamically generated button to the DeleteMe function. Clearly I am unable to do this as this would simply evaluate the function immediately:
myelement3.value = "Delete";
myelement3.onclick=DeleteMe(this.parentNode.parentNode.rowIndex);
myelement3.name = "Delete[]";
You are nearly there. .onclick is expected to be a function, so all you have to do is wrap that function call into another function:
myelement3.onclick = function() {
DeleteMe(this.parentNode.parentNode.rowIndex);
// or
// DeleteMe.call(this, this.parentNode.parentNode.rowIndex);
// to set `this` inside `DeleteMe` to the DOM element as well.
};
If the browser supports .bind, you could even do:
myelement3.onclick = DeleteMe.bind(
myelement3,
myelement3.parentNode.parentNode.rowIndex
);
but that would evaluate myelement3.parentNode.parentNode.rowIndex at the moment of creation and not when the element is clicked. If elements change their position, this could lead to problems, and in this case you'd rather go with the first solution.
Alternative, since this refers to the clicked element, you can access the row index inside DeleteMe:
function DeleteMe(){
var index = this.parentNode.parentNode.rowIndex;
}
// ...
myelement3.onclick = DeleteMe;
This works as long as you call DeleteMe only as event handler and not manually.
You can try this
function DeleteMe(e){
e = e || window.event;
var el = e.target || e.srcElement;
// here el is your button that's been clicked
alert(el.parentNode.parentNode.rowIndex);
}
I'm trying to use jQuery to open / close control 'boxes' on a webpage. Unfortunately, it doesn't look very good to close a box just to re-open it if the user happens to click on the already opened box. (Boxes are mutually exclusive).
The code I'm using doesn't work, and I'm not sure why. I still get a box closing just to open up anew, which isn't the desired functionality. I created the 'val' variable for debugging purposes; in the debugger, it shows 'val' as having the exact same value as $(this), which should prevent it from getting to the .slideToggle() inside the if statement, but doesn't.
function openBox(index)
{
val = $('#box' + index);
$('.profilePageContentBox').each(function(){
if($(this).css('display') != 'none')
{
if($(this) != val)
{
$(this).slideToggle(200);
}
}
});
val.slideToggle(200);
}
You can also do:
if(val.is(this))
Using the $() function will always create a new object, so no matter what, your equality check there will always fail.
For example:
var div = document.getElementById('myDiv');
$(div) === $(div); // false!
Instead, you could try just storing the actual DOM elements, since those are just referred to inside jQuery objects.
val = $('#box'+index).get(0);
...
if (this !== val) { }
Try this:
function openBox(index)
{
val=$('#box'+index);
$('.profilePageContentBox').each(function(){
if($(this).is(":visible"))
{
if(!$(this).is("#box"+index))
$(this).slideToggle(200);
}
});
val.slideToggle(200);
}