DEV Community

Cover image for How I made a mini filter app with Vanilla JavaScript
Raquel Santos | RS-coding
Raquel Santos | RS-coding

Posted on

How I made a mini filter app with Vanilla JavaScript

I have been doing the JavaScript30 from Wes Bos and one of the challenges is to change CSS Variables using JS.
I found the challenge so interesting that I decided to try myself and create a mini-filter image app by using the same concept that he used on the challenge.
Also, I decided to go further and made functionality to display an uploaded image and then change it with the filters available.

I will show you step by step what I did. You can check the Demo and full code here github.

First of all, I sketched what I wanted to look like in the end to help me trace a path.
sketch

Having the sketch done I created an HTML file with elements I wanted. As you can see I write a div container with 3 divs inside:

  • header-container - for the title and uploading icon,
  • img-container - for the displayed image,
  • controls - for the filters controls.

HTML structure

How To Display Uploaded Image In Html Using Javascript

Let's focus first on how to display an uploaded image. So let's take a look at the two first containers.

HTML structure

Inside header-container I created a div called upload-img that contains label and input elements.
The input has some attributes :

  • type='file' because we want to add a file
  • accept=' image/*' that takes as a value all the type of files permitted to upload (* - global). If we wanted only permit jpg files we would have to write accept='image/jpg'.
  • style='display: none;' because I wanted to show only the icon on the label instead of the input.

On the div img-container I added an img HTML tag without a source attribute but an id named "output" that will retrieve the image source from javaScript.
It's time to do JavaScript code to display the image in HTML element img :

JavaScript code

The first thing I did was to get the element input from the DOM and stored it in a variable named fileUpload.
Further, I added an event listener with event change and a function called loadFile.
Inside the loadFile function, I get the element img from DOM and store it in a variable called img ( you could call it an image or something else. I decided to call the same name as the tag).
After that, I created a source URL for that variable img that by using URL.createObjectURL(), a static method that creates a string containing URL representing the specific file inside the parameters that, in this case, is the selected file or files of the input:

e.target is the input type="file"
files[0] represents the file or the files that were selected

This part is Done!

How to change CSS Variables in JavaScript

Inside the third container controls let's just focus on the construction of the input element.
HTML
As you can see in the image there are a couple of Attributes important that I added. let's talk about each one:

  • id - the id of the element (example id="sepia")
  • type ="range" - it is the type of the input. in this case, I wanted a slider control
  • name - it is the name of the specific filter which is the same as the id (example name="sepia")
  • min, max value - min and max are the minima and maximum values the input range has and the value is the default value we want to point to at the beginning. To set the values for the min, max and value attributes for each filter control I researched here [filters characteristics]((https://www.w3schools.com/cssref/css3_pr_filter.asp)
  • data-sizing="%" - it is a custom attribute that has as value an % because all filters that I will use in CSS end with percentage.

Let's take a look at CSS file :
CSS file
Here I created CSS variables in the : root pseudo-class and added those named variables in the img element.

Now its time to code in JavaScript:

JavaScript

First of all, I stored in a variable all the inputs(plural).
Then I wanted to make an event listener for each input(individual) with change and input event.
So I did a forEach loop at the 'inputs' variable to get each input and add the event listener.

Why did I want to use two events and not just the first one change?
Because the change event only updates the result when the movement ended, and I wanted also to show changes in the image while I move the input range.

In the updateStyle function first, I made a variable called suffix that stores the value '%' of data-sizing or if there are none stores an empty string ' '.
After that, I set a new property value for the root element that takes the value of the input.

That is it!

Latest comments (2)

Collapse
 
madsstoumann profile image
Mads Stoumann • Edited

CSS filters are awesome – and kudos for doing it in Vanilla! A small tip: You can wrap your inputs in a <form> and have a single eventListener, instead of individual eventListeners on all the inputs.

If you set the name of the property in the name-attribute:

<form id="app">
  <input type="range" name="--blur" data-suffix="px">
  <input type="range" name="--hue-rotate" data-suffix="deg">
</form>
Enter fullscreen mode Exit fullscreen mode

You only need this snippet, in order to set any of the CSS Custom Properties:

app.addEventListener('input', (event) => {
  const input = event.target;
  app.style.setProperty(input.name, input.valueAsNumber + (input.dataset.suffix||''))
})
Enter fullscreen mode Exit fullscreen mode
Collapse
 
raquelsartwork profile image
Raquel Santos | RS-coding

Thank you so much for your tip! :D will do that