diff --git a/horizon/static/horizon/js/horizon.js b/horizon/static/horizon/js/horizon.js index 1341db097..6763d7832 100644 --- a/horizon/static/horizon/js/horizon.js +++ b/horizon/static/horizon/js/horizon.js @@ -47,7 +47,7 @@ var Horizon = function() { $("form").live("change", "#id_source_group", function(evt) { var $sourceGroup = $(this).find('#id_source_group'); var $cidrContainer = $(this).find('#id_cidr').parent().parent(); - if($sourceGroup.val() == "") { + if($sourceGroup.val() === "") { $cidrContainer.removeClass("hide"); } else { $cidrContainer.addClass("hide"); @@ -78,8 +78,45 @@ var Horizon = function() { var $row = $(this), $table = $row.closest('table'); $.ajax($row.attr('data-update-url'), { - complete: function (jqXHR, status) { - var $new_row = $(jqXHR.responseText); + error: function (jqXHR, textStatus, errorThrown) { + switch (jqXHR.status) { + // A 404 indicates the object is gone, and should be removed from the table + case 404: + // Update the footer count and reset to default empty row if needed + var $footer = $table.find('tr:last'), + row_count, footer_text, colspan, template, params, $empty_row; + + // existing count minus one for the row we're removing + row_count = $table.find('tbody tr').length - 1; + footer_text = "Displaying " + row_count + " item"; + if(row_count !== 1) { + footer_text += 's'; + } + $footer.find('span').text(footer_text); + + if(row_count === 0) { + colspan = $footer.find('td').attr('colspan'); + template = horizon.templates.compiled_templates["#empty_row_template"]; + console.log(template); + params = {"colspan": colspan}; + empty_row = template.render(params); + console.log(empty_row); + $row.replaceWith(empty_row); + } else { + $row.remove(); + } + break; + default: + if (horizon.conf.debug) { + horizon.alert("error", "An error occurred while updating."); + } + $row.removeClass("ajax-update"); + $row.find("i.ajax-updating").remove(); + break; + } + }, + success: function (data, textStatus, jqXHR) { + var $new_row = $(data); $new_row.find("td.status_unknown").prepend(''); // Only replace row if the html content has changed if($new_row.html() != $row.html()) { @@ -87,30 +124,13 @@ var Horizon = function() { // Preserve the checkbox if it's already clicked $new_row.find(':checkbox').prop('checked', true); } - if($new_row.length == 0) { - // Update the footer count and reset to default empty row if needed - var $footer = $table.find('tr:last'); - - // remove one row from existing count - var row_count = $table.find('tbody tr').length -1; - var footer_text = "Displaying " + row_count + " item"; - - if(row_count > 1) { footer_text += 's'; } - $footer.find('span').text(footer_text); - - if(row_count == 0) { - var colspan = $footer.find('td').attr('colspan'), - template = horizon.templates.compiled_templates["#empty_row_template"], - params = {colspan: colspan}, - empty_row = $(template.render(params)); - - $new_row = $(empty_row); - } - } $row.replaceWith($new_row); - $table.removeAttr('decay_constant'); } - // Revalidate the button check for updated table + }, + complete: function (jqXHR, textStatus) { + // Reset decay constant. + $table.removeAttr('decay_constant'); + // Revalidate the button check for the updated table horizon.datatables.validate_button(); } }); @@ -130,6 +150,7 @@ var Horizon = function() { setTimeout(horizon.datatables.update, next_poll); } }, + validate_button: function () { // Disable form button if checkbox are not checked $("form").each(function (i) { @@ -189,7 +210,7 @@ var Horizon = function() { /* Namespace for core functionality related to client-side templating. */ horizon.templates = { - template_ids: ["#modal_template", "#empty_row_template"], + template_ids: ["#modal_template", "#empty_row_template", "#alert_message_template"], compiled_templates: {} }; @@ -214,6 +235,21 @@ var Horizon = function() { return modal; }; + /* Utilities for common needs which aren't JS builtins. */ + horizon.utils = { + capitalize: function(string) { + return string.charAt(0).toUpperCase() + string.slice(1); + } + }; + + horizon.alert = function (type, message) { + var template = horizon.templates.compiled_templates["#alert_message_template"], + params = {"type": type, + "type_capitalized": horizon.utils.capitalize(type), + "message": message}; + return $(template.render(params)).prependTo("#main_content .messages"); + }; + return horizon; }; diff --git a/horizon/static/horizon/js/plugins.js b/horizon/static/horizon/js/plugins.js index 6a6427ba1..e35d89be3 100644 --- a/horizon/static/horizon/js/plugins.js +++ b/horizon/static/horizon/js/plugins.js @@ -10,7 +10,7 @@ }, opt); $(this).bind(options.trigger, function(e) { - options.container.find( options.selector + $(this).attr(options.retrieve) ).toggleClass(options.selected_class) + options.container.find( options.selector + $(this).attr(options.retrieve) ).toggleClass(options.selected_class); }); }; } (jQuery, this, document)); diff --git a/horizon/templates/horizon/_messages.html b/horizon/templates/horizon/_messages.html index f36080a4f..b8a80b53e 100644 --- a/horizon/templates/horizon/_messages.html +++ b/horizon/templates/horizon/_messages.html @@ -1,4 +1,5 @@ {% load i18n %} +
diff --git a/horizon/templates/horizon/client_side/_alert_message.html b/horizon/templates/horizon/client_side/_alert_message.html new file mode 100644 index 000000000..24b7098a3 --- /dev/null +++ b/horizon/templates/horizon/client_side/_alert_message.html @@ -0,0 +1,13 @@ +{% extends "horizon/client_side/template.html" %} +{% load horizon %} + +{% block id %}alert_message_template{% endblock %} + +{% block template %} +{% jstemplate %} +[[type_capitalized]]: [[message]]
+