Skip to content

Commit 4792270

Browse files
add .next() method for pagination. closes #39.
1 parent ca5aa5a commit 4792270

File tree

2 files changed

+59
-15
lines changed

2 files changed

+59
-15
lines changed

src/instafeed.coffee

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
class Instafeed
2-
constructor: (params) ->
2+
constructor: (params, context) ->
33
# default options
44
@options =
55
target: 'instafeed'
@@ -15,11 +15,30 @@ class Instafeed
1515
if typeof params is 'object'
1616
@options[option] = value for option, value of params
1717

18+
# save a reference to context, which defaults to curr scope
19+
# this will be used to cache data from parsing to the real
20+
# instance the user interacts with (for pagination)
21+
@context = if context? then context else this
22+
1823
# generate a unique key for the instance
1924
@unique = @_genKey()
2025

26+
# method to check if there are more results to load
27+
hasNext: ->
28+
return typeof @context.nextUrl is 'string' and @context.nextUrl.length > 0
29+
30+
# method to display next results using the pagination
31+
# data from API. Manually passing a url to .run() will
32+
# bypass the URL creation from options.
33+
next: ->
34+
# check for a valid next url first
35+
return false if not @hasNext()
36+
37+
# call run with the next results
38+
return @run(@context.nextUrl)
39+
2140
# MAKE IT GO!
22-
run: ->
41+
run: (url) ->
2342
# make sure either a client id or access token is set
2443
if typeof @options.clientId isnt 'string'
2544
unless typeof @options.accessToken is 'string'
@@ -41,16 +60,17 @@ class Instafeed
4160
# give the script an id so it can removed later
4261
script.id = 'instafeed-fetcher'
4362

44-
# assign the script src using _buildUrl()
45-
script.src = @_buildUrl()
63+
# assign the script src using _buildUrl(), or by
64+
# using the argument passed to the function
65+
script.src = url || @_buildUrl()
4666

4767
# add the new script object to the header
4868
header = document.getElementsByTagName 'head'
4969
header[0].appendChild script
5070

5171
# create a global object to cache the options
5272
instanceName = "instafeedCache#{@unique}"
53-
window[instanceName] = new Instafeed @options
73+
window[instanceName] = new Instafeed @options, this
5474
window[instanceName].unique = @unique
5575

5676
# return true if everything ran
@@ -89,6 +109,13 @@ class Instafeed
89109
if @options.success? and typeof @options.success is 'function'
90110
@options.success.call(this, response)
91111

112+
# cache the pagination data, if it exists. Apply the value
113+
# to the "context" object, which will be a true reference
114+
# if this instance was created just for parsing
115+
@context.nextUrl = ''
116+
if response.pagination?
117+
@context.nextUrl = response.pagination.next_url
118+
92119
# before images are inserted into the DOM, check for sorting
93120
if @options.sortBy isnt 'most-recent'
94121
# if sort is set to random, don't check for polarity
@@ -121,13 +148,13 @@ class Instafeed
121148
# to make it easier to test various parts of the class,
122149
# any DOM manipulation first checks for the DOM to exist
123150
if document? and @options.mock is false
124-
# clear the current dom node
125-
document.getElementById(@options.target).innerHTML = ''
126-
127151
# limit the number of images if needed
128152
images = response.data
129153
images = images[0..@options.limit] if images.length > @options.limit
130154

155+
# create the document fragment
156+
fragment = document.createDocumentFragment()
157+
131158
# filter the results
132159
if @options.filter? and typeof @options.filter is 'function'
133160
images = @_filter(images, @options.filter)
@@ -139,6 +166,9 @@ class Instafeed
139166
imageString = ''
140167
imgUrl = ''
141168

169+
# create a temp dom node that will hold the html
170+
tmpEl = document.createElement('div')
171+
142172
# loop through the images
143173
for image in images
144174
# use protocol relative image url
@@ -159,12 +189,14 @@ class Instafeed
159189
# add the image partial to the html string
160190
htmlString += imageString
161191

162-
# add the final html to the target DOM node
163-
document.getElementById(@options.target).innerHTML = htmlString
164-
else
165-
# create a document fragment
166-
fragment = document.createDocumentFragment()
192+
# add the final html string to the temp node
193+
tmpEl.innerHTML = htmlString
167194

195+
# loop through the contents of the temp node
196+
# and append them to the fragment
197+
for node in [].slice.call(tmpEl.childNodes)
198+
fragment.appendChild(node)
199+
else
168200
# loop through the images
169201
for image in images
170202
# create the image using the @options's resolution
@@ -186,8 +218,8 @@ class Instafeed
186218
# add the image (without link) to the fragment
187219
fragment.appendChild img
188220

189-
# Add the fragment to the DOM
190-
document.getElementById(@options.target).appendChild fragment
221+
# Add the fragment to the DOM
222+
document.getElementById(@options.target).appendChild fragment
191223

192224
# remove the injected script tag
193225
header = document.getElementsByTagName('head')[0]

test/instafeedTest.coffee

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,18 @@ describe 'Instafeed instace', ->
2424
feed.options.clientId.should.equal 'mysecretid'
2525
feed.options.resolution.should.equal 'thumbnail'
2626

27+
it 'should accept context as a parameter', ->
28+
context = {}
29+
feed = new Instafeed({}, context)
30+
feed.context.should.equal context
31+
32+
it 'should know if there are next results to load', ->
33+
feed = new Instafeed
34+
(feed.hasNext()).should.be.false
35+
36+
feed.nextUrl = "teststring"
37+
(feed.hasNext()).should.be.true
38+
2739
it 'should have a unique timestamp when instantiated', ->
2840
feed = new Instafeed
2941
feed.unique.should.exist

0 commit comments

Comments
 (0)