Вход

Просмотр полной версии : построит список из объекта


Dtri
15.07.2015, 23:30
Здравствуйте!
Есть вот такой объект.

jsonTree = {
"firstName": "Иван",
"lastName": "Иванов",
"address": {
"streetAddress": "Московское ш., 101, кв.101",
"city": "Ленинград",
"postalCode": 101101
},
"address2": [
"Адрес",
{
"streetAddress2": "Московское ш., 101, кв.101",
"city2": "Ленинград",
"adress3": 101101
}
],
"phoneNumbers": [
"812 123-1234",
"916 123-4567"
]
};

вложенность у этого объекта может быть неограниченная

Задача: Построить из него вот такой список (тоже не ограниченной вложенности).




<div class="tree">

<ul>
<li><input type="checkbox" name="firstName">Иван</li>
<li><input type="checkbox" name="lastName">Иванов</li>
<li><input type="checkbox" name="address">
<ul>
<li><input type="checkbox" name="streetAddress">Московское ш., 101, кв.101</li>
<li><input type="checkbox" name="city">Ленинград</li>
<li><input type="checkbox" name="postalCode">101101</li>
</ul>
</li>
<li><input type="checkbox" name="address2">Адрес
<ul>
<li><input type="checkbox" name="streetAddress2">Московское ш., 101, кв.101</li>
<li><input type="checkbox" name="city2">Ленинград</li>
<li><input type="checkbox" name="postalCode2">101101</li>
</ul>
</li>
<li><input type="checkbox" name="phoneNumbers">
<ul>
<li>812 123-1234</li>
<li>812 123-1234</li>
</ul>
</li>
</ul>

</div>


Начал вот с такого:

$('.tree').append('<ul></ul>');
for (var key in jsonTree) {
x++;
$('.tree ul').append('<li><input type="checkbox" name="'+key+'">'+jsonTree[key]+'</li>');

}



Естественно этот вариант не отображает вложенность.

<ul>
<li><input type="checkbox" name="firstName">Иван</li>
<li><input type="checkbox" name="lastName">Иванов</li>
<li><input type="checkbox" name="address">[object Object]</li>
<li><input type="checkbox" name="address2">Адрес,[object Object]</li>
<li><input type="checkbox" name="phoneNumbers">812 123-1234,916 123-4567</li>
</ul>


Вот тут начинается самое сложное.
как сделать такой перебор чтобы по всем ключам проходил.
Хотя может не правильно мыслю.
Подскажите как реализовать эту задачу.

Подчёркиваю. объект с сервера может приходить неограниченной вложенности, соответственно и список рисоваться должен неограниченной вложенностью.

laimas
15.07.2015, 23:42
как сделать такой перебор чтобы по всем ключам проходил

Проверять, если jsonTree[key] объект, значит вложение, запоминать тег открытый, и извлекать его после выхода из цикла обхода вложения.

jasper-blondin
15.07.2015, 23:59
Нужно написать рекурсивную функцию, которая выводит элементы списка в заданной форме для уровня вложенности "один". На каждой итерации проверять, является ли текущий экземпляр сам по себе объектом, если да -- запускать эту же функцию, но уже для текущего объекта.

Decode
16.07.2015, 00:54
Попробовал написать, но у меня чет фигня пока получается, лишний элемент <li> каждый раз вставляется.

<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
</head>
<body>
<div class="tree"></div>

<script>
$(document).ready(function() {
var jsonTree = {
"firstName": "Иван",
"lastName": "Иванов",
"address": {
"streetAddress": "Московское ш., 101, кв.101",
"city": "Ленинград",
"postalCode": 101101
},
"address2": {
"streetAddress2": "Московское ш., 101, кв.101",
"city2": "Ленинград",
"adress3": 101101
}
};

function createList(obj) {
debugger;
if(typeof obj !== 'object') return;

var ul = $('<ul />');

for(var key in obj) {
var item = $('<li> <input type="checkbox" name="' + key + '" />' + (obj[key] == '[object Object]' ? key : obj[key]) +'<li />');
var ulChilds = createList(obj[key]);
ulChilds && item.append(ulChilds);
ul.append(item);
}
return ul;
}

$('.tree').append( createList(jsonTree) );
});
</script>
</body>
</html>

laimas
16.07.2015, 01:18
Попробовал написать, но у меня чет фигня пока получается

Сперва надо входные данные к нормальному виду привести, а то у него один объект имеет метку "Адрес", а точно такой же выше без нее. Если такие данные будут, то или условностями все обрастет или запутаться можно.

рони
16.07.2015, 02:23
Если такие данные будут, то или условностями все обрастет
:yes:
при нормальных данных строка 43 будет в трое короче
<!DOCTYPE HTML>

<html>

<head>
<title>Untitled</title>
<meta charset="utf-8">
<style type="text/css">

</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
$(function(){
var jsonTree = {
"firstName": "Иван",
"lastName": "Иванов",
"address": {
"streetAddress": "Московское ш., 101, кв.101",
"city": "Ленинград",
"postalCode": 101101
},
"address2": [
"Адрес",
{
"streetAddress2": "Московское ш., 101, кв.101",
"city2": "Ленинград",
"adress3": 101101
}
],
"phoneNumbers": [
"812 123-1234",
"916 123-4567"
]
};
function fn(b) {
var d = $("<ul>");
Object.keys(b).forEach(function(a) {
var c = $("<li/>"),
e = $("<input/>", {
type: "checkbox",
name: a
});
"string" === $.type(b[a]) || "number" === $.type(b[a]) ? c.append(b[a]) : "address2" === a ? c.append(b[a][0]).append(fn(b[a][1])) : c.append(fn(b[a]));
isNaN(+a) && c.prepend(e);
c.appendTo(d)
});
return d
};
$("body").append(fn(jsonTree))
});
</script>
</head>

<body>


</body>

</html>

laimas
16.07.2015, 09:07
при нормальных данных строка 43 будет в трое короче

Ну да, а то какая-то несуразица получается - данные из базы, где они имеют одну и ту же структуру у каждого субъекта, но почему-то первый адрес это объект, а второй, это уже объект как элемент массива. И что интересно, это неограниченная вложенность, которую можно решить рекурсией, вот только трудно представить как будет на клиенте такое неограниченное вложение выглядеть, и как серверу обработать данные с таким "неограниченным именованием".

Что-то тут изначально представлено не то. )

Dtri
19.07.2015, 03:17
Всем спасибо за участие. Приношу извинения за столь долгий ответ.

Пересмотрел ваши варианты. Вы очень помогли идеей с рекурсией. Многое подчеркнул из примера рони

Но решил воспользоваться более стандартным циклом. и немного перебрал алгоритм, так как вариант автора не предполагал не ограниченной вложенности. В условии ("string" === $.type(b[a]) || "number" === $.type(b[a]) ? c.append(b[a]) : "address2" === a ? c.append(b[a][0]).append(fn(b[a][1])) : c.append(fn(b[a]));) приходилось бы дописывать лишние параметры при дальнейшем увеличении вложенных пунктов списка. а задача заключалась именно в создании универсального плагина.

Вот например данная вложенность как показано ниже у автора вызывала артефакты.

Вот что получилось в итоге:

Что касается рекурсии. всё понятно. Но хотелось бы методом итерации. Может кто-нибудь подскажет способ?





<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>

</head>
<body>
<div class="tree"></div>

<script>$(document).ready(function () {
var jsonTree = {
"firstName": "Иван",
"lastName": "Иванов",
"address1": {
"streetAddress1": "streetAddress1",
"city1": "city1",
"postalCode1": {
"streetAddress1": "streetAddress1",
"city1": "city1",
"postalCode1": {
"streetAddress1": "streetAddress1",
"city1": "city1",
"postalCode1": 'postalCode1'
}
}
},
"address2": [
"Адрес",
{
"streetAddress2": "streetAddress2",
"city2": "city2",
"postalCode2": [
"postalCode2",
{
"streetAddress2": "streetAddress2",
"city2": "city2",
"postalCode2": [
"postalCode2",
{
"streetAddress2": "streetAddress2",
"city2": "city2",
"postalCode2": [
"postalCode2",
{
"streetAddress2": "streetAddress2",
"city2": "city2",
"postalCode2": [
"postalCode2",
{
"streetAddress2": "streetAddress2",
"city2": "city2",
"postalCode2": 'postalCode2'
}
]
}
]
}
]
}
]
}
],
"phoneNumbers": [
"812 123-1234",
"812 123-1234"
]
};


//$('.tree').append(JSONtree(jsonTree));

(function ($) {


function JSONtree(obj) {
var
ul = $('<ul/>');
for (var key in obj) {
var
li = $('<li/>'),
input = $('<input/>', {
type: "checkbox",
name: key
});

if ($.type(obj[key]) == 'string' || $.type(obj[key]) == 'number') {
li.append(input).append(obj[key]);
ul.append(li);
}
if ($.type(obj[key]) == 'array' && $.type(obj[key][1]) !== 'object') {
li.append(input).append('Без названия').append(JSONtree(obj[key]));
ul.append(li);
}
if ($.type(obj[key]) == 'array' && $.type(obj[key][1]) == 'object') {
li.append(input).append(obj[key][0]).append(JSONtree(obj[key][1]));
ul.append(li);
}
if ($.type(obj[key]) == 'object') {
li.append(input).append('Без названия').append(JSONtree(obj[key]));
ul.append(li);
}
}
return ul;
}

$.fn.JSONtreeAppend = function (obj) {
return this.append(JSONtree(obj));
}
})(jQuery);
$('.tree').JSONtreeAppend(jsonTree);
});</script>
</body>
</html>