Измените элемент P на элемент ввода при нажатии в JS? - PullRequest
1 голос
/ 20 июня 2020

Моя цель - обновить мов ie. Итак, здесь я создал список mov ie из данных, извлеченных из базы данных. Теперь, когда я нажимаю кнопку обновления, я хочу, чтобы элементы P были заменены элементами ввода, которые содержат текущее значение элементов P. Я хочу удалить элемент P при создании элемента ввода. Затем, когда пользователь нажимает кнопку сохранения, элемент ввода удаляется, а значения из элементов ввода сохраняются в новых элементах P. Затем я отправлю эти данные в базу данных для сохранения на стороне сервера.

Этот код извлекает фильмы из базы данных и генерирует HTML.

// retrieve
getMoviesBtn.addEventListener('click', async(e) => {
  e.preventDefault();

  await axios.get('http://localhost:5000/movies/retrieve-movies')
    .then( res => {
      const movieList = res.data;

      for (let i = 0; i<movieList.length; i++) {
        const sections = document.createElement('section');
        sections.innerHTML = `
          <p class='id'> ${movieList[i].id} </p>
          <p id='title'> Title: ${movieList[i].title} </p>
          <p> Runtime: ${movieList[i].runtime} </p>
          <p> Release date: ${movieList[i].releaseDate} </p>
          <button class="delete-btn">Delete</button>
          <button class="update-btn">Update</button>
        `
        divMovieList.appendChild(sections);
      }
    });
  });

Это то, что у меня есть до сих пор

else if(e.target && e.target.textContent === 'Update') {
    const section = e.target.parentNode;
    const title = section.firstElementChild;
    const titleValue = title.innerHTML;
    const input = document.createElement('input');
    input.type = 'text';
    input.value = titleValue;
    section.insertBefore(input, title);
    section.removeChild(title)
  }

Теперь это работает, чтобы удалить первый элемент P и заменить его элементом ввода. Но как я могу перейти к другим элементам P в этом же разделе, чтобы сделать то же самое?

Спасибо!

1 Ответ

2 голосов
/ 20 июня 2020

Есть несколько вариантов, которые вы можете попробовать.

Вы можете выбрать все теги <p> из элемента <section> с помощью querySelectorAll() и l oop в каждом абзаце и создать для него ввод . Хотя вам все равно понадобится элемент <form>, чтобы обернуть входные данные для захвата данных при отправке.

И имейте в виду, что входам необходим атрибут name, чтобы знать, какое поле принадлежит каждому значению. Вы можете использовать значение атрибута class в качестве значения атрибута name каждого ввода, над которым вы oop.

else if(e.target && e.target.textContent === 'Update') {
  const section = e.target.parentNode;
  const paragraphs = section.querySelectorAll('p');
  for (const paragraph of paragraphs) {
    const name = paragraph.className;
    const input = document.createElement('input');
    input.name = name;
    input.type = 'text';
    input.value = paragraph.textContent;
    section.replaceChild(input, paragraph);
  }
}

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

const createDisplayTemplate = movie => `
  <p class="id"> ${movie.id}</p>
  <p class="title"> Title: ${movie.title}</p>
  <p class="runtime">Runtime: ${movie.runtime}</p>
  <p class="release-date">Release date: ${movie.releaseDate}</p>
  <button class="delete-btn">Delete</button>
  <button class="update-btn">Update</button>
`;

const createEditTemplate = movie => `
  <form>
    <input type="text" name="id" value="${movie.id}">
    <input type="text" name="title" value="${movie.title}">
    <input type="text" name="run-time" value="${movie.runtime}">
    <input type="text" name="release-date" value="${movie.releaseDate}">
    <button class="save-btn">Save</button>
  </form>
`;

const displayTemplate = createDisplayTemplate(movie);
const editTemplate = createEditTemplate(movie);

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

const section = document.querySelector('section');
const display = section.querySelector('.js-display');
const edit = section.querySelector('.js-edit');

section.addEventListener('click', event => {
  const { target } = event;
  if (target.classList.contains('update-btn')) {
    display.classList.add('hide');
    edit.classList.remove('hide');
  } else if (target.classList.contains('save-btn')) {
    display.classList.remove('hide');
    edit.classList.add('hide');
  }
});

edit.addEventListener('submit', event => {
  event.preventDefault();
});
.hide {
  display: none;
}
<section>
  <div class="js-display">
    <p class="id">1</p>
    <p class="title"> Title: The Matrix</p>
    <p class="runtime">Runtime: 2h 16m</p>
    <p class="release-date">Release date: 1999</p>
    <button class="delete-btn">Delete</button>
    <button class="update-btn">Update</button>
  </div>
  <form class="js-edit hide">
    <input type="text" name="id" value="1">
    <input type="text" name="title" value="The Matrix">
    <input type="text" name="run-time" value="2h 16m">
    <input type="text" name="release-date" value="1999">
    <button class="save-btn">Save</button>
  </form>
</section>

Или в крайнем случае: измените все ваши теги <p> на <input> с самого начала. Отключите теги ввода, чтобы их нельзя было сразу редактировать. При нажатии кнопки update l oop над входами и изменении свойства disabled на true или false.

Пример ниже показывает, как это должно выглядеть.

Единственное Проблема здесь - доступность. Вводимые данные не являются текстовыми элементами и будут по-разному считываться программами чтения с экрана и другими инструментами. Так что, если вас это беспокоит, используйте один из вариантов выше.

const section = document.querySelector('section');
const form = document.querySelector('.js-edit');

section.addEventListener('click', event => {
  const { target } = event;
  if (target.classList.contains('update-btn')) {
    for (const input of form.elements) {
      if (input.type === 'text') {
        input.disabled = !input.disabled;
      }
    }
  }
});

form.addEventListener('submit', event => {
  event.preventDefault();
});
form {
  display: flex;
  flex-direction: column;
}

input[type="text"] {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  margin: 10px 0;
  padding: 5px;
  background: #f7f7f7;
}

input[type="text"]:disabled {
  border: 0;
  background: none;
}
<section>
  <form class="js-edit" >
    <input type="text" name="id" value="1" disabled>
    <input type="text" name="title" value="The Matrix" disabled>
    <input type="text" name="run-time" value="2h 16m" disabled>
    <input type="text" name="release-date" value="1999" disabled>
    <button class="update-btn">Update</button>
    <button class="delete-btn">Delete</button>
  </form>
</section>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...