15.07.2015, 23:30
|
Аспирант
|
|
Регистрация: 14.12.2014
Сообщений: 86
|
|
построит список из объекта
Здравствуйте!
Есть вот такой объект.
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>
Вот тут начинается самое сложное.
как сделать такой перебор чтобы по всем ключам проходил.
Хотя может не правильно мыслю.
Подскажите как реализовать эту задачу.
Подчёркиваю. объект с сервера может приходить неограниченной вложенности, соответственно и список рисоваться должен неограниченной вложенностью.
Последний раз редактировалось Dtri, 15.07.2015 в 23:35.
|
|
15.07.2015, 23:42
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
Сообщение от Dtri
|
как сделать такой перебор чтобы по всем ключам проходил
|
Проверять, если jsonTree[key] объект, значит вложение, запоминать тег открытый, и извлекать его после выхода из цикла обхода вложения.
|
|
15.07.2015, 23:59
|
|
Аспирант
|
|
Регистрация: 11.07.2015
Сообщений: 33
|
|
Нужно написать рекурсивную функцию, которая выводит элементы списка в заданной форме для уровня вложенности "один". На каждой итерации проверять, является ли текущий экземпляр сам по себе объектом, если да -- запускать эту же функцию, но уже для текущего объекта.
|
|
16.07.2015, 00:54
|
Профессор
|
|
Регистрация: 31.01.2015
Сообщений: 576
|
|
Попробовал написать, но у меня чет фигня пока получается, лишний элемент <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>
|
|
16.07.2015, 01:18
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
Сообщение от Decode
|
Попробовал написать, но у меня чет фигня пока получается
|
Сперва надо входные данные к нормальному виду привести, а то у него один объект имеет метку "Адрес", а точно такой же выше без нее. Если такие данные будут, то или условностями все обрастет или запутаться можно.
|
|
16.07.2015, 02:23
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
Сообщение от laimas
|
Если такие данные будут, то или условностями все обрастет
|
при нормальных данных строка 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>
Последний раз редактировалось рони, 16.07.2015 в 02:25.
|
|
16.07.2015, 09:07
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
Сообщение от рони
|
при нормальных данных строка 43 будет в трое короче
|
Ну да, а то какая-то несуразица получается - данные из базы, где они имеют одну и ту же структуру у каждого субъекта, но почему-то первый адрес это объект, а второй, это уже объект как элемент массива. И что интересно, это неограниченная вложенность, которую можно решить рекурсией, вот только трудно представить как будет на клиенте такое неограниченное вложение выглядеть, и как серверу обработать данные с таким "неограниченным именованием".
Что-то тут изначально представлено не то. )
|
|
19.07.2015, 03:17
|
Аспирант
|
|
Регистрация: 14.12.2014
Сообщений: 86
|
|
Всем спасибо за участие. Приношу извинения за столь долгий ответ.
Пересмотрел ваши варианты. Вы очень помогли идеей с рекурсией. Многое подчеркнул из примера рони
Но решил воспользоваться более стандартным циклом. и немного перебрал алгоритм, так как вариант автора не предполагал не ограниченной вложенности. В условии (
"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>
Последний раз редактировалось Dtri, 19.07.2015 в 03:27.
|
|
|
|