mirror of
https://github.com/Mottie/tablesorter.git
synced 2024-11-15 23:54:22 +00:00
Mark: Add mark widget. Fixes #1243
This commit is contained in:
parent
04287900d3
commit
04f23cebb5
421
docs/example-widget-mark.html
Normal file
421
docs/example-widget-mark.html
Normal file
@ -0,0 +1,421 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>jQuery tablesorter 2.0 - Mark Widget</title>
|
||||
|
||||
<!-- jQuery -->
|
||||
<script src="js/jquery-latest.min.js"></script>
|
||||
|
||||
<!-- Demo stuff -->
|
||||
<link class="ui-theme" rel="stylesheet" href="css/jquery-ui.min.css">
|
||||
<script src="js/jquery-ui.min.js"></script>
|
||||
<link rel="stylesheet" href="css/jq.css">
|
||||
<link href="css/prettify.css" rel="stylesheet">
|
||||
<script src="js/prettify.js"></script>
|
||||
<script src="js/docs.js"></script>
|
||||
|
||||
<!-- Tablesorter: required -->
|
||||
<link rel="stylesheet" href="../css/theme.blue.css">
|
||||
<style id="css">/* Example showing how to change the mark color by column */
|
||||
tr td:nth-child(1) mark { background: #aa0000; color: #fff; }
|
||||
tr td:nth-child(2) mark { background: #00aa00; color: #fff; }
|
||||
tr td:nth-child(3) mark { background: #0000aa; color: #fff; }
|
||||
tr td:nth-child(4) mark { background: #aaaa00; color: #fff; }
|
||||
tr td:nth-child(5) mark { background: #00aaaa; color: #fff; }
|
||||
tr td:nth-child(6) mark { background: #aa00aa; color: #fff; }
|
||||
</style>
|
||||
<script src="../js/jquery.tablesorter.js"></script>
|
||||
<script src="../js/widgets/widget-filter.js"></script>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/7.0.2/jquery.mark.js"></script>
|
||||
<script src="../js/widgets/widget-mark.js"></script>
|
||||
|
||||
<script id="js">$(function() {
|
||||
|
||||
// ==============================
|
||||
// WITH filter widget
|
||||
// ==============================
|
||||
var $table = $('#table').tablesorter({
|
||||
theme: 'blue',
|
||||
widthFixed : true,
|
||||
// sort & filter diacritics
|
||||
sortLocaleCompare: true,
|
||||
widgets: ['zebra', 'filter', 'mark'],
|
||||
widgetOptions : {
|
||||
filter_external : 'input[name="keyword"]',
|
||||
filter_reset : 'button.reset',
|
||||
|
||||
// default settings
|
||||
mark_accuracy: 'partially',
|
||||
mark_className: '',
|
||||
mark_debug: false,
|
||||
mark_diacritics: true,
|
||||
mark_element: 'mark',
|
||||
mark_exclude: [],
|
||||
mark_iframes: false,
|
||||
mark_log: console,
|
||||
mark_separateWordSearch: true,
|
||||
mark_synonyms: {},
|
||||
// callback functions
|
||||
mark_done: function(totalMatches) {},
|
||||
mark_each: function(element) {},
|
||||
mark_filter: function(node, term, counter, totalCounter) { return true; },
|
||||
mark_noMatch: function(keyword) {}
|
||||
}
|
||||
});
|
||||
|
||||
// preset searches for the first table
|
||||
$('button[data-filter-column]').click(function(){
|
||||
var filters = [],
|
||||
$t = $(this),
|
||||
col = $t.data('filter-column'), // zero-based index, or "all" column
|
||||
txt = $t.data('filter-text') || $t.text(); // text to add to filter
|
||||
filters[col === "all" ? $table[0].config.columns : col] = txt;
|
||||
$.tablesorter.setFilters( $table, filters );
|
||||
return false;
|
||||
});
|
||||
|
||||
// ==============================
|
||||
// NO filter widget
|
||||
// ==============================
|
||||
var $table2 = $('#table2').tablesorter({
|
||||
theme: 'blue',
|
||||
widthFixed : true,
|
||||
// sort & filter diacritics
|
||||
sortLocaleCompare: true,
|
||||
widgets: ['zebra', 'mark'],
|
||||
widgetOptions : {
|
||||
// default settings
|
||||
mark_accuracy: 'partially',
|
||||
mark_className: '',
|
||||
mark_debug: false,
|
||||
mark_diacritics: true,
|
||||
mark_element: 'mark',
|
||||
mark_exclude: [],
|
||||
mark_iframes: false,
|
||||
mark_log: console,
|
||||
mark_separateWordSearch: true,
|
||||
mark_synonyms: {},
|
||||
// callback functions
|
||||
mark_done: function(totalMatches) {},
|
||||
mark_each: function(element) {},
|
||||
mark_filter: function(node, term, counter, totalCounter) { return true; },
|
||||
mark_noMatch: function(keyword) {}
|
||||
}
|
||||
});
|
||||
|
||||
// preset searches on the second table
|
||||
$('button.table2').click(function(){
|
||||
// check for reset
|
||||
var query = $(this).hasClass('reset2') ? '' : this.textContent;
|
||||
$('#table2-search')
|
||||
.val(query)
|
||||
.trigger('input');
|
||||
});
|
||||
|
||||
$('#table2-search').on('input', function() {
|
||||
var config = $table2[0].config,
|
||||
filters = [];
|
||||
// still target the "any" match column
|
||||
filters[config.columns] = this.value;
|
||||
// trigger a mark update
|
||||
$table2.trigger('markUpdate', [filters]);
|
||||
// or call the function directly
|
||||
// $.tablesorter.mark.update(config, filters);
|
||||
});
|
||||
|
||||
});</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="banner">
|
||||
<h1>table<em>sorter</em></h1>
|
||||
<h2>Mark Widget</h2>
|
||||
<h3>Flexible client-side table sorting</h3>
|
||||
<a href="index.html">Back to documentation</a>
|
||||
</div>
|
||||
<div id="main">
|
||||
|
||||
<p></p>
|
||||
<br>
|
||||
<div id="root" class="accordion">
|
||||
|
||||
<h3 id="notes"><a href="#">Notes</a></h3>
|
||||
<div>
|
||||
<ul>
|
||||
<li>Added <span class="verison">v2.27.0</span> for use with the <a href="https://markjs.io/">mark.js</a> plugin.</li>
|
||||
<li>Notable Issues:
|
||||
<ul>
|
||||
<li><button class="bad" type="button" data-filter-column="all">~ae</button> - Some rows won't be highlighted because the filter finds fuzzy matches across rows, while the mark widget is targeting separate cell content.</li>
|
||||
<li><button type="button" data-filter-column="all">/(aaron|bruce)/i</button> - Using a regular expression search will not include diacritics; use an " OR " search instead <button type="button" data-filter-column="all">aaron|bruce</button>.<br>
|
||||
I may fix this in future updates.
|
||||
</li>
|
||||
<li><button class="bad" type="button" data-filter-column="all">/.*/</button> or <button class="bad" type="button" data-filter-column="all">/(|)/</button> - When a regular expression matches everything, the regex is ignored by the mark widget otherwise, <a href="https://github.com/julmot/mark.js/issues/55">mark.js does bad things</a>; but this regex is okay: <button type="button" data-filter-column="all">/.+/</button>.</li>
|
||||
<li><button class="bad" type="button" data-filter-column="3"><=22</button> or <button class="bad" type="button" data-filter-column="5">10 - 20</button> - Operators & ranges are not fully supported (these are not supported at all by the filter widget in an "all" columns match - see the documentation on <a href="example-widget-filter-any-match.html#limitations">any match limitations</a>).</li>
|
||||
<li><button class="bad" type="button" data-filter-column="all">!aaron</button> - There is nothing to highlight for not matches.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>The <a href="https://markjs.io/#mark"><code>mark</code> function</a> is used for the following filter queries:
|
||||
<ul>
|
||||
<li>Plain text</li>
|
||||
<li>Logical AND (<code> and </code> or <code> && </code>) & logical OR (<code> or </code> or <code>|</code>) searches.</li>
|
||||
<li>Invalid regex (e.g. <code>/(|)/</code>).</li>
|
||||
<li>Operator, range, exact and not searches.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>The <a href="https://markjs.io/#markregexp"><code>markRegExp</code> function</a> is used when the filter contains:
|
||||
<ul>
|
||||
<li>A "valid" regular expression</li>
|
||||
<li>Fuzzy search (<code>~</code>)</li>
|
||||
<li>Wild card <code>?</code> or <code>*</code> search</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>Try out the <a href="http://jsfiddle.net/Mottie/odyfw8Lj/">jSFiddle Playground</a>.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h3><a href="#">Options</a></h3>
|
||||
<div>
|
||||
<h4>Mark widget defaults (added inside of tablesorter <code>widgetOptions</code>)</h4>
|
||||
<h5>The widgetOptions are essentially Mark.js settings with a <code>mark_</code> prefix. All options are dynamically updated.</h5>
|
||||
<div>
|
||||
<span class="label label-info">TIP!</span> Click on the link in the function column to reveal full details (or <a href="#" class="toggleAll">toggle</a>|<a href="#" class="showAll">show</a>|<a href="#" class="hideAll">hide</a> all) or double click to update the browser location.
|
||||
</div>
|
||||
<table class="options tablesorter-blue" data-sortlist="[[0,0]]">
|
||||
<thead>
|
||||
<tr><th>Option</th><th>Default</th><th class="sorter-false">Description</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr id="mark-tsupdateclass">
|
||||
<td><a href="#" class="permalink">mark_tsUpdate</a></td>
|
||||
<td>"markUpdate"</td>
|
||||
<td>This option sets the event that can be triggered on the table to update the marks.
|
||||
<div class="collapsible">
|
||||
<br>
|
||||
Use it as follows:
|
||||
<pre class="prettyprint lang-js">$('table').tablesorter({
|
||||
widgets: ['mark'],
|
||||
widgetOptions: {
|
||||
mark_tsUpdate: 'markFu'
|
||||
}
|
||||
});
|
||||
|
||||
$('button.update').click(function(){
|
||||
// update the marks in the table
|
||||
$('table').trigger('markFu');
|
||||
});</pre>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody class="tablesorter-infoOnly">
|
||||
<tr>
|
||||
<th colspan="3">Mark.js settings - see <a href="https://markjs.io/#api">official documentation</a></th>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
<tbody>
|
||||
<tr id="mark-element">
|
||||
<td><span class="permalink">mark_element</span></td>
|
||||
<td>"mark"</td>
|
||||
<td>HTML element to wrap matches.</td>
|
||||
</tr>
|
||||
<tr id="mark-classname">
|
||||
<td><span class="permalink">mark_className</span></td>
|
||||
<td>""</td>
|
||||
<td>A class name added to the element.</td>
|
||||
</tr>
|
||||
<tr id="mark-exclude">
|
||||
<td><span class="permalink">mark_exclude</span></td>
|
||||
<td>[]</td>
|
||||
<td>An array with exclusion selectors. Matches inside these elements will be ignored.</td>
|
||||
</tr>
|
||||
<tr id="mark-separatewordsearch">
|
||||
<td><span class="permalink">mark_separateWordSearch</span></td>
|
||||
<td>true</td>
|
||||
<td>Whether to search for each word separated by a blank.</td>
|
||||
</tr>
|
||||
<tr id="mark-accuracy">
|
||||
<td><span class="permalink">mark_accuracy</span></td>
|
||||
<td>"partially"</td>
|
||||
<td>Use "partially", "complementary", "exactly" or object - see markjs docs for details.</td>
|
||||
</tr>
|
||||
<tr id="mark-diacritics">
|
||||
<td><span class="permalink">mark_diacritics</span></td>
|
||||
<td>true</td>
|
||||
<td>If <code>true</code>, diacritic characters should be matched.</td>
|
||||
</tr>
|
||||
<tr id="mark-synonyms">
|
||||
<td><span class="permalink">mark_synonyms</span></td>
|
||||
<td>{}</td>
|
||||
<td>An object with synonyms..</td>
|
||||
</tr>
|
||||
<tr id="mark-iframes">
|
||||
<td><span class="permalink">mark_iframes</span></td>
|
||||
<td>false</td>
|
||||
<td>Whether to search also inside iframes.</td>
|
||||
</tr>
|
||||
<tr id="mark-each">
|
||||
<td><span class="permalink">mark_each</span></td>
|
||||
<td>function(element){}</td>
|
||||
<td>A callback for each marked element.</td>
|
||||
</tr>
|
||||
<tr id="mark-filter">
|
||||
<td><a href="#" class="permalink">mark_filter</a></td>
|
||||
<td>function(parameters){ return true; }</td>
|
||||
<td>A callback to filter or limit matches.
|
||||
<div class="collapsible">
|
||||
<br>
|
||||
When the <code>mark</code> function is called, the function parameters are:
|
||||
<pre class="prettyprint lang-js">function(node, keyword, matches, totalMatches) { return true; }</pre>
|
||||
When the <code>markRegExp</code> function is called, the function parameters are:
|
||||
<pre class="prettyprint lang-js">function(node, match, totalMatches) { return true; }</pre>
|
||||
<p>In both cases, a <code>return true</code> is needed to highlight the match.</p>
|
||||
<span class="label label-info">Note</span> See the notes section above to know when which function is called.
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="mark-nomatch">
|
||||
<td><a href="#" class="permalink">mark_noMatch</a></td>
|
||||
<td>function(keyword){}</td>
|
||||
<td>A callback function that will be called when there are no matches.
|
||||
<div class="collapsible">
|
||||
<br>
|
||||
When the <code>mark</code> function is called, the keyword parameter is a string.
|
||||
<p>When the <code>markRegExp</code> function is called, the keyword parameter is the regular expression.</p>
|
||||
<span class="label label-info">Note</span> See the notes section above to know when which function is called.
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="mark-done">
|
||||
<td><span class="permalink">mark_done</span></td>
|
||||
<td>function(totalMatches){}</td>
|
||||
<td>A callback function after all marks are done.</td>
|
||||
</tr>
|
||||
<tr id="mark-debug">
|
||||
<td><span class="permalink">mark_debug</span></td>
|
||||
<td>false</td>
|
||||
<td>If <code>true</code>, messages will be logged.</td>
|
||||
</tr>
|
||||
<tr id="mark-log">
|
||||
<td><span class="permalink">mark_log</span></td>
|
||||
<td>console</td>
|
||||
<td>Log message to this object.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<p></p>
|
||||
|
||||
<h1>Demo: With the Filter Widget</h1>
|
||||
<br>
|
||||
Search/Highlight all columns: <input type="text" name="keyword" data-column="all">
|
||||
<button type="button" class="reset">Reset</button>
|
||||
<button type="button" data-filter-column="all">13</button>
|
||||
<button class="bad" type="button" data-filter-column="all" title="See "Notes" on why the second row isn't highlighted">~ee</button>
|
||||
<button type="button" data-filter-column="all">br?n</button>
|
||||
<button type="button" data-filter-column="all">br*n</button>
|
||||
<button type="button" data-filter-column="all">aaron|bruce</button>
|
||||
<button type="button" data-filter-column="all">aaron && 2</button>
|
||||
<table id="table" class="tablesorter">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Rank</th>
|
||||
<th class="filter-match">First Name</th>
|
||||
<th>Last Name</th>
|
||||
<th>Age</th>
|
||||
<th>Total</th>
|
||||
<th>Discount</th>
|
||||
<th>Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>1</td><td>Philip Aaron Wong</td><td>Johnson Sr Esq</td><td>25</td><td>$5.95</td><td>22%</td><td>Jun 26, 2004 7:22 AM</td></tr>
|
||||
<tr><td>11</td><td>Aáron</td><td>Hibert</td><td>12</td><td>$2.99</td><td>5%</td><td>Aug 21, 2009 12:21 PM</td></tr>
|
||||
<tr><td>12</td><td>Brandon Clark</td><td>Henry Jr</td><td>51</td><td>$42.29</td><td>18%</td><td>Oct 13, 2000 1:15 PM</td></tr>
|
||||
<tr><td>111</td><td>Peter</td><td>Párker</td><td>28</td><td>$9.99</td><td>20%</td><td>Jul 6, 2006 8:14 AM</td></tr>
|
||||
<tr><td>21</td><td>John</td><td>Hood</td><td>33</td><td>$19.99</td><td>25%</td><td>Dec 10, 2002 5:14 AM</td></tr>
|
||||
<tr><td>013</td><td>Clark</td><td>Kènt Sr.</td><td>18</td><td>$15.89</td><td>44%</td><td>Jan 12, 2003 11:14 AM</td></tr>
|
||||
<tr><td>005</td><td>Bruce</td><td>Almighty Esq</td><td>45</td><td>$153.19</td><td>44%</td><td>Jan 18, 2021 9:12 AM</td></tr>
|
||||
<tr><td>10</td><td>Alex</td><td>Dumāss</td><td>13</td><td>$5.29</td><td>4%</td><td>Jan 8, 2012 5:11 PM</td></tr>
|
||||
<tr><td>16</td><td>Jim</td><td>Franco</td><td>24</td><td>$14.19</td><td>14%</td><td>Jan 14, 2004 11:23 AM</td></tr>
|
||||
<tr><td>166</td><td>Brüce Lee</td><td>Evans</td><td>22</td><td>$13.19</td><td>11%</td><td>Jan 18, 2007 9:12 AM</td></tr>
|
||||
<tr><td>100</td><td>Brenda Dexter</td><td>McMasters</td><td>18</td><td>$55.20</td><td>15%</td><td>Feb 12, 2010 7:23 PM</td></tr>
|
||||
<tr><td>55</td><td>Dennís</td><td>Bronson</td><td>65</td><td>$123.00</td><td>32%</td><td>Jan 20, 2001 1:12 PM</td></tr>
|
||||
<tr><td>9</td><td>Martha</td><td>delFuego</td><td>25</td><td>$22.09</td><td>17%</td><td>Jun 11, 2011 10:55 AM</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h1>Demo: Without the Filter Widget</h1>
|
||||
<br>
|
||||
Search/Highlight all columns: <input id="table2-search" type="search">
|
||||
<button class="table2 reset2" type="button">Reset</button>
|
||||
<button class="table2" type="button">13</button>
|
||||
<button class="table2 bad" type="button" title="See "Notes" on why the "005 Bruce Almighty" row isn't highlighted">~ee</button>
|
||||
<button class="table2" type="button">br?n</button>
|
||||
<button class="table2" type="button">br*n</button>
|
||||
<button class="table2" type="button">aaron|bruce</button>
|
||||
<button class="table2" type="button">aaron && 2</button>
|
||||
|
||||
<table id="table2" class="tablesorter">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Rank</th>
|
||||
<th class="filter-match">First Name</th>
|
||||
<th>Last Name</th>
|
||||
<th>Age</th>
|
||||
<th>Total</th>
|
||||
<th>Discount</th>
|
||||
<th>Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>1</td><td>Philip Aaron Wong</td><td>Johnson Sr Esq</td><td>25</td><td>$5.95</td><td>22%</td><td>Jun 26, 2004 7:22 AM</td></tr>
|
||||
<tr><td>11</td><td>Aáron</td><td>Hibert</td><td>12</td><td>$2.99</td><td>5%</td><td>Aug 21, 2009 12:21 PM</td></tr>
|
||||
<tr><td>12</td><td>Brandon Clark</td><td>Henry Jr</td><td>51</td><td>$42.29</td><td>18%</td><td>Oct 13, 2000 1:15 PM</td></tr>
|
||||
<tr><td>111</td><td>Peter</td><td>Párker</td><td>28</td><td>$9.99</td><td>20%</td><td>Jul 6, 2006 8:14 AM</td></tr>
|
||||
<tr><td>21</td><td>John</td><td>Hood</td><td>33</td><td>$19.99</td><td>25%</td><td>Dec 10, 2002 5:14 AM</td></tr>
|
||||
<tr><td>013</td><td>Clark</td><td>Kènt Sr.</td><td>18</td><td>$15.89</td><td>44%</td><td>Jan 12, 2003 11:14 AM</td></tr>
|
||||
<tr><td>005</td><td>Bruce</td><td>Almighty Esq</td><td>45</td><td>$153.19</td><td>44%</td><td>Jan 18, 2021 9:12 AM</td></tr>
|
||||
<tr><td>10</td><td>Alex</td><td>Dumāss</td><td>13</td><td>$5.29</td><td>4%</td><td>Jan 8, 2012 5:11 PM</td></tr>
|
||||
<tr><td>16</td><td>Jim</td><td>Franco</td><td>24</td><td>$14.19</td><td>14%</td><td>Jan 14, 2004 11:23 AM</td></tr>
|
||||
<tr><td>166</td><td>Brüce Lee</td><td>Evans</td><td>22</td><td>$13.19</td><td>11%</td><td>Jan 18, 2007 9:12 AM</td></tr>
|
||||
<tr><td>100</td><td>Brenda Dexter</td><td>McMasters</td><td>18</td><td>$55.20</td><td>15%</td><td>Feb 12, 2010 7:23 PM</td></tr>
|
||||
<tr><td>55</td><td>Dennís</td><td>Bronson</td><td>65</td><td>$123.00</td><td>32%</td><td>Jan 20, 2001 1:12 PM</td></tr>
|
||||
<tr><td>9</td><td>Martha</td><td>delFuego</td><td>25</td><td>$22.09</td><td>17%</td><td>Jun 11, 2011 10:55 AM</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h1>Page Header</h1>
|
||||
<div>
|
||||
<pre class="prettyprint lang-html"><!-- blue theme stylesheet -->
|
||||
<link rel="stylesheet" href="css/theme.blue.css">
|
||||
<!-- tablesorter plugin -->
|
||||
<script src="js/jquery-latest.min.js"></script>
|
||||
<script src="js/jquery.tablesorter.js"></script>
|
||||
<script src="js/jquery.tablesorter.widgets.js"></script>
|
||||
|
||||
<!-- jquery.mark.js & tablesorter mark widget loaded after the plugin -->
|
||||
<script src="js/jquery.mark.js"></script>
|
||||
<script src="js/widget-mark.js"></script></pre>
|
||||
</div>
|
||||
|
||||
<h1>CSS</h1>
|
||||
<div id="css">
|
||||
<pre class="prettyprint lang-css"></pre>
|
||||
</div>
|
||||
|
||||
<h1>Javascript</h1>
|
||||
<div id="javascript">
|
||||
<pre class="prettyprint lang-javascript"></pre>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -484,6 +484,7 @@
|
||||
</li>
|
||||
<li><a href="example-widget-header-titles.html">Header titles widget</a> (v2.15.6; <span class="version updated">v2.24.4</span>).</li>
|
||||
<li><span class="label label-info">Beta</span> <a href="example-widget-lazyload.html">Lazyload widget</a> (<span class="version">v2.24.0</span>; <span class="version updated">v2.25.7</span>).</li>
|
||||
<li><a href="example-widget-mark.html">Mark widget</a> (<span class="version">v2.27.0</span>).</li>
|
||||
<li><a href="example-widget-math.html">Math widget</a> (<span class="version">v2.16</span>; <span class="version updated">v2.25.5</span>).</li>
|
||||
<li>
|
||||
<a href="example-widget-output.html">Output widget</a> (<span class="version">v2.16</span>; <span class="version updated">v2.25.2</span>).
|
||||
|
135
js/widgets/widget-mark.js
Normal file
135
js/widgets/widget-mark.js
Normal file
@ -0,0 +1,135 @@
|
||||
/*! Widget: mark.js - updated 7/27/2016 (v2.27.0) *//*
|
||||
* Requires tablesorter v2.8+ and jQuery 1.7+
|
||||
* by Rob Garrison
|
||||
*/
|
||||
;( function( $ ) {
|
||||
'use strict';
|
||||
var ts = $.tablesorter;
|
||||
|
||||
ts.mark = {
|
||||
init : function( c, wo ) {
|
||||
if ( typeof $.fn.mark === 'function' ) {
|
||||
var tmp,
|
||||
update = c.widgetOptions.mark_tsUpdate;
|
||||
c.$table.on( 'filterEnd.tsmark' + ( update ? ' ' + update : '' ), function( e, filters ) {
|
||||
// filterEnd passes "config" as the param
|
||||
ts.mark.update( c, e.type === 'filterEnd' ? '' : filters );
|
||||
});
|
||||
// Regex to split up a query
|
||||
tmp = '(?:<|=|>|\\||\"|' + "\\'|" +
|
||||
'\\s+(?:&&|-|' +
|
||||
( ts.language.and || 'and' ) + '|' +
|
||||
( ts.language.or || 'or' ) + '|' +
|
||||
( ts.language.to || 'to' ) + ')\\s+)';
|
||||
ts.mark.regex.filter = new RegExp(tmp, 'gim');
|
||||
} else {
|
||||
console.warn('Widget-mark not initialized: missing "jquery.mark.js"');
|
||||
}
|
||||
},
|
||||
regex : {
|
||||
mark : /^mark_(.+)$/,
|
||||
// test for regex (e.g. "/(lorem|ipsum)/gi")
|
||||
pure : /^\/((?:\\\/|[^\/])+)\/([mig]{0,3})?$/
|
||||
},
|
||||
checkRegex : function( regex ) {
|
||||
if ( regex instanceof RegExp ) {
|
||||
// prevent lock up of mark.js (see https://github.com/julmot/mark.js/issues/55)
|
||||
var result = '\u0001\u0002\u0003\u0004\u0005'.match( regex );
|
||||
return result === null || result.length < 5;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
cleanMatches : function( matches ) {
|
||||
var results = [],
|
||||
indx = matches && matches.length || 0;
|
||||
while ( indx-- ) {
|
||||
if ( matches[indx] !== "" ) {
|
||||
results[ results.length ] = matches[ indx ];
|
||||
}
|
||||
}
|
||||
return results;
|
||||
},
|
||||
update : function( c, filters ) {
|
||||
var options = {},
|
||||
regex = ts.mark.regex,
|
||||
$rows = c.$table
|
||||
.find( 'tbody tr' )
|
||||
.unmark()
|
||||
.not( '.' + ( c.widgetOptions.filter_filteredRow || 'filtered' ) ),
|
||||
filters = filters || $.tablesorter.getFilters( c.$table );
|
||||
// extract & save mark options from widgetOptions (prefixed with "mark_")
|
||||
// update dynamically
|
||||
$.each( filters, function( indx, filter ) {
|
||||
if ( filter ) {
|
||||
var testRegex = null,
|
||||
matches = filter,
|
||||
useRegex = false,
|
||||
col = indx === c.columns ? '' : ':nth-child(' + ( indx + 1 ) + ')';
|
||||
// regular expression entered
|
||||
if ( regex.pure.test( filter ) ) {
|
||||
matches = regex.pure.exec( filter );
|
||||
// ignore "all" matches (i.e. /.*/)
|
||||
if (matches[1] === '.*') {
|
||||
matches[1] = '';
|
||||
}
|
||||
try {
|
||||
// make sure to include global flag when testing regex
|
||||
testRegex = new RegExp( matches[ 1 ], 'gim' );
|
||||
matches = new RegExp( matches[ 1 ], matches[ 2 ] );
|
||||
} catch (err) {
|
||||
matches = null;
|
||||
}
|
||||
if ( ts.mark.checkRegex( testRegex ) ) {
|
||||
$rows.children( col ).markRegExp( matches, options );
|
||||
}
|
||||
// matches is either null, invalid, or done my markRegExp
|
||||
return;
|
||||
}
|
||||
// all special querys (or, and, wild cards & fuzzy)
|
||||
// regex seems to not be consistent here; so use string indexOf
|
||||
// fuzzy or wild card matches
|
||||
if ( filter.indexOf( '~' ) === 0 ) {
|
||||
useRegex = true;
|
||||
// fuzzy search separate each letter
|
||||
matches = filter.replace( /~/g, '' ).split( '' );
|
||||
} else {
|
||||
// wild card matching
|
||||
if ( filter.indexOf( '?' ) > -1 ) {
|
||||
useRegex = true;
|
||||
filter = filter.replace( /\?/g, '\\S{1}' );
|
||||
}
|
||||
if ( filter.indexOf( '*' ) > -1 ) {
|
||||
useRegex = true;
|
||||
filter = filter.replace( /\*/g, '\\S*' );
|
||||
}
|
||||
matches = filter.split( regex.filter );
|
||||
}
|
||||
if ( useRegex && matches && matches.length ) {
|
||||
matches = new RegExp( ts.mark.cleanMatches( matches ).join( '.*' ), 'gim' );
|
||||
if ( ts.mark.checkRegex( matches ) ) {
|
||||
$rows.children( col ).markRegExp( matches, options );
|
||||
}
|
||||
} else {
|
||||
// pass an array of matches
|
||||
$rows.children( col ).mark( ts.mark.cleanMatches( matches ), options );
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
ts.addWidget({
|
||||
id: 'mark',
|
||||
options: {
|
||||
mark_tsUpdate : "markUpdate"
|
||||
},
|
||||
init : function( table, thisWidget, c, wo ) {
|
||||
ts.mark.init( c, wo );
|
||||
},
|
||||
remove : function( table, c ) {
|
||||
var update = c.widgetOptions.mark_tsUpdate;
|
||||
c.$table.off( 'filterEnd.tsmark' + ( update ? ' ' + update : '' ) );
|
||||
}
|
||||
});
|
||||
|
||||
})( jQuery );
|
Loading…
Reference in New Issue
Block a user