#javascript #html #jquery
#javascript #HTML #jquery
Вопрос:
Я новичок в javascript / jquery и на некоторое время застрял на этой проблеме. Итак, у меня есть две кнопки: кнопка очистки, которая очистит все формы в строке таблицы, и кнопка сброса, которая содержит все начальные значения для каждой строки таблицы.
Проблема: Поэтому в настоящее время, когда я запускаю скрипт, кнопка сброса будет продолжать переопределять кнопку очистки. Это означает, что когда я нажимаю очистить, это также будет действовать как сброс вместо очистки строки. Я попытался создать уникальные классы (.clear_button, .reset_button), которые будут вызываться так, как вы видите здесь. Мне трудно устранять неполадки в javascript, особенно будучи новичком в нем, так почему это происходит?
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$(".clear_button").click(function(){
function my_clearFunction(i) {
document.getElementById("id_form-" (i - 1) "-Name").value = " ";
document.getElementById("id_form-" (i - 1) "-Start").value = "";
document.getElementById("id_form-" (i - 1) "-End").value = "";
document.getElementById("id_form-" (i - 1) "-Advanced").value = " ";
}
});
$(".reset_button").ready(function(){
$('#reset :input:not([type="button"])').each(function(idx, ele) {
ele.dataset.initvalue = ele.value;
});
$('#reset [type="button"]').on('click', function(e) {
// reset current row............
$(this).closest('tr').find(':input:not([type="button"])').each(function(idx, ele) {
// restore the initial value
ele.value = ele.dataset.initvalue;
})
});
});
});
</script>
Примечание: я понимаю, что код неоднороден, например, моя логика clear button не была написана в jquery. Извините, я не смог прикрепить jsfiddle, этот проект относительно большой, и я использую django для импорта своих форм, поэтому его было сложно настроить. Поэтому любой ввод был бы очень признателен, поскольку я застрял на этом довольно долгое время и, похоже, не могу его получить. Также стоит упомянуть мои входные теги для кнопок, так что вот они.
<input type="button" class="clear_button" onclick="my_clearFunction({{ forloop.counter }})" value=" x ">
<input type="button" class="reset_button" value=" x ">
Комментарии:
1. Ваш
click
обработчик для кнопки очистки ничего не очищает. Все, что он делает, это определяет локальную функцию, которую он никогда не вызывает.2. Вы не можете вызвать
my_clearfunction()
fromonclick
, потому что это ищет только имена в глобальной области видимости, а функция локальна для функции обратного вызова обработчика щелчков.3. Если вы не получаете ошибку «неопределенная функция» при нажатии на кнопку очистить, у вас должно быть другое определение для
my_clearfunction()
.
Ответ №1:
когда я нажимаю очистить, это также будет действовать как сброс вместо очистки строки.
Ваш слушатель сброса объявлен как
$('#reset [type="button"]').on('click', function(e) {
...
})
Кажется, #reset
элемент содержит кнопки очистки и сброса, поэтому нажатие на любую из них восстановит исходные значения.
Кнопка очистки также имеет два собственных обработчика. В коде объявлен один, который, в свою очередь, объявляет функцию (которая не вызывается в самом обработчике) и встроенный обработчик, который пытается вызвать указанную функцию. Это не должно работать, поскольку оно не видно из глобальной области видимости.
Вместо
$(button).on('click',(e)=>{
function doSomethingWith(i) {
...
}
doSomethingWith(e.target.id);
})
Если должно быть
function doSomethingWith(i) {
...
}
$(document).ready(function(){
$(button).on('click',(e)=>{
doSomethingWith(e.target.id);
});
});
тогда она была бы видна для обработчика, но также и в глобальной области видимости, так что вы могли вызвать ее с помощью встроенного «onclick»
<button onclick="doSomethingWith({{ forloop.counter }})" >
Однако у вас не должно быть встроенного обработчика, если вы также объявляете его в JS. Поскольку вы имеете дело с кнопкой сброса в коде, придерживайтесь этого подхода и для кнопки очистки.
Теперь, подход, которому вы следуете для очистки строки, требует, чтобы вы знали относительный индекс строки и входные данные в каждой строке, для которых вы вычисляете их соответствующие идентификаторы. В то время как, когда дело доходит до сброса исходных значений, вам не нужно ничего знать:
$('.reset_button').on('click', function(e) {
// reset current row............
$(this).closest('tr').find(':input:not([type="button"])').each(function(idx, ele) {
// restore the initial value
ele.value = ele.dataset.initvalue;
})
});
Кнопке нужно только знать, что она находится внутри того же <tr>
элемента, что и другие входные данные, значение которых необходимо восстановить. Его не волнует индекс, идентификаторы, даже то, какие входные данные находятся на месте, если они не являются кнопками.
Вы должны сделать то же самое, чтобы очистить значения:
$('.clear_button').on('click', function(e) {
// reset current row............
$(this).closest('tr').find(':input:not([type="button"])').each(function(idx, ele) {
ele.value = "";
});
});
Когда дело доходит до сохранения исходного значения, я также привык прибегать к jQuery.данные . В любом случае, для этого варианта использования вы можете идеально придерживаться
input.dataset.initialValue = input.value
Вместо
$(input).data('initialValue',input.value)
Пока вы помните, что эти подходы не взаимозаменяемы. Вы не можете установить начальное значение с помощью dataset, а затем получить его с помощью jQuery.данные или наоборот.
function randomTime() {
return [
Number(100 * Math.random() % 12).toFixed(0).padStart(2, '0'),
Number(100 * Math.random() % 60).toFixed(0).padStart(2, '0')
].join(':');
}
function addFormRow(player_name = 'N/A') {
let tr = $('<tr class="form_row">'),
name = $('<input type="text" name="name" class="name">'),
start = $('<input type="time" name="start" class="start">'),
end = $('<input type="time" name="end" class="end">'),
advanced = $('<input type="number" name="advanced" class="advanced">'),
clear = $('<button class="clear_button">Clear</button>'),
reset = $('<button class="reset_button">Reset</button>');
name.val(player_name);
start.val(randomTime());
advanced.val(parseInt(Math.random() * 100, 10))
end.val(randomTime());
for (let input of [name, start, end, advanced, clear, reset]) {
$('<td>').append(input).appendTo(tr);
}
tr.appendTo('#forms tbody');
}
addFormRow('player one');
addFormRow('player two');
addFormRow('player three');
$(document).ready(function() {
$('#forms tbody tr').each((index,tr)=>{
$(tr).find('input').each((idx,input)=>{
$(input).data('initialValue',$(input).val());
});
})
$(".clear_button").on('click', (e) => {
let $this = $(e.target),
tr = $this.closest('tr');
tr.find('input').each((index, input) => {
input.value = '';
});
});
$(".reset_button").on('click', (e) => {
let $this = $(e.target),
tr = $this.closest('tr');
tr.find('input').each((index, input) => {
$(input).val($(input).data('initialValue'));
});
});
});
.advanced {
width: 4em;
}
.name {
width: 9em;
}
.start,
.end {
width: 5.5em;
}
.form_row input {
height: 1.1em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="forms">
<thead>
<tr>
<th>name</th>
<th>start</th>
<th>end</th>
<th>advance</th>
<th colspan="2">actions</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
Комментарии:
1. Если бы только я мог проголосовать более одного раза! Спасибо за всю эту полезную информацию.
Ответ №2:
Ваш $(".clear_button").click()
обработчик ничего не делает. Он определяет локальную функцию, но никогда не вызывает ее.
Вместо того, чтобы пытаться вызвать функцию из onclick()
, добавьте data
атрибут к кнопкам, содержащим индекс. Затем обработчик щелчка может получить этот атрибут и использовать его для поиска всех связанных элементов, которые ему необходимо очистить.
$(".clear_button").click(function() {
var i = $(this).data("rel-id");
document.getElementById("id_form-" (i - 1) "-Name").value = " ";
document.getElementById("id_form-" (i - 1) "-Start").value = "";
document.getElementById("id_form-" (i - 1) "-End").value = "";
document.getElementById("id_form-" (i - 1) "-Advanced").value = " ";
});
<input type="button" class="clear_button" data-rel-id="{{ forloop.counter }}" value=" x ">
Комментарии:
1. Я не знал об атрибуте данных, спасибо за полезную информацию! Я понимаю, почему onclick() влиял на сценарий, но теперь, когда я включил атрибут data, он все еще не работает, и сброс продолжает переопределять кнопку очистки.