JS-網站互動設計程式進化之道-Filtering-Searching-Sorting

JavaScript&JQuery-網站互動設計程式進化之道-Filtering, Searching, & Sorting

學習筆記(11) - Filtering, Searching, & Sorting

一名最好的醫生,就在於能最大限度地克制自己的感情,不讓對某些不可挽回的事情的悔恨,干擾完成未來任務的決心 - 保羅·海澤


引言

原文書名:JavaScript & JQuery: Interactive Front-End Web Development
作者:Jon Duckett
譯者:謝銘倫
出版社:碁峰
出版日期:2017/02/24


十二、Filtering, Searching, & Sorting


Filtering

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// .forEach() .push()
// CHECKS EACH PERSON AND ADDS THOSE IN RANGE TO ARRAY
var results = \[\]; // Array for people in range
people.forEach(function(person) { // For each person
if (person.rate >= 65 && person.rate <= 90) { // Is rate in range
results.push(person); // If yes add to array
}


// .filter() 回傳True False結果
// THE FUNCTION ACTS AS A FILTER
function priceRange(person) { // Declare priceRange()
return (person.rate >= 65) && (person.rate <= 90); // In range returns true
};

// FILTER THE PEOPLE ARRAY & ADD MATCHES TO THE RESULTS ARRAY
var results = \[\]; // Array for matching people
results = people.filter(priceRange); // filter() calls priceRange()

動態資料過濾

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// Dynamically Filtering an Array
(function() {
var rows = \[\], // rows array
$min = $('#value-min'), // Minimum text input
$max = $('#value-max'), // Maximum text input
$table = $('#rates'); // The table that shows results

function makeRows() { // Create table rows and the array
people.forEach(function(person) { // For each person object in people
var $row = $('<tr></tr>'); // Create a row for them
$row.append( $('<td></td>').text(person.name) ); // Add their name
$row.append( $('<td></td>').text(person.rate) ); // Add their rate
rows.push({ // Create rows array which links people objects to table rows
person: person, // Reference to the person object
$element: $row // Reference to row as jQuery selection
});
});
}

function appendRows() { // Adds rows to the table
var $tbody = $('<tbody></tbody>'); // Create <tbody> element
rows.forEach(function(row) { // For each object in the rows array
$tbody.append(row.$element); // Add the HTML for the row
});
$table.append($tbody); // Add the rows to the table
}

function update(min, max) { // Update the table content
rows.forEach(function(row) { // For each row in the rows array
if (row.person.rate >= min && row.person.rate <= max) { // If in range
row.$element.show(); // Show the row
} else { // Otherwise
row.$element.hide(); // Hide the row
}
});
}

function init() { // Tasks when script first runs
$('#slider').noUiSlider({ // Set up the slide control
range: \[0, 150\], start: \[65, 90\], handles: 2, margin: 20, connect: true,
serialization: {to: \[$min, $max\],resolution: 1}
}).change(function() { update($min.val(), $max.val()); });
makeRows(); // Create table rows and rows array
appendRows(); // Add the rows to the table
update($min.val(), $max.val()); // Update table to show matches
}

$(init); // Call init() when DOM is ready
}());

影像過濾(data-tags)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 處理標記data-tags
(function() {

var $imgs = $('#gallery img'); // Store all images
var $buttons = $('#buttons'); // Store buttons element
var tagged = {}; // Create tagged object

$imgs.each(function() { // Loop through images and
var img = this; // Store img in variable
var tags = $(this).data('tags'); // Get this element's tags

if (tags) { // If the element had tags
tags.split(',').forEach(function(tagName) { // Split at comma and
if (tagged\[tagName\] == null) { // If object doesn't have tag
tagged\[tagName\] = \[\]; // Add empty array to object
}
tagged\[tagName\].push(img); // Add the image to the array
});
}
});

}());

Searching

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// Searching cache = [];
(function() { // Lives in an IIFE
var $imgs = $('#gallery img'); // Get the images
var $search = $('#filter-search'); // Get the input element
var cache = \[\]; // Create an array called cache

$imgs.each(function() { // For each image
cache.push({ // Add an object to the cache array
element: this, // This image
text: this.alt.trim().toLowerCase() // Its alt text (lowercase trimmed)
});
});

function filter() { // Declare filter() function
var query = this.value.trim().toLowerCase(); // Get the query
cache.forEach(function(img) { // For each entry in cache pass image
var index = 0; // Set index to 0

if (query) { // If there is some query text
index = img.text.indexOf(query); // Find if query text is in there
}

img.element.style.display = index === -1 ? 'none' : ''; // Show / hide
});
}

if ('oninput' in $search\[0\]) { // If browser supports input event
$search.on('input', filter); // Use input event to call filter()
} else { // Otherwise
$search.on('keyup', filter); // Use keyup event to call filter()
}

}());

Sorting

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//Sorting data-sort
var compare = { // Declare compare object
name: function(a, b) { // Add a method called name
a = a.replace(/^the /i, ''); // Remove The from start of parameter
b = b.replace(/^the /i, ''); // Remove The from start of parameter

if (a < b) { // If value a is less than value b
return -1; // Return -1
} else { // Otherwise
return a > b ? 1 : 0; // If a is greater than b return 1 OR
} // if they are the same return 0
},
duration: function(a, b) { // Add a method called duration
a = a.split(':'); // Split the time at the colon
b = b.split(':'); // Split the time at the colon

a = Number(a\[0\]) * 60 + Number(a\[1\]); // Convert the time to seconds
b = Number(b\[0\]) * 60 + Number(b\[1\]); // Convert the time to seconds

return a - b; // Return a minus b
},
date: function(a, b) { // Add a method called date
a = new Date(a); // New Date object to hold the date
b = new Date(b); // New Date object to hold the date

return a - b; // Return a minus b
}
};

$('.sortable').each(function() {
var $table = $(this); // This sortable table
var $tbody = $table.find('tbody'); // Store table body
var $controls = $table.find('th'); // Store table headers
var rows = $tbody.find('tr').toArray(); // Store array containing rows

$controls.on('click', function() { // When user clicks on a header
var $header = $(this); // Get the header
var order = $header.data('sort'); // Get value of data-sort attribute
var column; // Declare variable called column

// If selected item has ascending or descending class, reverse contents
if ($header.is('.ascending') || $header.is('.descending')) {
$header.toggleClass('ascending descending'); // Toggle to other class
$tbody.append(rows.reverse()); // Reverse the array
} else { // Otherwise perform a sort
$header.addClass('ascending'); // Add class to header
// Remove asc or desc from all other headers
$header.siblings().removeClass('ascending descending');
if (compare.hasOwnProperty(order)) { // If compare object has method
column = $controls.index(this); // Search for column index no

rows.sort(function(a, b) { // Call sort() on rows array
a = $(a).find('td').eq(column).text(); // Get text of column in row a
b = $(b).find('td').eq(column).text(); // Get text of column in row b
return compare\[order\](a, b); // Call compare method
});

$tbody.append(rows);
}
}
});
});