"Transforming portfolio photos from black & white to vibrant color with the click of a filter button

I'm currently working on creating a portfolio that includes button filters to toggle between black and white images and colored images based on the category selected.

While I have successfully implemented the functionality to change the images to black and white, I am facing an issue where the active state of the button does not persist after clicking it. Additionally, I am struggling to remove the black and white filter from the images within the selected category.

I suspect there might be an error in my code snippet as it is displaying an error message.

var container = document.getElementById('filters-button-group');

container.addEventListener('click', event => {

  var activeItem = container.querySelector('.button-selected');

  if (activeItem !== null) {
    activeItem.classList.remove('button-selected');
  }

  if (event.target === activeItem) {
    return;
  }

  event.target.classList.add('button-selected');
  $('#img').css('filter', 'none');
});
button {
  /* Button Styles */
    border: 4px solid green;
    border-top: 0;
    border-right: 0;
  font-size: 10px;
  text-decoration: none;
  color: green;
  display: block;
  margin-bottom: 22px;
}

.button:active,
.button-selected {
  /* Selected Button Style */
  background: rgba(8, 140, 126, 50%);
  border: 4px solid green;
}

#portfolio { /* Positioning for Portfolio Section with Buttons */
    text-align: center;
    background: transparent;
    position: absolute;
}

#portfolio img {
  /* Black and White Image Filter */
  filter: grayscale(100%) opacity(30%);
}
<section id="portfolio">

<div class="button-group filters-button-group">

  <button class="button button-effect" data-filter=".A"><a href="#" class="opc-main-bg filter" >A</a></button>
  <button class="button button-effect" data-filter=".B"><a href="#" class="opc-main-bg filter" >B</a></button>
  <button class="button button-effect" data-filter=".C"><a href="#" class="opc-main-bg filter" >C</a></button>
  <button class="button button-selected" data-filter="*"><a href="#" class="selected opc-main-bg filter">ALL</a></button>

</div>

<div
<div class="A"><img src="http://fakeimg.pl/365x365/ff0000/" width="50%" height="auto">
  <div class="B"><img src="http://fakeimg.pl/365x365/ff0000/" width="50%" height="auto">
    <div class="C"><img src="http://fakeimg.pl/365x365/ff0000/" width="50%" height="auto">
    
</section>

Answer №1

It's recommended to use

 document.getElementsByClassName('filters-button-group')
instead of
document.getElementById('filters-button-group')
because filters-button-group is a class, not an id. By using `getElementsByClassName`, you can access its children as an array.

For more information, you can refer to the following link: https://www.w3schools.com/jsref/met_document_getelementsbyclassname.asp

Answer №2

This scenario showcases a unique approach where the initial two images belong to group "A" while the remaining photos are part of another group. Upon clicking a button, the code gathers all image tags associated with the specific category denoted in the "data-filter" attribute of the button and subsequently modifies their style.

var container = document.querySelectorAll('.filters-button-group .button');

for (let i = 0; i < container.length; i++) {
    container[i].addEventListener('click', function () {
        this.classList.toggle('button-selected');
        var x = document.querySelectorAll(this.getAttribute('data-filter') + ' img');
        var y = x[0].getAttribute('style');
        if (y) {
            for (var i = 0; i < x.length; i++) {
                x[i].removeAttribute('style');
            }
        } else {
            for (var i = 0; i < x.length; i++) {
                x[i].setAttribute('style', 'filter:none');
            }
        }
    });
}

// Button All -> add / remove effect on all images
var allFilterButt = document.querySelector('.filters-button-group .button-all');
var wrap = document.querySelector('#imgWrap');
var imgList = wrap.querySelectorAll('img');

allFilterButt.addEventListener('click', function () {
    var x = wrap.getAttribute('data-eff');
    if (x === 'off') {
        for (var i = 0; i < imgList.length; i++) {
            imgList[i].setAttribute('style', 'filter:none');
        }

        for (var i = 0; i < container.length; i++) {
            container[i].classList.add('button-selected');
        }

        wrap.setAttribute('data-eff', 'on');
    } else {
        for (var i = 0; i < imgList.length; i++) {
            imgList[i].removeAttribute('style');
        }

        for (var i = 0; i < container.length; i++) {
            container[i].classList.remove('button-selected');
        }

        wrap.setAttribute('data-eff', 'off');
    }
});
button {
    /* BUTTON SET UP */
    border: 4px solid green;
    border-top: 0;
    border-right: 0;
    font-size: 10px;
    text-decoration: none;
    color: green;
    display: block;
    margin-bottom: 22px;
}

.button:active,
.button-selected {
    /* SELECTED */
    background: rgba(8, 140, 126, 50%);
    border: 4px solid green;
}

#portfolio {
    /* POSITION TOTAL PORTFOLIO ZONE WITH BUTTONS */
    text-align: center;
    background: transparent;
    position: absolute;
}

#portfolio img {
    /* --- IMAGES BLACK AND WHITE --- */
    filter: grayscale(100%) opacity(30%);
}
<section id="portfolio">
    <div class="button-group filters-button-group">
        <button class="button button-effect opc-main-bg filter" data-filter=".A">A</button>
        <button class="button button-effect opc-main-bg filter" data-filter=".B">B</button>
        <button class="button button-effect opc-main-bg filter" data-filter=".C">C</button>
        <button class="button button-effect opc-main-bg filter" data-filter=".D">D</button>
        <button class="button button-effect opc-main-bg filter" data-filter=".E">E</button>
        <button class="button-all button-selected opc-main-bg filter selected" data-filter="*">ALL</button>
    </div>

    <div id="imgWrap" data-eff="off">
        <div class="A"><img
                src="https://blog.54ka.org/wp-content/uploads/2020/08/horses-on-summer-meadow_027_by_54ka.jpg"
                width="50%" height="auto"></div>
        <div class="A"><img
                src="https://blog.54ka.org/wp-content/uploads/2020/08/horses-on-summer-meadow_034_by_54ka.jpg"
                width="50%" height="auto"></div>
        <div class="B"><img
                src="https://blog.54ka.org/wp-content/uploads/2020/08/horses-on-summer-meadow_028_by_54ka.jpg"
                width="50%" height="auto"></div>
        <div class="C"><img
                src="https://blog.54ka.org/wp-content/uploads/2020/08/horses-on-summer-meadow_030_by_54ka.jpg"
                width="50%" height="auto"></div>
        <div class="D"><img
                src="https://blog.54ka.org/wp-content/uploads/2020/08/horses-on-summer-meadow_031_by_54ka.jpg"
                width="50%" height="auto"></div>
        <div class="E"><img
                src="https://blog.54ka.org/wp-content/uploads/2020/08/horses-on-summer-meadow_032_by_54ka.jpg"
                width="50%" height="auto"></div>
    </div>
</section>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

ERROR: mammoth has not been declared

I've been attempting to integrate the mammoth npm library with my Meteor project. When using the import command, import { mammoth } from "mammoth";, I encountered Uncaught TypeError: Cannot read property 'bind' of undefined After trying ...

How can I set up an automatic refresh for an angularjs iframe?

This code utilizes Angularjs and is designed to be run on a localhost server. The first part of the code can be found in index.html: <iframe src="{{Url}}" width="100%" height="500"></iframe> The second part of the code is located in app.js: ...

Dealing with numerous file uploads: At what point does the array update when you add an item to it?

I am facing an issue with creating a file input that allows for multiple CSV files to be uploaded simultaneously. Each file goes through data cleaning functions and is then added to a global array. However, the array does not seem to update even though it ...

Error encountered during installation of lite-server using `npm install lite-server --save-dev

Recently, I decided to give Node.js a try for the first time. After installing node.js, here is the version information: node -v v14.4.0 npm -v 6.14.5 I proceeded with the setup by creating a package.json file. However, when attempting to install lite-se ...

Retrieving data from an HTML Table using Javascript

I am in the process of designing a dynamic web form that populates from a stored procedure. The form consists of a table with a dropdown list, a text box, and a label. While I can successfully retrieve data from the dropdown and text box, I am facing diffi ...

Extracting JSON data from a string using jQuery

http://localhost/project1/index.php //AJAX region $(function(){ $.ajax({ type : 'GET', url : 'https://jsonplaceholder.typicode.com/posts/1', success : function(data){ console.log('success \n', data); }, error ...

How to toggle between arrays using ng-repeat

Currently, I am managing 3 arrays and wish to toggle between them using ng-repeat: $scope.fooDataObj = { array1:[{name:'john', id:'1'},{name:'jerry', id:'2'}], array2[{name:'bill', id:'1'},{name: ...

The controls for the HTML audio component are missing the download option on Safari

In my React application, I've declared an audio component with controls like the following: <audio controls> <source src={url} /> </audio> While this setup works perfectly in most browsers, it seems to have a bug when used in Safa ...

What could be the reason behind my Javascript code returning "object object"?

I am a beginner with jQuery. I attempted to calculate the sum of items from my django views using jQuery. Here's what I have so far: $(document).ready(function() { var sch = $('#sch-books'); var gov = $('#gov-books'); ...

How can I retrieve the id of a Jquery Object (this) in a JavaScript file?

I have been experimenting with a content carousel slider for my project. Everything has been working smoothly so far. However, I now need to include the same slider twice on a single page. To prevent conflicts caused by similar class names used by the Jav ...

Using AJAX to send data from knockout observables to the server in JSON format

I'm currently facing an issue where I am trying to send form fields that are linked to specific observables to my server as a JSON object, but I keep receiving an empty JSON string on the server side. I want to avoid sending the entire view model just ...

Execute a script when a post is loaded on a WordPress page

I am looking to have my jQuery script execute every time a post page is opened or loaded. I tried using echo in the script but it did not work. Where should I place the script to ensure it runs? single.php <script src="https://ajax.googleapis.com/aja ...

Combining the inline JavaScript linting tool ESLint with the popular Airbnb configuration and Facebook

In my current project, I am utilizing ESLint and looking to incorporate Facebook flow. However, I am encountering warnings from ESLint regarding flow type annotations. Within the project root directory, I have both .flowconfig and .eslintrc files present. ...

Using HTML and JavaScript allows for the video URL to seamlessly open in the default video player app on the device

Working on my mediaplayer website, I want to give users the option to choose which app to play their uploaded videos with. So far, I've attempted to implement a button that triggers this action: window.open("video.mkv", '_blank'); Howeve ...

Change background according to URL query

My goal is to dynamically change background images based on a URL parameter, specifically the destination code. With numerous background images available, it's crucial to display the correct one depending on the URL string. For instance, if the URL re ...

Retrieve the text from the outer span excluding any text from the inner elements

I am looking to retrieve specific text from an HTML element using Selenium and Javascript. <span class="myAttribute"> <b>SomeValueToIgnore</b> <span class="ignoreWhatsInside"> <em>ignore_that</em> </span& ...

"Click events on jQuery's cloned elements are not retained when the elements are removed and appended to a container for the second time

Take a look at this fiddle: https://jsfiddle.net/L6poures/ item.click(function() { alert("It's functioning") }) $("#container").append(item) var stored = item.clone(true, true) function add_remove() { $("#container").html("") $("#conta ...

"Chrome's failure to fire the appCache event for HTML5 has left developers scratching

Currently, I am working on an offline website using HTML5. In my JavaScript file, I have written some code for event listeners; however, the events are not being fired. var appCache = window.applicationCache; if (appCache) { appCache.addEventListener ...

Angular has been modified after being verified. The earlier value was 'null'

core.js:6162 ERROR Error: NG0100: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'null'. Current value: '{ When attempting to retrieve the {{dispositionDetails?.metricsData | json}} ...

How to update an array in Angular using ngModel and ngFor

I am attempting to display an array's values on a form and then allow for updating those same values in the array (using name="todos{{i}}" within the <input> tag does not work as it turns it into a string instead of an array). The curr ...