7

If the details tag has an open attribute, the summary text will say "Close".

My attempt at changing the text:

if (jQuery("details").click().attr("open")) {
  jQuery("summary").text("Close");
} else if (jQuery("details").click().attr("")) {
  jQuery("summary").text("Show")
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<details class="description" open>
  <summary class="">Show</summary>
  <p class="">Description text</p>
</details>
connexo
  • 53,704
  • 14
  • 91
  • 128
Nick0989
  • 459
  • 5
  • 15
  • Do you HAVE to use attribute? why not use data attribute with true and false? data-open="true" and read it's value like this: data('open'); and write like this: data('open', true); If you MUST use attribute... then look at this answer: https://stackoverflow.com/questions/1318076/jquery-hasattr-checking-to-see-if-there-is-an-attribute-on-an-element – Nawed Khan Mar 06 '19 at 20:33
  • No need for Javascript at all here. This can be achieved with CSS and is aeons faster. See my answer below. – connexo Mar 06 '19 at 20:58

3 Answers3

13

Simply use CSS for this, here combined with a neat fading/grow/shrink effect:

details.description summary::after {
  content: attr(data-open);
  opacity: 0;
  font-size: 5px;
}

details.description[open] summary::after {
  content: attr(data-open);
  opacity: 1;
  font-size: 14px;
}

details.description summary::before {
  content: attr(data-close);
  opacity: 0;
  font-size: 5px;
}

details.description:not([open]) summary::before {
  content: attr(data-close);
  opacity: 1;
  font-size: 14px;
}

details.description summary::after,
details.description summary::before {
  display: inline-block;
  transition: all .4s ease-in-out;
  transform-origin: center bottom;
}
<details class="description" open>
  <summary data-open="Close" data-close="Show"></summary>
  <p>Description text</p>
</details>

Here's the minimal version:

details.description[open] summary::after {
  content: attr(data-open);
}

details.description:not([open]) summary::after {
  content: attr(data-close);
}
<details class="description" open>
  <summary data-open="Close" data-close="Show"></summary>
  <p>Description text</p>
</details>
connexo
  • 53,704
  • 14
  • 91
  • 128
3

Use hasAttribute() to check if the attribute is existing or not.

$("summary").html("Close");

$("details").click(function() {
  if ($(this)[0].hasAttribute("open")) {
    $("summary").html("Show");
  } else {
    $("summary").html("Close");
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<details class="description" open>
  <summary class=""></summary>
  <p class="">Description text</p>
</details>
Paolo
  • 823
  • 6
  • 18
  • Thank you. By chance if I had 5 or 10 detail/summaries, would I be able to only affect the one that has been clicked? – Nick0989 Mar 06 '19 at 20:53
  • Again, simply use CSS for that instead of jQuery or Javascript. CSS also does not have this problem. – connexo Mar 06 '19 at 20:59
  • OP put jquery as a tag so I gave him an answer in jQuery. @connexo – Paolo Mar 06 '19 at 21:10
  • @Paolo That's perfectly fine! I just wanted to point out the superior solution for this special usecase. – connexo Mar 06 '19 at 21:12
0

Here is a minimalist solution without using CSS.
Simply add or remove the "open" attribute using .attr() and .removeAttr().

$("summary").click(function() {
  if($("details")[0].hasAttribute("open")) {
    $("summary").html("See details");
    $("details")[0].removeAttr("open");
  } else {
    $("summary").html("Hide details");
    $("details")[0].attr("open");
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div>
  <details>
    <summary>See details</summary>
    <p>My details</p>
  </details>
</div>
Mr. Tesla
  • 39
  • 5