Skip to content

Instantly share code, notes, and snippets.

@chrisnicola
Created July 28, 2012 00:58
Show Gist options
  • Save chrisnicola/3191297 to your computer and use it in GitHub Desktop.
Save chrisnicola/3191297 to your computer and use it in GitHub Desktop.
jQuery content changed plugin
# $ contentChanged
# By: Chris Nicola
#
# Provides an attachable 'contentChanged' event for text inputs and allows an
# event to be fired whenever changed content is detected. For convenience the
# event incldues properties for `previous`, `current` and `hasContent`.
#
$.fn.extend
contentChanged: (options) ->
settings =
pollPeriod: 500
settings = $.extend settings, options
checkForContentChanged = (target, stop) ->
$this = $(target)
previous = $this.data('lastValue')
current = $this.val()
$this.data('lastValue', current)
e = $.Event('contentChanged', {
previous: previous
current: current
hasContent: (current and current isnt '')
})
$this.trigger(e) if previous isnt current
if not stop
$this.data('pollTimeout', setTimeout((() => checkForContentChanged(target)), settings.pollPeriod))
@each () ->
if this.nodeName isnt 'INPUT' and this.nodeName isnt 'TEXTAREA'
$.error 'contentChanged only works for input elements'
$this = $(@)
$this.data('content-changed', true)
current = $this.val()
$this.data('lastValue', current)
onFocus = () =>
pollTimeout = $this.data('pollTimeout')
clearTimeout(pollTimeout) if pollTimeout
$this.data('pollTimeout', setTimeout((() => checkForContentChanged(@)), settings.pollPeriod))
onFocus() if $this.is(':focus')
$this.focus onFocus
$this.blur () ->
pollTimeout = $(@).data('pollTimeout')
clearTimeout(pollTimeout) if pollTimeout
checkForContentChanged(@, true)
$ () ->
# If the browser supports the 'input' event use that, otherwise we fallback
# to polling for changes.
if 'oninput' of document.body
$('body').on 'input', (e) ->
$this = $(e.target)
previous = $this.data('lastValue')
current = $this.val()
$this.data('lastValue', current)
e = $.Event('contentChanged', {
previous: previous
current: current
hasContent: (current and current isnt '')
})
$this.trigger(e)
else
$('body').on 'focus.content-changed', 'input, textarea', (e) ->
return if @nodeName isnt 'INPUT' and @nodeName isnt 'TEXTAREA'
$this = $(@)
$this.contentChanged() unless $this.data('content-changed')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment