ttoshiro
ttoshiro

Reputation: 526

How to change the text of a label when clicked without using buttons?

I have a table with collapsible cells that I'd like to change the text of when expanded. Specifically, when the cells are collapsed, a plus sign exists next to the cell text (so as to signal to the user that there is more to see), and the text "(Click to expand...)" is shown. I would like, however, to replace the plus sign with a minus sign when the label is clicked, and to erase the "(Click to expand...)" text.

The issue I am facing is that the minus sign icon and plus sign icon appear together and disappear together, rather than the minus sign replacing the plus sign and vice versa. How would I go about making them replace each other with every collapse/expand?

Below is a working example of a simplified version of my code:

$(document).ready(function() {
  $('.hide').hide();
  $('[data-toggle="toggle"]').change(function() {
    $("label[for='" + this.id + "'] i.fa-plus-circle").toggle();
    $("label[for='" + this.id + "'] i.fa-minus-circle").toggle();
    $("label[for='" + this.id + "'] span").toggle();
    $(this).parents().next('.hide').toggle();
  });
});
[data-toggle="toggle"] {
  display: none;
}

.label {
  display: block;
}

.fa-minus-circle {
  display: none;
}

table,
tr,
th,
td {
  border: 1px solid black;
  border-collapse: collapse;
  font-family: Arial;
  width: 100%;
}
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>

<table>
  <tbody class="section">
    <tr>
      <td colspan="2">
        <label class="label" for="person">
            <i class="fa fa-plus-circle"></i>
            <i class="fa fa-minus-circle"></i>
            <b>Person</b>
            <span class="clicktoexpand">(Click to expand...)</span>
        </label>
        <input type="checkbox" id="person" data-toggle="toggle">
      </td>
    </tr>
  </tbody>

  <tbody class="hide">
    <tr>
      <td class="people">Jack</td>
      <td class="right cell" id="jack">
        <span>0</span>
      </td>
    </tr>

    <tr>
      <td class="people">Jill</td>
      <td class="right cell" id="jill">
        <span>0</span>
      </td>
    </tr>
  </tbody>
  <tbody class="section">
    <tr>
      <td colspan="2">
        <label class="label" for="place">
          <i class="fa fa-plus-circle"></i>
          <i class="fa fa-minus-circle"></i>
          <b>Place</b> 
          <span class="clicktoexpand">(Click to expand...)</span>
        </label>
        <input type="checkbox" id="place" data-toggle="toggle">
      </td>
    </tr>
  </tbody>
  <tbody class="hide">
    <tr>
      <td class="city">LA</td>
      <td class="right cell" id="nyc">
        <span>0</span>
      </td>
    </tr>

    <tr>
      <td class="city">NYC</td>
      <td class="right cell" id="nyc">
        <span>0</span>
      </td>
    </tr>
  </tbody>
</table>

Upvotes: 0

Views: 827

Answers (3)

ezeKG
ezeKG

Reputation: 166

You can put the "(Click to expand...)" inside of a <span> as well as adding "<i class="fa fa-minus-circle"></i>" and hiding it with js. Then just toggle everything along with "<i class="fa fa-plus-circle"></i>"

The finished code:

$(document).ready(function() {
  $('.hide').hide();
  $('.fa-minus-circle').hide(); //This hides the minus button
  $('[data-toggle="toggle"]').change(function() {
  
    //This takes the label of the same id as the input, so we can get their children. Afterwards we toggle everything.
    $("label[for='"+this.id+"'] i.fa-plus-circle").toggle()
    $("label[for='"+this.id+"'] i.fa-minus-circle").toggle()
    $("label[for='"+this.id+"'] span").toggle()

    $(this).parents().next('.hide').toggle();    
    
  });
});
[data-toggle="toggle"]{
  display: none;
}

.label {
  display: block;
}

table,
tr,
th,
td {
  border: 1px solid black;
  border-collapse: collapse;
  font-family: Arial;
  width: 100%;
}
<table>
  <tbody class="section">
    <tr>
      <td colspan="2">
        <label class="label" for="person">
                <i class="fa fa-plus-circle"></i>
                
                <!-- New minus <i> -->
                <i class="fa fa-minus-circle"></i>
                
                <!-- Click to expand inside span <i> -->
                <b>Person</b> <span>(Click to expand...)</span>
              </label>
        <input type="checkbox" id="person" data-toggle="toggle">
      </td>
    </tr>
  </tbody>

  <tbody class="hide">
    <tr>
      <td class="people">Jack</td>
      <td class="right cell" id="jack">
        <span>0</span>
      </td>
    </tr>

    <tr>
      <td class="people">Jill</td>
      <td class="right cell" id="jill">
        <span>0</span>
      </td>
    </tr>
  </tbody>
  <tbody class="section">
    <tr>
      <td colspan="2">
        <label class="label" for="place">
                <i class="fa fa-plus-circle"></i>
                
                <!-- New minus <i> -->
                <i class="fa fa-minus-circle"></i>
                
                <!-- Click to expand inside span <i> -->
                <b>Place</b> <span>(Click to expand...)</span>
              </label>
        <input type="checkbox" id="place" data-toggle="toggle">
      </td>
    </tr>
  </tbody>
  <tbody class="hide">
    <tr>
      <td class="city">LA</td>
      <td class="right cell" id="la">
        <span>0</span>
      </td>
    </tr>

    <tr>
      <td class="city">NYC</td>
      <td class="right cell" id="nyc">
        <span>0</span>
      </td>
    </tr>
  </tbody>
</table>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

Upvotes: 1

SKJ
SKJ

Reputation: 2326

I added a span with class arround your text.

I used the function parent() to get to td previous tag and find() function to the span tag and a "close" class name to your button to check if it's close or not in a condition.

$(document).ready(function() {
  $('.hide').hide();
  $('[data-toggle="toggle"]').click(function() {
    if($(this).is('.close')) {
       $(this).parent('td').find('b:first').text('Person (-)');
       $(this).parent('td').find('.textLabel').text('');
       $(this).removeClass('close');
    } else {
       $(this).parent('td').find('b:first').text("Person");   
       $(this).parent('td').find('.textLabel').text('(Click to expand...)');
       $(this).addClass('close');
    }
    $(this).parents().next('.hide').toggle();
  });
});
[data-toggle="toggle"] {
  display: none;
}

.label {
  display: block;
}

table,
tr,
th,
td {
  border: 1px solid black;
  border-collapse: collapse;
  font-family: Arial;
  width: 100%;
}
<table>
  <tbody class="section">
    <tr>
      <td colspan="2">
        <label class="label" for="person">
           <i class="fa fa-plus-circle"></i>
           <b>Person</b> <span class="textLabel">(Click to expand...)</span>
        </label>
        <input type="checkbox" id="person" data-toggle="toggle" class="close">
      </td>
    </tr>
  </tbody>

  <tbody class="hide">
    <tr>
      <td class="people">Jack</td>
      <td class="right cell" id="jack">
        <span>0</span>
      </td>
    </tr>

    <tr>
      <td class="people">Jill</td>
      <td class="right cell" id="jill">
        <span>0</span>
      </td>
    </tr>
  </tbody>
  <tbody class="section">
    <tr>
      <td colspan="2">
        <label class="label" for="place">
                <i class="fa fa-plus-circle"></i>
                <b>Place</b> <span class="textLabel">(Click to expand...)</span>
              </label>
        <input type="checkbox" id="place" data-toggle="toggle" class="close">
      </td>
    </tr>
  </tbody>
  <tbody class="hide">
    <tr>
      <td class="city">LA</td>
      <td class="right cell" id="nyc">
        <span>0</span>
      </td>
    </tr>

    <tr>
      <td class="city">NYC</td>
      <td class="right cell" id="nyc">
        <span>0</span>
      </td>
    </tr>
  </tbody>
</table>

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

Upvotes: 1

Yorai Levi
Yorai Levi

Reputation: 750

This does almost what you asked for:

if($(this).parents().next('.hide').is(':visible'))
    $(this).prev("label").text("-")
else
    $(this).prev("label").text("(Click to expand...)")

It selects the label sibling that holds the text that you want to modify and checks if the element that you hid is visible or not, then changes the text inside. because "Person" and "Place" are a part of the labels' text they're being overwritten. this can be solved by multiple ways, ones of which is nesting the text to be changed in another html tag and instead of changing the labels' text changing that tag's text content aka wrapping it with a <span></span>. see:

$(document).ready(function() {
  $('.hide').hide();
  $('[data-toggle="toggle"]').change(function() {
    $(this).parents().next('.hide').toggle();
    if($(this).parents().next('.hide').is(':visible'))
        $(this).prev("label").find("span").text("-")
    else
        $(this).prev("label").find("span").text("(Click to expand...)")
  });
});
[data-toggle="toggle"] {
  display: none;
}

.label {
  display: block;
}

table,
tr,
th,
td {
  border: 1px solid black;
  border-collapse: collapse;
  font-family: Arial;
  width: 100%;
}
<table>
  <tbody class="section">
    <tr>
      <td colspan="2">
        <label class="label" for="person">
                <i class="fa fa-plus-circle"></i>
                <b>Person</b> <span>(Click to expand...)</span>
              </label>
        <input type="checkbox" id="person" data-toggle="toggle">
      </td>
    </tr>
  </tbody>

  <tbody class="hide">
    <tr>
      <td class="people">Jack</td>
      <td class="right cell" id="jack">
        <span>0</span>
      </td>
    </tr>

    <tr>
      <td class="people">Jill</td>
      <td class="right cell" id="jill">
        <span>0</span>
      </td>
    </tr>
  </tbody>
  <tbody class="section">
    <tr>
      <td colspan="2">
        <label class="label" for="place">
                <i class="fa fa-plus-circle"></i>
                <b>Place</b> <span>(Click to expand...)</span>
              </label>
        <input type="checkbox" id="place" data-toggle="toggle">
      </td>
    </tr>
  </tbody>
  <tbody class="hide">
    <tr>
      <td class="city">LA</td>
      <td class="right cell" id="nyc">
        <span>0</span>
      </td>
    </tr>

    <tr>
      <td class="city">NYC</td>
      <td class="right cell" id="nyc">
        <span>0</span>
      </td>
    </tr>
  </tbody>
</table>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

Upvotes: 1

Related Questions