我有一个模态弹出窗体,用户可以单击取消退出表单。如果用户已开始在表单中输入数据,系统会询问用户是否要确认是否要退出而不保存更改。
发生的事情是我输入一些数据,当我点击取消按钮时,设置了_isModalDirty标志,但按钮点击事件(即$(' .modal-cancel')。点击( function(){...});)未被触发。当我再次单击取消按钮时,它会被触发。 我需要更改什么,以便第一次触发按钮单击事件?
$('.controls :input').change(function (){
_isModalDirty = true;
});
$('.modal-cancel').click(function (){
if (_isModalDirty) {
if (confirm('Are you sure you want to cancel? You will lose your unsaved changes.')) {
closeModalPopup();
}
} else {
closeModalPopup();
}
});
var closeModalPopup = function () {
resetModalPopup();
_isModalDirty = false;
$('.modal').modal('hide');
}
var resetModalPopup = function() {
$('.controls :input').each(function () {
var $this = $(this);
$this.val('');
});
}
EDIT 这是html;
<div class="modal fade" id="edit-quote-form">
@using (Html.BeginForm("Edit", "Quote", FormMethod.Post, new { id = "editQuoteForm", @class = "modalPopup" }))
{
<input type="hidden" id="EditQuoteQuoteId" name="QuoteId" />
<fieldset>
<legend>Edit Quote for Tender</legend>
<p style="color: white;font-weight: bold;"><span id="EditCompany"></span></p>
<div class="modal-body">
<div class="row">
<div class="controls col-md-2">
<label class="control-label label-default" for="Status">Status</label>
</div>
<div class="controls col-md-2">
<select id="QuoteStatus">
</select>
</div>
</div>
<div class="row">
<div class="controls col-md-2">
<label class="control-label label-default" for="Value">Value</label>
</div>
<div class="controls col-md-2">
<input type="text" id="EditQuoteValue" name="maskValue" class="maskValue"
style="text-align: right; width: 160px;"
data-inputmask="'alias': 'numeric', 'groupSeparator': ',', 'autoGroup': true, 'digits': 2, 'digitsOptional': false, 'prefix': '£ ', 'placeholder': '0'" />
<input type="hidden" name="editValue" class="editValue" />
</div>
</div>
<div class="row">
<div class="controls col-md-2">
<label class="control-label label-default" for="Comments">Comments</label>
</div>
<div class="controls col-md-2" style="white-space: nowrap;">
<textarea id="EditComments" name="Comments" class="commentsTextarea"></textarea>
</div>
</div>
<div class="modal-footer" style="padding-bottom: 10px;">
<input type="button" class="btn btn-warning modal-cancel" value="Cancel" />
<input type="submit" class="btn btn-success" value="Save" />
</div>
</div>
</fieldset>
}
</div>
EDIT2
上面的表单是从主窗体中的以下超链接触发的;
<fieldset>
<legend>Tender Quotes</legend>
<div style="padding-bottom: 10px;" class="bootstrapLink">
<a href="#edit-quote-form" class="btn btn-info btn-xs" data-toggle="modal">Add New Quote</a>
</div>
@grid.GetHtml()
</fieldset>
EDIT3 这是它不起作用的小提琴; http://jsfiddle.net/arame3333/mto9mt9v/7/
答案 0 :(得分:0)
听起来旗帜没有按预期运作。
$('.controls :input').change(function (){
_isModalDirty = true;
});
我会在提交时对原始与当前进行比较,而不是更改事件。 因此,首先在模态创建,存储原始值:
var origdata=[];
$('.controls :input').each(function () {
origdata.push($(this).val());
});
取消后,将它们与当前数据字段进行比较。
var _isModalDirty=0;
$('.controls :input').each(function (i, item) {
if(origdata[i]!=item.val())
_isModalDirty++;
});
您的真/假测试仍然有效,因为0将返回false,并且任何不匹配的实例将递增并将其置为布尔正值。
答案 1 :(得分:0)
您收到错误,因为_isModalDirty最初未定义。如果我添加
var _isModalDirty = false;
到你的javascript顶部然后它适用于我
编辑:您可能需要考虑将表单的状态设置为表单上的数据而不是变量:
$('.controls :input').change(function (){
console.log('change run');
$(this).closest('.modal').data('isModalDirty', true);
});
$('.modal-cancel').click(function (){
console.log('click run');
if ( $(this).closest('.modal').data('isModalDirty') ) {
if (confirm('Are you sure you want to cancel? You will lose your unsaved changes.')) {
closeModalPopup();
}
} else {
closeModalPopup();
}
});
var closeModalPopup = function () {
resetModalPopup();
$('.modal').data('isModalDirty', false).modal('hide');
}
var resetModalPopup = function() {
$('.controls :input').each(function () {
var $this = $(this);
$this.val('');
});
}
这样可以更轻松地在页面上支持多个这样的模态,因为它不使用全局变量。 Fiddle using data
编辑2
OP在评论中说他们仍然需要点击两次。我认为问题实际上是您用于调试的警报。如果在一个字段中输入文本,则立即单击取消按钮,更改事件的警报将运行。警报是一个阻塞过程,在该块中,click事件似乎丢失了。尝试将alert
更改为console.log
(这在用户和功能上都不那么烦人且不那么干扰 - 在我看来调试数据的方式)并且我认为它有效(直到上面讨论的未定义变量问题。)
答案 2 :(得分:0)
我找到了答案。说实话,我不明白为什么这是答案,我不明白为什么JsFiddle没有重现它。 但是我只是交换了函数的顺序,然后它起作用了;
var _isModalDirty = false;
$('.modal-cancel').click(function () {
if (_isModalDirty) {
if (confirm('Are you sure you want to cancel? You will lose your unsaved changes.')) {
closeModalPopup();
}
} else {
closeModalPopup();
}
});
$('.controls :input').change(function () {
_isModalDirty = true;
});