1

I have a site that displays a number of stories from users when the page loads. I want to only display the fist 2 sentences of each story, with a show more link underneath which the user can press. I tried to incorporate the code from the accepted answer for this question link.

The top 2 rows are being hidden and the display is as I would want, but I can't get the jQuery attached to the link to fire and show all rows. Is it a selector error?

My Fiddle: link

Html (generated from an Ajax call on window load):

<div class="post">
    <div class="hideContent">
        <div class="post-text">
        Lorem ipsum dolor sit amet, ex mel graece iuvaret. Ius cu cetero nonumes complectitur, no clita accusam splendide pri. Ea sit tale democritum, ea meis rebum est..</div>
            <div class="post-action">
               <input type="button" value="Like" id="like_86_cmpq0" class="like">
               <span class="likesTotal" id="likes_86_cmpq0">0</span></div>
            </div>
<div class="showMore"><a href="#">Show more</a></div>
</div>

CSS:

.hideContent {
    overflow: hidden;
    line-height: 1em;
    height: 2em;
}

.showContent {
    line-height: 1em;
    height: auto;
}

JQuery:

$(".showMore a").on("click", function() {

    var $this = $(this); 
    //var $content = $this.parent().prev("div.content");
    var $content = $this.closest("hideContent");
    var linkText = $this.text().toUpperCase();    
    
    if(linkText === "SHOW MORE"){
        linkText = "Show less";
        $content.switchClass("hideContent", "showContent", 400);
    } else {
        linkText = "Show more";
        $content.switchClass("showContent", "hideContent", 400);
    }

    $this.text(linkText);
});

EDIT:

JQuery that creates the html above:

$(window).on('load', function () {

    $.ajax({
      url: 'serverside/stories.php',
      method: 'POST',
      dataType: 'json',
      success: function(response) {

      $(".content").html("")
      $(".total").html("")

        if(response){
          var total = response.length;
          $('#intro') .append("<p>Get inspired by reading personal stories about anxiety</p>");
         }
        
        $.each(response, function() {
          $.each($(this), function(i, item) {

            var mycss = (item.Type == 1) ? ' style="color: #ffa449;"' : '';
            $('.content').append('<div class="post"><div class="hideContent"><div class="post-text"> ' + item.MessageText + ' </div><div class="post-action"><input type="button" value="Like" id="like_' + item.ID + '_' + item.UserID + '" class="like" ' + mycss + ' /><span class="likesTotal" id="likes_' + item.ID + '_' + item.UserID + '">' + item.CntLikes + '</span></div></div>' + '<div class="showMore"><a href="#">Show more</a></div></div>');
          });
        });
      }
    });
});
CGarden
  • 169
  • 17
  • isn't this: `var $content = $this.closest("hideContent");` suppost to be this: `var $content = $this.closest(".hideContent");`, added a dot in the hideContent selection – Ramon de Vries Jun 21 '20 at 12:11

2 Answers2

1

Need to add two JS script paths for the jquery codes and switchClass function to work. Besides, I have changed variable name from $content to content (not important). Also, I added var content = $this.parent().prev() for the switch class purpose.

$(".showMore a").on("click", function() {

  var $this = $(this);
  //var $content = $this.parent().prev("div.content");
  /* var content = $this.closest(".hideContent") */

  // Add this line
  // Change $content to content
  var content = $this.parent().prev()
  var linkText = $this.text().toUpperCase();

  //Edit: Add console log here
  //console.log(content[0].className);
  //Edit 2: Add console log here
  //console.log(content[0]);
  
  if (linkText === "SHOW MORE") {
    linkText = "Show less";
    content.switchClass("hideContent", "showContent", 400);

  } else {
    linkText = "Show more";
    content.switchClass("showContent", "hideContent", 400);
  }

  $this.text(linkText);
});
.hideContent {
  overflow: hidden;
  line-height: 1em;
  height: 2em;
  transition: all 0.25s linear; /* Edit 3: Add transition on height*/
}

.showContent {
  line-height: 1em;
  height: auto;
  transition: all 0.25s linear; /* Edit 3: Add transition on height*/
}
<!-- jquery script path -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- jqueryui script path-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

<div class="post">
  <div class="hideContent">
    <div class="post-text">
      Lorem ipsum dolor sit amet, ex mel graece iuvaret. Ius cu cetero nonumes complectitur, no clita accusam splendide pri. Ea sit tale democritum, ea meis rebum est..</div>
    <div class="post-action">
      <input type="button" value="Like" id="like_86_cmpq0" class="like">
      <span class="likesTotal" id="likes_86_cmpq0">0</span></div>
  </div>
  <div class="showMore"><a href="#">Show more</a></div>
</div>
yinsweet
  • 2,823
  • 1
  • 9
  • 21
  • Thank you. Sorry forgot to put the jQuery library link in. What is the second link ? – CGarden Jun 21 '20 at 14:20
  • jQueryUI - u need it for `switchClass` function – yinsweet Jun 21 '20 at 15:05
  • When I add this code to my site and run it on my test server, I press the Show more link, the page then seems to treat it as a link and takes me to the top of the page. – CGarden Jun 21 '20 at 17:32
  • Do u set the jQueryUI path after the jQuery path? I tested on fiddle n it works as well. Do you have the test server link that I can troubleshoot? – yinsweet Jun 21 '20 at 18:48
  • I believe so yes. It's an abyss virtual server so I can't share it sadly. I think it's because my jQuery gennerates the html. Thank you. Should I share that code? – CGarden Jun 21 '20 at 19:28
  • jQuery supposingly not generating any codes. But, what codes that you mention was generated? Do you see errors in the browser console log? – yinsweet Jun 21 '20 at 20:16
  • There are no errors in the browser console log. I have added the jQuery that creates the html code. It creates the class 'post' and all the divs under it. When the page loads I fire an Ajax request that pulls user stories from a mysql database, these are then displayed on the page. As regards the show more functionality, I don't think it's triggering the jQuery when clicked. I don't think it's finding it. Thanks again for your help. Much appreciated! – CGarden Jun 21 '20 at 20:45
  • Just to state multiple stories are displayed on the page so there will be multiple 'post' classes. – CGarden Jun 21 '20 at 20:56
  • Np. Glad to help. – yinsweet Jun 22 '20 at 09:37
  • Sorry did you have any thoughts to why it might not be working? Thank you. – CGarden Jun 23 '20 at 20:26
  • Have you tried to use console log to check if target the right div with `hideContent` class? `e.g. console.log(content[0].className); ` – yinsweet Jun 24 '20 at 01:47
  • Sorry how does that work? How do you apply that? I add that to the jQuery? Thanks. I'm still new to this. – CGarden Jun 24 '20 at 02:08
  • 1
    I have added the console log in the code snippet. Check the code snippet - `//Edit: Add console log here`. When you click on the `show more` / `show less`, the console from browser will display the class name. – yinsweet Jun 24 '20 at 02:17
  • Thank you for that. I've added to the JQuery the console log code and nothing is appearing in the console window when I press the 'Show More' link. What do you think? – CGarden Jun 24 '20 at 12:49
  • That means you are not targeting the `
    ` with `hideContent` class. This has to do with your html code generated with JS and AJAX. `var content = $this.parent().prev()` does not find your `
    ` with `hideContent` class. Is the HTML code generated the same as you posted in the question?
    – yinsweet Jun 24 '20 at 14:19
  • I thought that it was yes. I took it from the browser inspector using Google Chrome. The Ajax JQuery that creates the html is shown in my question EDIT section. – CGarden Jun 24 '20 at 15:19
  • 1
    Sorry, I can't translate the Ajax query codes to HTML as I am inexperience to that. You may want to try one more thing. Use the console log to print out the target of the var `content`... `console.log(content[0]);` You can run the code snippet for an example. – yinsweet Jun 24 '20 at 15:32
  • Thank you for your help but that didn't do anything either. I might change the link for a button instead. – CGarden Jun 24 '20 at 22:00
  • Ok, I'm using the code logic, which was used for the like button and that is working or me now. I'll post that code later. It is hiding and unhiding, however it is also using the href as a link taking me to the top of the page when I press the Show More button. So still some work. I'll use a button instead. Thanks for your help @yinsweet – CGarden Jun 24 '20 at 22:18
  • I was hoping you could offer some advice. I have adopted the method below, but when the show less button is clicked the excess text is hidden but there is a millisecond flicker of some text once the text is hidden. Do you know why that is? Thank you. Happy to update this question accordingly. – CGarden Jul 01 '20 at 21:32
  • 1
    I am not sure what is causing the text hidden. You may add the transition property to mitigate the issue. `transition: all 0.25s linear; /* Edit 3: Add transition on height*/` Hope it helps. – yinsweet Jul 01 '20 at 22:43
  • Sorry, what I mean is the show less and show more functionality works as expected. However when you press the show less button the lines reduce down to 2, which is great, but then after that for a split second it looks like 2 additional lines show on the page. I can't make out what these sentences are. I tried to slow the transition down to read them, but they are still only shown for a millisecond. – CGarden Jul 01 '20 at 22:59
  • Sorry, I mean I don't know what is causing the flickering. I don't see 2 additional lines show on the page. Sorry, can't help. – yinsweet Jul 02 '20 at 06:23
0

Looking through similar code I have on my website I found the below solved the issue. Because the content div is a parent that is there when the page loads, before the Ajax request creates the rest of the html, I used this to attach to the showMore div. Thank you yinsweet for your help!

$(document).ready(function(){

$(".content").on("click",".showMore a", function() {

  var $this = $(this);

  var content = $this.parent().prev()
  var linkText = $this.text().toUpperCase();

  if (linkText === "SHOW MORE") {
    linkText = "Show less";
    content.switchClass("hideContent", "showContent", 400);

  } else {
    linkText = "Show more";
    content.switchClass("showContent", "hideContent", 400);
  }

  $this.text(linkText);
});

});
CGarden
  • 169
  • 17