1

I am very new to jquery and haven't been able to find a solution for my problem. I have a table created for some messages. At the beginning of a messages row there is a fontawesome icon showing the message is not expanded. Once clicked and expanded I want that icon to change to a different one. I have been toying with a function found elsewhere on this site which uses the value of the first <td> in a row to show either + or -.

Here's the function followed by my table:

$(function() {
    $("td[colspan=7]").find("p").hide();
    $("table").click(function(event) {
        event.stopPropagation();
        var $target = $(event.target);
        if ( $target.closest("td").attr("colspan") > 1 ) {
            $target.closest("td").children("p").slideUp();

            $target.closest("tr").prev().find("td:first").html("+");//NOT MINE - CHANGE

        } else {
            $target.closest("tr").next().find("p").slideToggle();

            if ($target.closest("tr").find("td:first").html() == "+")//NOT MINE - CHANGE
                $target.closest("tr").find("td:first").html("-");//NOT MINE - CHANGE
            else
                $target.closest("tr").find("td:first").html("+"); //NOT MINE - CHANGE

        }                    
    });
});

...

                    echo "<tr class='message-body'>";
                    echo "<th><i class='far fa-envelope'></i> ".$title."</th>";
                    echo "<th></th>";
                    echo "<th>".$date."</th>";
                    echo "<th></th>";
                    echo "<th></th>";
                    echo "<th></th>";
                    echo '<th><div class="right"><form method="post" action="">
                        <input type="hidden" name="id" value="'.$id.'">
                        <button class="rem-button"> Delete</button></form></div></th>';
                    echo "</tr>";
                    echo "<tr colspan='7'><td class='message-body-body' colspan='7'><p><br>".$body."</p></td></tr>";

Ideally I want to do something like:

closed -> first <i> class is = far fa-envelope

opened -> first <i> class is = far fa-envelope-open

EDIT

Currently the function allows me to click a row and expand to show the body of a message. Before expanding i want to keep the envelope icon. After expanding I want that icon to change to envelope-open.

EDIT 2

I need this line

$target.closest("tr").prev().find("td:first").html("+");

changed to this one (but functional)

$target.closest("tr").prev().find("i:first").class.html("far fa-envelope");

the other lines needing to be changed will be, in a similar manner

EDIT 3 solution my question is based off of

EDIT 4 My Fiddle not sure how to link fontawesome here

FamousAv8er
  • 2,345
  • 2
  • 9
  • 27
  • I don't clearly understand what you want, you want that when icon is clicked, then change the class of the `` tag? – Calvin Nunes Sep 26 '19 at 18:33
  • @CalvinNunes I added an edit. Please let me know if you need more info. – FamousAv8er Sep 26 '19 at 18:36
  • Possible duplicate of [Javascript/Jquery to change class onclick?](https://stackoverflow.com/questions/7014385/javascript-jquery-to-change-class-onclick) – Calvin Nunes Sep 26 '19 at 18:36
  • It looks like you are asking to handle a case of clicking on the `i` or message, yet your event binding is for clicking on the `table`. – Taplar Sep 26 '19 at 18:42
  • @Taplar I want the clicking on the table. I just want the icon (only for that row) to change when the row is clicked to expand the message. – FamousAv8er Sep 26 '19 at 18:45
  • @Taplar added second edit – FamousAv8er Sep 26 '19 at 18:57
  • @CalvinNunes added second edit – FamousAv8er Sep 26 '19 at 18:58
  • @FamousAv8er, can you provide a [fiddle](https://jsfiddle.net/) to better illustrate what you have? – mgarcia Sep 26 '19 at 19:04
  • @mgarcia see edit 4 – FamousAv8er Sep 26 '19 at 19:14
  • @WOUNDEDSTevenJones not exactly sure how to use those in conditional statements `if ($target.closest("tr").find("td:first").html() == "+")` – FamousAv8er Sep 26 '19 at 19:15
  • The `` element is not in a `` in your code, it's in a ``. After reading one of the answers in the question you referenced, I can see why the click event is on the table. – EternalHour Sep 26 '19 at 19:15
  • There is a problem with your design. If you add the envelope icon to a ``, that icon will apply to ***all*** messages. You need the icon in a `` so you'll have one for each message and you can control them individually. Same issue with your delete button. `` is for the *headings*. – EternalHour Sep 26 '19 at 19:18
  • @EternalHour I agree my design could use some work, however the expanding and deletion currently work flawlessly on the row selected. Im hoping that in the same function that expands my selected row, I can change just that rows icon – FamousAv8er Sep 26 '19 at 19:27

2 Answers2

1

Try this:

$target.closest("tr").prev().find("i:first").toggleClass("fa-envelope fa-envelope-open");

Another possible solution:

$('#message-table').find('th:first-child i').toggleClass("fa-envelope fa-envelope-open");

Working fiddle: https://jsfiddle.net/gbhsa19v/

Marcelo The Mage Coder
  • 1,944
  • 2
  • 11
  • 29
  • @FamousAv8er it will work correct. See this fiddle I've made: https://jsfiddle.net/gbhsa19v/ – Marcelo The Mage Coder Sep 26 '19 at 19:46
  • so this does work and I appreciate your solution however, when applied to my code this will change the icon for each row in the table rather than just the row we are clicking – FamousAv8er Sep 26 '19 at 19:52
  • @FamousAv8er you just want to it to slide up/down and change the icon when clicked on ? When clicking in any table row, the table should be hidden or still be visible? – Marcelo The Mage Coder Sep 26 '19 at 19:58
  • https://jsfiddle.net/obyv8e4L/ I think my change here shows what youre asking. The rows below our expanded row just slide down – FamousAv8er Sep 26 '19 at 20:00
1

As discussed in the comments, in my opinion <th> should be reserved for the column headings. Then you can put your message content in <td> tags. Also, by hiding the <p> tag by default, no need to hide it.

In order to switch the classes, you can use toggleClass() method. Here is an example I put together with my suggestions to what you've provided. You can further optimize it by adding classes to each <td> which would allow you to remove first() and target the elements individually.

$(function() {
  $("table").click(function(event) {
    event.stopPropagation();
    var $target = $(event.target.parentNode);
 
    $target.children().first().find('i')
    .toggleClass("fa-envelope fa-envelope-open");
    
    $target.next().find(".message-body-body").slideToggle();
  });
});
table {
  border-collapse: collapse;
}
th, td {
  border: 1px solid #000;
}
th {
background-color: #ccc;
}
.message-row {
  cursor: pointer;
}
.message-body-body {
  padding: 20px;
  background-color: #f5f5f5;
  /* prevents element from flashes when page is loaded */
  display: none;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<table>
  <tr class='message-body'>
    <th></th>
    <th>Date</th>
    <th>Title</th>
    <th>To</th>
    <th>From</th>
    <th>Action</th>
  </tr>
  <tr class="message-row">
    <td><i class='far fa-envelope message-icon'></i></td>
    <td>09/26/2019</td>
    <td>Message #1</td>
    <td>someone@demo.com</td>
    <td>someone@demo.com</td>
    <td>
      <div class="right">
        <form method="post" action="">
          <input type="hidden" name="id" value="20">
          <button class="rem-button"> Delete</button>
        </form>
      </div>
    </td>
  </tr>
  <tr colspan='6'>
    <td class='message-body-body' colspan='6'>
      This is the message body #1
    </td>
  </tr>
  <tr class="message-row">
    <td><i class='far fa-envelope message-icon'></i></td>
    <td>09/26/2019</td>
    <td>Message #2</td>
    <td>someone@demo.com</td>
    <td>someone@demo.com</td>
    <td>
      <div class="right">
        <form method="post" action="">
          <input type="hidden" name="id" value="20">
          <button class="rem-button"> Delete</button>
        </form>
      </div>
    </td>
  </tr>
  <tr colspan='6'>
    <td class='message-body-body' colspan='6'>
      This is the message body #2
    </td>
  </tr>
</table>
EternalHour
  • 8,308
  • 6
  • 38
  • 57
  • Im not able to play with this at the moment but I will later. I appreciate the extra effort you are putting in to help me. Thank you – FamousAv8er Sep 26 '19 at 20:08