jQuery form validation questions? - javascript

I am new to jQuery and javascript and I am used mainly to php. I am upgrading my site so it contains a little ajax to improve usability and to keep me busy!
I am using this simple little script I threw together for the login page. All works well at the minute but I have a couple of questions I'd like to ask!
$('#loginForm .submit').click(function(event) {
$('.error').hide();
event.preventDefault();
var errors = 0;
var loginEmail = $('#loginEmail').val();
var loginPassword = $('#loginPassword').val();
if (loginEmail.length == 0) {
$('#loginEmail').after('<div class="error"></div>');
errors++;
}
if (loginPassword.length == 0) {
$('#loginPassword').after('<div class="error"></div>');
errors++;
}
if (!errors) {
$('.submit').submit();
}
});
You will notice that the first line of code within the function is;
$('.error').hide();
Now in php I would normally use;
if (isset(........)) {
Is there a simliar way to do this in javascript as when the user first activates the function there will be no html with the class .error?
Also I am trying to add a new parameter to the function as well as the event parameter, how would I do this? I have tried the following?
$('#loginForm .submit').click(function(event, var) {
$('#loginForm .submit').click(function(event var) {
$('#loginForm .submit').click(function('event', 'var') {
And all seem not to work. Then again I am going by php, jQuery/javascript is not my strong point!
Thanks

Before performing an action, you can check if the function $() selected element by using the following syntax:
if ($('.error').length)
{
// actions
}

If the .error - div exists in the DOM by default and is just hidden, you can't just check the length of $('.error'), because even if it's empty, length will return 1.
You could do something like this:
if($('.error').html().length !== 0){
//do something
}
This will check the containing string of the error-div, so if it's empty, length will return 0.
Still I would recommend setting a boolean var. If errors occur, it gets set to false and you can check the var and you do not have to query for DOM-elements for such a simple task.
To your second question, try something like this:
$('#loginForm .submit').bind("click", {variable1: var}, handleSubmit);
function handleSubmit(event){
var passedVar = event.data.variable1;
}

Related

Using a javascript class method to reset the values of a previously submitted form

I am attempting to use a class method to clear a form that may have been previously submitted using vanilla Javascript. While the functionality works outside of a class, inside has been a nightmare to figure out, and using .reset() returns the previously submitted values. Ideally I'd be able to call this methods inside of other methods to keep things DRY as clearing the form is used quite a lot.
The result of what I have below is no console errors, and otherwise expected functionality, just the previously submitted data still populating the form. Console logging the elements (input) in the clearForm() method returns the expected DOM element.
There seems to be some sort of knowledge gap on my part and I'd like to fill it.
Currently I have this for clearing:
[class and constructor]...
/* in my constructor this._form = document.querySelector(target); where target is a param
containing the target element's id or class */
clearForm() {
[...this._form.elements].forEach((input) => {
if (input.type == "checkbox") {
input.checked = false
input.setAttribute("value", false);
return;
}
input.value = "";
input.setAttribute("value", "");
});
}
And I put it to use in other methods such as:
async populateForm(id) {
try {
await this.clearForm();
[additional functionality]...
} catch (e) {
...
}
}
Thanks for any help!

Looping through multiple checkboxes and adding the checked values to an array to write back to Sharepoint

I have a block of code that is supposed to look at which checkboxes are checked and then write the value of those checkboxes to an array so that I can write the data back to Sharepoint. I got it working before when I used an if/else statement, but I need it to be able to handle multiple checkboxes being selected. I did some research and found part of my code from another answer and combined it with some of my code but it doesn't seem to be working and I'm not sure why. None of the other answers I came across seem to be what I'm looking for.
Basically, what I'm asking is, what is the best way to achieve what I'm trying to do?
function addCustomers() {
$(document).ready(function () {
var customers = [];
var ckbox = $('.customer-options');
$('input').on('click', function () {
if (ckbox.is(':checked')) {
customers.push(ckbox).val();
}
else {
}
});
customers.toString();
document.getElementById('mxID04').innerHTML = customers;
});
}
It's not exactly clear what you are trying to do. First, your function contains document.ready which doesn't look right. Then you create some vars which I think you want to fill because at the end you are setting another element's innerHTML to, but in between you've just created a click handler which isn't going to work. Here's what I've put together for testing. I think you should be able to modify my example into what it is you're after
function addCustomers() {
var customers = [];
var ckbox = $('.customer-options');
alert('add handler');
$('input').change(function() {
$('input:checked').each(function() {
customers.push(this);
});
});
}
$( document ).ready(function() {
// alert('here');
addCustomers();
});

Simple jQuery function not picking up click function

I am having a go at my very first jQuery function. What needs to happen is that a form will be assigned to the function. When a user clicks on the submit button it needs to first do validation on each :input field within the the function.
I am assigning a form as the selector for my function:
$("form[name='form_name']").validator();
This then gets passed into the function and is assigned to a function property called "selected_form". Within my jQuery function I have another function which needs to wait for the submit button to be clicked, and after that it needs to iterate through all of the :input form elements and handle simple validation.
The issue now is:
a) Within my jQuery function I am making a call to return validate(); Validate then checks to see whether the button as clicked. I suspect that because the function is run and there was no button clicked, it continues and basically returns the validate() function back as false without doing any checks. I assume I will need to customize this to almost wait until the button is pressed, but I really have no idea how to do that.
b) $(selected_form+" :input").each(function() { ... } does not work as it appears to not be able to use that as a selected. I need to iterate through the "selected_form" property and select only the :input fields. Any assistance?
c) If you have any other suggestions or best practices for me regarding building a proper jQuery function please assist, this is my first attempt and I would rather learn the best practices now as appose to following my own ideas.
(function($) {
$.fn.validator = function(user_options) {
var default_options = {
exclusions: false,
rules: false,
submit_btn_name: 'event_form_submit'
};
var selected_form = this;
var selected_element = false;
var element_type = false;
var options = $.extend(default_options,user_options);
function validate() {
// Run only if form has been submitted: (this does not appear to work now, the form gets submitted without the return false;
$("input[type='"+options.submit_name+"']").click(function(event) {
event.preventDefault();
// The selector here appears to be wrong?
$(selected_form+" :input").each(function() {
// Individual element validation will happen here, for now I am just looking to log the element types :)
selected_element = this;
console.log(get_element_type());
});
return false;
});
return false;
};
function get_element_type() {
return element_type = element.type;
}
return validate();
}
})(jQuery);
// Run the validator:
$(document).ready(function() {
$("form[name='tepg_form_processor']").validator();
});
As jalynn2 and others have mentioned, my selector was incorrect. Fixed and working :)

Find out if html form has changed

Using jquery I've added a change handler to a form.
This works when any input is changed BUT only if the user manually changes an input and not when some other code changes the input.
Is there any way to detect if a form has changed even if its inputs are changed by code?
Yes, there seems to be some confusion over this. In an ideal world you would expect the onchange event to happen whenever the inputs change but thats not what happens. I'm sure for good reasons to - maybe not.
One way I've overcome this obstacle is to capture the form state into a variable just after displaying it and then just before submitting it to check if the state has changed and to act accordingly.
An easy state to store is what the serialize function returns. An easy place to store the state is using the data functionality. Both serialize and data are available with jquery.
Of course you can use other different forms of state (some form of hash) or storage for this state (standard global variable for example).
Here is some prototype code:
If your form id is 'xform' then you can call the following code when the form has displayed:
$('#xform').data('serialize',$('#xform').serialize());
And then, when you need to check, for example just before a button submit you can use:
if($('#xform').serialize()!=$('#xform').data('serialize')){
// Form has changed!!!
}
You could wrap all this up into a copy & paste javascript snippet that will give you a formHasChanged() function to call wherever you need it (NOT TESTED):
$(function() {
$('#xform').data('serialize',$('#xform').serialize());
});
function formHasChanged(){
if($('#xform').serialize()!=$('#xform').data('serialize')){
return(true);
}
return(false);
}
But I'll stop here otherwise I'll create yet another jquery plugin.
Serializing the form is certainly an option, but it will not work if:
you want to know which fields have changed
it only needs to check a subset of the fields
dynamically adding or removing fields.
Fortunately, every form element has a default value associated with its object:
input, textarea : defaultValue
checkbox, radio : defaultChecked
select: defaultSelected
for ex: to ckeck if input or textarea has changed:
var changed = false;
$(":text,textarea").each(function(){
changed = this.value != this.defaultValue;
return !changed; // return if at least one control has changed value
});
This is easily achieved in JavaScript without jQuery. initChangeDetection() can be called multiple times:
function initChangeDetection(form) {
Array.from(form).forEach(el => el.dataset.origValue = el.value);
}
function formHasChanges(form) {
return Array.from(form).some(el => 'origValue' in el.dataset && el.dataset.origValue !== el.value);
}
Test on JS Bin
For older browsers that don't support newer arrow/array functions:
function initChangeDetection(form) {
for (var i=0; i<form.length; i++) {
var el = form[i];
el.dataset.origValue = el.value;
}
}
function formHasChanges(form) {
for (var i=0; i<form.length; i++) {
var el = form[i];
if ('origValue' in el.dataset && el.dataset.origValue !== el.value) {
return true;
}
}
return false;
}
Not in a regular way.
You can change with input and then trigger the change event.
$('#inputId').val('foo').trigger('change');
or with this:
$('#inputId').val('foo').change();
Here is what i did (i found my solution using zaf's answer)
$("form").change(function() {
$(this).data("changed","true");
});
$("input[type='submit']").click(function() {
if($("form").data("changed") == "true") {
var discard = confirm("Some unsaved changes. Discard them ?");
if(!discard) return false;
}
});
Try onchange attribute
According to W3c it should trigger anytime the content of an element, the selection, or the checked state have changed.

How to validate a form with jQuery?

I tried to find the answer in other questions but actually nothing worked -.- Somehow I hate JavaScript ... Anyway! My Code looks like:
function validate()
{
if ($(":input").length == 0)
{
$(":input").addClass("notvalid");
return false;
}
else
{
$(":input").removeClass("notvalid");
return true;
}
return true;
}
$(":input").blur(validate());
$(":input").keyup(validate());
$("#customForm").submit(function(){
if(validate()){
return true;
}
else
{
return false;
}
});
I just want to test every tag to be not empty. The test should be done when the focus is lost or after every key type. And of course after the submit button has been clicked.
It doesn't work. Firefox error console says something like: unknown pseudoclass or pseudoelement 'input'. What does this mean?
You can alway use AJAX to validate your fields if you are more familiar with server side scripting like PHP.
Back to JS here what i think you want to accomplish:
$("input:text").bind("blur, keyup", function(){
if($(this).val().length > 0){
//Valid not empty
$(this).removeClass("notvalid");
}else{
//invalid empty
$(this).addClass("notvalid");
}
});
$("#customForm").submit(function(){
$("input:text").keyup(); //triggers the keyup event on input fields
//which then validates your fields according the
//code above.
if($("form .notvalid").length > 0){
//You got some invalid fields in form
return false;
}else{
//All fields are valid continue
return true;
}
});
it may look a whole different then your approach but if you want to learn jQuery is better to get familiar with it. I commented some of the process, but if you have any doubt of the methods or functions used in code above you just google it. Good Luck!
The error says the jQuery doesn't know what elements to select with :input. Just replace :input but input:text in your selectors. You could also take a look at the jquery.validate plugin which will simplify your validation logic. There are many demos on the site that should help you get started.
UPDATE:
My mistake. There's :input selector according to the documentation.
Instead of:
function validate()
{
if ($(":input").length == 0)
{
$(":input").addClass("notvalid");
return false;
}
else
{
$(":input").removeClass("notvalid");
return true;
}
return true;
}
Use:
function validate()
{
$(":input").each(function(){
if ($(this).val() === '')
{
$(this).addClass("notvalid");
return false;
}
else
{
$(this).removeClass("notvalid");
return true;
}
});
return true;
}
If your using jQuery already you should really use jquery.validate plugin like Darin said.
This will make you code much cleaner and easier to add standard validation rules like valid email, URL, min length, max length etc. Also removes the need of having to add and remove classes at does it for you.

Categories

Resources