123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- function replaceDocument(docString) {
- var doc = document.open("text/html");
- doc.write(docString);
- doc.close();
- }
- function doAjaxSubmit(e) {
- var form = $(this);
- var btn = $(this.clk);
- var method = (
- btn.data('method') ||
- form.data('method') ||
- form.attr('method') || 'GET'
- ).toUpperCase();
- if (method === 'GET') {
- // GET requests can always use standard form submits.
- return;
- }
- var contentType =
- form.find('input[data-override="content-type"]').val() ||
- form.find('select[data-override="content-type"] option:selected').text();
- if (method === 'POST' && !contentType) {
- // POST requests can use standard form submits, unless we have
- // overridden the content type.
- return;
- }
- // At this point we need to make an AJAX form submission.
- e.preventDefault();
- var url = form.attr('action');
- var data;
- if (contentType) {
- data = form.find('[data-override="content"]').val() || ''
- if (contentType === 'multipart/form-data') {
- // We need to add a boundary parameter to the header
- // We assume the first valid-looking boundary line in the body is correct
- // regex is from RFC 2046 appendix A
- var boundaryCharNoSpace = "0-9A-Z'()+_,-./:=?";
- var boundaryChar = boundaryCharNoSpace + ' ';
- var re = new RegExp('^--([' + boundaryChar + ']{0,69}[' + boundaryCharNoSpace + '])[\\s]*?$', 'im');
- var boundary = data.match(re);
- if (boundary !== null) {
- contentType += '; boundary="' + boundary[1] + '"';
- }
- // Fix textarea.value EOL normalisation (multipart/form-data should use CR+NL, not NL)
- data = data.replace(/\n/g, '\r\n');
- }
- } else {
- contentType = form.attr('enctype') || form.attr('encoding')
- if (contentType === 'multipart/form-data') {
- if (!window.FormData) {
- alert('Your browser does not support AJAX multipart form submissions');
- return;
- }
- // Use the FormData API and allow the content type to be set automatically,
- // so it includes the boundary string.
- // See https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects
- contentType = false;
- data = new FormData(form[0]);
- } else {
- contentType = 'application/x-www-form-urlencoded; charset=UTF-8'
- data = form.serialize();
- }
- }
- var ret = $.ajax({
- url: url,
- method: method,
- data: data,
- contentType: contentType,
- processData: false,
- headers: {
- 'Accept': 'text/html; q=1.0, */*'
- },
- });
- ret.always(function(data, textStatus, jqXHR) {
- if (textStatus != 'success') {
- jqXHR = data;
- }
- var responseContentType = jqXHR.getResponseHeader("content-type") || "";
- if (responseContentType.toLowerCase().indexOf('text/html') === 0) {
- replaceDocument(jqXHR.responseText);
- try {
- // Modify the location and scroll to top, as if after page load.
- history.replaceState({}, '', url);
- scroll(0, 0);
- } catch (err) {
- // History API not supported, so redirect.
- window.location = url;
- }
- } else {
- // Not HTML content. We can't open this directly, so redirect.
- window.location = url;
- }
- });
- return ret;
- }
- function captureSubmittingElement(e) {
- var target = e.target;
- var form = this;
- form.clk = target;
- }
- $.fn.ajaxForm = function() {
- var options = {}
- return this
- .unbind('submit.form-plugin click.form-plugin')
- .bind('submit.form-plugin', options, doAjaxSubmit)
- .bind('click.form-plugin', options, captureSubmittingElement);
- };
|