Merge "Adds client-side templating capabilities."
This commit is contained in:
commit
3dc1555e7a
File diff suppressed because one or more lines are too long
|
@ -20,6 +20,15 @@ var Horizon = function() {
|
|||
|
||||
/* Call all initialization functions and clear the queue. */
|
||||
horizon.init = function() {
|
||||
// Load client-side template fragments and compile them.
|
||||
horizon.templates.compile_templates();
|
||||
|
||||
// Bind event handlers to confirm dangerous actions.
|
||||
$("body").on("click", "form .btn.danger", function (evt) {
|
||||
horizon.datatables.confirm(this);
|
||||
return false;
|
||||
});
|
||||
|
||||
$.each(initFunctions, function(ind, fn) {
|
||||
fn();
|
||||
});
|
||||
|
@ -28,6 +37,7 @@ var Horizon = function() {
|
|||
initFunctions = [];
|
||||
};
|
||||
|
||||
/* Namespace for core functionality related to DataTables. */
|
||||
horizon.datatables = {
|
||||
update: function () {
|
||||
var rows_to_update = $('tr.status_unknown');
|
||||
|
@ -41,6 +51,50 @@ var Horizon = function() {
|
|||
}
|
||||
};
|
||||
|
||||
/* Generates a confirmation modal dialog for the given action. */
|
||||
horizon.datatables.confirm = function (action) {
|
||||
var $action = $(action),
|
||||
action_string, title, body, modal, form;
|
||||
action_string = $action.text();
|
||||
title = "Confirm " + action_string;
|
||||
body = "Please confirm your selection. This action cannot be undone.";
|
||||
modal = horizon.modals.create(title, body, action_string);
|
||||
modal.modal('show');
|
||||
modal.find('.btn.primary').click(function (evt) {
|
||||
form = $action.closest('form');
|
||||
form.append("<input type='hidden' name='" + $action.attr('name') + "' value='" + $action.attr('value') + "'/>");
|
||||
form.submit();
|
||||
});
|
||||
return modal;
|
||||
};
|
||||
|
||||
/* Namespace for core functionality related to client-side templating. */
|
||||
horizon.templates = {
|
||||
template_ids: ["#modal_template"],
|
||||
compiled_templates: {}
|
||||
};
|
||||
|
||||
/* Pre-loads and compiles the client-side templates. */
|
||||
horizon.templates.compile_templates = function () {
|
||||
$.each(horizon.templates.template_ids, function (ind, template_id) {
|
||||
horizon.templates.compiled_templates[template_id] = Hogan.compile($(template_id).text());
|
||||
});
|
||||
};
|
||||
|
||||
/* Namespace for core functionality related to modal dialogs. */
|
||||
horizon.modals = {};
|
||||
|
||||
/* Creates a modal dialog from the client-side template. */
|
||||
horizon.modals.create = function (title, body, confirm, cancel) {
|
||||
if (!cancel) {
|
||||
cancel = "Cancel";
|
||||
}
|
||||
var template = horizon.templates.compiled_templates["#modal_template"],
|
||||
params = {title: title, body: body, confirm: confirm, cancel: cancel},
|
||||
modal = $(template.render(params)).appendTo("body");
|
||||
return modal;
|
||||
};
|
||||
|
||||
return horizon;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
{% extends "horizon/client_side/template.html" %}
|
||||
{% load horizon %}
|
||||
|
||||
{% block id %}modal_template{% endblock %}
|
||||
|
||||
{% block template %}
|
||||
{% jstemplate %}
|
||||
<div class="modal hide fade">
|
||||
<div class='modal-header'>
|
||||
<a class='close' data-dismiss='modal'>×</a>
|
||||
<h3>[[title]]</h3>
|
||||
</div>
|
||||
<div class='modal-body'>
|
||||
[[body]]
|
||||
</div>
|
||||
<div class='modal-footer'>
|
||||
<a href='#' class='btn primary'>[[confirm]]</a>
|
||||
<a href='#' class='btn' data-dismiss='modal'>[[cancel]]</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endjstemplate %}
|
||||
{% endblock %}
|
|
@ -0,0 +1 @@
|
|||
<script type="text/html" id="{% block id %}{% endblock %}">{% block template %}{% endblock %}</script>
|
|
@ -94,3 +94,25 @@ def horizon_dashboard_nav(context):
|
|||
return {'components': non_empty_panels,
|
||||
'user': context['request'].user,
|
||||
'current': context['request'].horizon['panel'].slug}
|
||||
|
||||
|
||||
class JSTemplateNode(template.Node):
|
||||
""" Helper node for the ``jstemplate`` template tag. """
|
||||
def __init__(self, nodelist):
|
||||
self.nodelist = nodelist
|
||||
|
||||
def render(self, context, ):
|
||||
output = self.nodelist.render(context)
|
||||
return output.replace('[[', '{{').replace(']]', '}}')
|
||||
|
||||
|
||||
@register.tag
|
||||
def jstemplate(parser, token):
|
||||
"""
|
||||
Replaces ``[[`` and ``]]`` with ``{{`` and ``}}`` to avoid conflicts
|
||||
with Django's template engine when using any of the Mustache-based
|
||||
templating libraries.
|
||||
"""
|
||||
nodelist = parser.parse(('endjstemplate',))
|
||||
parser.delete_first_token()
|
||||
return JSTemplateNode(nodelist)
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
<script src="{{ STATIC_URL }}dashboard/js/bootstrap/bootstrap-popover.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ STATIC_URL }}dashboard/js/bootstrap/bootstrap-transition.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ STATIC_URL }}dashboard/js/bootstrap/bootstrap-typeahead.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ STATIC_URL }}horizon/js/hogan-1.0.5.min.js" type="text/javascript"></script>
|
||||
<script src='{{ STATIC_URL }}horizon/js/horizon.js' type='text/javascript' charset='utf-8'></script>
|
||||
<script src='{{ STATIC_URL }}dashboard/js/plugins.js' type='text/javascript' charset='utf-8'></script>
|
||||
<script src='{{ STATIC_URL }}dashboard/js/tables.js' type='text/javascript' charset='utf-8'></script>
|
||||
|
@ -49,7 +50,8 @@
|
|||
<div id="footer">
|
||||
{% block footer %}{% endblock %}
|
||||
</div>
|
||||
{% block footer_js %}{% endblock %}
|
||||
{% block footer_js %}
|
||||
{% include "horizon/client_side/_modal.html" %}
|
||||
{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
Loading…
Reference in New Issue