#javascript #html #jquery
#javascript #HTML #jquery
Вопрос:
У меня есть несколько форм, отрисованных из Django modelFormset. Для каждой формы я создаю кнопку «Вставить» рядом с ней, чтобы добавить новую форму после нее. Когда я загружаю страницу, формы отображаются из строк базы данных, затем я нажимаю на любую кнопку insert и добавляется моя новая форма. Теперь, когда я нажимаю на кнопку insert, которая находится рядом с этой недавно созданной формой, ничего не происходит, функция внутри моего метода click-event даже не вводится. Все эти кнопки имеют один и тот же класс.
Я создаю новую форму, клонируя элемент div, который его содержит, затем изменяя его атрибуты, а затем вставляя его.
Вот как выглядит мой шаблон перед добавлением новой формы. У меня сейчас есть только две строки в моей таблице базы данных, которые я создал вручную для тестирования.
<body>
<form method="POST" class="note-form">
<input type="hidden" name="csrfmiddlewaretoken" ...>
<div class="notes-pane">
<div id="management-form">...<div>
</div>
<div class="note" id="id-note-1">
<input type="number" name="form-0-note_number" value="1" class="disabled" readonly="readonly" id="id_form-0-note_number">
<textarea name="form-0-note_text" cols="100" rows="8" id="id_form-0-note_text">This is the first note</textarea>
<button id="ins-after-1" class="ins-note-after" type="button" value="ins-after-1">Insert</button>
<input type="hidden" name="form-0-id" value="60" id="id_form-0-id">
</div>
<div class="note" id="id-note-2">
<input type="number" name="form-1-note_number" value="2" class="disabled" readonly="readonly" id="id_form-1-note_number">
<textarea name="form-1-note_text" cols="100" rows="8" id="id_form-1-note_text">This is the second note</textarea>
<button id="ins-after-2" class="ins-note-after" type="button" value="ins-after-2">Insert</button>
<input type="hidden" name="form-1-id" value="61" id="id_form-1-id">
</div>
</div>
</form>
</body>
Это мой JavaScript для добавления кнопок в форму и создания новых форм.
Вероятно, это не очень чисто. Я все еще новичок в JavaScript.
<script>
$(document).ready(function() {
//------------------------------------------------------------------
//--------------------ADDING INSERT-NOTE BUTTONS--------------------
var noteFormList = $(".note").find("textarea");
for (noteElement of noteFormList) {
var buttonNumber = Number(noteElement.id.match(/d /)) 1
var newButton = $("<button></button>").text("Insert");
newButton.attr("id", "ins-after-" buttonNumber);
newButton.attr("class", "ins-note-after");
newButton.attr("type", "button");
newButton.attr("value", "ins-after-" buttonNumber);
$("#" noteElement.id).after(newButton);
}
//------------------------------------------------------------------
//----------------------INSERTING A NEW NOTE------------------------
$(".ins-note-after").click(function() {
var insertAfter = $(this).attr("value").match(/d /)[0];
// To see if the function is entered.
console.log(insertAfter);
console.log("Inserting note after " insertAfter);
// Update the total and initial forms in the management form.
var newTotalForms = $("#id_form-TOTAL_FORMS").attr("value");
newTotalForms ;
$("#id_form-TOTAL_FORMS").attr("value", newTotalForms);
$("#id_form-INITIAL_FORMS").attr("value", newTotalForms);
// Getting the list of notes that need to be moved.
// They're not moved, actually, only their indexes/numbers are changed.
var notesToMove = $(".note").filter(function() {
return this.id.match(/d /) > insertAfter
});
var newNote;
var noteNumberToMod;
var textareaToMod;
var buttonToMod;
var idToMod;
// This is executed when the note will be inserted between notes.
if (notesToMove.length > 0) {
// Clone the first note that will be moved.
// The insertion will be made from this one.
newNote = $(notesToMove[0]).clone();
newNote.find("textarea").text("");
// Insert the new note form where it corresponds.
$("#id-note-" insertAfter).after(newNote);
var changeIndex = Number(insertAfter);
// Modify the attributes of every single note form
// after the inserted one.
for (note of notesToMove) {
note.id = "id-note-" (changeIndex 2);
noteNumberToMod = $(note).find("#id_form-" changeIndex "-note_number");
textareaToMod = $(note).find("#id_form-" changeIndex "-note_text");
buttonToMod = $(note).find("#ins-after-" (changeIndex 1));
idToMod = $(note).find("#id_form-" changeIndex "-id");
noteNumberToMod.attr("name", "form-" (changeIndex 1) "-note_number");
noteNumberToMod.attr("value", (changeIndex 2));
noteNumberToMod.attr("id", "id_form-" (changeIndex 1) "-note_number");
textareaToMod.attr("name", "form-" (changeIndex 1) "-note_text");
textareaToMod.attr("id", "id_form-" (changeIndex 1) "-note_text");
buttonToMod.attr("id", "ins-after-" (changeIndex 2));
buttonToMod.attr("value", "ins-after-" (changeIndex 2));
idToMod.attr("name", "form-" (changeIndex 1) "-id");
idToMod.attr("id", "id_form-" (changeIndex 1) "-id");
idToMod.attr("value", "");
changeIndex ;
}
// This is executed when the insertion is after the last note.
} else {
var insAfter = Number(insertAfter);
newNote = $("#id-note-" insAfter).clone();
insAfter--;
noteNumberToMod = newNote.find("#id_form-" insAfter "-note_number");
textareaToMod = newNote.find("#id_form-" insAfter "-note_text");
buttonToMod = newNote.find("#ins-after-" (insAfter 1));
idToMod = newNote.find("#id_form-" insAfter "-id");
newNote.attr("id", "id-note-" (insAfter 2));
noteNumberToMod.attr("name", "form-" (insAfter 1) "-note_number");
noteNumberToMod.attr("value", (insAfter 2));
noteNumberToMod.attr("id", "id_form-" (insAfter 1) "-note_number");
textareaToMod.attr("name", "form-" (insAfter 1) "-note_text");
textareaToMod.attr("id", "id_form-" (insAfter 1) "-note_text");
buttonToMod.attr("id", "ins-after-" (insAfter 2));
buttonToMod.attr("value", "ins-after-" (insAfter 2));
idToMod.attr("name", "form-" (insAfter 1) "-id");
idToMod.attr("id", "id_form-" (insAfter 1) "-id");
idToMod.attr("value", "");
newNote.find("textarea").text("");
$("#id-note-" (insAfter 1)).after(newNote);
}
}
</script>
После нажатия на любую из этих двух кнопок новая форма добавляется должным образом. Вот так:
(Пожалуйста, смотрите Комментарии)
<body>
<form method="POST" class="note-form">
<input type="hidden" name="csrfmiddlewaretoken" ...>
<div class="notes-pane">
<div id="management-form">...<div>
</div>
<div class="note" id="id-note-1">
<input type="number" name="form-0-note_number" value="1" class="disabled" readonly="readonly" id="id_form-0-note_number">
<textarea name="form-0-note_text" cols="100" rows="8" id="id_form-0-note_text">This is the first note</textarea>
<button id="ins-after-1" class="ins-note-after" type="button" value="ins-after-1">Insert</button>
<input type="hidden" name="form-0-id" value="60" id="id_form-0-id">
</div>
<div class="note" id="id-note-2">
<input type="number" name="form-1-note_number" value="2" class="disabled" readonly="readonly" id="id_form-1-note_number">
<!-- The textarea is empty because this is the new note that was added, after the first one-->
<textarea name="form-1-note_text" cols="100" rows="8" id="id_form-1-note_text"></textarea>
<button id="ins-after-2" class="ins-note-after" type="button" value="ins-after-2">Insert</button>
<input type="hidden" name="form-1-id" value="61" id="id_form-1-id">
</div>
<div class="note" id="id-note-3">
<input type="number" name="form-2-note_number" value="3" class="disabled" readonly="readonly" id="id_form-2-note_number">
<!-- This one says "This is the second note" because it was moved after inserting one before it-->
<textarea name="form-2-note_text" cols="100" rows="8" id="id_form-2-note_text">This is the second note</textarea>
<button id="ins-after-3" class="ins-note-after" type="button" value="ins-after-3">Insert</button>
<!-- Don't mind this line. I still don't know how to handle it's value-->
<input type="hidden" name="form-2-id" value id="id_form-2-id">
</div>
</div>
</form>
</body>
Я могу снова нажать кнопку insert на первой заметке, и после нее будет добавлена еще одна новая заметка, или на последней заметке, и после нее тоже будет добавлена новая заметка. Проблема заключается в том, что при нажатии на кнопки заметок, которые были добавлены с помощью этого кода. Ничего не происходит, функция не введена. Я удостоверяюсь, что их класс точно такой же, но, тем не менее, функция даже не введена.
Комментарии:
1. измените
$(".ins-note-after").click(function() {
на$(document).on('click', '.ins-not-after', () => {
2. рекомендация функции с жирной стрелкой @fedesc
never
идеально подходит для использования в jQuery. Поскольку она не распознает$(this)
, и OP опубликует другой вопрос по этому поводу!3. Правильно. Сила привычки 😀 … Просто хотел указать на изменение в событии click. вы правы ->
$(document).on('click', '.ins-not-after', function () {
4. @fedesc Отлично. Это работает. Я читаю о разнице между использованием
$().click()
и$().on(click, ...)
, и теперь ясно, что первое не будет работать для динамически создаваемых элементов. Но разве первые две кнопки не создаются также динамически? Они не существовали при первой загрузке страницы.5.@TheSprinter В вашем 1-м блоке кода вы начинаете с двух кнопок.
id="ins-after-1"
id="ins-after-2"