Как вывести на страницу отсортированные данные из массива чтобы они не дублировались повторно?

#1

Задача:

  1. вывести на страницу данные, передаваемые из поля ввода - поочередно

  2. отсортировать эти данные (возьмем например метод sort) - так чтобы на странице они появились в определенном порядке.
    Код этой задачи - https://jsfiddle.net/xn7megw4/
    продублирую этот код здесь
    HTML

        <input type = "text" name="add" class = "text-input" id = "text-input" >
       <button class = "add" id = "add" name="addb">Add</button>
       <div class = "text-area" id = "text-area"></div>  
       <button class = "btn" id = "sortname">Sort by name</button>
    

JS

var firstArr = [];
	
var addclick = function(eventclick){
var secondarr = [];
var textinp = document.getElementById("text-input").value;

var res = firstArr.push(textinp);
document.getElementById('text-area').innerHTML += textinp + '<br>';
}

var sortname  = function(sort){
	var textinp = document.getElementById("text-input").value;

	var sortn = firstArr.sort();
	console.log(sortn);
	document.getElementById('text-area').innerHTML += sortn + '<br>';
}

var clickbtn = document.getElementById('add');
clickbtn.addEventListener('click', addclick, false);

var clicksort = document.getElementById('sortname');
clicksort.addEventListener('click', sortname, false);

На втором этапе решения задачи (когда данные уже попали в массив и отобразились в DOM) - почему то после сортировки данные выводятся на страницу повторно: то есть, данные которые были введены пользователем не меняются динамически, а под ними добавляются еще раз эти же данные но отсортированные.
111
Здесь вопрос - как очистить уже имеющиеся данные, которые были введены до сортировки, чтобы остались только те, которые после сортировки?
Предполагаю, что в функции sortname надо как-то удалить данные, которые были добавлены с помощью document.getElementById('text-area').innerHTML += textinp + '<br>'; есть ли какой-то способ, обратный innerHTML чтобы можно было удалить из DOM значения из textinp? - но так чтобы все вместе сразу.
И почему-то отсортированные данные на страницу приходят без пробела и через запятую (как в массиве), ведь для их вывода в DOM есть такая переменная
document.getElementById('text-area').innerHTML += sortn + '<br>';
почему там не срабатывает <br> ?

0 Likes

#2

Тут фишка в том что нужно было заранее планировать как ты будешь очищать содержимое узла. Иногда невозможно решить задачу не сделав шаг назад и не пересмотрев уже существующую реализацию.

Вот в этой строке document.getElementById('text-area').innerHTML += sortn + '<br>'; в переменной sortn - массив. А логика строки - “возьми какой есть innerHTML у узла и сконкатенируй с ним содержимое массива”. Тут js пытается автоматом привести массив к строке, и алгоритм по умолчанию - сконкатенировать элементы массива символом запятой. Результат ты наблюдаешь.


Теперь по поводу подхода

Всегда хорошая стратегия разделять данные от представления.

В твоем случае данные - это массив строк. Представление - это то как этот массив отображается на странице.

Добавление элемента означает что ты

  1. Добавляешь элемент в массив
  2. Вызываешь функцию отрисовки данных на странице

Сортировка означает что

  1. Берешь массив с данными (он будет храниться так же как firstArr в твоем примере).
  2. Сортируешь его
  3. Вызываешь функцию отрисовки данных

Теперь по функции отрисовки. Ее задача - каким бы ни было состояние firstArr, вывести его на страницу. Если в нем 1 элемент, то отрисуется 1 штка, если в массив добавить еще элемент, то после вызова отрисовки отрисуется 2 итд. Самая простая стратегия для функции отрисовки - это очистить узел куда отрисовываются данные и отрисовать все заново.

Это подсказывает как тебе быть дальше?

1 Like

Как правильно использовать insertAdjacentHTML ?
#3

точно… надо было приводить к строке еще когда данные в массиве, в общем вот так:

var sortname  = function(sort){
	var textinp = document.getElementById("text-input").value;
	var sortn = firstArr.sort();
	var end = sortn.join('<br>');
	console.log(end);
	document.getElementById('text-area').innerHTML += end;
}

Остается непонятным только - как очистить уже добавленные данные. Потому что нет какой-либо переменной которая отвечает за вставку данных в DOM, там это делает функция без переменной. Тогда - создавать переменную для document.getElementById('text-area').innerHTML += textinp + '<br>' чтобы потом в другой функции (очистки данных) можно было её использовать ? Или может есть какой другой способ?
И сразу еще вопрос:после сортировки данные находятся в массиве end, и для того чтобы еще что то сделать с этими данными потом (например отсортировать методом reverse также при клике по третьей кнопке Reverse) - тут придется доставать данные из массива end, приводить их split-ом снова к массиву… Или лучше создать функцию в которой заново брать значение из поля ввода
var nextinp = document.getElementById("text-input").value; ?

0 Likes

#4

Сработает для твоего примера.

Я выше написал что лучше всего данные всегда хранить в массиве и отрисовывать их из массива. Тогда не будет проблем типа “как достать из ДОМ то что отрисовано”.

Доставать значения из DOM - вообще не комильфо, и породит кучу других проблем.

0 Likes

#5

если создать переменную, тогда почему присваивание значения в таком случае не работает?

var textinp = document.getElementById("text-input").value;
var insert = document.getElementById('text-area').innerHTML;
insert += textinp + '<br>';

не передает в text-area ничего и ошибок в консоли нет

0 Likes

#6

В переменную записывается значение-строка. Если менять значение переменной insert += textinp + '<br>';, это никак не отразится на значении в DOM.

Если ты хочешь модифицировать DOM, то нужно менять свойства в DOM объектах.

0 Likes

#7

можно подробнее? что именно надо сделать на этом участке кода? как там присваивать значения из ("text-input").value ?

0 Likes

#8

Я вот это имел в виду:

var textinp = document.getElementById("text-input").value;
var insert = document.getElementById('text-area');
insert.innerHTML += (textinp + '<br>');
1 Like