Get all consecutive DIVs with specific class - php

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

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.

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'])

Inserting content within HEREDOC using Functions

Been trying to go bout how to accomplish dividing content on view output.
I'm loading records from Mysql, inserting values into HEREDOC to then output to view.
I want to display only a certain amount of characters in a particular row within the HEREDOC, hide the rest from view on DOM.
I tried using a function like this within the HEREDOC to insert a "More" link after certain amount of characters.
I've tried a couple methods:
1
<<<EOT
<div id="$id_op">
{substr_replace($contents, "More", 400)}
</div>
EOT;
2
<<<EOT
<div id="$id_op">
{${substr_replace($contents, "More", 400)}}
</div>
EOT;
There might be other better methods to accomplish this. For now I want to load the record completely into dom but hide part of it until user have clicked a jQuery selector.
Any help / direction will be truly appreciated.
Functions does not execute in HEREDOC. This will work
$div = substr_replace($contents, "More", 400);
$data = <<<EOT
<div id="$id_op">
$div
</div>
EOT;
Compute any variable content before starting the HEREDOC, then insert the variables into the string as you go.

Determing div layout dimensions php

I have three div's which are being filled with dynamic text from a database. The div #container is a fixed height and width where the text inside wraps. The three divs are different font sizes. Any of the three div's could have enough text to exceed the container size. I need to determine if the text exceeds the container size and at which letter in which div it occurs. The extraneous text will then be wrapped in something like <span class=hide">text here</span>
<div id="container">
<div id="first"><?php echo $arr['first'] ?></div>
<div id="mid"><?php echo $arr['mid'] ?></div>
<div id="last"><?php echo $arr['last'] ?></div>
</div>
I'm thinking this is impossible to do in PHP as the styling is done client side. Maybe there is a way to fake it? Though that could get ugly really fast.
I'm trying really hard not to do it in javascript because this calculation will be done about 10 times per page viewed. Please don't tell me it's impossible to do in PHP, there's always a way.
Any ideas?
Just in case you decide that client-side makes more sense for you I put together a fiddle. I realize you want to avoid client-side, but you mentioned this would be happening ten times which honestly is very little these days with how much js speed has increased in browsers. It is also a much simpler problem client side.
http://jsfiddle.net/JSRtk/
Basically you detect if the container is overflown. If so you display a 'read more' button. When clicked it will expand the container to show all text and go away.
$('#container > div').each( function() {
if (checkOverflow(this)) {
console.log('overflow detected in ' + $(this).attr('id'));
$(this).after('<p>Read more...</p>');
}
});
$('p').live('click', function() {
$(this).prev('div').css('height', 'auto');
$(this).hide();
});
function checkOverflow(el)
{
var curOverflow = el.style.overflow;
if ( !curOverflow || curOverflow === "visible" )
el.style.overflow = "hidden";
var isOverflowing = el.clientWidth < el.scrollWidth
|| el.clientHeight < el.scrollHeight;
el.style.overflow = curOverflow;
return isOverflowing;
}
Do you have to wrap it in a span for a purpose (i.e. crawlers/seo)? If not you could either set the CSS on the div with a fixed width to have overflow hidden, alternatively, you could figure out how many characters roughly fit in that width (count them) then use strlen() and substr() like so
<?php
$string = "This is a string thats too long to fit";
if(strlen($string) > 20)
echo substr($string,0,20);
else
echo $string;
?>
There is no way for you to calculate the size of a display element in PHP since it is run on the server and not on the client, and it's the client that renders the HTML.
If you have the same container size every time and the same font and font size and styles and everything, you could probably estimate a number of character and cut it off in PHP at that number of characters using substr. But even then, unless you build a table of character sizes or use a monospaced font, there is no way to reliably do what you want.

Jquery sortable list won't serialize, why?

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

Categories