Kyle Underhill
Kyle Underhill

Reputation: 109

jQuery - Append/ Remove input or button value to list if checked / clicked

I want to append the span to the list if it is the selected input, but then replace it with the next selected input, and if none, completely remove it.

I tried to assign a unique id tag to tell what input group the selection belongs to so that it only replaces/removes the tag from that group:

var sort_key = "sort-" + span;

And then used append and remove to target the tags from that group:

  if ($(this).is(":checked")) {
  $keys.append("<span id='" + sort_key + "'>" + span + "</span>"); // Append the div from out of the loop
} else {
  if ($keys.has("#" + sort_key)) {
    $("#" + sort_key).remove();
  }
}

The span tags are being added, but my remove function isn't replacing the tags with the next selected value, only appending it again. How do I fix the remove(); function so that a span tag is appended given the input selection, and then replaced by the next selected input (or removed if unchecked).

Is there a way to create one function to handle append / remove of the tags instead if iterating for every on.change or on.click?

$(document).ready(function() {
  var allRadios = $("#radios input[type='radio']");
  $(allRadios).change(function() {
    var span = $(this)
      .closest("label")
      .find("input")
      .attr("value")
      .trim();

    var sort_key = "sort-" + span;
    var $keys = $('input[type="radio"]:checked')
      .closest(".all")
      .find(".selections");

    if ($(this).is(":checked")) {
      $keys.append("<span id='" + sort_key + "'>" + span + "</span>"); // Append the div from out of the loop
    } else {
      if ($keys.has("#" + sort_key)) {
        $("#" + sort_key).remove();
      }
    }
    console.log(span);
  });
  var allCheckboxes = $("#checkboxes input[type='checkbox']");
  $(allCheckboxes).change(function() {
    var span = $(this)
      .closest("label")
      .find("input")
      .attr("value")
      .trim();

    var sort_key = "sort-" + span;
    var $keys = $('input[type="checkbox"]:checked')
      .closest(".all")
      .find(".selections");

    if ($(this).is(":checked")) {
      $keys.append("<span id='" + sort_key + "'>" + span + "</span>"); // Append the div from out of the loop
    } else {
      if ($keys.has("#" + sort_key)) {
        $("#" + sort_key).remove();
      }
    }
    console.log(span);
  });
  $(".button").click(function() {
    var span = $(this)
      .text()
      .trim();
    var $keys = $(this)
      .closest(".all")
      .find(".selections");
    $keys.find("span").remove("#" + span);
    $keys.append("<span id='" + span + "'>" + span + "</span>");
    console.log(span);
  });
});
.selections {
  display: flex;
  algin-items: center;
  height: 40px;
}

.selections span {
  padding: 9px;
  min-height: 20px;
  border-radius: 6px;
  background: blue
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="all">
  <div class="selections">Selections Here:</div>
  <div id="radios">
    <label>
      <input type="radio" name="sort" id="up" value="Up">
         <span>Up</span>
    </label>
    <label>
      <input type="radio" name="sort" id="down" value="Down">
         <span>Down</span>
    </label>
    <label>
      <input type="radio" name="sort" id="sideways" value="Sideways">
      <span>Sideways</span>
    </label>
  </div>
  <div id="checkboxes">
    <label>
      <input type="checkbox" name="check" id="food" value="Food">
         <span>Food</span>
    </label>
    <label>
      <input type="checkbox" name="check" id="drink" value="Drink">
         <span>Drink</span>
    </label>
    <label>
      <input type="checkbox" name="check" id="snack" value="Snack">
      <span>Snack</span>
    </label>
  </div>
  <div id="buttons">
    <button class="button cat-button" data-filter="animals">Animals</button>
    <button class="button cat-button" data-filter="shapes">Shapes</button>
    <button class="button cat-button" data-filter="colors">Colors</button>
  </div>
</div>

Upvotes: 1

Views: 65

Answers (1)

zer00ne
zer00ne

Reputation: 43880

Not 100% sure what OP objective is so here's an outline of what I understand it to be:

  1. Three groups of inputs each a different [type]


    • Each group is placed within its own <fieldset>.
    • Each input is assigned a class that indicates which group it belongs to.

      • .rad for radio buttons
      • .chk for checkboxes
      • .btn for buttons
    • The <button> tags are now <input type='button'> in order to facilitate a cohesive collection process.
  2. When an input is selected, a tag appears above with the input's value and other tags are removed. Here's where it is unclear ... what exactly is removed?

    • Are only the tags from that particular group removed?
    • Are all tags removed regardless of group?
    • Are the tags of the group currently being modified only removed if they are inactive?

    • So I decided to implement #3 since it's the most useful.
    • Added a <section> and nested three <article>s within it. Each article is assigned a class corresponding with a group: .rads, .chks, .btns.

Details are commented in the demo.

$(function() {

  // If any <input> is clicked...
  $('input').on('click', function(e) {

    // Store a htmlString of output.tag in a variable
    var tag = `<output class='tag'></output>`;

    /*
    if input.rad...
    Clear article.rads
    Append a .tag with its value to.rads
    */
    if ($(this).is('.rad')) {
      $('.rads').empty();
      $(tag).appendTo('.rads').val($(this).val());

      /*
      or if its input.chk...
      Clear article.chks
      On each .chk that is checked appand a tag with its
      value to .chks
      */
    } else if ($(this).is('.chk')) {
      $('.chks').empty();
      $('.chk:checked').each(function() {
        $(tag).appendTo('.chks').val($(this).val())
      });

      /*
      but if its input.btn...
      Remove .active class if it has it otherwise add it
      Clear article.btns
      On each button.active append a tag with its value to
      .btns 
      */
    } else if ($(this).is('.btn')) {
      //$(this).toggleClass('active');
      $('.btns').empty();
      // $('.btn.active').each(function() {

      $(tag).appendTo('.btns').val($(this).val())
      //});

      // Otherwise terminate function
    } else {
      return false;
    }
  });

});
.sel {
  display: flex;
  flex-flow: row wrap;
  justify-content: center;
  height: 40px;
  background: rgba(100, 100, 100, 1);
}

.sel .tag {
  display: inline-block;
  padding: 9px;
  min-height: 20px;
  width: fit-content;
  border: 1px solid white;
  border-radius: 6px;
  color: white;
}

.rads .tag {
  background: red;
}

.chks .tag {
  background: green;
}

.btns .tag {
  background: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<form id='all'>

  <section class='sel'>
    <article class='rads'></article>
    <article class='chks'></article>
    <article class='btns'></article>
  </section>
  <fieldset class='radio'>
    <legend>Radio Buttons</legend>
    <input id="r1" class='rad' name="rad" type="radio" value="1">
    <label for='r1'>1</label>

    <input id="r2" class='rad' name="rad" type="radio" value="2">
    <label for='r2'>2</label>

    <input id="r3" class='rad' name="rad" type="radio" value="3">
    <label for='r3'>3</label>
  </fieldset>

  <fieldset class='check'>
    <legend>Checkboxes</legend>
    <input id='c4' class='chk' name="chk" type="checkbox" value=" 4 ">
    <label for='c4'>4</label>

    <input id='c5' class='chk' name="chk" type="checkbox" value=" 5 ">
    <label for='c5'>5</label>

    <input id='c6' class='chk' name="chk" type="checkbox" value=" 6 ">
    <label for='c6'>6</label>
  </fieldset>

  <fieldset class='button'>
    <legend>Buttons</legend>
    <input id='b7' class='btn' name="btn" type='button' value=" 7 ">

    <input id='b8' class='btn' name="btn" type='button' value=" 8 ">

    <input id='b9' class='btn' name="btn" type='button' value=" 9 ">
  </fieldset>

</form>

Upvotes: 1

Related Questions