Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show first ten characters, expand on click (or hover)

I have a HTML snippet which looks like this:

<pre>
Traceback (most recent call last):
  File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 69, in execute_job_and_create_log
    output = self._execute_job_and_create_log()
  File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 127, in _execute_job_and_create_log
    return self.execute_job_and_create_log__ftp()
  File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 133, in execute_job_and_create_log__ftp
    return self._execute_job_and_create_log__ftp()
  File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 140, in _execute_job_and_create_log__ftp
    port=self.job_group.remote.port, session_factory=SessionOnPort) as host:
  File "/home/foobar_cok_p/lib/python2.7/site-packages/ftputil/host.py", line 72, in __init__
    self._session = self._make_session()
  File "/home/foobar_cok_p/lib/python2.7/site-packages/ftputil/host.py", line 135, in _make_session
    session = factory(*args, **kwargs)
  File "/home/foobar_cok_p/lib/python2.7/site-packages/ftputil/error.py", line 151, in __exit__
    raise FTPOSError(*exc_value.args, original_exception=exc_value)
FTPOSError: [Errno 110] Timeout
Debugging info: ftputil 3.4, Python 2.7.13 (linux2)
</pre>

Since most users do not care for the details, I would like to hide the traceback and only show the first few characters.

The remaining text should only be visible if you expand the text.

This should be visible as hyperlink: "Traceback ...."

How to do this with?

(I can't modify the html, a JavaScript/jquery/CSS solution is needed)

like image 425
guettli Avatar asked May 23 '19 12:05

guettli


5 Answers

Here is a pure CSS solution. It's a bit clumsy, but jquery not required

pre {
    width: 10em;
    height: 1em;
    overflow: hidden;
    white-space: pre;
    text-overflow: ellipsis;
    background-color: lightgreen;
    border-radius: 8px;
    border: 2px solid #6c6;
    transition: width 1s ease;
}
pre:hover {
    width: 100%;
    height: auto;
    overflow: auto;
    text-overflow: clip;
} 
<pre>
Traceback (most recent call last):
  File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 69, in execute_job_and_create_log
    output = self._execute_job_and_create_log()
  File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 127, in _execute_job_and_create_log
    return self.execute_job_and_create_log__ftp()
  File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 133, in execute_job_and_create_log__ftp
    return self._execute_job_and_create_log__ftp()
  File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 140, in _execute_job_and_create_log__ftp
    port=self.job_group.remote.port, session_factory=SessionOnPort) as host:
  File "/home/foobar_cok_p/lib/python2.7/site-packages/ftputil/host.py", line 72, in __init__
    self._session = self._make_session()
  File "/home/foobar_cok_p/lib/python2.7/site-packages/ftputil/host.py", line 135, in _make_session
    session = factory(*args, **kwargs)
  File "/home/foobar_cok_p/lib/python2.7/site-packages/ftputil/error.py", line 151, in __exit__
    raise FTPOSError(*exc_value.args, original_exception=exc_value)
FTPOSError: [Errno 110] Timeout
Debugging info: ftputil 3.4, Python 2.7.13 (linux2)
</pre>
like image 164
Banzay Avatar answered Oct 12 '22 14:10

Banzay


You could hide the pre's text by adding following CSS / class:

.hidden {
    text-overflow: ellipsis;
    width: 100px;
    overflow: hidden;
    white-space: nowrap;
} 

To achive the desired behaviour, you could toggle this class on click.

$('pre').click(function() {
    $(this).toggleClass('hidden')
})

Here is a working example:

https://codepen.io/anon/pen/PvQJxr

like image 24
ihkawiss Avatar answered Oct 12 '22 15:10

ihkawiss


Try using details and summary. Its very easy and fast to implement.

Also you don't have to handle any click events or css classes or anything else.

Check out this snippet:

let text = $("pre").html()
let header = text.split('\n')[0] // The header is the first line
text = text.substr(header.length); // The text everything besides the first line

// Set the html inside of the pre tag to a details/summary tag combo
$("pre").html(`<details>
    <summary>${header}</summary>
    ${text}
</details>`)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<pre>
Traceback (most recent call last):
  File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 69, in execute_job_and_create_log
    output = self._execute_job_and_create_log()
  File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 127, in _execute_job_and_create_log
    return self.execute_job_and_create_log__ftp()
  File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 133, in execute_job_and_create_log__ftp
    return self._execute_job_and_create_log__ftp()
  File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 140, in _execute_job_and_create_log__ftp
    port=self.job_group.remote.port, session_factory=SessionOnPort) as host:
  File "/home/foobar_cok_p/lib/python2.7/site-packages/ftputil/host.py", line 72, in __init__
    self._session = self._make_session()
  File "/home/foobar_cok_p/lib/python2.7/site-packages/ftputil/host.py", line 135, in _make_session
    session = factory(*args, **kwargs)
  File "/home/foobar_cok_p/lib/python2.7/site-packages/ftputil/error.py", line 151, in __exit__
    raise FTPOSError(*exc_value.args, original_exception=exc_value)
FTPOSError: [Errno 110] Timeout
Debugging info: ftputil 3.4, Python 2.7.13 (linux2)
</pre>
like image 4
MauriceNino Avatar answered Oct 12 '22 14:10

MauriceNino


I just satisfied below conditions

  1. I hide the content in pre tag and only show the first few characters.
  2. Remaining text should only be visible if you expand the text.

pre{
 width: 11ch;
 height: 2ch;
 overflow: hidden;
 text-overflow: ellipsis;
 color:blue;
 text-decoration: underline;
}
pre:active{
 width: 100%;
  height: 100%;
  color:black;
 text-decoration: none;
}
<pre>
Traceback (most recent call last):
  File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 69, in execute_job_and_create_log
    output = self._execute_job_and_create_log()
  File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 127, in _execute_job_and_create_log
    return self.execute_job_and_create_log__ftp()
  File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 133, in execute_job_and_create_log__ftp
    return self._execute_job_and_create_log__ftp()
  File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 140, in _execute_job_and_create_log__ftp
    port=self.job_group.remote.port, session_factory=SessionOnPort) as host:
  File "/home/foobar_cok_p/lib/python2.7/site-packages/ftputil/host.py", line 72, in __init__
    self._session = self._make_session()
  File "/home/foobar_cok_p/lib/python2.7/site-packages/ftputil/host.py", line 135, in _make_session
    session = factory(*args, **kwargs)
  File "/home/foobar_cok_p/lib/python2.7/site-packages/ftputil/error.py", line 151, in __exit__
    raise FTPOSError(*exc_value.args, original_exception=exc_value)
FTPOSError: [Errno 110] Timeout
Debugging info: ftputil 3.4, Python 2.7.13 (linux2)
</pre>
like image 2
Badri Chorapalli Avatar answered Oct 12 '22 14:10

Badri Chorapalli


In case you already have bootstrap in your project. You might want to utilize the built-in popover :)

Steps: 1. Hide the traceback (using CSS) 2. Display the button (plain HTML) 3. Setup javascript code (JS/JQuery)

Hide the traceback using CSS

<style>
    pre{
       display:none;
    }
</style>
<pre>
    Traceback (most recent call last):
      File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 69, in execute_job_and_create_log
        output = self._execute_job_and_create_log()
      File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 127, in _execute_job_and_create_log
        return self.execute_job_and_create_log__ftp()
      File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 133, in execute_job_and_create_log__ftp
        return self._execute_job_and_create_log__ftp()
      File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 140, in _execute_job_and_create_log__ftp
        port=self.job_group.remote.port, session_factory=SessionOnPort) as host:
      File "/home/foobar_cok_p/lib/python2.7/site-packages/ftputil/host.py", line 72, in __init__
        self._session = self._make_session()
      File "/home/foobar_cok_p/lib/python2.7/site-packages/ftputil/host.py", line 135, in _make_session
        session = factory(*args, **kwargs)
      File "/home/foobar_cok_p/lib/python2.7/site-packages/ftputil/error.py", line 151, in __exit__
        raise FTPOSError(*exc_value.args, original_exception=exc_value)
    FTPOSError: [Errno 110] Timeout
    Debugging info: ftputil 3.4, Python 2.7.13 (linux2)
</pre>

Somewhere in your HTML, you prepare and display the popover button

<button type="button" class="btn btn-lg btn-danger" data-placement="bottom" data-toggle="popover" title="The full Traceback">Traceback...</button>

Setup the Javascript which would trigger the Bootstrap popover

<script>
    $('[data-toggle="popover"]').popover({
      content: $('pre').text().trim()
    });
</script>

Advantages:

  • You can display any button text that you want. ex: "Display Full Traceback" etc..

  • Take advantage of Bootstrap popover options. Ex. You can easily manipulate where you want the popover to display (left, right, bottom, top) For more info, you can go to https://getbootstrap.com/docs/4.3/components/popovers/

  • The flexibility of how you want to handle the "Traceback" data


If you don't have Bootstrap, you may want to do a similar approach in pure HTML, CSS, Javascript, and JQuery as well. Here's how...

<style>
    pre{
      display:none;
    }

    .full-trace-back{
      width: 500px;
      padding: 20px;      
      background:#fafafa;
      border: 1px solid #ddd;
      -webkit-border-radius: 5px;
              border-radius: 5px;
    }
</style>

  <pre>
    Traceback (most recent call last):
      File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 69, in execute_job_and_create_log
        output = self._execute_job_and_create_log()
      File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 127, in _execute_job_and_create_log
        return self.execute_job_and_create_log__ftp()
      File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 133, in execute_job_and_create_log__ftp
        return self._execute_job_and_create_log__ftp()
      File "/home/foobar_cok_p/src/foobar/foobar/models/job.py", line 140, in _execute_job_and_create_log__ftp
        port=self.job_group.remote.port, session_factory=SessionOnPort) as host:
      File "/home/foobar_cok_p/lib/python2.7/site-packages/ftputil/host.py", line 72, in __init__
        self._session = self._make_session()
      File "/home/foobar_cok_p/lib/python2.7/site-packages/ftputil/host.py", line 135, in _make_session
        session = factory(*args, **kwargs)
      File "/home/foobar_cok_p/lib/python2.7/site-packages/ftputil/error.py", line 151, in __exit__
        raise FTPOSError(*exc_value.args, original_exception=exc_value)
    FTPOSError: [Errno 110] Timeout
    Debugging info: ftputil 3.4, Python 2.7.13 (linux2)
  </pre>

  <script>
    (function () {      
      let isOpen = false;
      $('.trace-back-link').on('click', toggleFullTraceback);

      function toggleFullTraceback() {
        isOpen = !isOpen;
        if (isOpen) {
          const tracebackData = $('pre').text().trim();
          const tracebackLink = $('.trace-back-link');
          tracebackLink.after( "<p class='full-trace-back'>"+tracebackData+"</p>" );
        }else{
          const fullTraceback = $('.full-trace-back');
          fullTraceback.remove();
        }
      }
    }());
  </script>
like image 2
balfonso Avatar answered Oct 12 '22 14:10

balfonso