Reputation: 355
I have separated JS functions from different web pages (index, login, register and others) into their own JS files which are then imported to the main JS file, that includes functions that are shared across more than one page. I have done this for the purpose of maintenance and readability of code (I hope), otherwise I would have hundreds of lines of code in one file.
login.js
export function loginSubmit() {
$("#login-form").submit(function (event) {
event.preventDefault();
event.stopPropagation();
let formValid;
$("#login-form input").each(function () {
if ($(this).val() === "") {
fieldInputInvalid($(this));
formValid = false;
}
});
if (formValid !== false) {
// submit the form for authentication
}
});
}
register.js
export function loginSubmit() {
$("#register-form").submit(function (event) {
event.preventDefault();
event.stopPropagation();
let formValid;
// other form validation functions (not shown as not necessary to post)
$("#register-form input").each(function () {
if ($(this).val() === "") {
fieldInputInvalid($(this));
formValid = false;
}
});
if (formValid !== false) {
// submit the form for user registration
}
});
}
main.js
// import all functions from these js files
import * as login from "../scripts/login.js";
import * as register from "../scripts/register.js";
// general functions used on more than one page
function fieldInputInvalid(inputField) {
// Changes styling of inputField to display to user that it is invalid.
}
function fieldInputValid(inputField) {
// Changes styling of inputField to display to user that it is valid.
}
function createElement(elemName, elemAttributes) {
// Create document element
var elem = document.createElement(elemName);
// Check if element attirbutes were passed
if (elemAttributes !== "undefined") {
// Loop through each argument
$.each(elemAttributes, function (key, value) {
// and assign it to the document element
elem.setAttribute(key, value);
});
}
// Return document element
return elem;
}
As you can see from my code samples, both the login.js and register.js functions call the function fieldInputInvalid() from main.js, however, I get the Uncaught ReferenceError: fieldInputInvalid is not defined
error when either forms are submitted. I know that I can get around this by putting the fieldInputInvalid function into both login.js and register.js, but I thought this would break the do not duplicate code rule. Is there a way to get this to work with my current structure or a better way to achieve the result I desire?
(NOTE: I have many other general functions that are not included in this post that would be used across my website. I am aware that I could put the code from login.js and register.js together into one file named identity.js with the fieldInputInvalid and fieldInputValid functions and then export, but this would not solve any of the other general functions that are included in my project.
Upvotes: 1
Views: 421
Reputation: 370779
Declare fieldInputInvalid
in its own file, and then have login
and register
import it:
// fieldInputInvalid.js
export const fieldInputInvalid = () => {
// ...
}
// login.js
import { fieldInputInvalid } from './fieldInputInvalid';
// ...
Another option would be, whenever loginSubmit
is called, pass it the fieldInputInvalid
function, if you can, eg:
loginSubmit(fieldInputInvalid);
// login.js (and register.js):
export function loginSubmit(fieldInputInvalid) {
// ...
Then you'll be able to call fieldInputInvalid
inside loginSubmit
.
If you have multiple shared functions and you don't want to pass each one individually, you could also pass an object of functions to all loginSubmit
s, like:
loginSubmit({ fieldInputInvalid, someOtherHelper });
// login.js (and register.js):
export function loginSubmit({ fieldInputInvalid, someOtherHelper }) {
// ...
Upvotes: 1