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)
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>
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
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>
I just satisfied below conditions
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>
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With