Jquery sortable list won't serialize, why? - php

I'm implementing a sortable list of images with jquery in a Zend Framework application.
I just can't get the .sortable('serialize') method to return more than an empty string.
When I try with a few simple examples outside my application it works.
Does it matter that the snippet below is wrapped in various other and other tags. I think it shouldn't. The unordered list should be found just by the id, right?
HTML:
<ul id="mylist">
<li id="1">
<div>
<img src="image_1.jpg" />
<p class="value_item">some text</p>
</div>
</li>
<li id="2">
<div>
<img src="image_2.jpg" />
<p class="value_item">some text</p>
</div>
</li>
</ul>
JavaScript:
$(document).ready(function() {
$('#mylist').sortable({
update: function() {
var order = $('#mylist').sortable('serialize');
alert(order);
}
});
});

http://api.jqueryui.com/sortable/#method-serialize
If serialize returns an empty string, make sure the id attributes include an underscore. They must be in the form: "set_number" For example, a 3 element list with id attributes foo_1, foo_5, foo_2 will serialize to foo[]=1&foo[]=5&foo[]=2. You can use an underscore, equal sign or hyphen to separate the set and number. For example foo=1 or foo-1 or foo_1 all serialize to foo[]=1.

Jquery runs into problems when you use non-compliant ids.
Ids are not allowed to begin with a number. They can have numbers in them, just not as the first character.

(link update)
hi, I stumbled across a similiar problem a few days ago, though in my case it was important to keep the order of the elements intact. I coded a small plugin which will allow you to serialize ul and ol lists of arbitrary depth and complexity:
serializeTree

Related

How to style the output of an echo to display a grid?

My team and I have made a database in php my admin for a restaurant, and I'm currently working on the customer dashboard. Im using for each loops to display complete orders in one of the dashboard tabs, and have the code working, but right now it just outputs regular black text. I was wondering how to style it to output the rows as a grid, similar to bootstrap grids.
I've tried to just add containers with rows and columns to the foreach echo itself, but its just not working as I thought it would.
<div id="CurrentOrders" class="tabcontent" style="margin-left: 24px">
<!-- This information will be pulled from the Orders table in the DB -->
<h3>Current Orders</h3>
<p>
<div class="container">
<?php
foreach ($orderno as $order) {
$n = $order['OrderNo'];
$menunamequery = "SELECT * FROM OrderItem WHERE OrderNo = '{$n}'";
$currentorders = getRows($menunamequery);
foreach ($currentorders as $currentorder) {
echo "Order Number -"." ".$currentorder['OrderNo']." , "."Order -"." ".$currentorder['MenuName']." , "."Quantity -"." ".$currentorder['Quantity']."<br>";
}
}
?> </div>
</p>
</div>
The expected result is for these rows im outputting to have some sort of grid layout, the actual result is just plaintext currently.
Sorry if this is a bad question, my team and I just learned php this semester and are hoping to continue getting better at it. Any help would be appreciated.
You can simply output HTML from PHP:
echo '<span style="color: red">'.$currentorder['MenuName'].'</span>';
However, it is advised that you sanitize your output, so nobody can "create HTML" by putting tags in the database;
echo '<span style="color: red">'.htmlspecialchars($currentorder['MenuName']).'</span>';
This does exactly what it says; makes HTML entities from special characters. For example, > will be printed as >, which the browser will safely render as >, instead of trying to interpret it as an HTML element closing bracket.
Alternatively, you can simply write HTML directly if you wish, by closing and opening the PHP tags:
// PHP Code
?>
<span class="some-class"><?=htmlspecialchars($currentorder['MenuName'])?></span>
<?php
// More PHP Code
You may also want to look into templating engines to make it easier for you, although it depends on the project if it's worth it for you to look into that, since there is a little bit of a learning curve to it.

Get all consecutive DIVs with specific class

There is HTML like
<h3>Specifications</h3>
<div class="row"> some text </div>
<div class="row"> some text 2 </div>
<div class="row"> some text 3 </div>
<div class="detail-anchor" id="pricing"></div>
<div class="row"> some text 4</div>
I am using PHP + phpQuery to scrape a site
I want to get only first 3 divs, in other words, I want to get all consecutive div.row.
This is code I am using
foreach (pq('h3:contains("Specifications")', $profile_page)->nextAll('div.row') as $div) {
}
But what it does, it also scrapes the some text 4 div as well.
I have tried nextAll('div.row') as well but it gives me same result.
So my question is, how do I get all consecutive div.row after <h3>Specifications</h3>, if any other tag comes in between then just STOP.
PS:
Answers in pure jQuery will also be accepted, since phpQuery library uses same function as jQuyery does.
You can use the :first selector to get the first .row element, then nextUntil() to capture the rest. Try this:
var $rows = $('.row:first').nextUntil(':not(.row)');
If you want to also include the first row in the matched set you can use addBack(), like this:
var $rows = $('.row:first').nextUntil(':not(.row)').addBack();
Working example
jQuery:
$("h3").nextUntil("#pricing");
Captures all the elements after h3 until it reaches that with the id of pricing
Consecutive divs, eh? It sounds like you want something like:
div.row:has(+ div.row),div.row + div.row
I don't know if PHPQuery supports that, if not you should consider switching.
Another idea is to do h3 + .row and then just keep iterating + .row

Wrap data in container after each 3 iterations using PHP

First of all I know this question(or similer) has been already asked for several times, but I didn't get 100% perfact answer anywhere.
I want to wrap each 3 array elements in a container div. like:
Array $arr = [0,1,2,3,4,5,6]; should be represented like below:
<div class="container">
<p>0</p><p>1</p><p>2</p>
</div>
<div class="container">
<p>3</p><p>4</p><p>5</p>
</div>
<div class="container">
<p>6</p>
</div>
Note: $arr can have any no of elements (not fixed).
I have found lot of post which gives above result, but they have issues with HTML. They are not generating 100% correct HTML(Keep left uncompleted HTML tags for last container tag). I want to achieve same result with valid HTML i.e all tags should be completed properly.
Note: I want to achieve it using simple loops and variables(wihtout using any built in array functions etc.).
This answers is pretty close, but has uncompete HTML tags.
Wrapping a div around every third item in a foreach loop PHP
Any help would be appreciated.
Thanks
you need for loop and steps 3 for example:
<?php for($i=0; $i<count($arr);$i+3): ?>
<div class="container">
<p>$arr[0+$i]</p><p>$arr[1+$i]</p><p>$arr[2+$i]</p>
</div>
<?php endfor; ?>
and don't forgot check array item by function isset($arr['key'])

PHP Simple HTML DOM parser give faulty data

I'm using PHP Simple HTML DOM to parse a web page with the following HTML. Notice the extra </span>-tags in each <li>.
<li>
<span class="name">
Link asdasd
</span>
</span>
</li>
<li>
<span class="name">
Link asdasd2
</span>
</span>
</li>
My queries are:
$lis = $dom->find('li');
foreach ($lis as $li) {
$spans = $li->find('span');
foreach ($spans as $span) {
echo $span->plaintext."<br>";
}
}
My output is:
Link asdasd
Link asdasd2
-----------
Link asdasd2
-----------
As you can see the find('span') finds two spans as children to the first <li> and getting the value from the next <span> it can find (even though it's a child of the next <li>). Removing the trailing </span> fixes the problem.
My questions are:
Why is this happening?
How I can solve this particular case?
Everything else works well and I'm not in a position to make big changes to my script. I can change the DOM queries easily though if needed.
I am thinking about counting start and closing tags and stripping one </span> if there are too many of them. Since they will always be <span>s, are there a smart way to check it with regexp?
1) Simple is trying to fix your extra </span> by adding a <span> somewhere. So now you have an extra span that shouldn't be there. For the record, DomDocument would do the same thing, although perhaps in a more predictable way.
2) Simplify:
foreach ($dom->find('li > span') as $span) {
echo $span->plaintext."<br>";
}
// Link asdasd <br> Link asdasd2 <br>
Now you've told it you only want the span that is a child of a li. Even better, do something like:
foreach ($dom->find('span.name') as $span) {
echo $span->plaintext."<br>";
}
Use those attributes, that's what they're good for.
$newTxt = preg_replace('/\<\/span\>[\S]*\<\/span\>/','</span>',$txt);
The method 'find(x)' is an overloaded function that can return the equivalents of:
$e->getElementById(x);
$e->getElementsById(x);
$e->getElementByTagName(x); and
$e->getElementsByTagName(x);
In your first call makes it use of the last call. In the second $li of the third possibility. It is probably a method of optimization which question you were asking according to the API. I guess you have found a bug in the API, because you were asking in both cases the use of the third call:
$e->getElementByTagName();

Persist nested jquery sortable list in html?

The Problem:
I have a nested list on my configuration page that looks like this:
<a id='Save'>Save<a>
<ul id='configuration-list'>
<li id='e1'>Elem A
<ul>
<li id='ey'>Elem Y </li>
<li id='ex'>Elem X
<ul><!-- and so on until 5 levels of nesting --></ul>
</li>
<li id='ez'>Elem Z </li>
</ul>
</li>
<li id='e45'>
<ul>
<!-- more li's and ul's nesting here -->
</ul>
</li>
<!-- even more li's and ul's nesting here -->
<li id='eN'>
</li>
</ul>
Each li on the list can have another unordered list inside, which contains li, that can contain other unordered list inside.
All the list are sortable, using jquery ui.sortable plugin. Items cannot be switched through list.
The total of nodes in the list is more than 1k.
When the configuration is saved (Save link) I have to send the list order configuration (form the first to the deepest node) to the server which will parse it and save all the elements order in the database. For this, php is used.
The questions:
Whats the 'best' or the less wrong way to parse the configuration, and how should I pass it to my php parser?
Is there a method similar to $('#configuration-list').sortable('serialize') or $('#configuration-list').sortable('toArray') that generates me a xml, JSON or similar with all the structure? An extension of ui.sortable or another plugin that have this functionality?
Thanks in advance.
It's not clear if <li> contains radio/checks/textboxes, so the suggestion may vary. A lot of time ago (5-6 years i think) I've encountered similar situation, and that time i've used names recalling array structures (if i remember correctly, too old memories :/)
I.e.
<input type="text" name="nodes[node1][item1]" />
<input type="text" name="nodes[node1][item2]" />
Maybe it can help you.
.sortable('serialize') takes an optional second parameter (or, serialize() takes a single parameter. God I hate the plugin apis):
make sure the id attributes include an
underscore. They must be in the form:
"set_number" For example, a 3 element
list with id attributes foo_1, foo_5,
foo_2 will serialize to
foo[]=1&foo[]=5&foo[]=2. You can use
an underscore, equal sign or hyphen to
separate the set and number. For
example foo=1 or foo-1 or foo_1 all
serialize to foo[]=1.
When you are saving large nested sets you should consider the Nested Set Model, it's a different approach for storing hierarchical data in a flat table, which MySQL or any other non-XML database is. NSM works with two numbers, left and right for defining the range of a set and all childs in it.
A link which was very usefull to me:
http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
In your PHP controller (or whereever you handle / control your data before saving it) you can simply loop through your configurations. I prefer to use array values for forminputs in this case, just like the other posters said.
You should use form element for this, i prefer hidden fields, give the name of the field something like node_# where # represents the parent-id for the child. And the value must then be the ID of the current child.
Use a simple for-loop to loopthrough 'node_#' and get the arrayvalues from the element-value 1 by 1. Increasing the sortorder for each node with the same parent by 1 when a node passes by.
Sample:
<input type="hidden" name="node_1[]" value="4"/>
<input type="hidden" name="node_1[]" value="5"/>
<input type="hidden" name="node_1[]" value="6"/>
<input type="hidden" name="node_1[]" value="7"/>
Then nodes 4 t/m 7 will be stored as an array in $_POST["node_1"].

Categories