loop through an anchor id - php

I apologize is any of this does not look right, it is my first time asking a question on this site.
I am creating a webpage using html, css, and php. Specifically, I am trying to create subnavigation links on my page using information from a database.
Here is the code I have:
foreach ($subArr as $sub => $result)
{
if (mysql_num_rows($result) > 0)
{
$resultString .= '<a id="$sub" style="cursor: poimter; color: #0076cf;" href="$sub">'.' | '.$sub.' | '.'</a>';
}
}
$subArr is an array of subcategories that I would like the user to be able to click on the link with the subcategory's name and it will take them to that part of the same page. As of right now, all it does is create one giant link under all of the subcategory names instead of creating each individual link.
Obviously I need some sort of loop, but I am not sure how to look through the $resultString to change both the anchor id and href.
Any help is much appreciated!!

(Of topic, but important)
You have a typo, it should be :
style="cursor: pointer; ..."
Instead of :
style="cursor: poimter; ..."

There is an error in your code.
You put variable in '' which php won't parse to get proper result you need to put variable in "".
foreach ($subArr as $sub => $result)
{
if (mysql_num_rows($result) > 0)
{
$resultString .= '<a id="'.$sub.'" style="cursor: pointer; color: #0076cf;" href="'.$sub.'"> | '.$sub.' | </a>';
}
}
Moreover it looks weird to have same ID as href is.
I've noticed you use mysql_* function which are depracated and will be removed in future. Consider using PDO or MySQLi instead.

foreach ($subArr as $sub => $result)
{
if (mysql_num_rows($result) > 0)
{
$resultString = '<a id="$sub" style="cursor: pointer; color: #0076cf;" href="$sub">'.' | '.$sub.' | '.'</a>';
}
$resultstring="";
}

you seem to be on the right track but have a few things mixed up.
Menu
Firstly when making a menu you want to use an unordered list, then style it with CSS. A basic example of this is:
<ul class="menu">
<li>Test</li>
<li>Test 2</li>
<li>Test 3</li>
</ul>
You then style it with the following CSS
ul.menu, ul.menu * {
list-style: none;
padding: 0;
margin: 0;
}
ul.menu {
width: 100%;
height: 20px;
background: #ccc;
padding: 5px 0; /* Add padding top and bottom */
}
ul.menu > li {
height: 20px;
line-height: 20px;
float: left;
}
/* Make a tag fill the entire LI so users can click
anywhere, not just on the text. */
ul.menu > li > a {
display: block;
padding: 0 10px; /* Add padding between items */
color: #000;
text-decoration: none;
}
ul.menu > li > a:hover, ul.menu > li > a:active {
background: #000;
color: #FFF;
}
/* Add divider between items, except last item (Does not work with earlier versions of IE) */
ul.menu > li:not(:last-child) {
border-right: 1px solid #000;
}
PHP Loop
Firstly a note. You're using mysql, which is depreciated. That means that in a version of PHP some time soon it is not going to be available any more. A lot of people recommend you learn PDO. Personally I prefer MySQLi over prepared statements, but that's just my preference. Either is fine, but learn one of them.
Now for your loop. You seem to be checking for a result from your mysql query within your loop, that's wrong. I'm guessing above that you have a query which loads it's results into $subArr. You need to call mysql_num_rows before you load them into $subArr.
The loop itself is fine other than that once you apply it to a list as above. Your final code should look something like this. Note, I've used MySQLi in my example, I recommend you do the same although it shouldn't be too hard for you to convert it to MySQL if you wish to.
<?php
$subArr = array();
$query = "SELECT something FROM somewhere";
$result = $mysql->query($query);
if($result->num_rows) {
while($row = $result->fetch_assoc()) { //I personally prefer fetch_assoc over the others, but fetch_row or fetch_array are both fine here too.
$subArr = $row;
}
}
//Lets output the menu
$resultString .= '<ul class="menu">';
foreach($subArr as $sub => $result) {
$resultString .= '<li>' . $result['name'] . '</li>'
}
$resultString = '</ul>';
As one last point of note, you don't need to put a cursor: pointer on an a tag, it has that styling by default.
I hope this manages to clear some things up for you.

Related

How to change li CSS in mpdf?

I work with mPDF to generate invoices to send to my customers. I have an invoice that has some metadata that is listed using an li element. I want the dots from the li element to not be visible. I've tried applying 'list-style-type: none;' to the element in which this information is displayed. I've tried both
of this inline and in the actual CSS.
<?php
foreach ( $invoice->get_columns_data() as $index => $row ) {
echo '<tr class="item">';
// Display row data.
foreach ( $row as $column_key => $data ) {
$templater->display_data_recursive( $column_key, $data );
}
echo '</tr>';
}
?>
The PDF ignores all changes to the metadata that is passed through, but it will change the tr element's background, for example.
.item {
list-style-type: none!important;
background-color: yellow;
}
list-style-type: none; will not work, even if I add !important
background-color: yellow; will work regardless.
Example of element change
I don't know what to do to get this element to listen to my CSS.
Could anyone help me out or point me in the right direction so I can continue?
Simple add css line to local page:
.item{list-style-type: none!important;}
Or add new class like
//css .nodots{list-style-type: none!important;}
//php echo '<tr class="item nodots">';

How to insert colors into rows and columns

I am working on a piece of code that displays a table that shows different drug details. I have a color coding system, red = danger, yellow = alert, green = safe.
However I am not happy with the colors that I am using. Is there any way of inserting brighter colors into this code below?
<?php $row_class = "";
while($row = mysql_fetch_assoc($dbResult1))
{
if($row['total_mai'] <= 2)
$row_class = "success";
else if($row['total_mai'] >= 5)
$row_class = "danger";
else if($row['total_mai'] >= 3 and $row['total_mai'] < 5)
$row_class = "warning";
// echo $row_class;
?>
The colors actually aren't in your code here. The colors are defined in classes in your css. Somewhere in the header of your file, you'll need to look for a reference to a css file:
<link rel="stylesheet" type="text/css" href="mystyle.css">
It could also be in the actual html page between <style> tags.
<head>
<style>
body {
background-color: linen;
}
h1 {
color: maroon;
margin-left: 40px;
}
</style>
</head>
Though there will be a lot there, you're probably looking for sections which look something like this:
.success {
color: green;
}
.danger {
color: red;
}
.warning {
color: yellow;
}
There could be many other attributes defined too, but the .word "selector" tells the browser to render colors on the text with these classes you're adding. To change the colors, change the attributes. You might not see color names liek above. You could see hex colors (something like #d0e4fe;). The W3Schools page on CSS is a good place to get started. They also have a nice color reference for color names:
There are other ways the CSS might reference the classes, so you might want to look at a tutorial on Selectors. For instance, they might use tr.danger { ... } to reference only danger classes which are applied to table rows.
If using Bootstrap
Then I'm not an expert, so I can only help so much, but Bootstrap pre-defines some of these styles for you. You could make new classes and use !important to override the classes with new colors. Important can get confusing since it's a "nevermind" to previous CSS, but you need it here if bootstrap is applying the background to cells individually. I just found some code on another answer here about doing this in Bootstrap:
.table tbody tr > td.success {
background-color: #dff0d8 !important;
}
.table tbody tr > td.error {
background-color: #f2dede !important;
}
.table tbody tr > td.warning {
background-color: #fcf8e3 !important;
}
.table tbody tr > td.info {
background-color: #d9edf7 !important;
}
.table-hover tbody tr:hover > td.success {
background-color: #d0e9c6 !important;
}
.table-hover tbody tr:hover > td.error {
background-color: #ebcccc !important;
}
.table-hover tbody tr:hover > td.warning {
background-color: #faf2cc !important;
}
.table-hover tbody tr:hover > td.info {
background-color: #c4e3f3 !important;
}
This would be in your own CSS file preferably. If you start modifying the Bootstrap css file, it could get frustrating if you need to upgrade Bootstrap to a new version. The "important" takes care of your settings being more, well... important.
You could also use the links I added above to learn how to make your own classes and then add your own classes instead of Bootstraps.

For every other output in php

So I have a $res
$res = $conn->query("SELECT username, Hours,joined FROM users ORDER by Hours DESC LIMIT 10");
which leads to this table:
while ($row =$res->fetch_assoc()){
echo "<tr><td>" .$row["username"] ."</td><td>"
. $row["Hours"]."</td><td>".$row["joined"]."</td></tr>";
}
Then using html and css:
table, td, th {
background-color:#F2F2F2;
font-size:20px;
left:20px;
th {
background-color: green;
color: white;
}
How do I make the first output a certain color, which in this case would be #F2F2F2(light gray) background. Then a second output(column) a white background color? Then third output #F2F2F2 again, so it's basically every other time. I am thinking about an if statement? but couldn't exactly think of a specific one. So far I am getting, as planned, a ugly pure gray back grounded table.
There is a cleaner way to do it with CSS3 you can do this without using php using the nth_child() selector like this
table, td, th {
background-color:#F2F2F2;
font-size:20px;
left:20px;
th {
background-color: green;
color: white;
}
tr:nth-child(even) {
background-color:#fff
}
In your case this makes all the even table rows i.e 2,4,6.... have a background color of white, you can also change the argument even to odd, depending on how you want to use it. It should also be noted that Internet Explorer 8 and earlier versions do not support the :nth-child() selector
This is a quick and dirty way:
$i=0;
while ($row =$res->fetch_assoc()){
$bg="";
if ($i & 1) $bg=' bgcolor="#f2f2f2"';
echo "<tr$bg><td>" .$row["username"] ."</td><td>"
. $row["Hours"]."</td><td>".$row["joined"]."</td></tr>";
$i++;
}

Alternating Color HTML Table PHP

I am trying to get my table to alternate colors but I am having some difficulty.
if ($i % 2 == 0)
$color = "grey";
else
$color = "white"; $i++;
$table .= "<tr style=backround-color=$color>";
This does not work. I have tried this as well but it did not work either.
$table .= "<tr:nth-child(even) {background: #CCC}; tr:nth-child(odd) {background: #FFF}; >";
You misspelled background and you don't use = in CSS, you use :. I also added quotes around your attribute values as it is best practice:
$table .= "<tr style='background-color:$color'>";
The last line in your question isn't even close to valid HTML or CSS. Looks kinda neat though.
I found an interesting link here that does what you are looking for. I put the code from the link into a jsfiddle and here is the css styles that I got from the link:
.TFtableCol{
width:100%;
border-collapse:collapse;
}
.TFtableCol td{
padding:7px; border:#4e95f4 1px solid;
}
/* improve visual readability for IE8 and below */
.TFtableCol tr{
background: #b8d1f3;
}
/* Define the background color for all the ODD table columns */
.TFtableCol tr td:nth-child(odd){
background: #b8d1f3;
}
/* Define the background color for all the EVEN table columns */
.TFtableCol tr td:nth-child(even){
background: #dae5f4;
}

I have a css array that I want to merge

I have an HTML class that I use to create templates.
My class works like this:
<?php
$page = \TEST\HTML::dispense(':html');
$page->mainWrapper(':div') //creates a child object by using __call() and sets the "div" model
->id('mainWrapper') //sets id
->style('background','red') //adds a style
->text('blah') //adds a text
->addClass('someClass'); //adds a class
->someSpan(':span')
->addClass('spanClass')->addClass('someClass')
->style('font-size','12pt')
->style('border-bottom','1pt dashed black')
->style('background','red');
?>
This allows me for rapid development of html markup without worrying about about a missing character or a misquoted property. Everything gets cached and I have no performance issues.
Now I'd like to take this one step further. In production mode, everything works fine, but for the final output, I'd like to strip out all the inline "style" properties and minimize them and cache them in a css file.
Now, I have a function that loops through all my HTML objects, and aggregates the data according to tag, id, and classes.
My question is: once I have my neat css array in that form:
$style['tag']['.class']['#id']['styleKey'] = styleValue
How do I trim out redundant values so I am left with a relevant css file? Minifying and gzipping can come at a later stage. What I want now is to compare values and optimize the array before dumping it so all 'styleKeys' common to all elements that have the same tag/id/class are grouped together.
So in the example above, for example, since two elements (the div and the span) share the style "background: red" and the class "someClass", I would have a "someClass" CSS rule with "background:red"
If it is of any interest, here is my "extractstyles" function:
<?php
public static function extractStyles($element, array &$styles=array()){
if($element instanceof \TEST\HTML){$element = $element->htmlData();}
$tag = isset($element['#acronym']) ? $element['#acronym'] : NULL;
$id = isset($element['#id']) ? '#'.$element['#id'] : NULL;
$classes = isset($element['#class']) ? $element['#class'] : NULL;
if(isset($element['#style']) && ($tag || $id || $class)){
$ref = &$styles;
if($id){if(!isset($ref[$id])){$ref[$id] = array();};$ref = &$ref[$id];}
if($classes){
if(\is_array($classes)){$classes = '.'.implode('.',$classes);}
if(!isset($ref[$classes])){$ref[$classes] = array();};$ref = &$ref[$classes];
}
if($tag){if(!isset($ref[$tag])){$ref[$tag] = array();};$ref = &$ref[$tag];}
foreach($element[self::ATTRIBUTES]['#style'] as $style=>$value){
$ref[$style] = $value;
}
}
if(isset($element[self::CHILDREN]) && count($element[self::CHILDREN])){
foreach($element[self::CHILDREN] as $child){
self::extractStyles($child, $styles);
}
}
return $styles;
}
?>
Any pointer would be more than welcome...I am really lost. I don't even know if what I am looking for is doable.
As said above, performance is not an issue for now. If it works, I will find a way to optimize it.
Also, please no links to xCSS and other frameworks, as they work on strings and my CSS is created as an array.
Thanks in advance for any help you can give me!
A first order optimization is to Build a hierarchy tree. A parent to child relationship in this tree is a child is a superset of the parent. The root node of this tree is an empty style (which you won't display).
Thus if you had
.parent {
background: red;
}
.childA {
background: red;
border: 1px solid black;
}
.childB {
background: red;
font-weight: 800;
}
The parent is set as the lowest common denominator in the tree. This can then be compressed into 3 classes with less text. The children elements will have all the classes in the path, If you originally had <span class="childA"> you would then get <span class="parent childA">
The compressed classes look like:
.parent {
background: red;
}
.childA {
border: 1px solid black;
}
.childB {
font-weight: 800;
}
A note on IDs, IDs will always be a child of the most appropriate class. Thus if you had
#menu {
background: red;
border: 1px solid black;
margin: 15px 40px;
color: white;
}
It would become the child of ChildA, and its css would be reduced to
#menu {
margin: 15px 40px;
color: white;
}
And displayed as <ul id="menu" class="parent childA">
To create the tree, you will need an object that will store an array of the same children objects (recursively) And a function that when given two objects can determine if their css is a subset, equal or superset, the number of differences, or if there is no commonality.
If you are not familiar with binary search trees, this would be a good time to bone up on that, even though this will be more complex than that, it will be a good start in the right direction.
A second order optimization is determining if nesting of child elements can further reduce the need of classes. For example if all your <li> inside <ul id="#menu"> were styled similarly it would make sense that you could create a rule for #menu li
To do this, you need to go to each node, and analyze its children. If all the children of the same node type share a common style element (use the set comparer above), extract the common set element as a parent. The differences become the children.
Lets say you have this as an example (note is has already gone through pass 1):
<ul id="menu" class="parent childA">
<li class="top menuli">Item</li>
<li class="menuli">Item</li>
<li class="menuli">Item</li>
<li class="menuli">Item</li>
<li class="bottom menuli">Item</li>
</ul>
We note that all the <li> have a common element .menuli, this means we can eliminate this class that was created in pass 1 and replace it with a flat rule of #menu li. We do this by removing the menuli class from each child li, and replacing the .menuli rule with the #menu li rule.
Our css changes like from:
#menu {
margin: 15px 40px;
color: white;
}
.menuli {
font-size: 30px;
font-weight: 800;
margin: 8px 0;
}
to
#menu {
margin: 15px 40px;
color: white;
}
#menu li {
font-size: 30px;
font-weight: 800;
margin: 8px 0;
}
And the html looses the class menuli
<ul id="menu" class="parent childA">
<li class="top">Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li class="bottom">Item</li>
</ul>
Remember to use a breadth first search when searching down your node tree instead of depth first search. If you are aggressive, you can keep checking 2nd levels for similar tags across many paths, a common 2nd level search might reveal similar classes for #menu li a or #container div p etc. This becomes an NP hard problem if you allow unlimited depth searching.
Hope this helps. If this is the direction you want to go, I'd be happy to help with more code concerning the set comparator and possibly the tree searcher, although that is significantly more complex.

Categories