182 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			182 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<!DOCTYPE html>
 | 
						||
<html>
 | 
						||
<head>
 | 
						||
  <title>Library</title>
 | 
						||
  <script type="text/javascript" src='js/jquery.js'></script>
 | 
						||
  <script type="text/javascript" src='js/mustache.js'></script>
 | 
						||
  <script type="text/javascript" src='js/lodash.min.js'></script>
 | 
						||
  <script src='https://cdnjs.cloudflare.com/ajax/libs/tabletop.js/1.5.1/tabletop.min.js'></script>
 | 
						||
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"></link>
 | 
						||
  <link rel="stylesheet" href="css/reset.css"></link>
 | 
						||
  <link rel="stylesheet" href="css/style.css"></link>
 | 
						||
  <link href="https://fonts.googleapis.com/css?family=Libre+Baskerville:400,700" rel="stylesheet">
 | 
						||
  <script type='text/javascript'>    
 | 
						||
    var publicSpreadsheetUrl = 'https://docs.google.com/spreadsheets/d/1w5Dc57wV0_rrKFsG7KM-qdPWEpqYk6lFu3JzAA0cSv0/pubhtml';
 | 
						||
    var sortState = {
 | 
						||
      sortBy: 'authorLast',
 | 
						||
      sortOrder: 'asc'
 | 
						||
    };
 | 
						||
 | 
						||
    function init() {
 | 
						||
      Tabletop.init({
 | 
						||
        key: publicSpreadsheetUrl,
 | 
						||
        callback: showInfo,
 | 
						||
        simpleSheet: true
 | 
						||
      });
 | 
						||
    }
 | 
						||
 | 
						||
    function showInfo(data, tabletop) {
 | 
						||
      $("#reloadLink").unbind('click');
 | 
						||
      $("#reloadLink").on("click", function() { init(); });
 | 
						||
 | 
						||
      $("#search").unbind('input');
 | 
						||
      $("#search").on("input", function(e) { search(data, e.target.value); });
 | 
						||
 | 
						||
      $.each(data, function(key, value) {
 | 
						||
        value.sortTitle = titleCleaner(value.title);
 | 
						||
        if (!value['isbn-10'] && value['isbn-13']) {
 | 
						||
          value['isbn-10'] = generateISBNfromEAN(value['isbn-13']);
 | 
						||
        }
 | 
						||
        if (!value.coverurl && value['isbn-10']) {
 | 
						||
          value.coverurl = generateAmazonCoverUrl(value['isbn-10']);
 | 
						||
        }
 | 
						||
      });
 | 
						||
 | 
						||
      renderTable(data);
 | 
						||
    }
 | 
						||
 | 
						||
    function search(data, searchString) {
 | 
						||
      searchBy = searchString.toLowerCase();
 | 
						||
      relevantFields = ['title', 'author', 'genre', 'publisher', 'series', 'year'];
 | 
						||
 | 
						||
      if (!searchString) {
 | 
						||
        renderTable(data);
 | 
						||
        return false;
 | 
						||
      }
 | 
						||
 | 
						||
      renderTable(_.filter(data, function(book) {
 | 
						||
        return _.find(_.pick(book, relevantFields), function(field) {
 | 
						||
          return field.toLowerCase().replace('"', '').replace(':', '').indexOf(searchBy) !== -1;
 | 
						||
        });
 | 
						||
      }));
 | 
						||
    }
 | 
						||
 | 
						||
    function renderTable(data, sortField) {
 | 
						||
      if (sortField) {
 | 
						||
        if (sortState.sortBy === sortField) {
 | 
						||
          sortState.sortOrder = (sortState.sortOrder === 'asc') ? 'desc' : 'asc'; // swap if we're looping
 | 
						||
        } else {
 | 
						||
          sortState.sortOrder = 'asc'; // reset if we've changed columns
 | 
						||
        }
 | 
						||
        sortState.sortBy = sortField;
 | 
						||
      }
 | 
						||
      data = _.orderBy(data, function(o) { return o[sortState.sortBy].toLowerCase(); }, sortState.sortOrder);
 | 
						||
 | 
						||
      $.each(data, function(key, value) {
 | 
						||
        value.rowNumber = key; // re-key for new sort
 | 
						||
      });
 | 
						||
 | 
						||
      var template = $('#Table').html();
 | 
						||
      var rendered = Mustache.render(template, {books: data});
 | 
						||
      $('#books').html(rendered);
 | 
						||
      $("#books tbody tr").not(':first').on("click", function() {
 | 
						||
        updateCurrentBook(data[$(this)[0].id]); // ignore the headers
 | 
						||
      });
 | 
						||
      $("#books tbody tr th[data-sort-by]").on("click", function() {
 | 
						||
        renderTable(data, $(this).data('sortBy')); // only add callback when there's a sortBy attribute
 | 
						||
      });
 | 
						||
      $("#books tbody tr th[data-sort-by=" + sortState.sortBy + ']').addClass(sortState.sortOrder);
 | 
						||
    }
 | 
						||
 | 
						||
    function updateCurrentBook(book) {
 | 
						||
      var template = $('#View').html();
 | 
						||
      var rendered = Mustache.render(template, {book: book});
 | 
						||
      $('#current').html(rendered);
 | 
						||
    }
 | 
						||
 | 
						||
    function titleCleaner(title) {
 | 
						||
      return title
 | 
						||
        .replace('"', '')
 | 
						||
        .replace(':', '')
 | 
						||
        .replace(/^(An?|The)\s/i, '');
 | 
						||
    }
 | 
						||
 | 
						||
    function generateAmazonCoverUrl(ISBN) {
 | 
						||
      return "https://images-na.ssl-images-amazon.com/images/P/" + ISBN + ".01.LZZ.jpg"
 | 
						||
    }
 | 
						||
 | 
						||
    function generateISBNfromEAN(EAN) {
 | 
						||
      ISBN = EAN.slice(3,12);
 | 
						||
      var checkdigit = ((11 - (_.reduce(ISBN.split(''), function(sum, num, key) {
 | 
						||
        return sum + (num * (10 - key));
 | 
						||
      }, 0) % 11)) % 11);
 | 
						||
      return ISBN + (checkdigit == 10 ? 'X' : checkdigit);
 | 
						||
    }
 | 
						||
 | 
						||
    window.addEventListener('DOMContentLoaded', init);
 | 
						||
  </script>
 | 
						||
</head>
 | 
						||
<body>
 | 
						||
  <div class="wrapper">
 | 
						||
    <div id="header">
 | 
						||
      <h1>Library</h1>
 | 
						||
      <a target="_blank" href="https://docs.google.com/spreadsheets/d/1w5Dc57wV0_rrKFsG7KM-qdPWEpqYk6lFu3JzAA0cSv0/edit">spreadsheet</a>
 | 
						||
      <a target="_blank" href="https://github.com/deltamualpha/my-library">github</a>
 | 
						||
      <a id="reloadLink" href="#">reload</a>
 | 
						||
      <div id="searchBox">
 | 
						||
        <input id="search" type="text" name="search" placeholder="Search..."/>
 | 
						||
      </div>
 | 
						||
    </div>
 | 
						||
    <div id="current">No Book Selected</div>
 | 
						||
    <div id="books"></div> <!-- Table goes here -->
 | 
						||
  </div>
 | 
						||
 | 
						||
  <script id="Table" type="text/html">
 | 
						||
    <table class="bookTable">
 | 
						||
      <tr>
 | 
						||
        <th data-sort-by="sortTitle" class="tHeader title">Title</th>
 | 
						||
        <th data-sort-by="authorLast" class="tHeader author">Author</th>
 | 
						||
        <th data-sort-by="publisher" class="tHeader publisher">Publisher</th>
 | 
						||
        <th data-sort-by="year" class="tHeader year">Year</th>
 | 
						||
        <th class="tHeader isbn">ISBN</th>
 | 
						||
      </tr>
 | 
						||
      {{#books}}
 | 
						||
        <tr class="tRow" id="{{rowNumber}}">
 | 
						||
          <td class="title">{{title}}{{#signed}} <span title="Signed by the author">✔</span>︎{{/signed}}</td>
 | 
						||
          <td class="author">{{author}}</td>
 | 
						||
          <td class="publisher">{{publisher}}</td>
 | 
						||
          <td class="year">{{year}}</td>
 | 
						||
          <td class="isbn">{{isbn-13}}</td>
 | 
						||
        </tr>
 | 
						||
      {{/books}}
 | 
						||
    </table>
 | 
						||
  </script>
 | 
						||
 | 
						||
  <script id="View" type="text/html">
 | 
						||
    {{#book}}
 | 
						||
      {{#coverurl}}
 | 
						||
        <img src="{{coverurl}}"/>
 | 
						||
      {{/coverurl}}
 | 
						||
      <h1>{{title}}</h1>
 | 
						||
      <h2>{{author}}</h2>
 | 
						||
      <span>{{isbn-13}}</span><br/>
 | 
						||
      <span>{{publisher}}, {{year}}</span><br/>
 | 
						||
      {{#series}}
 | 
						||
        <span>{{series}}, Volume {{volume}}</span><br/>
 | 
						||
      {{/series}}
 | 
						||
      {{#signed}}
 | 
						||
        <span>Signed by the author</span><br/>
 | 
						||
      {{/signed}}
 | 
						||
      <span>{{format}}</span>
 | 
						||
      <div class="description">
 | 
						||
        <p>{{description}}</p>
 | 
						||
        {{#notes}}
 | 
						||
          <span>Notes:</span>
 | 
						||
          <p>{{notes}}</p>
 | 
						||
        {{/notes}}
 | 
						||
      </div>
 | 
						||
    {{/book}}
 | 
						||
  </script>
 | 
						||
</body>
 | 
						||
</html>
 |