//= require simple_inheritance //= require debug_logger var initThinMan = function() { thin_man = { getSubClass: function(sub_class_name, parent_class) { if ((typeof(sub_class_name) == 'string') && (sub_class_name != '') && (sub_class_name != 'true')) { var this_class = sub_class_name; } else { var this_class = parent_class; } return this_class; }, getLinkGroup: function(name) { if (thin_man.hasOwnProperty('link_groups') && thin_man.link_groups.hasOwnProperty(name)) { return thin_man.link_groups[name] } else { return thin_man.addLinkGroup(name) } }, addLinkGroup: function(name) { if (!thin_man.hasOwnProperty('link_groups')) { thin_man.link_groups = {} } if (!thin_man.link_groups.hasOwnProperty(name)) { var this_group = new thin_man.LinkGroup(name) thin_man.link_groups[name] = this_group return this_group } }, addLinkToGroup: function(link, sequence_number, group_name) { var group = thin_man.getLinkGroup(group_name) group.addLink(link, sequence_number) }, LinkGroup: Class.extend({ init: function(name) { this.name = name this.resetLinks() }, resetLinks: function() { this.links = {} this.current_number = 0 }, addLink: function(link_submission, sequence_number) { if (this.links.hasOwnProperty(sequence_number)) { //If there is already a link with this number, we're starting over with a new list this.resetLinks() } this.links[sequence_number] = link_submission link_submission.addWatcher(this) if (sequence_number == this.current_number) { this.fire() } }, fire: function() { if (this.links.hasOwnProperty(this.current_number)) { this.links[this.current_number].fire() } }, linkCompleted: function(link_submission) { this.current_number += 1 this.fire() } }), AjaxSubmission: Class.extend({ init: function(jq_obj, params) { this.jq_obj = jq_obj this.params = params if (!this.params) { this.params = {} } // Bail out if this is a no-mouse-click ajax element and we were mouse clicked if (this.wasMouseClicked() && this.noMouseClick()) { return false } this.getTrigger() this.getTarget() this.getErrorTarget() this.progress_color = jq_obj.data('progress-color') this.progress_target = $(jq_obj.data('progress-target')) this.mask_target = jq_obj.data('mask-target') if(this.mask_target){this.$mask_target = $(this.mask_target)} this.$mask_message = jq_obj.data('mask-message') this.custom_progress = typeof(jq_obj.data('custom-progress')) != 'undefined'; this.scroll_to = jq_obj.data('scroll-to') this.watchers = [] this.search_params = jq_obj.data('search-params') this.search_path = jq_obj.data('search-path') if (this.progress_target.length == 0 && this.trigger.length > 0) { this.progress_target = this.trigger this.trigger_is_progress_target = true } this.insert_method = this.getInsertMethod() var ajax_submission = this this.ajax_options = { url: ajax_submission.getAjaxUrl(), type: ajax_submission.getAjaxType(), datatype: ajax_submission.getAjaxDataType(), data: ajax_submission.getData(), beforeSend: function(jqXHr) { return ajax_submission.ajaxBefore(jqXHr) }, success: function(data, textStatus, jqXHR) { ajax_submission.ajaxSuccess(data, textStatus, jqXHR) }, error: function(jqXHr) { ajax_submission.ajaxError(jqXHr) }, complete: function(jqXHr) { ajax_submission.ajaxComplete(jqXHr) }, processData: ajax_submission.getProcessData() }; if (!this.sendContentType()) { this.ajax_options.contentType = false }; if (typeof this.customXHR === 'function') { this.ajax_options.xhr = this.customXHR this.ajax_options.thin_man_obj = this; } this.handleGroup() if (this.readyToFire()) { this.fire() } }, fire: function() { $.ajax(this.ajax_options); }, readyToFire: function() { if (!this.sequence_group) { return true } }, handleGroup: function() { this.sequence_group = this.jq_obj.data('sequence-group'); this.sequence_number = this.jq_obj.data('sequence-number'); if (typeof(this.sequence_number) == 'number' && !this.sequence_group) { console.log('Warning! Thin Man Link has sequence number but no sequence group.') } if (this.sequence_group && typeof(this.sequence_number) != 'number') { console.log('Warning! Thin Man Link has sequence group ' + this.sequence_group + ' but no sequence number.') } if (this.sequence_group) { thin_man.addLinkToGroup(this, this.sequence_number, this.sequence_group) } }, getTarget: function() { this.target_selector = this.jq_obj.data('ajax-target'); if (this.target_selector) { if ($(this.target_selector).length > 0) { this.target = $(this.target_selector); } else { console.log('Warning! Thin Man selector ' + this.target_selector + ' not found') } } else { console.log('Warning! Thin Man selector not given') } }, getErrorTarget: function() { if ($(this.jq_obj.data('error-target')).length > 0) { this.error_target = $(this.jq_obj.data('error-target')); } else { this.error_target = $(this.jq_obj.data('ajax-target')); } }, getAjaxDataType: function() { return this.jq_obj.data('return-type') || 'html'; }, getInsertMethod: function() { return this.jq_obj.data('insert-method') || 'html'; }, getData: function() { return null; }, getProcessData: function() { return true; }, sendContentType: function() { return true; }, insertHtml: function(data) { debug_logger.log("thin_man.AjaxSubmission.insertHtml target:", 1, 'thin-man') debug_logger.log(this.target, 1, 'thin-man') debug_logger.log("thin_man.AjaxSubmission.insertHtml insert_method:", 1, 'thin-man') debug_logger.log(this.insert_method, 1, 'thin-man') if (this.target) { this.target[this.insert_method](data); if (this.refocus()) { this.target.find('input,select,textarea').filter(':visible:enabled:first').each(function() { if (!$(this).data('date-picker')) { $(this).focus(); } }); } if (this.scroll_to) { if (this.target.is(':hidden')) { if (this.target.parents('[data-tab-id]').length > 0) { this.target.parents('[data-tab-id]').each(function() { var tab_key = $(this).data('tab-id') $('[data-tab-target-id="' + tab_key + '"]').trigger('click') }) } } var extra_offset = 0 if ($('[data-thin-man-offset]').length > 0) { extra_offset = $('[data-thin-man-offset]').outerHeight() } if(this.jq_obj.data('scroll-center')){ var window_height = window.innerHeight var target_height = this.target.outerHeight() if(window_height > target_height){ extra_offset = (window_height - target_height)/2 } } $('html, body').animate({ scrollTop: this.target.offset().top - extra_offset }, 1000); } } }, refocus: function() { return true; }, ajaxSuccess: function(data, textStatus, jqXHR) { debug_logger.log("thin_man.AjaxSubmission.ajaxSuccess data:", 1, 'thin-man') debug_logger.log(data, 1, 'thin-man') if (typeof data === 'string') { this.insertHtml(data); } else if (typeof data === 'object') { if (typeof data.html != 'undefined') { if (typeof data.hooch_modal != 'undefined') { new hooch.Modal($(data.html),data.dismissable) } else { this.insertHtml(data.html) } } if (typeof data.class_triggers != 'undefined') { $.each(data.class_triggers, function(class_name, params) { try { klass = eval(class_name); new klass(params); } catch (err) { console.log("Error trying to instantiate class " + class_name + " from ajax response:") console.log(err) } }) } if (typeof data.function_calls != 'undefined') { $.each(data.function_calls, function(func_name, params) { try { func = eval(func_name); func(params); } catch (err) { console.log("Error trying to instantiate function " + func_name + " from ajax response:") console.log(err) } }) } if (typeof data.replacement_path != 'undefined') { this.replacement_path = data.replacement_path } if (typeof data.push_path != 'undefined') { this.push_path = data.push_path } } if (this.target) { var ajax_flash = this.target.children().last().data('ajax-flash'); if ((jqXHR.status == 200) && ajax_flash) { new thin_man.AjaxFlash('success', ajax_flash.notice, this.target); } } if (this.removeOnSuccess()) { if ($(this.removeOnSuccess())) { $(this.removeOnSuccess()).remove(); } } if (this.emptyOnSuccess()) { if ($(this.emptyOnSuccess())) { $(this.emptyOnSuccess()).empty(); } } if ($.contains(document, this.jq_obj[0])) { this.jq_obj.find('.error').removeClass('error') this.jq_obj.find('.help-inline').remove() } this.handleHistory() }, handleHistory: function(){ if(!this.replacement_path){ //if it wasn't passed in the response, look for it on the trigger object this.replacement_path = this.jq_obj.data('replacement-path') } if(this.replacement_path){ this.handleReplaceState() } if(!this.push_path){ //if it wasn't passed in the response, look for it on the trigger object this.push_path = this.jq_obj.data('push-path') } if(this.push_path){ this.handlePushState() } }, handleReplaceState: function(){ if('/' === this.replacement_path[0]){ this.replacement_path = this.replacement_path.slice(1) } var new_url = [location.protocol, '//', location.host, '/', this.replacement_path].join('') var new_path = '/' + this.replacement_path history['replaceState']({path: new_path, target: this.target_selector, thin_man: true}, null, new_url); }, handlePushState: function(){//TODO must implement onPopState handler which is commented out below if('/' === this.push_path[0]){ this.push_path = this.push_path.slice(1) } var new_url = [location.protocol, '//', location.host, '/', this.push_path].join('') var new_path = '/' + this.push_path history['pushState']({path: new_path, target: this.target_selector, thin_man: true}, null, new_url); }, addWatcher: function(watcher) { if (!this.hasOwnProperty('watchers')) { this.watchers = [] } this.watchers.push(watcher) }, notifyWatchers: function() { $.each(this.watchers, function() { this.linkCompleted(this) }) }, ajaxComplete: function(jqXHR) { debug_logger.log('thin_man.AjaxSubmission.ajaxComplete jqXHR:', 1, 'thin-man') debug_logger.log(jqXHR, 1, 'thin-man') this.showTrigger(); this.notifyWatchers(); if (this.progress_indicator) { this.progress_indicator.stop(); } else if (!this.trigger_is_progress_target) { this.progress_target.remove(); } if (typeof this.mask != 'undefined') { this.mask.remove(); } try { var response_data = JSON.parse(jqXHR.responseText) } catch (err) { var response_data = {} // hmmm, the response is not JSON, so there's no flash. } if (typeof response_data.flash_message != 'undefined') { var flash_style = this.httpResponseToFlashStyle(jqXHR.status); var flash_duration = null; if (typeof response_data.flash_persist != 'undefined') { if (response_data.flash_persist) { flash_duration = 'persist' } else { flash_duration = 'fade' } } if (this.target) { this.flash = new thin_man.AjaxFlash(flash_style, response_data.flash_message, this.target, flash_duration); } else { this.flash = new thin_man.AjaxFlash(flash_style, response_data.flash_message, this.jq_obj, flash_duration); } } if ('function' == typeof this.params.on_complete) { this.params.on_complete() } }, ajaxBefore: function(jqXHr) { this.toggleLoading(); if (!this.custom_progress) { this.progress_indicator = new thin_man.AjaxProgress(this.progress_target, this.target, this.progress_color); } if (this.$mask_target) { this.mask = new thin_man.AjaxMask(this.$mask_target, this.$mask_message) } }, ajaxError: function(jqXHR) { debug_logger.log('thin_man.AjaxSubmission.ajaxError jqXHR:', 1, 'thin-man') debug_logger.log(jqXHR, 1, 'thin-man') if ([409,422,424,428].indexOf(jqXHR.status) >= 0) { try { var data = JSON.parse(jqXHR.responseText); debug_logger.log("thin_man.AjaxSubmission.ajaxError responseText is valid JSON, parsing to an object:", 1, 'thin-man') } catch (error) { debug_logger.log("thin_man.AjaxSubmission.ajaxError responseText is not JSON, assuming a string:", 1, 'thin-man') debug_logger.log(jqXHR.responseText, 1, 'thin-man') var data = jqXHR.responseText; debug_logger.log("thin_man.AjaxSubmission.ajaxError data to insert:", 1, 'thin-man') debug_logger.log(data, 1, 'thin-man') } debug_logger.log("thin_man.AjaxSubmission.ajaxError error target:", 1, 'thin-man') debug_logger.log(this.error_target, 1, 'thin-man') debug_logger.log("thin_man.AjaxSubmission.ajaxError data:", 1, 'thin-man') debug_logger.log(data, 1, 'thin-man') if (typeof data === 'string') { debug_logger.log("thin_man.AjaxSubmission.ajaxError data is a string, inserting into target.", 1, 'thin-man') this.error_target.html(data); } else if (typeof data === 'object') { debug_logger.log("thin_man.AjaxSubmission.ajaxError data is an object.", 1, 'thin-man') if (typeof data.html != 'undefined') { debug_logger.log("thin_man.AjaxSubmission.ajaxError data.html exists, inserting into target.", 1, 'thin-man') if (typeof data.hooch_modal != 'undefined') { new hooch.Modal($(data.html),data.dismissable) } else { this.error_target.html(data.html); } } } } else if (jqXHR.status == 500) { if (this.sendHelpLink()) { if (window.confirm('There was an error communicating with the server. Please click "ok" to submit a bug report. If a new tab does not open, please disable pop up blocking and try again. Clicking "Cancel" will return you to the current page.')) { this.updateAndSubmitForm() }; } else { window.alert('There was an error communicating with the server.') } } }, sendHelpLink: function() { var sendHelpLink = $("meta[name='sendHelpLink']").attr("content") return (undefined !== sendHelpLink && "true" === sendHelpLink) }, updateAndSubmitForm: function() { var $form = $('#ajax-500-help') var user = this.getCurrentUser() var token = $("meta[name='helpToken']").attr("content") $form.children('input[name="http_request_details[requested_path]"]').val(this.ajax_options.url) $form.children('input[name="http_request_details[referred_from]"]').val(window.location.href) $form.children('input[name="http_request_details[request_method]"]').val(this.ajax_options.type) $form.children('input[name="http_request_details[data]"]').val(this.ajax_options.data) $form.children('input[name="submission[occured_at]"]').val(new Date()) $form.children('input[name="submission[url]"]').val(window.location.href) $form.children('input[name="submission[url]"]').val(window.location.href) $form.children('input[name="user[name]"]').val(user.name) $form.children('input[name="user[email]"]').val(user.email) $form.children('input[name="user[time_zone]"]').val(user.time_zone) $form.children('input[name="token"]').val(token) $form.submit() }, getCurrentUser: function() { user = { name: $("meta[name='userName']").attr("content"), email: $("meta[name='userEmail']").attr("content"), time_zone: $("meta[name='userTimeZone']").attr("content") } return user }, getTrigger: function() {}, hideTrigger: function() {}, showTrigger: function() {}, toggleLoading: function() { if (this.target) { if (this.target.find('[data-loading-visible="false"]').length > 0) { this.target.find('[data-loading-visible="false"]').hide(); } if (this.target.find('[data-loading-visible="true"]').length > 0) { this.target.find('[data-loading-visible="true"]').show(); } } }, removeOnSuccess: function() { return this.jq_obj.data('remove-on-success') }, emptyOnSuccess: function() { return this.jq_obj.data('empty-on-success') }, httpResponseToFlashStyle: function(response_code) { if ([403, 409, 500].indexOf(response_code) > -1) { return 'error' } if ([200, 202].indexOf(response_code) > -1) { return 'success' } return 'error' }, wasMouseClicked: function() { return this.params.e && this.params.e.type && this.params.e.type == 'click' }, noMouseClick: function() { return this.jq_obj.data('no-mouse-click') } }), AjaxBrowserPushConnector: Class.extend({ init: function($connector) { this.trigger = $connector.find('button, input[type="submit"]'); if (this.trigger.length < 1) { this.trigger = $connector; } this.browser_push_progress_indicator = new thin_man.AjaxProgress(this.trigger, this.trigger, this.progress_color); $connector.data('browser-push-progress-indicator-object', this.browser_push_progress_indicator); } }), AjaxBrowserPushFlash: Class.extend({ init: function($flash) { this.message = $flash.data('ajax-browser-push-flash') this.$target = $($flash.data('ajax-browser-push-flash-target')); this.$target.data('ajax-browser-push-flash', this.message); } }), AjaxProgress: Class.extend({ init: function(target, alt, progress_color) { if (target.length > 0 && target.is(':visible') && target.css('display') != 'inline' && target.css('display') != 'inline-block') { this.progress_target = target; } else if (typeof(alt) != 'undefined' && alt.is(':visible')) { this.progress_target = alt; } else if (target.length > 0 && target.is(':hidden')) { this.progress_target = $('') } else { this.progress_target = $('body'); } if (typeof(progress_color) == 'undefined') { var progress_color = 'black'; } this.progress_container = $('#ajax_progress_container').clone(); var uuid = new UUID; this.progress_container.prop('id', 'thin_man_ajax_progress_' + uuid.value); this.progress_target.append(this.progress_container); var css = { display: 'block', visibility: 'visible', 'color': progress_color, 'z-index': 1000000 } $.extend(css, { position: 'absolute', top: '50%', left: '50%', '-ms-transform': 'translate(-50%, -50%)', /* IE 9 */ '-webkit-transform': 'translate(-50%, -50%)', /* Safari */ 'transform': 'translate(-50%, -50%)' }) this.progress_container.css(css) }, stop: function() { this.progress_container.remove(); } }), AjaxMask: Class.extend({ init: function($mask_target, mask_message) { var uuid = new UUID; this.$mask_target = $mask_target this.$mask = $('#thin_man_mask').clone() this.$mask.prop('id', 'thin_man_mask' + uuid.value) if (typeof mask_message != 'undefined') { var $message = this.$mask.find('[data-thin-man-mask-message]') $message.html(mask_message) } var height = this.$mask_target.outerHeight() var width = this.$mask_target.outerWidth() var radius = this.$mask_target.css('border-radius') this.$mask.css({ 'height': height, 'width': width, 'left': 0, 'top': 0, 'border-radius': radius }) this.$mask.css({ 'position': 'absolute', 'z-index': 10000 }) this.$mask_target.append(this.$mask) this.disableScroll() this.arrangeContent() }, arrangeContent: function(){ this.$mask.css({'max-height': window.innerHeight}) this.$mask.show() }, disableScroll: function(){ if($(window).width() >= 640){ var mask = this mask.old_height = $('body')[0].style.height mask.old_overflow = $('body')[0].style.overflow $('body').css({height: '100%',overflow: 'hidden'}) } else { $('body').children().not('.ajax-mask-public').hide() } }, enableScroll: function(){ if($(window).width() >= 640){ $('body').css({height: this.old_height, overflow: this.old_overflow}) } else { $('body').children().not('#ajax-mask-public').show() } }, remove: function() { this.enableScroll() this.$mask.remove() } }), AjaxFlash: Class.extend({ init: function(type, message, elem, duration) { this.flash_container = $('[data-thin-man-flash-template]').clone(); this.flash_container.removeAttr('data-thin-man-flash-template'); this.flash_container.attr('data-thin-man-flash-container', true); $('body').append(this.flash_container); this.flash_container.css({ position: 'absolute', visibility: 'hidden' }); this.alert_type = type; this.elem = elem; var alert_class = 'alert-' + type; this.flash_container.addClass(alert_class); this.flash_content = this.flash_container.find('[data-thin-man-flash-content]'); this.flash_content.html(message); this.flash_container.show(); this.setFadeBehavior(duration); this.reposition(elem); this.bindDismisser(); }, setFadeBehavior: function(duration) { if (duration) { if ('persist' == duration) { this.fade = false } else { this.fade = true } } else { //default behavior if persist duration is not sent back with message if ('error' == this.alert_type || 'warning' == this.alert_type || 'info' == this.alert_type) { this.fade = false; } else { this.fade = true; } } }, reposition: function(elem) { var this_window = { top: $(window).scrollTop(), left: $(window).scrollLeft(), height: $(window).outerHeight(), width: $(window).outerWidth() }; var this_flash = { height: this.flash_container.outerHeight(), width: this.flash_container.outerWidth() } this_window.vert_middle = (this_window.top + (this_window.height / 2)); this_window.horiz_middle = (this_window.left + (this_window.width / 2)); this_flash.half_height = (this_flash.height / 2); this_flash.half_width = (this_flash.width / 2); var new_top = this_window.vert_middle - this_flash.half_height; var new_left = this_window.horiz_middle - this_flash.half_width; this.flash_container.css({ left: new_left, top: new_top, visibility: 'visible' }); var ajax_flash = this; if (this.fade) { setTimeout(function() { ajax_flash.fadeOut() }, 1618); } }, fadeOut: function() { this.flash_container.fadeOut('slow'); }, bindDismisser: function() { this.$dismisser = this.flash_container.find('[data-dismiss]') var ajax_flash = this this.$dismisser.on('click', function(){ ajax_flash.flash_container.remove() }) } }), AjaxSorter: Class.extend({ init: function($sort_container) { var base_url = $sort_container.data('url'); $sort_container.sortable({ helper: "clone", tolerance: 'pointer', stop: function(event, ui) { new thin_man.AjaxSortSubmission($sort_container); } }); $sort_container.disableSelection(); } }) }; thin_man.AjaxFormSubmission = thin_man.AjaxSubmission.extend({ getAjaxUrl: function() { return this.jq_obj.attr('action'); }, getAjaxType: function() { return this.jq_obj.attr('method') || 'POST' }, getData: function() { var $clicked = $(document.activeElement); var browserTabId = $("meta[name='browser_tab_id']").attr("content"); if ($clicked.length && $clicked.is('button[type="submit"], input[type="submit"], input[type="image"]') && $clicked.is('[name]')) { var button_name = $clicked.attr('name') var button_value = $clicked.attr('value') } var event_data = this.params if (!event_data.hasOwnProperty('e')) { var thin_man_submitter = 'link_now' } else { var thin_man_submitter = this.params['e'].type } if ((this.getAjaxType().toLowerCase() == 'get') || (typeof FormData == 'undefined')) { var data_array = this.jq_obj.serializeArray(); if (button_name && button_value) { data_array.push({ name: button_name, value: button_value }) } data_array.push( { name: 'thin_man_submitter', value: thin_man_submitter }, { name: 'browser_tab_id', value: browserTabId } ) return data_array; } else { // need to implement a data-attribute for multiple file fields so we can allow selecting mutliple files at once. example here: // http://stackoverflow.com/questions/12989442/uploading-multiple-files-using-formdata var fd = new FormData(this.jq_obj[0]); if (button_name && button_value) { if (typeof fd.set != 'undefined') { fd.set(button_name, button_value) } else if (typeof fd.append != 'undefined') { fd.append(button_name, button_value) } } if (typeof fd.set != 'undefined') { fd.set('thin_man_submitter', thin_man_submitter) fd.set('browser_tab_id', browserTabId) } else if (typeof fd.append != 'undefined') { fd.append('thin_man_submitter', thin_man_submitter) fd.append('browser_tab_id', browserTabId) } return fd } }, ajaxSuccess: function(data, textStatus, jqXHR) { debug_logger.log('thin_man.AjaxFormSubmission.ajaxSuccess', 1, 'thin-man') this._super(data, textStatus, jqXHR) if (this.resetOnSuccess()) { this.jq_obj[0].reset(); $(this.jq_obj).find('input[type=text],textarea,select').filter(':visible:first').focus(); } }, resetOnSuccess: function() { return this.jq_obj.data('reset-on-success') }, getProcessData: function() { if (this.getAjaxType().toLowerCase() == 'get') { return true; } else { return false; } }, sendContentType: function() { if (this.getAjaxType().toLowerCase() == 'get') { return true; } else { return false; } }, getTrigger: function() { this.trigger = this.jq_obj.find('button, input[type="submit"]'); if (this.trigger.length != 1) { var $active_element = $(document.activeElement) if ($active_element[0].nodeName.toLowerCase() != 'body') { this.trigger = $active_element } } }, hideTrigger: function() { this.trigger.css('visibility', 'hidden'); }, showTrigger: function() { this.trigger.css('visibility', 'visible'); } }), thin_man.AjaxLinkSubmission = thin_man.AjaxSubmission.extend({ getAjaxUrl: function() { if (this.search_path) { if (this.search_params) { return this.search_path + '?' + this.search_params } else { return this.search_path } } else { return this.jq_obj.attr('href'); } }, getData: function() { var this_data = { authenticity_token: $('[name="csrf-token"]').attr('content'), browser_tab_id: $("meta[name='browser_tab_id']").attr("content") }; if (this.jq_obj.data('form-data')) { $.extend(this_data, this.jq_obj.data('form-data')) } return this_data }, getProcessData: function() { return true; }, getAjaxType: function() { return this.jq_obj.data('ajax-method') || 'GET' }, getTrigger: function() { this.trigger = this.jq_obj; }, hideTrigger: function() { this.trigger.css('visibility', 'hidden'); }, showTrigger: function() { this.trigger.css('visibility', 'visible'); }, refocus: function() { if (this.jq_obj.data('ajax-link-now')) { return false } return true }, }), thin_man.AjaxModalOpener = thin_man.AjaxLinkSubmission.extend({ ajaxSuccess: function(data, textStatus, jqXHR) { this._super(data, textStatus, jqXHR); $(this.jq_obj.data('ajax-modal')).modal(); } }), thin_man.AddALineForm = thin_man.AjaxFormSubmission.extend({ ajaxSuccess: function(data, textStatus, jqXHR) { this._super(data, textStatus, jqXHR); $(this.jq_obj.data('container')).empty(); }, ajaxError: function(jqXHR) { this.insert_method = 'html'; this._super(jqXHR); } }), thin_man.EmptyForm = thin_man.AjaxFormSubmission.extend({ ajaxSuccess: function(data, textStatus, jqXHR) { var clicked_button = $("input[type=submit][clicked=true]")[0]; this._super(data, textStatus, jqXHR); if ($(clicked_button).data('clone') != true) { $(this.jq_obj)[0].reset(); }; $(this.jq_obj).find('input[type=text],textarea,select').filter(':visible:first').focus(); $("[data-autocomplete]").trigger("chosen:updated"); }, ajaxError: function(jqXHR) { this.insert_method = 'html'; this._super(jqXHR); } }), thin_man.ModalCloserForm = thin_man.AjaxFormSubmission.extend({ ajaxSuccess: function(data, textStatus, jqXHR) { this._super(data, textStatus, jqXHR); $modal = $(this.jq_obj.data('modal-container')); $modal.modal('hide'); $modal.remove(); }, ajaxError: function(jqXHR) { this._super(jqXHR); $modal = $(this.jq_obj.data('modal-container')); $modal.modal(); } }), thin_man.ResetOnSubmitForm = thin_man.AjaxFormSubmission.extend({ ajaxSuccess: function(data, textStatus, jqXHR) { this._super(data, textStatus, jqXHR); $(this.jq_obj).each(function() { this.reset(); }); } }), thin_man.DeleteLink = thin_man.AjaxSubmission.extend({ ajaxSuccess: function(data, textStatus, jqXHR) { this._super(data, textStatus, jqXHR); if (this.jq_obj.data('replace-response')) { this.insertHtml(data); } else { if (this.target) { this.target.remove(); } } }, getTrigger: function() { this.trigger = this.jq_obj; }, getAjaxType: function() { return 'DELETE'; }, getAjaxUrl: function() { return this.jq_obj.attr('href'); }, getData: function() { return { authenticity_token: $('[name="csrf-token"]').attr('content'), browser_tab_id: $("meta[name='browser_tab_id']").attr("content") }; }, getProcessData: function() { return true; }, ajaxBefore: function(jqXHR) { if (!this.jq_obj.data('no-confirm')) { return confirm("Are you sure you want to delete this?"); } } }), thin_man.ReplaceDelete = thin_man.DeleteLink.extend({ ajaxSuccess: function(data, textStatus, jqXHR) { this.target[this.insert_method](data); }, ajaxBefore: function(jqXHR) { //noop } }), thin_man.AjaxSortSubmission = thin_man.AjaxLinkSubmission.extend({ init: function($form) { this.sort_field = $form.data('sort-field'); this._super($form); }, getAjaxUrl: function() { return this._super() + '?' + 'sort_field=' + this.sort_field + '&' + this.jq_obj.sortable("serialize"); }, getAjaxType: function() { return 'PUT'; }, ajaxSuccess: function() { } }); window.any_time_manager.registerListWithClasses({ 'sortable': 'AjaxSorter', 'ajax-link-now': 'AjaxLinkSubmission', 'ajax-form-now': 'AjaxFormSubmission' }, 'thin_man'); $(document).ready(function() { $(document).on('click apiclick', '[data-ajax-link],[data-ajax-link-now]', function(e) { e.preventDefault(); var this_class = eval('thin_man.' + thin_man.getSubClass($(this).data('sub-type'), 'AjaxLinkSubmission')); var submission = new this_class($(this), { e: e }); return false; }); $(document).on('submit apisubmit', '[data-ajax-form]', function(e) { e.preventDefault(); var this_class = eval('thin_man.' + thin_man.getSubClass($(this).data('sub-type'), 'AjaxFormSubmission')); var submission = new this_class($(this), { e: e }); return false; }); $(document).on('click apiclick', '[data-ajax-delete]', function(e) { e.preventDefault(); var this_class = eval('thin_man.' + thin_man.getSubClass($(this).data('sub-type'), 'DeleteLink')); var deletion = new this_class($(this), { e: e }); }); $(document).on('click', '[data-change-url]', function(e) { e.preventDefault(); new thin_man.AjaxPushState($(this)) }); $('[data-sortable]').each(function() { new thin_man.AjaxSorter($(this)); }); // TODO, make this work to reload content when history changes to previous content loaded by thin_man // and recorded in browser history with pustState // $(window).bind("popstate", function(e){ // $('[data-thin-man-back-link]').remove() // var previous_state = e.originalEvent.state // if(previous_state.thin_man && previous_state.path && previous_state.target){ // if($(previous_state.target).length > 0){ // var $this_target = $(previous_state.target) // } // var $reload_link = $('