My second Hacktoberfest PR!
Tags: hacktoberfest, opensource, webdev, javascript
Published: 2023-10-25 01:21:10

As I continued to look for repos to contribute to, I found a really cool [website](https://piyushkdas0611.github.io/Profile-Card-Generator/) that generates web profile cards for you based on some entered info.

![Card Gen F](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8rees7y0kvy44wsnwf2q.png)

Here's what the generated cards looked like:

![Generated Cards](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/163dr0a0vg5rhk5fbgre.png)

The project was in a fairly early stage, hence the limited amount of features and designs, but that made it an ideal project for a meaningful contribution.

## Table of Contents
&nbsp;1. [The Issue](#the-issue)
&nbsp;2. [Working on the issue](#working-on-the-issue)
&nbsp;3. [The Pull Request 🎊](#the-pull-request)
&nbsp;4. [Conclusion](#conclusion)

## The Issue

When I was first trying out the tool, I felt a strong itch on seeing the form controls lacked any validation and the user could click on `Generate Card` button only to receive templates for dummy cards with placeholder info.

Since there was no existing issue for this, I decided to open one myself for this enhancement. I asked the maintainer if I could work on it, and got a green flag fairly quickly.


![Partial Issue](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gvq0cbg3qaupd72927fk.png)


Follow this link for more details :
[[Feature] Adding input validations to the form ](https://github.com/piyushkdas0611/Profile-Card-Generator/issues/47)

## Working on the issue

Initially I thought this was going to be a no brainer, as all I had to do was add basic client-side validation to an html form, something you do in your first year.

**Exactly that happened!**

After writing a few lines of code, I was taken back to the good old [WEB222 notes](https://web222.ca/weeks/week11/) from my second semester. Since I had worked on forms using **vanilla js** almost an eternity ago, I was struggling to remember how you did certain basic things like what method you use to check if the form is in a valid state 🤭.

As soon as I got a hang of working with normal forms (no frameworks), I got stuck with a problem with the regular expression I was using to validate urls, even though I copied it from a credible source.

**Here we go again!**

Now I had to revisit [**ULI101**](https://seneca-ictoer.github.io/ULI101/A-Tutorials/tutorial9) notes from semester 1 to make sure how to group regular expressions correctly (using `|`).

After figuring out problems with my regular expression, which was an accidentally copied character, I ended up with these 2 functions listening for any changes in the inputs, and only enabling the `Generate Card` button once all the validation checks passed.

```js
//#region Form Validation

function configureFormValidation() {
  const inputSelector = "input, textarea, select";
  const cardForm = document.getElementById('card-form');
  const controls = cardForm.querySelectorAll(inputSelector);

  controls.forEach(control => {
    control.addEventListener("input", () => {
        generateButton.disabled = !validateForm(); // intersection with custom check
    });
  });

  generateButton.disabled = !validateForm();
}

/**
 * Custom Validation for form inputs
 * 
 * @returns True if all input elements pass validation checks
 */
function validateForm() {
  const cardForm = document.getElementById('card-form');
  let valid = cardForm.checkValidity();

  // Get controls
  const twitterLink = document.getElementById("twitter").value;
  const githubLink = document.getElementById("github").value;
  const linkedinLink = document.getElementById("linkedin").value;

  const links = [twitterLink, githubLink, linkedinLink];
  const validLinkRegex = /^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$/i;

  // Every link should be of valid format and at least one link should not be empty
  valid = valid && links.every(link => validLinkRegex.test(link.trim()) || link.length === 0) && links.some(link => link.trim().length);

  return valid;
}

//#endregion
```

**Note:** I used a very minimialistic regular expression, which could be replaced with a more robust one.

## The Pull Request 🎊

Once I was finished testing the functionality against all possible edge cases I could think of, I opened a [Pull Request](https://github.com/piyushkdas0611/Profile-Card-Generator/pull/48) into the `upstream` main branch explaining all the changes I had made and how the validation worked.

I also pushed a couple more commits to add `*` symbols against required field labels (forgot initally), and refactoring my code to be more concise.

The merge process was really smooth this time, as the maintainer approved the PR, just minutes after I pushed my latest commits.

## Conclusion

All in all, this PR, although not hard, served as a valuable recap of some of the basic concepts from my early college terms.

What I expected would take me no more than **20 minutes**, ended up taking more than **2 hours** of figuring out concepts, debugging and finishing up the enhancement. 

> Working on open source projects is filled with uncertainties. Always start early, and give yourself enough time to recover from unexpected crises.