Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Нужна помощь с двумерным массивом (https://javascript.ru/forum/jquery/3506-nuzhna-pomoshh-s-dvumernym-massivom.html)

SirNaFigator 27.04.2009 23:42

Нужна помощь с двумерным массивом
 
Доброго времени суток.
Некоторое время уже бьюсь с jquery, но вот в упор не могу понять как мне парстить двумерный массив полученный в json формате.

ПО сути мне приходит массив сообщений вот в таком формате:
Код:

{
    mess:{
        message:'время','кто сказал','кому скаали','цвет текста','сообщение',
        message:'время','кто сказал','кому скаали','цвет текста','сообщение',
        message:'время','кто сказал','кому скаали','цвет текста','сообщение',
        message:'время','кто сказал','кому скаали','цвет текста','сообщение'
    }
}

сообщений может быть от 0 до 100 за один запрос.
так же у меня кроме jquery подключается яваскрипт с функцией по отрисовке полученных сообщений ShowMessage(data)

на данном этапе скрипт выглядит так:
Код:

jQuery(document).ready(function(){
        jQuery.getJSON('chat_test.php', {}, function(json){
                jQuery('#mes').append(json.messages.message + '<br/>');
        });
});

соответственно оно не работает :wacko:
в лучшем случае, чего я добивался, это отображения одной строки из всех полученных.

Люди добрый поможите советом, христа ради, ибо заи***ся я уже =)
Заранее прошу прощения если я туплю и решение элементарно и лежит под носом.

Riim 27.04.2009 23:57

json не валидный



{
    mess:{
        message1:['время','кто сказал','кому скаали','цвет текста','сообщение'],
        message2:['время','кто сказал','кому скаали','цвет текста','сообщение'],
        message3:['время','кто сказал','кому скаали','цвет текста','сообщение'],
        message4:['время','кто сказал','кому скаали','цвет текста','сообщение']
    }
}

SirNaFigator 28.04.2009 00:00

хммм, точно!!!
А по функции обработки?

Riim 28.04.2009 00:03

Я кроме названия этой функции (ShowMessage) саму ее не вижу.

SirNaFigator 28.04.2009 00:10

я имел в виду, каким образов отображать весь массив сообщений, а не только первое.

Riim 28.04.2009 00:13

Цитата:

Сообщение от SirNaFigator
я имел в виду, каким образов отображать весь массив сообщений, а не только первое.

Не массив у вас, а объект (если вы про json.mess). И ключи в нем одинаковые. Каждый следующий перезаписывает предыдущий. Т. е. у вас один ключ.

SirNaFigator 28.04.2009 00:51

с учетом исправлений получается следующий ответ сервера:
Код:

{
    messages:{
        mess_312:['время','кто сказал','кому скаали','цвет текста','сообщение'],
        mess_542:['время','кто сказал','кому скаали','цвет текста','сообщение'],
        mess_9113:['время','кто сказал','кому скаали','цвет текста','сообщение'],
        mess_1214:['время','кто сказал','кому скаали','цвет текста','сообщение']
    }
}

Теперь возникает вопрос, как применить функцию ShowMess к каждому члену объекта, если я не знаю его ключ.

x-yuri 28.04.2009 01:02

for(var k in obj)

SirNaFigator 28.04.2009 01:11

Господа, огромное спасибо, теперь все работает =)

Riim 28.04.2009 01:21

А я бы json.messages массивом сделал. Трафик меньше и сервер генерацией ключей грузить не надо.

czar 28.04.2009 15:22

вот я делал обновлялку для таблицы с данными. каждые $timer секунд у меня шёл запрос к базе и получал данные от не в виде обекта джейсона
формата вида:
data = {"bids":[{"Security":" ","QType":" ","Volume":" ","Price":" ","Trader":null,"Client":null,"Comments":" ","Date_add":null,"Date_update":null,"Type":"1","A ction":{"n":true,"e":false,"d":false}}],"offers":[{"Security":" ","QType":" ","Volume":" ","Price":" ","Trader":null,"Client":null,"Comments":" ","Date_add":null,"Date_update":null,"Type":"2","A ction":{"n":true,"e":false,"d":false}}]}

собвенно переделывал массив php в джейсон...саму функцию не помню, бо переделывал зендом.Zend_Json::encode($array);
у меня две таблицы bids и offers потому два объекта внутри.
чистить код для данного примера не захотел,думаю и так понятно.. запускается аджакс запрос, при получении данных пробигнается по всему массиву и добавляет построчно в таблицу строки. используется плагин dataTable для вида таблицы и сортировки-фильтрации, но это к делу не сильно относится. суть в получении и прохождению по данным массива.

думаю будет полезно :))
$("#message").everyTime(
			$timer,
			function(i){
				$.ajax({
					url: "<?php echo $this->baseUrl?>flow/get.new.rows/<?php echo $this->locid.$this->forLink.$this->urlEnd;?>",
					global: false,
					type: "POST",
					dataType: 'json',
					beforeSend: function(){
						$('.ui-widget').show();
					},
					complete : function(){
						$(".ui-widget").hide();
						$('td a').addClass('thickbox');
					},
					success: function($data){
					//alert($data.bids !== undefined);
						if($data.bids != undefined || $data.offers != undefined)
						{
							if($data.bids.length > 0) bidsTable.fnClearTable( 0 );
							if($data.offers.length > 0)offersTable.fnClearTable( 0 );
							$.each($data,function(a,b){
								$.each(b,function(i,v){
									var date_add = v.Date_add != null ? new Date(v.Date_add*1000): '';
									var date_update = v.Date_update != null ? new Date(v.Date_update*1000): '';
									
									var $act_n = v.Action.n ? '<a href="http://flow:81/flow/edit.<?php echo $this->loc?>-'+v.Type+'-0<?php echo $this->urlEnd?>?height=250&width=300" class="thickbox"><img src="/design/img/btn_add.png" /></a>':'';
									var $act_e = v.Action.e ? '<a href="http://flow:81/flow/edit.<?php echo $this->loc?>-'+v.Type+'-'+v.id+'<?php echo $this->urlEnd?>?height=250&width=300" class="thickbox"><img src="/design/img/btn_edit.png" /></a>':'';
									var $act_d = v.Action.d ? '<a href="http://flow:81/flow/delete.'+v.id+'-<?php echo $this->locid.$this->urlEnd?>"><img src="/design/img/btn_delete.png" /></a>':'';
								
									
									var $row = [
										v.Security != null ? v.Security.toString(): '', 
										v.QType != null ? v.QType.toString(): '',
										v.Volume != null ? v.Volume.toString(): '',
										v.Price != null ? v.Price.toString(): '',
										v.Trader != null ? v.Trader.toString(): '',
										v.Client != null ? v.Client.toString(): '',
										v.Comments != null ? v.Comments.toString(): '',
										v.Date_add != null ? date_add.format('d.m.Y H:i').toString(): date_add.toString(),
										v.Date_update != null ? date_update.format('d.m.Y H:i').toString():date_update.toString(),
										$act_n+' '+$act_e+' '+$act_d
									];
								
									if(v.Type.toString() == "1")
									{
										bidsTable.fnAddData($row);
									}
									if(v.Type.toString() == "2"){
										offersTable.fnAddData($row);
									}
								
								});
							});
						}
					}
				});
			}
		);


если нужно сортировать сам массив, то я его сортирую до получения, то есть средсвами php...ну это начальная сортировка..потом уже как душе угодно.

e1f 29.04.2009 14:43

Лучше отдельно передавать массив хидеров, а вместо хеша будут массивы -- меньше траффика

x-yuri 29.04.2009 19:33

Цитата:

А я бы json.messages массивом сделал. Трафик меньше и сервер генерацией ключей грузить не надо.
я б сказал, что если не нужно по id искать сообщения, то делать хэш - ненужная сложность

czar 30.04.2009 10:50

Цитата:

Сообщение от e1f (Сообщение 17859)
Лучше отдельно передавать массив хидеров, а вместо хеша будут массивы -- меньше траффика

не понял... что такое хидеры?? можно пример или более доступно объяснить?

e1f 30.04.2009 16:12

data = {
    "head": [ "Security", "QType", "Volume", "Price", "Trader", "Client", "Comments", "Date_add", "Date_update", "Type", "Action" ],
    "rows": [
        { "id":"bids", "data": [ " ", " ", " ", " ", null, null, " ", null, null, "1", {"n":true,"e":false,"d":false}] }
        { "id":"offers", "data": [ " ", " ", " ", " ", null, null, " ", null, null, "1", {"n":true,"e":false,"d":false}] }
    ]
}

czar 30.04.2009 19:30

хм..как вариант...надо попробовать.. может быстрее гонять будет.. хотя у меня и так не превышает 100 строчек.

SirNaFigator 05.05.2009 00:20

А вот еще вопрос на засыпку:
на данный момент происходит следующее.

По таймеру получаются данные в json формате, обрабатываются функцией отображения и вставляются аппендом в див заданой высоты с overflow-y: scroll;

Так вот. При вставке новых сообщений их не видно, тоесть приходится самому крутить колесо мышки чтобы увидеть их в самом низу дива.
А можно ли сделать так, чтобы после вставки сообщения происходил как бы скрол на последнее? focus и scrollby пробовал, не помогает =(
Хотелось бы узнать можно ли это сделать средствами jquery ??

e1f 05.05.2009 13:37

$('#myDiv').scrollTop($('#myDiv').height()||0)

SirNaFigator 05.05.2009 18:16

Однако, почему-то не работает. :cray:

вот собственно мой код:
Код:

var count = 0;
var chat_mode = 'all';
function ChatGetMess(){ jQuery.getJSON('chat_gm.php?chat_mode='+chat_mode+'', {}, function(json){
                                        for(var k in json.messages){
                                                count++;
                                                jQuery('#mes').append('<div class=\"shoutbox-list\" id=\"list-'+count+'\">' + ShowMessage(json.messages[k]) + '</div>');

                                                $('#list-'+count).fadeIn('slow');
                                                $(function(){
                                                        $('.scroll-pane').jScrollPane({showArrows:true, scrollbarWidth:16, dragMaxHeight:20});
                                                });
                                                $('#mes').scrollTop($('#mes').height()||0);
                                        }
                                });
                                timeoutID = setTimeout(ChatGetMess, 5000);
                        }

сдвига в самый низ дива не происходит =(((((

e1f 05.05.2009 18:37

Всегда знал, что методы .height, .width -- УГ.
$('#mes').scrollTop($('#mes').get(0).scrollHeight||0)

SirNaFigator 05.05.2009 19:40

млин, ну ведь все равно не работает :blink:

сообщения продолжают добавляться, но автоматический скролл в самы низ дива не происходит.
Может быть стоит копать в сторону айдишника дива последнего сообщения?
хотя фокусом, также не скроллит :-E

вот итоговый код:

Код:

echo"<html><head>
<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=windows-1251'>
<script type='text/javascript' src='jquery.js'></script>
<script type='text/javascript' src='jquery.mousewheel.min.js'></script>
<script type='text/javascript' src='jScrollPane.js'></script>
<script type='text/javascript'>
        $(function(){
                $('.scroll-pane').jScrollPane({showArrows:true, scrollbarWidth:16, dragMaxHeight:20});
        });
</script>
</head><body margin='0' border='0' onload='ChatGetMess();'>
<script type='text/javascript'>
                        var count = 0;
                        var chat_mode = 'all';
                        function ChatGetMess(){
                                jQuery.getJSON('chat_gm.php?chat_mode='+chat_mode+'', {}, function(json){
                                        for(var k in json.messages){
                                                count++;
                                                jQuery('#mes').append('<div class=\"shoutbox-list\" id=\"list-'+count+'\">' + ShowMessage(json.messages[k]) + '</div>');

                                                $('#list-'+count).fadeIn('slow');
                                                $(function(){
                                                        $('.scroll-pane').jScrollPane({showArrows:true, scrollbarWidth:16, dragMaxHeight:20});
                                                });
                                                $('#mes').scrollTop($('#mes').get(0).scrollHeight||0);
                                        }
                                });
                                timeoutID = setTimeout(ChatGetMess, 5000);
                        }
                </script>
<div id='mes' class='scroll-pane' style='height:200px;'></div>
</body></html>


SirNaFigator 06.05.2009 01:04

Господа гуру. сори если жутко туплю, но всетаки, подскажите лошаре в чем ошибка...не работает зараза =( уж очень нада!!!

e1f 06.05.2009 03:02

Скажите-ка, а какая у вас версия jquery, а то в примере не видно. В 1.2.3. метода scrollTop нет, в 1.2.6 -- есть. Вот это работает в ИЕ/ФФ/Опера:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="jquery-1.2.6.js"></script>
</head>
<body>
<div id='mes' style='height:200px;width:500px;border:1px solid yellow;overflow:scroll'></div><button onclick="$('#mes').append('<div style=\'border:1px solid green;height:30px\'></div>')">Append</button><button onclick="$('#mes').scrollTop($('#mes').get(0).scrollHeight||0)">Scroll</button>
</body>
</html>

SirNaFigator 06.05.2009 10:04

Действительно, пример работает. Огромное спасибо за помощь.
Ошибка видимо в том, что у меня плагин, который меняет вид скролла, на мой заданный. Видимо он сам по себе управляет скроллом и не дает им управлять мне =( Буду разбирацца....
А может стоит управлять скроллом с помощью функции скроллинга из этого плагина?

e1f 06.05.2009 13:13

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

e1f 06.05.2009 14:19

Скачал плагин... Похоже, он этого не поддежривает. Если поправить на коленке -- то можно так:
замените строку 59
var currentScrollPosition = settings.maintainPosition ? $this.position().top : 0;

на
var currentScrollPosition = (settings.hasOwnProperty('scrollPosition') && -settings.ScrollPosition) || (settings.maintainPosition ? $this.position().top : 0);

используйте при реините параметр scrollPosition:
$('.scroll-pane').jScrollPane({showArrows:true, scrollbarWidth:16, dragMaxHeight:20, scrollPosition:$('#mes').get(0).scrollHeight||0});

e1f 06.05.2009 14:34

Демонстрационный файл после изменения плагина:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="jScrollPane.css" />
<script type="text/javascript" src="jquery-1.2.6.js"></script>
<script type="text/javascript" src="jScrollPane-1.2.3.js"></script>
<script type="text/javascript">
<!--
$(document).ready(function(){
    $('.scroll-pane').jScrollPane({showArrows:true, scrollbarWidth:16, dragMaxHeight:20});
});
//-->
</script>
</head>
<body>
<div id='mes' class="scroll-pane" style='height:200px;width:500px;overflow:auto'></div>
<button onclick="$('#mes').append('<div style=\'border:1px solid green;height:30px\'>test div</div>')">Append</button>
<button onclick="$('.scroll-pane').jScrollPane({showArrows:true, scrollbarWidth:16, dragMaxHeight:20, scrollPosition:$('#mes').get(0).scrollHeight||0});">Scroll</button>
</body>
</html>

Скрипт и CSS взят с http://code.google.com/p/jscrollpane/downloads/list

SirNaFigator 06.05.2009 15:23

Огромное спасибо!!!!
я тоже основательно порылся на этом ресурсе. В итоге обнаружил что всетаки плагин это поддерживает =) Но вот незадача.

Есть отдельный тестовый ХТМЛ документ, там все прекрасно работает...и именно так как мне нужно, но вот когда я код засовываю в свой скрипт то в отладчике вижу ошибку ScrollTop is not a function
причем я переносил все файлы включая последнюю версию jquery и самого плагина.

Код рабочей тестовой странички:
Код:

<HTML><HEAD><TITLE>jScrollPane</TITLE>
<META http-equiv=content-type content="text/html; charset=windows-1251">
<META content="MSHTML 6.00.2900.2180" name=GENERATOR>
<LINK media=all href="jScrollPane.css" type=text/css rel=stylesheet>
<SCRIPT src="jquery.min.js" type=text/javascript></SCRIPT>
<SCRIPT src="jquery.mousewheel.js" type=text/javascript></SCRIPT>
<SCRIPT src="jScrollPane.js" type=text/javascript></SCRIPT>

<SCRIPT type=text/javascript>
            count = 0;
                        $(function(){
                                $('#add-content').bind(
                                        'click',
                                        function(){
                                                count++;
                                                $pane = $('#mes');
                                                var autoScroll = $pane.data('jScrollPanePosition') == $pane.data('jScrollPaneMaxScroll');
                                                $pane.append('<div class="shoutbox-list" id="list-'+count+'">tyj</div>').jScrollPane({scrollbarWidth: 20, scrollbarMargin: 10, animateTo: true});
                                                $('#list-'+count).fadeIn('slow');
                                                if(autoScroll){
                                                        $pane[0].scrollTo($pane.data('jScrollPaneMaxScroll'));
                                                }
                                        }
                                );
                        });

                </SCRIPT>
</HEAD><BODY>
<DIV class=scroll-pane id=mes></DIV>
<A id=add-content href="javascript:;">here</A>
</BODY></HTML>


SirNaFigator 06.05.2009 16:15

Все, разобрался, всем огромное спасибо =)
Дело было в самой библиотеке. Пример выше стопрацентнорабочий, поьзуйтесь, если кому понадобится =)

e1f 07.05.2009 03:35

Все же поправка, чтоб народ не путать. Сам плагин даную опцию не поддерживает, эмулируется извне, к примеру как в статье http://code.google.com/p/jscrollpane...pec=svn45&r=45


Часовой пояс GMT +3, время: 09:13.