Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   разделение строки из куки на массивы (https://javascript.ru/forum/jquery/34483-razdelenie-stroki-iz-kuki-na-massivy.html)

mi.rafaylik 07.01.2013 01:19

разделение строки из куки на массивы
 
Здравствуйте )
Плагин jquery.cookie подключен.
Я получаю из куки $.cookie("basket") строку такого типа:
Название1:Количество1:Цена1:Розмер1:Цвет1;Название2:Количество2:Цена2:Размер2:Цвет2;Название3:Количество3:Цена3:Размер3:Цвет3; и т.д.

Хочу разбить сначала по символу ";" на массив:
Название:Количество:Цена:Размер:Цвет
Название:Количество:Цена:Размер:Цвет

а потом полученный массив разбить по символу ":" на новые массивы:
Название1
Количество1
Цена1
Размер1
Цвет1

Название2
Количество2
Цена2
Размер2
Цвет2

и т.д.

После чего каждый элемент определённого типа (например каждое название) я буду оборачивать в определённый тэг, например:
<div>
<p class="item-name">Название1</p>
<p class="item-copy">Количество1</p>
<p class="item-price">Цена1</p>
<p class="item-size">Размер1</p>
<p class="item-color">Цвет1</p>
</div>

<div>
<p class="item-name">Название2</p>
<p class="item-copy">Количество2</p>
<p class="item-price">Цена2</p>
<p class="item-size">Размер2</p>
<p class="item-color">Цвет2</p>
</div>

Вот что я делаю:
basket = decodeURI($.cookie("basket")); // получаю строку из куки
basketArray = basket.split(";"); // разбиваю полученную строку на массив
for (var i=0; i<basketArray.length-1;i++) {
  goodsId = basketArray[i].split(":"); // разбиваю каждый пункт полученного массива на новый массив
};

$('textarea').val( goodsId ); // смотрю результат

В результате я вижу только первый элемент массива (или первый элемент подмассива) вместо списка :(
В PHP я наверное использовал конкатенацию, но в jQuery не знаю как. Буду рад любым советам )

Deff 07.01.2013 01:42

mi.rafaylik,
Есть LocalStorage - куда можно просто запихнуть сформированны код HTML и куки не потребуются - кроссбраузерное решение для LocalStorage тут => http://javascript.ru/forum/project/2...a-ie6-7-a.html

Зы - куки в ИЕ 6-8 ограничены четырьмя килобайтами (Дальнейшие версии не тестил,
Русские символы в куках поддерживают не все браузеры (В частности FF
Перевод русского в ескейп последовательность увеличивает длину строки примерно в 4 раза

Deff 07.01.2013 01:59

Цитата:

Сообщение от mi.rafaylik
Хочу разбить сначала по символу ";" на массив:
Название:Количество:Цена:Р змер:ЦветНазвание:Количес во:Цена:Размер:Цвет

var a='Название1:Количество1:Цена1:Розмер1:Цвет1;Название2:Количество2:Цена2:Размер2:Цвет2;Название3:Количество3:Цена3:Размер3:Цвет3;'
var Zarr = a.replace(/;\s*$/,'').split(";");
alert(Zarr.join('\n'));
function Buid (Z) {
  var str ='',zJ;
  var arItem =['name','copy','price','size','color']        
    for (var i=0; i<Z.length; i++){
      str+='<div>\n';
         zJ = Z[i].split(":");
           for (var j=0; j<zJ.length; j++){
               str+='<p class="item-'+i+'-'+arItem[j]+'">'+zJ[j]+'</p>\n';
           }str+='</div>\n\n'
     } return str;
}
var OutStr = Buid (Zarr);
alert(OutStr)

В приципе достаточно такого входного массива
Название:Количество:Цена:Размер:Цвет

Цифру в конце запросто пишем в цикле

var a='Название:Количество:Цена:Размер:Цвет';
var Zarr = a.split(":");

function Buid (zJ,N) {
  var  str ='';
  var arItem =['name','copy','price','size','color']        
    for (var i=1; i<=N; i++){
       str+='<div>\n';
           for (var j=0; j<zJ.length; j++){
               str+='<p class="item-'+i+'-'+arItem[j]+'">'+zJ[j]+i+'</p>\n';
           }str+='</div>\n\n'
     } return str;
}
var OutStr = Buid (Zarr,3);
alert(OutStr)

Telnet 07.01.2013 02:24

По мойму Вы просто
goodsId = basketArray[i].split(":");
при каждой итерации перезаписываете переменную goodsId поэтому и видите только первое значение
мне кажется Вам нужно переменную goodsId сделать массивом, а потом пройтись по ней в цикле методом wrap для оборачивание в тег p

mi.rafaylik 07.01.2013 02:29

спасибо Deff!
вот что у меня получилось:
var cartA = $.cookie("cart");
var cartB = cartA.split(";");
var cartC = cartB.join('\r\n\r\n');
var cartD = cartC.split(":");
var cartE = cartD.join('\r\n');

$('#result').html( cartE );

получил визуально-правильный результат:
T-Shirt
2 шт
170
размер XS
цвет белый

Shoes
3 шт
520
размер 38
цвет черный

Bag
2 шт
375
размер 42
цвет черный

Jeans
1 шт
430
размер XS
цвет черный

но не понял, как обернуть элементы, например с помощью wrap(), так как они остались в массиве.
т.к. каждую группу я хочу обернуть в <div class='item'></div>
а каждый элемент группы в соответственный ему тэг. это нужно для того, чтоб после редактирования заново собрать массивы в строку, вот такая элиада...

Deff 07.01.2013 02:37

Цитата:

Сообщение от mi.rafaylik
т.к. каждую группу я хочу обернуть в

Там все обернуто - жмите кнопки
Поправил

mi.rafaylik 07.01.2013 02:59

по этому коду (второй не подходит, так как переменные будут разные, т.к. вводяться пользователем):
var a = $.cookie("basket");
var Zarr = a.replace(/;\s*$/,'').split(";");
function Buid (Z) {
  var str ='<div>\n',zJ;
  var arItem =['name','copy','price','size','color']       
    for (var i=0; i<Z.length; i++){
         zJ = Z[i].split(":");

           for (var j=0; j<zJ.length; j++){
               str+='<p class="item-'+zJ[j]+'</p>\n';
           }str+='</div>\n\n'
     } return str;
}
var OutStr = Buid (Zarr);


такой результат:
<div>
<p class="item-T-Shirt</p>
<p class="item-2</p>
<p class="item-170</p>
<p class="item-размер XS, </p>
<p class="item-цвет белый, </p>
</div>

<p class="item-Shoes</p>
<p class="item-2</p>
<p class="item-520</p>
<p class="item-размер 38, </p>
<p class="item-цвет черный, </p>
</div>

<p class="item-Bag</p>
<p class="item-2</p>
<p class="item-375</p>
<p class="item-</p>
<p class="item-цвет черный, </p>
</div>

<p class="item-Jeans</p>
<p class="item-2</p>
<p class="item-430</p>
<p class="item-размер XS, </p>
<p class="item-цвет черный, </p>
</div>

почему-то полностью обернут только первый div, а p не получили своих class, а тэг незакрытый я исправлю, не проблема

mi.rafaylik 07.01.2013 03:06

вы просто золото )
я так понимаю - случайные цифры в конце каждого значения, это похоже на id которые нужно присвоить div?
вот исправленный код:
var a = $.cookie("basket");
var Zarr = a.replace(/;\s*$/,'').split(";");
function Buid (Z) {
  var str ='',zJ;
  var arItem =['name','copy','price','size','color']       
    for (var i=0; i<Z.length; i++){
      str+='<div>\n';
         zJ = Z[i].split(":");

           for (var j=0; j<zJ.length; j++){
               str+='<p class="item-'+arItem[j]+'">'+zJ[j]+'</p>\n';
           }str+='</div>\n\n'
     } return str;
}
var OutStr = Buid (Zarr);

и результат:
<div>
<p class="item-name">T-Shirt</p>
<p class="item-copy">2</p>
<p class="item-price">170</p>
<p class="item-size">размер XS, </p>
<p class="item-color">цвет белый, </p>
</div>

<div>
<p class="item-name">Shoes</p>
<p class="item-copy">2</p>
<p class="item-price">520</p>
<p class="item-size">размер 38, </p>
<p class="item-color">цвет черный, </p>
</div>

<div>
<p class="item-name">Bag</p>
<p class="item-copy">2</p>
<p class="item-price">375</p>
<p class="item-size"></p>
<p class="item-color">цвет черный, </p>
</div>

<div>
<p class="item-name">Jeans</p>
<p class="item-copy">2</p>
<p class="item-price">430</p>
<p class="item-size">размер XS, </p>
<p class="item-color">цвет черный, </p>
</div>

Deff 07.01.2013 03:10

mi.rafaylik,
Нун такой вид массива
name:Название; copy:Количество; price:Цена; size:Размер; color:Цвет
Посколь англицкое приходится на соответствующий тег - и если число позиций возрастет , к примеру: скидка = скрипт придётся каждый раз поправлять

mi.rafaylik 07.01.2013 03:18

Deff,
нее, число позиций останется, всё отлично.
огромное спасибо, ибо потратил больше суток на поиски нужной документации )

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

Deff 07.01.2013 03:24

Не хватает кавычки
11 str+='<p class="item-'+i+'-'+arItem[j]+'">'+zJ[j]+'</p>\n

Deff 07.01.2013 03:25

Цитата:

Сообщение от mi.rafaylik
Весело мне будет, когда после внесения изменений я буду обратно в строку куки эти данные собирать .

Нет смысла собирать в куки - собирайте в длинную строку и Отправляйте Аяксом(*если не будет перехода на страницу - а если будет - чисто в скрытую форму

mi.rafaylik 07.01.2013 07:02

не в том суть повторного сбора в строку.
Данные отправляются не скрытым полем, а обычным через $_POST.
Мне нужно повторно собрать данные в строку для случая, если пользователь решит не отправлять форму, а вернётся в магазин и продолжит добавлять товары. Тогда произойдёт переход на другую страницу, и изменённые данные (например удаление какого-нибудь из товаров) не сохранятся.
Поэтому по событию нажатия любой кнопки удаления товара я собираю массивы в строку в то же состояние, из которого я их и доставал. такая вот камасутра )
Но сначала нужно поспать ))

Слегка изменил функцию разбора строки в массивы (в основном я поменял местами элементы массива, добавил комментарии между элементами и вывод новой суммы если к примеру количество больше одного):
var a = $.cookie("basket");
var b = a.replace(/;\s*$/,'').split(";");
function allItemsListConstruct (Z) {
	var str ='',zJ;
		for (var i=0; i<Z.length; i++){
			str+='<div>\r\n';
			zJ = Z[i].split(":");
			var itemPriceFinal = zJ[2] * zJ[1];
			str+=
			'<p class="item-name">'+zJ[0]+'</p> ('+
			'<p class="item-size">'+zJ[3]+'</p> '+
			'<p class="item-color">'+zJ[4]+'</p> '+
			'<p class="item-price">'+zJ[2]+'</p> грн.) - '+
			'<p class="item-copy">'+zJ[1]+'</p> шт. (' +
			'<p class="item-price-final">'+itemPriceFinal+'</p> грн.)'
			;
			str+='\r\n</div>\r\n'
		} return str;
}
var allItemsList = allItemsListConstruct (b);

Deff 07.01.2013 13:51

Цитата:

Сообщение от mi.rafaylik
(например удаление какого-нибудь из товаров) не сохранятся.

Это однозначно LocalStorage

function setValue(key,Value) {
    localStorage.setItem(key,Value)
alert('Записалось ... \n' + key+':'+Value)
}
//Записываем Данные
var   key='price', Value='Цена2';
setValue(key,Value)
var   key='size', Value='600'
setValue(key,Value)


function getValue(key) {
    return localStorage.getItem(key);;
}
//Читаем Данные
var   key='price';
alert(key+"="+getValue(key));
var   key='size';
alert(key+"="+getValue(key));

Можно перезагрузить страницу и запустить второй скрипт

mi.rafaylik 07.01.2013 15:59

Всё же я хочу сначала попробовать способ сбора массива в строку, т.к. данных будет немного (максимум 10 товаров, в записанном куки это не превысит и килобайта я думаю).
P.S. это не товары в магазине, а уже выбранные покупателем товары в корзине, поэтому длина строки будет небольшая.

Вот то, из чего я буду собирать в строку:
<div class="item">
<p class="item-array item-name">T-Shirt</p>
<p class="item-array item-size">размер S</p>
<p class="item-array item-color">цвет белый</p>
<p class="item-array item-price">170</p> грн.
<p class="item-array item-copy">4</p> шт.
</div>

<div class="item">
<p class="item-array item-name">Jeans</p>
<p class="item-array item-size">размер XS</p>
<p class="item-array item-color">цвет синий</p>
<p class="item-array item-price">420</p> грн.
<p class="item-array item-copy">2</p> шт.
</div>

и начало моих размышлений:
basketNew = new Array ($('.item-array').text()); // создание массива из элементов класса
// $.cookie("basket", basketNew); // запись в куки

Но массив не получился, т.к. данные просто склеились. Выглядит это вот так:
T-Shirtразмер Sцвет белый1704Jeansразмер XSцвет синий4202

а должно так, где элементы каждого товара разделены двоеточием, а товары разделены точкой с запятой:
T-Shirt:размер S:цвет белый:170:4;Jeans:размер XS:цвет синий:420:2;

То есть нужно создать массив из всех <div class="item"></div> с разделителем ";",
в каждом из которых будет массив из дочерних <p class="item-array item-price"></p> с разделителем ":".

Deff 07.01.2013 17:06

Цитата:

Сообщение от mi.rafaylik
то есть в localStorage записывается не один массив со всеми товарами, а значение каждого указанного мной элемента (если он изменён) ?

Ну вы ведь кликаете по каждому товару ?

А для сбора всего массива и отсылки суммарного на сервер или перепарса на странице - есть методы доступа к localStorage
Либо пишите/читает строку в один ключ
По ключам (по опыту удобнее)
В Один ключ - это подобие куков, но каждый раз при добавке - смене товара придется распаковывать данные, (в куках таже проблема, с заменой - добавкой товара,
Сбор по ключам и объединение для отсылки или распарса на странице
(- ксать для распарса на очередной странице - даже не надо объединять,
Главное чтобы нулевой ключ(заранее известный) - имел массив всех ключей, нужных для перебора

jokersoft 07.01.2013 17:48

ТЗ нечеткое.
Я так понял, в итоге нужна строка, а не массив. Хотя я советовал бы думать о будущем и о юзабилити. И оперировать таки с массивом, а не со строкой. Но ладно, пусть будет строка.
Итак, пишем сразу строку

var str = ''; //инициализируем пустую строку

$('div.item').each(function(){
$(this).children('p').each(function(){
str += $(this).html() + ":";//пишем хар-ку товара + ":"
});
str += ";"//отделяем товар + ";"
});

ЗЫ: да, знаю, в конце будем получать не ";", а ":;", но если дальше правильно парсить - не имеет значения и не стоит лишней строки кода здесь.

Deff 07.01.2013 17:54

jokersoft,
:) Cобствна вопрос - (не юзал jQuery.cocie)
Во всех ли браузерах воспринимает произвольные символы в данных для куков (В обычных куках, к примеру - русские(в FF) не воспринимаются, перевод в ескейп последовательность - может превысить длину кука в ИЕ(она возрастет примерно раза в 4

mi.rafaylik 07.01.2013 18:18

Адаптировал код jokersoft:
var strCookie = ''; //инициализируем пустую строку

$('div.item').each(function(){
	$(this).children('p:eq(0)').each(function(){ strCookie += $(this).html() + ":"; }); // количество характеристик всегда будет 5
	$(this).children('p:eq(1)').each(function(){ strCookie += $(this).html() + ":"; });
	$(this).children('p:eq(2)').each(function(){ strCookie += $(this).html() + ":"; });
	$(this).children('p:eq(3)').each(function(){ strCookie += $(this).html() + ":"; });
	$(this).children('p:eq(4)').each(function(){ strCookie += $(this).html(); }); // таким образом я убрал последний ":" в каждом товаре
	strCookie += ";" //отделяем товар + ";"
});

Результат получился такой:
T-Shirt:размер S:цвет белый:170:4;;;Jeans:размер XS:цвет синий:420:2;;;Shoes:размер 41:цвет хаки:560:1;;;

Это работает, но лишние разделители при следующих запросах строки из куки будут создавать пустые товары..
Сейчас после каждого товара разделитель не один ";" а их столько, сколько и товаров всего :/
Подскажите как правильно парсить, чтобы привести строку в такой вид:
T-Shirt:размер S:цвет белый:170:4;Jeans:размер XS:цвет синий:420:2;Shoes:размер 41:цвет хаки:560:1;

P.S. в следующих сообщениях уже исправил )

Deff 07.01.2013 18:24

mi.rafaylik,
1. Составьте список используемых браузеров( с версиями для ИЕ
2. Приведите полный вид максимально длинной строки заказов отправляемой на сервер
3. Если использовать не куки - то способ отправки через форму - подойдёт ?

mi.rafaylik 07.01.2013 18:42

1. Deff, jquery.cookie и в FF кириллицу нормально выводят, насчёт эскейп-последовательности не знаю.
2. Максимально длинная строка, например:
T-Shirt:размер S:цвет белый:170:4;Jeans:размер XS:цвет синий:420:2;Shoes:размер 41:цвет хаки:560:1;T-Shirt:размер M:цвет серый:150:1;Jeans:размер S:цвет чёрный:380:1;Shoes:размер 42:цвет черный:490:2;

3. без куки хм.. я бы использовал localStorage, как Вы и предложили, очень понравился вариант, но в данном случае кук вполне достаточно

Deff 07.01.2013 18:48

Цитата:

Сообщение от mi.rafaylik
1. Deff, jquery.cookie и в FF кириллицу нормально выводят,

:) Во всех бразерах ?
Цитата:

Сообщение от mi.rafaylik
3. без куки хм.. я бы использовал localStorage, как Вы и предложили, очень понравился вариант, но в данном случае кук вполне достаточно

Да использовать localStorage как куки - нет проблем - пишите с одним и тем жа ключом - полный аналог куков - но нун Нужно знать какие браузеры - иначе в старых ИЕ его еще не было( хотя есть плагин, полностью имитирующий)
суть в отправке в итоге на сервер
По второму - вопросу - судя по строке, - ИЕ 6-8 - выпадает из списка - куков -такой длины Оно не обслужит

mi.rafaylik 07.01.2013 18:48

изменив код, задачу решил вот так:
var strCookie = ''; // инициализируем пустую строку

$('div.item').each(function(){
    $(this).children('p:eq(0)').each(function(){ strCookie += $(this).html() + ":"; }); // количество характеристик всегда будет 5
    $(this).children('p:eq(1)').each(function(){ strCookie += $(this).html() + ":"; });
    $(this).children('p:eq(2)').each(function(){ strCookie += $(this).html() + ":"; });
    $(this).children('p:eq(3)').each(function(){ strCookie += $(this).html() + ":"; });
    $(this).children('p:eq(4)').each(function(){ strCookie += $(this).html() + ";"; }); // отделяем товар
});

и правильный результат:
T-Shirt:размер S:цвет белый:170:4;Jeans:размер XS:цвет синий:420:2;Shoes:размер 41:цвет хаки:560:1;

всё :)
ребята, спасибо, эта тема была интересной, я получил удовольствие и опыт )

mi.rafaylik 07.01.2013 18:51

Deff, у меня FF постоянно обновляется, т.е. я использую актуальную версию. Он правильно достаёт кириллицу с помощью jquery.cookie, насчёт более ранних версий FF не знаю

Deff 07.01.2013 18:54

Цитата:

Сообщение от mi.rafaylik
Deff, у меня FF постоянно обновляется, т.е. я использую актуальную версию

Думаю тут не в длине дело , а , jquery, оно кодирует/декодирует кирилицу - проверьте запись куков максимальной длины в ИЕ

mi.rafaylik 07.01.2013 19:04

Deff, спасибо, попробую как только на Windows попаду (я работаю на Mac OS, там нет IE, но я всегда проверяю свои коды где-нибудь в другом месте), и отпишусь о результате

jokersoft 07.01.2013 19:16

Цитата:

Сообщение от mi.rafaylik (Сообщение 225821)
$(this).children('p:eq(0)').each(function(){ strCookie += $(this).html() + ":"; }); // количество характеристик всегда будет 5

each здесь в таком случает не нужен.
Делай тогда просто так:
strCookie += $(this).children('p:eq(0)').html() + ":";

Deff 07.01.2013 19:29

Цитата:

Сообщение от mi.rafaylik
попробую как только на Windows попад

Пробу(просто записать куки и считывать их на страницу) желательно провести на реальном сайте, посколь там имеются и еще кроме ваших
чо нить типо такого (Должен быть подключен jQuery и плагин куков
<div id="Mycookie"></div>

<script type="text/javascript">
$(document).ready(function() {  
var a='T-Shirt:размер S:цвет белый:170:4;Jeans:размер XS:цвет синий:420:2;Shoes:размер 41:цвет хаки:560:1;T-Shirt:размер M:цвет серый:150:1;Jeans:размер S:цвет чёрный:380:1;Shoes:размер 42:цвет черный:490:2;';
$("#Mycookie").html($.cookie("My",a));
});
</script>

MVS 24.01.2013 01:30

Добрый..вечер!
Подскажите, как можно сохранять 10 куки в файл, я имею ввиду что если сохраняется 11-тый, то самый старый, то есть первый удаляется а на его место становится второй (вроде карусели), задача связана точно с таким случаем, но запоминать нужно всего 10 кук и крутить по кругу.
Спасибо!

дополняю примером, а то сам не понял из прочитаного чего хочу
примерно такой код для получения куки библиотекой "jquery cookie"
function runCookie() {
var a = $.cookie("cart");
var b = a.replace(/[,]/g, '').split(":");
function allItemsListConstruct (Z) {
	var str ='',zJ;
		for (var i=0; i<Z.length; i++){
			str+='<div>\n';
			zJ = Z[i].split("|");
			str+=
			'<p>'+zJ[0]+'</p>'
			;
			str+='\n</div>'
		} return str;
}
document.getElementById('st').innerHTML = allItemsListConstruct (b);
}

Задача сводиться к тому, что нужно записать куки в таком виде: 001, 002, 003, ..., 010
примерно вот так, id подставляется автоматически
<a href="javascript:cookie('+id+');">сохранить</a>
$.cookie("cart", "id");
количество записанных кук 10 шт., то есть при записи 11-той первая кука удаляется и на ее место становиться вторая и получается первой.
У меня не получается записать куки в строку и тем более недопонимаю как сделать удаление кук если их более 10 и пишем 11-тую.
Помогите реализовать такую вещь - это будет модуль последних просмотренный товаров.
Спасибо!

MVS 30.01.2013 22:25

помогите удалить
 
сделал так, код г-но, зато рабочий
function setCokii(cookie_value) { //здесь ставить куки setCokii(id);
var x,y;
x = $.cookie("history");
if(x == null) {  // если это первая
$.cookie('history', cookie_value, { expires: 7 });  
} else {
y = x.split(","); // если уже есть
// это проверка на существование куки, если уже есть - то не пишем, одинаковые не нужны
if(y[0] != cookie_value && y[1] != cookie_value && y[2] != cookie_value && y[3] != cookie_value && y[4] != cookie_value && y[5] != cookie_value && y[6] != cookie_value && y[7] != cookie_value && y[8] != cookie_value && y[9] != cookie_value) {
$.cookie('history', cookie_value+','+y, { expires: 7 });
 // если устанавливается 10 кука, то перезаписываем - нужно только 10 последних
if(y[9]) { rewriteCokii(); }  }
}
}
// функция получения и перезаписи куки
function rewriteCokii() {
var u = $.cookie("history");
var c = u.split(",");
var f = [c[0],c[1],c[2],c[3],c[4],c[5],c[6],c[7],c[8],c[9]]; // это вроде как извращение над js но по другому не смог
$.cookie('history', f, { expires: 7 });
}
// удаление всех кук "history"
function delCokii() {
$.cookie('history', null);
}

Прошу помощи не так в модернизации кода, как в том, что не могу понять как можно удалить например 4 куку, если кто может покажите примером, но и по возможности расскажите как можно привести код к нормальному виду
Спасибо!

Deff 31.01.2013 08:20

Цитата:

Сообщение от MVS
удалить например 4 куку

Пробуйте вписать отрицательное время установки для кука с данным именем

Вообще есть код попроще http://javascript.ru/forum/misc/3491...tml#post229165


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