/** * @file * * Provides modal-like functionality that opens a "megarow" in a table * instead of opening a dialog. Multiple megarows can be open at the same time, * each inserted below the triggering (parent) row. * * Inspired by CTools modal. */ (function ($) { // Add a help to scroll to the closed item // We scroll to a padding above the selected item due to the potential admin bar, // shortcuts and potential sticky table headers. // The value of the padding is defined in the view style settings. $.fn.viewsMegarowGoTo = function (scrollPadding) { $('html, body').animate({ scrollTop: ($(this).offset().top - scrollPadding) + 'px' }, 'fast'); return this; }; Drupal.ViewsMegarow = Drupal.ViewsMegarow || {}; /** * Display the megarow. */ Drupal.ViewsMegarow.open = function(entityId, target) { // If there's already a megarow opened for this entity, abort. var row_parent_megarow = $(target).parents('tr').next('tr.megarow'); if (row_parent_megarow != undefined && row_parent_megarow.length > 0) { return; } var defaults = { megarowTheme: 'ViewsMegarowDialog', throbberTheme: 'ViewsMegarowThrobber', animation: 'show', animationSpeed: 'fast' }; var settings = {}; $.extend(true, settings, defaults, Drupal.settings.ViewsMegarow); Drupal.ViewsMegarow.currentSettings = settings; // Get the megarow HTML, add the "Loading" title and animation. var megarowContent = $(Drupal.theme(settings.megarowTheme, entityId)); $('.megarow-title', megarowContent).html(Drupal.ViewsMegarow.currentSettings.loadingText); $('.megarow-content', megarowContent).html(Drupal.theme(settings.throbberTheme)); megarowContent.hide(); // Extract the width of the megarow. var views_table = target.parents('.views-table'); var nbcols = 1; var arr_classes = views_table.attr('class').split(' '); for (var i = 0 ; i < arr_classes.length ; i++) { result = arr_classes[i].substr(0, 5); if (result == 'cols-') { nbcols = arr_classes[i].substr(5); } } // Create our megarow. var wrapper_html = ''; wrapper_html += ''; wrapper_html += ' '; wrapper_html += '
'; wrapper_html += $(megarowContent).html(); wrapper_html += '
'; wrapper_html += ' '; wrapper_html += ''; $('tr.item-' + entityId, views_table).after(wrapper_html); // Mark the parent row as active. $('tr.item-' + entityId, views_table).addClass('views-row-active'); // Get the megarow from the DOM, now that it's been inserted. var megarow = views_table.find('.views-megarow-content-' + entityId, views_table); // Bind a click for closing the megarow. $('.close', megarow).bind('click', { entityId: entityId }, function(event) { Drupal.ViewsMegarow.close(event.data.entityId, event.target); event.preventDefault(); }); }; /** * Close the megarow. */ Drupal.ViewsMegarow.close = function(entityId, target) { // Target the megarow of the triggering element // (submit button or close link). var megarow = $(target).parents('.views-megarow-content:first'); if (Drupal.ViewsMegarow.currentSettings.scrollEnabled) { $(megarow).viewsMegarowGoTo(Drupal.ViewsMegarow.currentSettings.scrollPadding); } // Unbind the events. $(document).trigger('CToolsDetachBehaviors', megarow); // Set our animation parameters and use them. var animation = Drupal.ViewsMegarow.currentSettings.animation; if (animation == 'fadeIn') { animation = 'fadeOut'; } else if (animation == 'slideDown') { animation = 'slideUp'; } else { animation = 'hide'; } // Close and remove the megarow. $(megarow).hide()[animation](Drupal.ViewsMegarow.currentSettings.animationSpeed); $(megarow).parents('tr:first').remove(); // Mark the parent row as inactive. $('tr.item-' + entityId).removeClass('views-row-active'); } /** * Provide the HTML to create the megarow. */ Drupal.theme.prototype.ViewsMegarowDialog = function (entityId) { var html = ''; html += '
'; // This div doesn't get inserted into a DOM. html += '
'; html += ' '; html += ' ' + Drupal.ViewsMegarow.currentSettings.close + ''; html += '
'; html += '
'; html += '
'; return html; } /** * Provide the HTML to create the throbber. */ Drupal.theme.prototype.ViewsMegarowThrobber = function () { var html = ''; html += '
'; html += '
'; html += Drupal.ViewsMegarow.currentSettings.throbber; html += '
'; html += '
'; return html; }; /** * Handler to prepare the megarow for the response */ Drupal.ViewsMegarow.clickAjaxLink = function () { var classes = $(this).parents('tr').attr('class'); // Extract the entity idem from a custom class storing it // to ease the manipulation of the rows. var entityId = /item\-([0-9]+)/.exec(classes)[1]; Drupal.ViewsMegarow.open(entityId, $(this)); return false; }; /** * Bind links that will open megarows to the appropriate function. */ Drupal.behaviors.ViewsMegarow = { attach: function(context) { // Bind links // Note that doing so in this order means that the two classes can be // used together safely. $('a.views-megarow-open:not(.views-megarow-open-processed)', context) .addClass('views-megarow-open-processed') .click(Drupal.ViewsMegarow.clickAjaxLink) .each(function () { // Create a DOM attribute to ease the manipulation of the row // by any other module. var classes = $(this).parents('tr').attr('class'); var entityId = /item\-([0-9]+)/.exec(classes)[1]; $(this).parents('tr').attr('data-entity-id', entityId); // Create a drupal ajax object var elementSettings = {}; if ($(this).attr('href')) { elementSettings.url = $(this).attr('href'); elementSettings.event = 'click'; elementSettings.progress = { type: 'throbber' }; } var base = $(this).attr('href'); Drupal.ajax[base] = new Drupal.ajax(base, this, elementSettings); } ); // Bind our custom event to the form submit $('.megarow-content form:not(.views-megarow-open-processed)') .addClass('views-megarow-open-processed') .each(function() { var elementSettings = {}; elementSettings.url = $(this).attr('action'); elementSettings.event = 'submit'; elementSettings.progress = { 'type': 'throbber' } var base = $(this).attr('id'); Drupal.ajax[base] = new Drupal.ajax(base, this, elementSettings); Drupal.ajax[base].form = $(this); $('input[type=submit], button', this).click(function() { Drupal.ajax[base].element = this; this.form.clk = this; }); }); } }; /** * AJAX command to place HTML within the megarow. */ Drupal.ViewsMegarow.megarow_display = function(ajax, response, status) { var target = $(ajax.element).parents('.views-table'); var megarow = $('.views-megarow-content-' + response.entity_id, target); // Update the megarow content. $('.megarow-title', megarow).html(response.title); // .html strips off
tag for version Jquery 1.7, using append instead. $('.megarow-content', megarow).html(''); $('.megarow-content', megarow).append(response.output); Drupal.attachBehaviors(); } /** * AJAX command to dismiss the megarow. */ Drupal.ViewsMegarow.megarow_dismiss = function(ajax, response, status) { // Close the megarow of the calling element // (form submit button or close link). Drupal.ViewsMegarow.close(response.entity_id, ajax.element); } /** * AJAX command to refresh the parent row of a megarow. */ Drupal.ViewsMegarow.megarow_refresh_parent = function(ajax, response, status) { // No row found, nothing to update. if ($('tr.item-' + response.entity_id).length == 0) { return; } // Fetch the current page using ajax, and extract the relevant data. var table = $('tr.item-' + response.entity_id).parents('table'); var viewName = table.attr('data-view-name'); var display = Drupal.settings.ViewsMegarow.display_id; // If we don't have a specify display defined extract it from our table. if (display === undefined) { display = table.attr('data-view-display'); } var url = Drupal.settings.basePath + 'views_megarow/refresh/' + viewName + '/' + display; // Add arguments to the url if they have been passed in. if (Drupal.settings.ViewsMegarow.args !== undefined) { url += '/' + Drupal.settings.ViewsMegarow.args; } // Preserve initial destination URL query parameter. url += '?destination=' + Drupal.ViewsMegarow.currentSettings.destination; $.get(url, function(data) { $('tr.item-' + response.entity_id + ' td', data).each(function(index) { // Ignore cells that contain form elements. if ($('input', this).length == 0 && $('select', this).length == 0) { var targetElement = $('tr.item-' + response.entity_id + ' td:eq(' + index + ')'); var newContent = $(this).html(); targetElement.html(newContent); Drupal.attachBehaviors(targetElement); } }); }); } $(function() { Drupal.ajax.prototype.commands.megarow_display = Drupal.ViewsMegarow.megarow_display; Drupal.ajax.prototype.commands.megarow_dismiss = Drupal.ViewsMegarow.megarow_dismiss; Drupal.ajax.prototype.commands.megarow_refresh_parent = Drupal.ViewsMegarow.megarow_refresh_parent; }); })(jQuery);