Skip to content

Commit

Permalink
- \#27: Added a removeDuplicates option which if set to true remo…
Browse files Browse the repository at this point in the history
…ves new duplicate items when they are loaded.
  • Loading branch information
mac89 committed Dec 11, 2018
1 parent ded5c94 commit bc95d9b
Show file tree
Hide file tree
Showing 6 changed files with 425 additions and 131 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [3.0.0] - 2018-11-12
### Added
- \#27: Added a `removeDuplicates` option which if set to `true` removes new duplicate items when they are loaded.

## [2.3.0] - 2018-09-24
### Added
- \#25: Added a `lazyloaderreset` event. This event is triggered before a reset request is made.
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,12 @@ The server response is expected to be in a JSON format with the mandatory `items
<td>No</td>
<td>The search query that is posted along in the request. Changing this option will trigger the `reset` function.</td>
</tr>
<tr>
<td>removeDuplicates</td>
<td>true</td>
<td>No</td>
<td>Removes new duplicate items loaded by a load more request. Items within a request are not compared to one another.</td>
</tr>
<tr>
<td>ajaxSettings</td>
<td>{<br>
Expand Down
181 changes: 130 additions & 51 deletions dist/jquery.mobile.lazyloader.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,13 @@ $.widget( "mobile." + widgetName, $.mobile.listview, {
*/
ajaxSettings: {
type: "POST"
}
},

/**
* Indicates duplicate items need to be removed.
* @type {boolean}
*/
removeDuplicates: true
},

/**
Expand Down Expand Up @@ -392,81 +398,154 @@ $.widget( "mobile." + widgetName, $.mobile.listview, {

// Check if the items property is an array
if ( Array.isArray( items ) ) {
var count = items.length,
html = [],

// Check if we're done loading
done = count < options.retrieve;

// Update the number of retrieved items
options.retrieved += count;

// Get the ich templates
ich.grabTemplates();
var count = items.length;

// Trigger event to allow for manipulation of the loaded items before rendering
// takes place
this._trigger( "beforerender", {}, [ items ] );

// Render items
items.forEach( function( item ) {
self._renderItems( items );

// Create html for the item using the template
html.push( ich[ options.templateId ]( item ) );
} );
// Finish the load more operation.
self._finish( count );
} else {

// Trigger an event to announce that an error occurred during parsing
self._handleError( parseResultErrorCode, data );
}
},

/**
* Renders the provide items.
* @param {Object[]} items The items to render.
* @private
*/
_renderItems: function( items ) {
var self = this,
options = self.options,
$element = self.element,
html = [],
$children = $element.children();

// Add the list items html to the list
$element.append( html );
// Get the ich templates
ich.grabTemplates();

// Refresh the listview so it is re-enhanced by JQM
// Render items
items.forEach( function( item ) {

// Create html for the item using the template
html.push( ich[ options.templateId ]( item ) );
} );

// Add the list items html to the list
$element.append( html );

if ( options.removeDuplicates ) {

// Refresh the listview so it is re-enhanced by JQM and an accurate comparison can be made
// between items
self.refresh();

// Check if the element's height exceeds that of the window/scroll parent
var elementHeightExceedsWindowHeight = self._showHierarchy( function() {
// Check if any of the new items already exist within the list
$children.each( function() {

// Check if there any items left
if ( html.length === 0 ) {

// Get the scroll parent
var $scrollParent = self._getScrollParent();
// Exit the loop as there's nothing left to compare with
return false;
}

var $child = $( this ), classesToRemove = "ui-first-child ui-last-child";
html.some( function( $value, index ) {

// Check if the HTML matches
if ( $value.clone().removeClass( classesToRemove ).prop( "outerHTML" ) ===
$child.clone().removeClass( classesToRemove ).prop( "outerHTML" ) ) {

// Remove from the array
html.splice( index, 1 );

// If the scroll parent is the document its height will always be higher than that of the
// list. Therefor we're going to use the window's height.
var scrollParentHeight = $scrollParent.is( document ) ?
self._getWindowHeight() : $scrollParent.height();
// Remove element
$value.remove();

// Get the height of the listview and window
return $element.height() > scrollParentHeight;
// Exit
return true;
} else {
return false;
}
} );
} );
}

// Only hide the progress element if no more items are going to be loaded
// immediately after this
if ( elementHeightExceedsWindowHeight || done ) {
// Refresh the listview so it is re-enhanced by JQM
self.refresh();

// Hide the progress element
$( options.$progress ).hide();
}
// Update the number of retrieved items with the number of actually added items
options.retrieved += html.length;
},

// Indicate whether or not all items have been loaded
self._done = done;
/**
* Finishes the load more operation.
* If the number of retrieved items is lower than the requested number of items the lazy loader
* considers itself to be done.
*
* If the number of retrieved items is equal or higher one of two things can happen. Either the
* list fills its scroll parent and only an event is emitted or the list does not fill its scroll
* parent and another request is sent out.
*
* @param {number} numberRetrieved The number of newly retrieved items.
* @private
*/
_finish: function( numberRetrieved ) {
var self = this,
options = self.options,

if ( done ) {
// Check if we're done loading
done = numberRetrieved < options.retrieve;

// Trigger an event to announce that the lazyloader is done loading
self._trigger( doneLoadingEvent );
// Check if the element's height exceeds that of the window/scroll parent
var elementHeightExceedsWindowHeight = self._showHierarchy( function() {

// Trigger an event to announce that the lazyloader is done loading entirely
self._trigger( allDoneEvent );
} else if ( !elementHeightExceedsWindowHeight ) {
// Get the scroll parent
var $scrollParent = self._getScrollParent();

// No scrolling is possible yet, so load some more right away
self._load();
} else {
// If the scroll parent is the document its height will always be higher than that of the
// list. Therefor we're going to use the window's height.
var scrollParentHeight = $scrollParent.is( document ) ?
self._getWindowHeight() : $scrollParent.height();

// Trigger an event to announce that the lazyloader is done loading
self._trigger( doneLoadingEvent );
}
// Get the height of the listview and window
return self.element.height() > scrollParentHeight;
} );

// Only hide the progress element if no more items are going to be loaded
// immediately after this
if ( elementHeightExceedsWindowHeight || done ) {

// Hide the progress element
$( options.$progress ).hide();
}

// Indicate whether or not all items have been loaded
self._done = done;

if ( done ) {

// Trigger an event to announce that the lazyloader is done loading
self._trigger( doneLoadingEvent );

// Trigger an event to announce that the lazyloader is done loading entirely
self._trigger( allDoneEvent );
} else if ( !elementHeightExceedsWindowHeight ) {

// No scrolling is possible yet, so load some more right away
self._load();
} else {

// Trigger an event to announce that an error occurred during parsing
self._handleError( parseResultErrorCode, data );
// Trigger an event to announce that the lazyloader is done loading
self._trigger( doneLoadingEvent );
}
},

Expand Down
2 changes: 1 addition & 1 deletion dist/jquery.mobile.lazyloader.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit bc95d9b

Please sign in to comment.