Включить / отключить элемент HTML с динамически генерируемыми именами / тегами - PullRequest
0 голосов
/ 28 февраля 2020

У меня есть таблица в HTML, где идентификатор динамически генерируется из счетчика строк:

$(table).find('tbody').append("<tr>name=\"tableRow\"</tr>"
    + "<td>"
      + "<select id=\"shapeSelect_" + rowCount + "></td>"
        + "<option onclick=\"sphereSelect()\" value=\"sphere\">Sphere</option>"
        + "<option onclick=\"cylinderSelect()\" value=\"cylinder\">Cylinder</option>"
      + "</select>"
    + "</td>"
    + "<td><input type=\"text\" id=\"altitude" + rowCount + "\"</td>"
    + "<td><input type=\"text\" name=\"maxAlt\" id=\"maxAltitude_" + rowCount + "></td>"
    + "</tr>"

Мне нужно, чтобы maxAltitude отключалась для ввода при выборе сферы. Когда цилиндр выбран, он должен быть включен для ввода.

Каждый пример, который я нахожу, довольно прост, но требует точного знания идентификатора, где в моем коде он генерируется динамически. Это пример того, что я нахожу:

$(#maxAltitude).prop("disabled", true);

Как я могу сделать это, когда maxAltitude будет больше похожа на: maxAltitude_10? В таблице может быть 1-n рядов, и мне нужно специально отключить максимальную высоту в ряду, где был выбран раскрывающийся список.

Я пробовал jQuery и javascript, но не могу найти хороший способ сделать это:

<option onclick="shapeSelect()" value="sphere">Sphere</option>
<option onclick="shapeSelect()" value="cylinder">Cylinder</option>

function shapeSelect() {
    var shapeSelects = document.getElementsByName("shapeSelect");
    var maxAlts = document.getElementsByName("maxAlt");
    for(var i = 0; i < shapeSelects.length; i++) {
        switch(shapeSelects[i].value) {
        case "sphere":
            maxAlts[I].disabled = True;
            break;
        case "cylinder":
            maxAlts[i].disabled = False;
        }
    }
}

С приведенным выше кодом я получаю: SyntaxError: неожиданный токен: идентификатор всякий раз, когда запускается shapeSelect ().

Я изменил код следующим образом:

<table class="myTable" id="myTable"></table>

$(table).find('tbody').append("<tr>name=\"tableRow\"</tr>"
        + "<td>"
          + "<select id=\"shapeSelect_" + rowCount + "></td>"
            + "<option value=\"sphere\">Sphere</option>"
            + "<option value=\"cylinder\">Cylinder</option>"
          + "</select>"
        + "</td>"
        + "<td><input type=\"text\" id=\"altitude_" + rowCount + "\"</td>"
        + "<td><input class=\"maxAltitudeInput\" type=\"text\" id=\"maxAltitude_" + rowCount + "\" disabled></td>"
        + "</tr>"

$('#myTable').on('change','.shapeSelector',function(){
    var shouldDisableInput = $(this).val() === 'sphere';
    $(this).closest('tr').find('.maxAltitudeInput').attr('disabled',shouldDisableInput);
}

И все же ничего не происходит при изменении выпадающего списка формы.

РЕДАКТИРОВАТЬ:

Извинения за несоответствия именования. Моя dev-машина подключена к сети с воздушным зазором, и я вручную глушил пост здесь, на переполнении стека. Переменная rowCount создавалась и увеличивалась в другой функции. Я пытался для краткости разместить только соответствующий код в сообщении.

I был пропустил класс из shapeSelector. Это было недостающее звено. Это работает сейчас!

1 Ответ

0 голосов
/ 28 февраля 2020

jQuery на самом деле делает это действительно простым, привязывая this к любому элементу, вызвавшему событие.

Например, вместо написания обобщенной функции c для изменения этого значения, вы можете использовать jQuery для привязки слушателя события к ним:

$('#myTable').on('change','.shapeSelector',function(){
    var shouldDisableInput = $(this).val() === 'sphere';
    $(this).closest('tr').find('.maxAltitudeInput').attr('disabled',shouldDisableInput);
}

В этом фрагменте вы заметите несколько вещей:

  1. Элемент, к которому мы привязываем слушателя, это таблица, а не отдельный ряд. Это потому, что строка динамическая c, и нам не нужно постоянно добавлять слушателей каждый раз, когда мы добавляем строку. Вместо этого мы добавляем его к родительскому элементу, который является стабильным, но затем мы указываем, что нам интересны его дочерние элементы, которые соответствуют ".shapeSelector"
  2. Слушатель использует имена классов, а не идентификаторы, так как мы хотим сопоставить несколько их копии, а не конкретная c. Поэтому вам нужно добавить эти имена классов или аналогичный способ сопоставления нескольких элементов
  3. Внутри функции обратного вызова, которая запускается, вы заметите, что пара использует this. jQuery связал это с элементом, который вызвал прослушиватель событий, в данном случае с элементом управления <select>. Поэтому, когда мы используем this, мы должны думать об этом с этой точки зрения. Мы можем получить его значение по $(this).val(), мы можем найти его с помощью $(this).parent(), et c. В этом случае я еду до ближайшего tr, затем оттуда до входа tr, который я хочу отключить. Вам нужно будет немного отрегулировать в зависимости от вашего домена.
  4. Также обратите внимание, что this является элементом DOM, а не jQuery результатом. Вот почему, когда мы хотим запустить на нем больше jQuery команд, мы должны снова поместить его в $ ().

Вот так я бы подошел. У нас здесь нет всего вашего кода, поэтому вам придется немного подстроиться, но, надеюсь, это подтолкнет вас в правильном направлении.

EDIT

Честно говоря, было много несоответствий имен и вещей, которые не совпадали. Например, вы пытались добавить тег tbody, но этот тег не существовал. Вы использовали переменную rowCount, но никогда ее не устанавливали и не увеличивали. У тега select не было имени класса, который вы пытались использовать.

Я предлагаю вам посмотреть на фрагмент кода по частям, спросить себя, что вы говорите браузеру, а затем сделать это. в уме, чтобы убедиться, что компьютер может это сделать.

HTML:

<table class="myTable" id="myTable"><tbody></tbody></table>

JavaScript:

var rowCount = 0;

function addRow(){
   $('.myTable tbody').append(`<tr name="tableRow">
        <td> 
          <select class="shapeSelector" id="shapeSelect_${rowCount}">
            <option value="sphere">Sphere</option>
            <option value="cylinder">Cylinder</option>
          </select>
        </td>
        <td><input type="text" id="altitude_${rowCount}" /></td>
        <td><input class="maxAltitudeInput" type="text" id="maxAltitude_${rowCount}" disabled></td>"
        </tr>`);
   rowCount++;
}


$('.myTable').on('change','.shapeSelector',function(){
    var shouldDisableInput = $(this).val() === 'sphere';
    $(this).closest('tr').find('.maxAltitudeInput').attr('disabled',shouldDisableInput);
});

addRow();
addRow();
addRow();

https://jsfiddle.net/32vnjq81/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...