Home > Enterprise >  Getting jQuery to push a value from an 'a' link
Getting jQuery to push a value from an 'a' link

Time:05-02

Hoping this is fairly simple and I've just overlooked something...

I currently have a page with a bunch of checkbox options. Each checkbox will execute a very simple script adding its value to a string, where it then gets passed over to PHP to do the rest.

The html part for the checkboxes looks like this (repeated for multiple years):

<input type="checkbox" value="2017"  onclick="filterdb()" />2017

And the script looks like this:

var year = [];
       
$('.value_year').each(function(){  
            if($(this).is(":checked"))  
            {  
                 year.push($(this).val());  
            }  
       });  

year = year.toString();

This works perfectly for a checkbox. However, I'm giving the site a makeover now and want to replace checkboxes with regular 'a' links, that I've styled up in CSS to look much prettier when selected/unselected. The problem is I can't figure out how to replicate the behaviour of the script when clicking the link as opposed to checking a checkbox.

The html for the new link looks like this:

<a class='filter value_year' id='filter2017' value='2017' onclick='filterdb()' href='javascript:void(0);'>2017</a>

Is there a simple way to adapt the script to work here?

Many thanks

CodePudding user response:

If you insist on using <a> elements as your option switches (see @RobinZigmond and my comments above) then maybe this might be helpful:

var year = [];

document.querySelectorAll("a.value_year").forEach(l=>l.onclick=ev=>{
  ev.preventDefault();
  l.classList.toggle("checked");
  console.log([...document.querySelectorAll("a.value_year.checked")].map(l=>l.getAttribute('href')).join(","));

})
.checked {color:red}
<a class='filter value_year' href='2017'>2017</a> 
<a class='filter value_year' href='2018'>2018</a> 
<a class='filter value_year' href='2019'>2019</a>
<a class='filter value_year' href='2000'>2020</a>

The click handler for the a.value_year elements does two things:

  • it sets the checked class for the clicked element
  • it loops over all a.value_year.checked elements and collects all their .href attribute values into an array.

CodePudding user response:

Don't use an <a>nchor, value isn't supported, it's type of interaction is different than a form control, stick to what you already have. Just hide the checkboxes (they are pain to style) and add a <label> for each checkbox.

In the example below, each <label> is associated to the <input> positioned before it. When a <label> is associated with an <input>, the <label> becomes an extension to the <input> -- clicking the <label> causes the associated <input> to act as it was clicked as well. This association is enabled by assigning the <label> the following:

<label for="ID_of_input_it_is_associated_with"></label>

The JavaScript can stay as it is, in the example, it is modified as an event handler for demo purposes, but there's no harm in using it if it actually serves your purposes.

CSS has details commented in example. Note: hiding checkboxes and a few other rulesets are valid but they are not good for accessibility. Seeing that you're new to this facet, that concern is probably not a factor yet.

let years = [];

$('.year').on('change', function() {
  years.length = 0;
  $('.year').each(function() {
    if ($(this).is(':checked')) {
      years.push($(this).val());
    }
  });
  console.log(years.toString());
});
/* ✣ Not good for accessability */
html {
  font: 2ch/1.25 Consolas
}

/* Each checkbox is hidden ✣ */
.year {
  display: none;
}

label {
  display: inline-block;
  font: inherit;
  margin: 2px;
  padding: 2px 4px;
  color: navy;
  border: 1px groove rgba(129, 129, 129, 0.3);
  border-radius: 6px;
  cursor: pointer;
  box-shadow: rgba(0, 0, 0, 0.07) 0px 1px 1px, rgba(0, 0, 0, 0.07) 0px 2px 2px, rgba(0, 0, 0, 0.07) 0px 4px 4px, rgba(0, 0, 0, 0.07) 0px 8px 8px, rgba(0, 0, 0, 0.07) 0px 16px 16px;
  /* 
  These two rules remove the
  highlighting for Chrome and
  Android ✣
  */
  -webkit-tap-highlight-color: transparent;
  user-select: none;
}

/*
The " " means apply styles to <label>
if there is a ".year" that is ":checked" 
positioned before it.
Google "adjacent sibling combinator"
*/
.year:checked label {
  color: cyan;
  background: #000;
}

.year:checked label:hover {
  color: lightblue;
  background: rgba(0,0,0,0.5);
}

label:hover,
label:active {
  color: white;
  background: rgba(51, 51, 51, 0.4);
}

label:active {
  transform: scale(0.90);
  transform-origin: center;
  transition: all 0.3s ease-out;
}

/* Remove Chrome blue outline ✣ */
:focus {
  outline: none !important;
}

/*
Demo purposes only -- styles for console
*/
.as-console-row::after { width: 0; font-size: 0; }
.as-console-row-code { width: 100%; word-break: break-word; }
.as-console-wrapper { max-height: 50% !important; max-width: 100%; }
<input id='chx1' class='year' type='checkbox' value='2017'>
<label for='chx1'>2017</label>

<input id='chx2' class='year' type='checkbox' value='2018'>
<label for='chx2'>2018</label>

<input id='chx3' class='year' type='checkbox' value='2019'>
<label for='chx3'>2019</label>

<input id='chx4' class='year' type='checkbox' value='2020'>
<label for='chx4'>2020</label>

<input id='chx5' class='year' type='checkbox' value='2021'>
<label for='chx5'>2021</label>

<input id='chx6' class='year' type='checkbox' value='2022'>
<label for='chx6'>2022</label>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

  • Related