Skip to content

Instantly share code, notes, and snippets.

@thefringeninja
Created August 7, 2013 20:45
Show Gist options
  • Save thefringeninja/6178478 to your computer and use it in GitHub Desktop.
Save thefringeninja/6178478 to your computer and use it in GitHub Desktop.
class window.Ajaxinator
constructor: (document) ->
@document = document
serialize = (form) ->
return if not form or form.nodeName isnt "FORM"
q = []
i = form.elements.length - 1
while i >= 0
element = form.elements[i]
i = i - 1
name = element.name
continue if name is ""
encodedValue = encodeURIComponent(element.value)
switch element.nodeName
when "INPUT"
switch element.type
when "text", "hidden", "password", "button", "reset", "submit"
q.push name + "=" + encodedValue
when "checkbox", "radio"
q.push name + "=" + encodedValue if element.checked
when "TEXTAREA"
q.push name + "=" + encodedValue
when "SELECT"
switch element.type
when "select-one"
q.push name + "=" + encodedValue
when "select-multiple"
j = element.options.length - 1
while j >= 0
option = element.options[j]
j = j - 1
q.push name + "=" + encodeURIComponent(option.value) if option.selected
when "BUTTON"
switch element.type
when "reset", "submit", "button"
q.push name + "=" + encodedValue
q.join "&"
inferContentType = (body) ->
if typeof body == "object" then "application/json" else "application/x-www-form-urlencoded"
findXhr = ->
try
xhr = new XMLHttpRequest()
catch e
try
xhr = new ActiveXObject("Msxml2.XMLHTTP");
catch e
xhr
startTimeout = (xhr, errorCallback) ->
setTimeout ->
xhr.abort()
errorCallback xhr
, 10000
defaults = (options) ->
options.method = (options.method || 'GET').toUpperCase()
options.headers = options.headers || {}
options.success = options.success || (data, xhr) ->
options.error = options.error || (data, xhr) ->
if (options.method == "POST" || options.method == "PUT")
options.headers["Content-Type"] = options.headers["Content-Type"] || inferContentType(options.body)
options.headers.Accept = options.headers.Accept || "application/json"
options.headers["X-Requested-With"] = "XMLHttpRequest"
options
handle = (xhr, callback) ->
contentType = xhr.getResponseHeader("Content-type")
data = (if contentType.indexOf("json") > -1 then JSON.parse(xhr.responseText) else xhr.responseText)
callback data, xhr
invoke = (options) =>
throw "expected a url, got " + options.url + " instead." unless typeof options.url == "string"
options = defaults options
xhr = findXhr()
return unless xhr
timeout = startTimeout xhr, options.error
xhr.onreadystatechange = ->
return undefined if xhr.readyState != 4
clearTimeout timeout
if xhr.status < 400 then handle xhr, options.success else handle xhr, options.error
xhr.open(options.method, options.url, true)
xhr.setRequestHeader key, value for key,value of options.headers
xhr.send options.body
xhr
@post = (form, success, error) ->
success = success || (response, xhr) ->
error = error || (response, xhr) ->
processResponse = (response) ->
container = document.createElement "div"
container.innerHTML = response
scripts = container.querySelectorAll "script"
document.body.innerHTML += response
eval script.innerText for script in scripts
options =
url: form.action
headers:
Accept: 'text/html'
body: serialize form
method: 'POST',
success: (response, xhr) ->
processResponse response
success response, xhr
error: (response, xhr) ->
processResponse response
error response, xhr
invoke(options)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment