mirror of
				https://github.com/janeczku/calibre-web
				synced 2025-10-31 15:23:02 +00:00 
			
		
		
		
	Show book details in modal dialog
With them shown in a modal, you don't lose your place in the pagination. If the request comes via Ajax, the minimal layout is used. If via a normal request, the full layout is used. That lets you open the details in a new tab and have the full experience, but if you're clicking through the results of a search, you can view many without losing your place.
This commit is contained in:
		| @@ -121,6 +121,17 @@ $(function() { | |||||||
|         }); |         }); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|  |     $('#bookDetailsModal') | ||||||
|  |       .on('show.bs.modal', function(e) { | ||||||
|  |         var $modalBody = $(this).find('.modal-body'); | ||||||
|  |         $.get(e.relatedTarget.href).done(function(content) { | ||||||
|  |           $modalBody.html(content); | ||||||
|  |         }); | ||||||
|  |       }) | ||||||
|  |       .on('hidden.bs.modal', function() { | ||||||
|  |         $(this).find('.modal-body').html('...'); | ||||||
|  |       }); | ||||||
|  |  | ||||||
|     $(window).resize(function(event) { |     $(window).resize(function(event) { | ||||||
|         $(".discover .row").isotope("reLayout"); |         $(".discover .row").isotope("reLayout"); | ||||||
|     }); |     }); | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| {% extends "layout.html" %} | {% extends is_xhr|yesno("fragment.html", "layout.html") %} | ||||||
| {% block body %} | {% block body %} | ||||||
| <div class="single"> | <div class="single"> | ||||||
|   <div class="row"> |   <div class="row"> | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
|     <div class="col-sm-3 col-lg-2 col-xs-6 book"> |     <div class="col-sm-3 col-lg-2 col-xs-6 book"> | ||||||
|       <div class="cover"> |       <div class="cover"> | ||||||
|         {% if entry.has_cover is defined %} |         {% if entry.has_cover is defined %} | ||||||
|           <a href="{{ url_for('show_book', book_id=entry.id) }}"> |           <a href="{{ url_for('show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false"> | ||||||
|             <img src="{{ url_for('get_cover', cover_path=entry.path.replace('\\','/')) }}" /> |             <img src="{{ url_for('get_cover', cover_path=entry.path.replace('\\','/')) }}" /> | ||||||
|           </a> |           </a> | ||||||
|         {% endif %} |         {% endif %} | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								cps/templates/fragment.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								cps/templates/fragment.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | <div class="container-fluid"> | ||||||
|  |   {% block body %}{% endblock %} | ||||||
|  | </div> | ||||||
|  | {% block js %}{% endblock %} | ||||||
| @@ -8,7 +8,7 @@ | |||||||
|     {% for entry in random %} |     {% for entry in random %} | ||||||
|     <div id="books_rand" class="col-sm-3 col-lg-2 col-xs-6 book"> |     <div id="books_rand" class="col-sm-3 col-lg-2 col-xs-6 book"> | ||||||
|       <div class="cover"> |       <div class="cover"> | ||||||
|           <a href="{{ url_for('show_book', book_id=entry.id) }}"> |           <a href="{{ url_for('show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false"> | ||||||
|             {% if entry.has_cover %} |             {% if entry.has_cover %} | ||||||
|               <img src="{{ url_for('get_cover', cover_path=entry.path.replace('\\','/')) }}" /> |               <img src="{{ url_for('get_cover', cover_path=entry.path.replace('\\','/')) }}" /> | ||||||
|             {% else %} |             {% else %} | ||||||
| @@ -44,7 +44,7 @@ | |||||||
|     {% for entry in entries %} |     {% for entry in entries %} | ||||||
|     <div id="books" class="col-sm-3 col-lg-2 col-xs-6 book"> |     <div id="books" class="col-sm-3 col-lg-2 col-xs-6 book"> | ||||||
|       <div class="cover"> |       <div class="cover"> | ||||||
|           <a href="{{ url_for('show_book', book_id=entry.id) }}"> |           <a href="{{ url_for('show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false"> | ||||||
|             {% if entry.has_cover %} |             {% if entry.has_cover %} | ||||||
|               <img src="{{ url_for('get_cover', cover_path=entry.path.replace('\\','/')) }}" /> |               <img src="{{ url_for('get_cover', cover_path=entry.path.replace('\\','/')) }}" /> | ||||||
|             {% else %} |             {% else %} | ||||||
|   | |||||||
| @@ -188,6 +188,20 @@ | |||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
|     </div> |     </div> | ||||||
|  |     <div class="modal fade" id="bookDetailsModal" tabindex="-1" role="dialog" aria-labelledby="bookDetailsModalLabel"> | ||||||
|  |       <div class="modal-dialog modal-lg" role="document"> | ||||||
|  |         <div class="modal-content"> | ||||||
|  |           <div class="modal-header"> | ||||||
|  |             <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> | ||||||
|  |             <h4 class="modal-title" id="bookDetailsModalLabel">{{_('Book Details')}}</h4> | ||||||
|  |           </div> | ||||||
|  |           <div class="modal-body">...</div> | ||||||
|  |           <div class="modal-footer"> | ||||||
|  |             <button type="button" class="btn btn-default" data-dismiss="modal">{{_('Close')}}</button> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|     {% block modal %}{% endblock %} |     {% block modal %}{% endblock %} | ||||||
|     {% block js %}{% endblock %} |     {% block js %}{% endblock %} | ||||||
|   </body> |   </body> | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ | |||||||
|     <div class="col-sm-3 col-lg-2 col-xs-6 book"> |     <div class="col-sm-3 col-lg-2 col-xs-6 book"> | ||||||
|       <div class="cover"> |       <div class="cover"> | ||||||
|         {% if entry.has_cover is defined %} |         {% if entry.has_cover is defined %} | ||||||
|            <a href="{{ url_for('show_book', book_id=entry.id) }}"> |            <a href="{{ url_for('show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false"> | ||||||
|             <img src="{{ url_for('get_cover', cover_path=entry.path.replace('\\','/')) }}" /> |             <img src="{{ url_for('get_cover', cover_path=entry.path.replace('\\','/')) }}" /> | ||||||
|           </a> |           </a> | ||||||
|         {% endif %} |         {% endif %} | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ | |||||||
|     <div class="col-sm-3 col-lg-2 col-xs-6 book"> |     <div class="col-sm-3 col-lg-2 col-xs-6 book"> | ||||||
|       <div class="cover"> |       <div class="cover"> | ||||||
|         {% if entry.has_cover is defined %} |         {% if entry.has_cover is defined %} | ||||||
|           <a href="{{ url_for('show_book', book_id=entry.id) }}"> |           <a href="{{ url_for('show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false"> | ||||||
|             <img src="{{ url_for('get_cover', cover_path=entry.path.replace('\\','/')) }}" /> |             <img src="{{ url_for('get_cover', cover_path=entry.path.replace('\\','/')) }}" /> | ||||||
|           </a> |           </a> | ||||||
|         {% endif %} |         {% endif %} | ||||||
|   | |||||||
| @@ -411,6 +411,11 @@ def timestamptodate(date, fmt=None): | |||||||
|     return native.strftime(time_format) |     return native.strftime(time_format) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @app.template_filter('yesno') | ||||||
|  | def yesno(str, yes, no): | ||||||
|  |     return yes if str else no | ||||||
|  |  | ||||||
|  |  | ||||||
| def admin_required(f): | def admin_required(f): | ||||||
|     """ |     """ | ||||||
|     Checks if current_user.role == 1 |     Checks if current_user.role == 1 | ||||||
| @@ -1233,7 +1238,7 @@ def show_book(book_id): | |||||||
|         else: |         else: | ||||||
|             have_read = None |             have_read = None | ||||||
|  |  | ||||||
|         return render_title_template('detail.html', entry=entries, cc=cc, |         return render_title_template('detail.html', entry=entries, cc=cc, is_xhr=request.is_xhr, | ||||||
|                                      title=entries.title, books_shelfs=book_in_shelfs, have_read=have_read) |                                      title=entries.title, books_shelfs=book_in_shelfs, have_read=have_read) | ||||||
|     else: |     else: | ||||||
|         flash(_(u"Error opening eBook. File does not exist or file is not accessible:"), category="error") |         flash(_(u"Error opening eBook. File does not exist or file is not accessible:"), category="error") | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jonathan Rehm
					Jonathan Rehm