我在Laravel 8中做了一个blogging application。我目前正在通过jQuery(v3.5.0)AJAX添加 * 评论回复 *。
在comment-form.blade.php
中,我有:
<div class="form-wrapper">
<div class="alert-box-ajax alert-box alert-box--success">
Your comment is pending
</div>
<div class="alert-box-ajax alert-box alert-box--error">
Failed to add comment!
</div>
<form class="commentForm" method="post" action="{{ route('comment.submit') }}" autocomplete="off" novalidate>
@csrf
<fieldset>
<input type="hidden" name="article_id" value="{{ isset($article->id) ? $article->id : $article_id }}">
<input type="hidden" name="parent_id" value="{{ $comment->id ?? '' }}">
<div class="message form-field">
<textarea name="msg" id="message" class="h-full-width" placeholder="Your Message" required></textarea>
@error('msg')
<p class="help-block text-danger">{{ $message }}</p>
@enderror
</div>
<br>
<input name="submit" id="submit" class="btn btn--primary btn-wide btn--large h-full-width" value="Add Comment" type="submit">
</fieldset>
</form>
</div>
字符串
当然,上面的模板对每个评论都重复,这样回复就可以添加到任何评论中。
回复通过jQuery Ajax提交:
$(".commentForm").each(function () {
var form = $(this);
form.validate({
errorElement: "p",
errorClass: "help-block text-danger",
submitHandler: function (_form, event) {
event.preventDefault();
var $fields = form.find("textarea"),
url = form.attr("action"),
data = form.serialize();
$.ajax({
dataType: "json",
type: "post",
url: url,
data: data,
cache: false,
success: function (response) {
if (response.status === 'success') {
form.closest(".form-wrapper").find(".alert-box--success").slideDown(250).delay(2500).slideUp(250)
.slideDown(250)
.delay(2500)
.slideUp(250);
$fields.val("");
} else {
form.closest(".form-wrapper").find(".alert-box--error").slideDown(250).delay(2500).slideUp(250)
.slideDown(250)
.delay(2500)
.slideUp(250);
}
},
error: function (err) {
console.log(err);
},
});
},
});
});
型
问题
有一个选项可以为每个帖子初始加载最多10个comemnts,其余的通过Ajax调用加载到页面滚动中。
当此选项处于活动状态时,上面的脚本无法阻止通过Ajax加载的表单的默认行为。
**!注意:**问题不是提交事件,而是提交事件的 * 预防 *。
常见问题
1.是什么导致了这个问题?
1.解决这个问题最可靠的方法是什么?
4条答案
按热度按时间q7solyqu1#
这将工作,无论有多少形式为每个评论,因为每个形式将属于单一的评论。
字符串
pu82cl6c2#
您遇到的问题是由于jQuery .each()函数和.validate()方法只应用于代码运行时存在于DOM中的元素。这意味着稍后(通过AJAX)添加到DOM的任何元素(在您的情况下,注解表单)都不会应用这些方法。
要解决这个问题,您可以使用事件委托。事件委托允许您将单个事件侦听器附加到父元素,该侦听器将为匹配选择器的所有后代触发,无论这些后代现在存在还是将来添加。
以下是如何修改jQuery代码以使用事件委托:
字符串
我是这么想的。新代码:
型
91zkwejq3#
这个问题已经在评论中解释过了。你所展示的JavaScript在页面加载时运行,那里的选择器只会匹配页面加载时存在的元素。如果你稍后动态添加元素,Javascript不会再次运行,那些选择器不会匹配它们。
在这种情况下,这意味着
$(".commentForm")
只匹配那些在页面加载时存在的具有该类的表单,因此只有这些表单才会应用验证代码。当您稍后向页面添加新的$(".commentForm")
s时,在页面加载时运行的JS不会再次为新表单运行,并且它们根本没有验证。提交这些表单不会运行任何JavaScript,它们只是正常提交,这就是你所看到的为了解决这个问题,你可以让你的验证成为一个可以随时调用的函数,例如:
字符串
现在你可以在一个新表单被添加到DOM的时候动态地添加验证。你还没有给我们展示添加新表单的代码,但是为了演示的目的,假设你正在克隆一些主表单模板,可能是这样的:
型
无论代码是什么样子,你需要做的唯一重要的部分就是在新表单上调用新的验证函数:
型
类似问题供参考:
或者,您也可以使用事件委托来实现这一点,尽管这有点棘手,而且IMO并不是一个整洁的解决方案。
首先,我们需要将事件处理程序附加到页面加载时存在的选择器,并且将成为当前和未来所有表单的父级。让我们称之为
.someContainer
。接下来我们过滤选择器以仅匹配表单:型
现在,在该容器内发生的任何
submit
事件都会触发此处理程序-即使是页面加载后添加的表单。无需添加单独的代码来处理页面加载时存在的表单,这将捕获所有表单。接下来,我们显然需要添加代码来初始化刚刚提交的表单上的验证。我们可以使用现有的
commentFormValidation()
函数来完成这一点:型
但是有一个问题。提交表单会添加验证,但它实际上不会 * 运行 * 验证。因此,第一次提交表单时,什么都不会发生,因为提交操作已被此处理程序拦截,添加了验证,.
所以我们需要在添加验证后手动运行它,你可以通过在表单上调用the
.valid()
method来完成--尽管它在这里不起作用,我不知道为什么。因此,我们可以手动重新提交表单,这将运行验证。
这里有一个演示这种委托方法的工作片段。检查控制台输出以查看发生的各个阶段。
的字符串
nfzehxib4#
一个简单的解决方法是区分初始化和未初始化的内容。让我们创建一个函数,将其 Package 在代码中,并确保稍微修改代码以初始化未初始化的元素:
字符串
请确保在页面加载时以及“下一个内容”AJAX完成并追加新表单时调用此函数。
编辑
你还需要小心,因为如果容器的
innerHTML
被改变,那么所有的事件监听器都会被破坏。所以你需要测试当你加载下一个10个元素时,你的第一个元素是否仍然工作。如果是这样,那么我的初始解决方案就可以工作。如果不是,那么你可以将初始行改为$(".commentForm:not(.initialized)").each(function () {
并删除form.addClass("initialized");
行。编辑2
下面是一个创建事件并在容器的.innerHTML`更改后重新创建事件的工作示例:
的数据