Я построил плагин, который должен преобразовать любую кнопку в форму модального стиля, с учетом URL-адреса, где можно получить форму.Плагин jQuery, использующий только значения последнего элемента
Он отлично работает только с одним элементом, но когда селектор возвращает несколько элементов, все кнопки используют данные последнего элемента, когда методы получения & вызывают внутри плагина.
Я попытался ответить на несколько вопросов в формате SO, но не смог найти и исправить ошибку. Похоже, я что-то упускаю.
Вот полный код. Вы увидите несколько {% django tags %}
и {{ django context variables }}
, но просто игнорируете их.
Спасибо!
A.
EDIT: typo; EDIT2: добавлен html; EDIT3: удалены теги django и контекстные vars.
<div class="modal fade" id="modal-1234" data-uuid="1234">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="title-1234">Title</h4>
</div>
<div class="modal-body" id="body-1234">Body</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal" id="cancel-1234">Close</button>
<button type="button" class="btn btn-primary" id="confirm-1234">Save changes</button>
</div>
</div>
</div>
</div>
<script type="text/javascript">
(function($){
// define the modalform class
function ModalForm($button){
/*
You can use ModalForm to automate the ajax-form-modal process with TB3.
Usage:
var mf = new ModaForm($('#my-button')); // that's it
*/
self = this;
self.$button = $button;
self.$modal = $('#modal-1234');
// get vars
self.target = self.$button.attr('data-target');
self.uuid = self.$modal.attr('data-uuid');
self.$modal_title = $('#title-' + self.uuid);
self.$modal_body = $('#body-' + self.uuid);
self.$modal_confirm = $('#confirm-' + self.uuid);
self.modal_confirm_original_text = self.$modal_confirm.html()
self.$modal_cancel = $('#cancel-' + self.uuid);
self.$alerts = $('[data-exsutils=push-alerts]').first();
self.$spinner = $('<p class="center"><i class="ace-icon fa fa-spinner fa-spin orange bigger-300"></i></p>');
// bind button click to _get
self.$button.on('click', function(e){
e.preventDefault();
self._get();
});
}
ModalForm.prototype._get = function(){
/*
Issue a get request to fetch form and either render form or push alert when complete.
*/
var self = this;
// show modal, push spinner and change title
self.$modal.modal('show');
self.$modal_body.html(self.$spinner);
self.title = typeof(
self.$button.attr('data-title')) !== 'undefined' ?
self.$button.attr('data-title') : 'Modal form';
self.$modal_title.html(self.title);
// get content
$.ajax({
type: 'GET',
url: self.target,
statusCode: {
403: function(data){
// close modal
// forbidden => close modal & push alert
setTimeout(function(){
self.$modal.modal('hide');
self.$alerts.html(data.responseText);
}, 500);
},
200: function(data){
// success => push form
// note that we will assign self.$form
var $response = $(data);
self.$form = $response.filter('form').first();
self.$modal_body.html($response);
self.$modal_confirm.click(function(e){
e.preventDefault();
self._submit(self.$form);
});
}
},
error: function(data){
console.log(data);
}
});
}
ModalForm.prototype._submit = function(){
/*
Post this.$form data and rerender form or push alert when complete.
*/
var self = this;
// change submit button to loading state
self.$modal_confirm.addClass('disabled').html('Loading...');
// issue pot request
// cleanup
// rebind if rerender or push alerts
$.ajax({
type: 'POST',
url: self.$form.attr('action'),
data: self.$form.serialize(),
statusCode: {
200: function(data){
// this is a form error
// so we must rerender and rebind form
// else we need to rerender and rebind
self.$form.remove();
var $response = $(data);
self.$form = $response.filter('form').first();
self.$modal_body.html($response);
self.$modal_confirm.on('click', function(e){
e.preventDefault();
self._submit(self.$form);
});
},
201: function(data){
// this means object was created
// so we must push an alert and clean up
self.$form.remove();
delete self.$form;
self.$modal.modal('hide');
self.$modal_body.html('');
// we will push alerts only if there is no 201 callback
var callback_201 = self.$button.attr('data-callback-201');
if (typeof(window[callback_201]) !== 'undefined') {
window[callback_201](data);
} else {
self.$alerts.prepend(data);
};
},
403: function(data){
// this means request was forbidden => clean up and push alert
self.$form.remove();
delete self.$form;
self.$modal.modal('hide');
self.$modal_body.html('');
self.$alerts.prepend(data.responseText);
}
},
complete: function(){
// reset button
self.$modal_confirm.removeClass('disabled').html(
self.modal_confirm_original_text);
}
});
}
window.ModalForm = ModalForm;
// define plugin
$.fn.modalForm = function(){
var self = this;
return self.each(function(){
var el = this;
var _ = new window.ModalForm($(el));
$.data(el, 'modalform', _);
});
}
// run plugin
$('[data-exsutils=modal-form]').modalForm();
})(jQuery);
</script>
Редактируйте @Daniel Arant:
jsFiddle с упрощенной рабочей версией коды плагина можно найти here
Примечания мной: Пожалуйста, прочитайте выбранный ответ. Этот jsfiddle + добавление var self = this
даст вам полную картину проблемы и хороший способ ее устранения.
Как выглядит ваш HTML-код? И из любопытства, почему вы устанавливаете window.ModalForm равным ModalForm? –
Привет, добавлен HTML. О window.ModalForm, причина заключается в отладке в другом контексте, как в 'console.log (window.ModalForm)'. – misterte
У меня нет абсолютно никакого опыта работы с django, так что простите меня, если это глупый вопрос, но почему вы используете теги django в коде JavaScript? В частности, я смотрю на строку, которая читает 'self.uuid = self. $ Modal = $ ('# modal - {{uuid}}');'. –