RRP
RRP

Reputation: 2853

Filtering content based on year

I have three buttons in my layout, which lets the user filter the content accordingly to the year selected. The buttons look as the following

 2019      2018      2017 or berfore

The main data is array of an objects which looks like

const data = [
   {
     .....
     year: "2018"
   },
   {
     .....
     year: "2017"
   },
   {
     .....
     year: "2016"
   },
   {
     .....
     year: "2019"
   },
   {
     .....
     year: "2015"
   },

]

I am able to filter the content for buttons 2019 and 2018. But when the user picks 2017 or before it needs to filter content for the year 2017 and any previous year.

My code at the moment

data.filter(val => val.year === pickedYear) //filter data by year
.map(...) // do more based on filtered data

Any suggestions on how to handle the use case for 2017 or before?

Upvotes: 0

Views: 127

Answers (3)

vol7ron
vol7ron

Reputation: 42109

Here's an example of something that's a little more robust, based on the current year. Of note it includes newer/lesser-used mechanics of the language, including:

It also doesn't use jQuery, though browser-compliance will vary. This isn't a complete solution, but is intended to help demonstrate the potential of where things could go:

const buttons = document.querySelectorAll('.btn.filter')
const buttonDetails = buttonGen(buttons.length) // use generator for dynamic button

// Create Buttons (text, event, value, etc)
buttons.forEach(el => {
  let data = buttonDetails.next().value
  el.value = data.value
  el.textContent = data.text
  // set button text based on 'value'
  el.addEventListener('click', filterData) // add click handler
})


// Button Click function
function filterData() {
  let button = this;
  let btn_year, op;

  if (isNaN(button.textContent)) {
    btn_year = button.value
    op = '<='
  } else {
    btn_year = button.value
    op = '=='
  }

  let data = fetchData()

  filtered_data = data.filter(data => eval(`${data.year} ${op} ${btn_year}`))
  console.log(JSON.stringify(filtered_data));
  return filtered_data
}


// Some function will most likely be an AJAX-fetch
function fetchData() {
  return [{
      year: "2018"
    },
    {
      year: "2017"
    },
    {
      year: "2016"
    },
    {
      year: "2019"
    },
    {
      year: "2015"
    }
  ]
}


// Button Info Generator
function* buttonGen(button_count) {
  const current_year = (new Date).getFullYear();
  let year = current_year
  while (true) {
    if (year <= current_year - button_count + 1)
      yield {
        text: 'earlier',
        value: year
      }
    else
      yield {
        text: year,
        value: year
      }

    year--
  }
}
button {
  text-transform: capitalize
}
<button class="btn filter"></button>
<button class="btn filter"></button>
<button class="btn filter"></button>

Upvotes: 0

ic3b3rg
ic3b3rg

Reputation: 14927

We can take advantage of type coercion:

const data = [
   {
     year: "2018"
   },
   {
     year: "2017"
   },
   {
     year: "2016"
   },
   {
     year: "2019"
   },
   {
     year: "2015"
   }
];

const filterByYear = yearFilter => data.filter(({year}) => yearFilter > 2017 ? year == yearFilter : year < 2018);

console.log(filterByYear('2019'));
console.log(filterByYear('2018'));
console.log(filterByYear('2017 or before'))

Upvotes: 1

Ben
Ben

Reputation: 2706

Try something like this:

const pickedYear = "2017";
const data = [
    {
      year: "2018"
    },
    {
      year: "2017"
    },
    {
      year: "2016"
    },
    {
      year: "2019"
    },
    {
      year: "2015"
    }
];

const filteredData = data.filter((data) => {
    return parseInt(pickedYear) > 2017 ? data.year === pickedYear : parseInt(data.year) <= 2017;
});

console.log(JSON.stringify(filteredData));

Upvotes: 1

Related Questions