How I made a mini filter app with Vanilla JavaScript
Tags: devjournal, javascript, codenewbie, 100daysofcode
Published: 2021-06-27 14:03:31

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](https://rs-coding.github.io/FilterImageApp/) and full code here [github](https://github.com/RS-coding/FilterImageApp).

First of all, I sketched what I wanted to look like in the end to help me trace a path.
![sketch](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s5i53g3lm2s1jaakqrpy.jpg)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/apbo72ypk0xgcleqb9b9.jpg)


## 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g93odyksokv0nd32qy5j.jpg)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n517ddgs99p18gao4qkn.jpg)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bws0wp04fdgsmyd5oplb.jpg)
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t6cwrkv1uc0bugifkr1f.jpg)
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w4lyruapcgvpgkiitkls.jpg)

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!