Psycho
Moderators-
Posts
12,157 -
Joined
-
Last visited
-
Days Won
129
Everything posted by Psycho
-
I would like to get some input on the below problem and my proposed solution. Is there a more efficient or elegant way to accomplish the requirements? I'm assuming others may have solved this previously and I see no reason to repeat other's mistakes if I can avoid them. Problem Statement: I am storing blocks of text that includes references to different 'entities' that will exists in the application. For my example below the entities are 'products' and 'companies'. I will have dual purposes for this text. In some cases, I will want to display the text as plain text (no html) and in others I will want those entities to be a hyperlink to view the record (or some other function). Also, I want the ability to change where those links go without having to modify the stored data. These 'entities' will be the only content within the text to need to use HTML. The Plan: My plan is to store the data with placeholders for the entities that include the entity type and the entity id. I can then use that data to either strip out the placeholder content (for plain text output) or dynamically create the hyperlinks using the entity type and id parameters. How I would store the text Example code <?php //Function to return plain text function outputPlainText($input) { //Strip out entity tags return strip_tags($input); } //Function to return text with hyperlinks function outputHtmlText($input) { //Find 'entity' tags and parse out parameters $pattern = "#<entity type='([^']*)' id='([^']*)'>([^<]*)</entity>#"; return preg_replace_callback($pattern, 'formatEntityLink', $input); } //Function to format hyperlinks function formatEntityLink($e) { //Format entity match as a valid hyperlink //** Actual logic would be more complicated //** Will probably use a switch statement for each entity type return "<a href='display_record.php?type={$e[1]}&id={$e[2]}'>{$e[3]}</a>"; } ?> Usage #1 echo outputPlainText($content); Output: Usage #2 echo outputHtmlText($content); Output:
-
I used the EXACT same example page that I posted in post #7 with the change I provided on post #10. But, the snippet you posted on post #10 had changed the color. This is what I posted: li.active a.dropbtn { background-color: #990000; } This is what you posted li.active a.dropbtn { background-color: #f6f6f6; /* This set the background of the actively selected top menu item */ } Change it back.
-
I guess I'm a little confused over why you changed the color of that property to gray. I thought you wanted the selected parent to be dark-red and the drop-down items to be gray. The change I made to the selector is to only apply the properties to the active' anchor tags with the dropbtn class - which would only be the parent item. When doing that I get the result below. Is that what you want?
-
If you are having a problem with client-side code - please post client-side code. Without knowing what the output from the PHP code would be, it is difficult to replicate the issue and find a solution. Take the HTML source from a page where the problem exists and strip out everything that is not germane to the issue and post that. I tried to use the code above and replace dynamic content with values and my output looks very different from what you have posted. EDIT: I'm guessing you are using JQueryUI. The main element to output the content is nested in a div with the class 'slidingDiv' and your CSS has this for that class .slidingDiv { position: relative; display: none; } With that display: none; property the content doesn't get displayed. The JQueryUI is manipulating the CSS properties to display the content. So, it is impossible to know what the "real" properties are when viewed in the page from what you have provided. You could try creating a working JSFiddle page that displays the problem, then give us a link to that.
-
You should typically not use a foreach loop to dump all fields out anyway. If you were to ever include a field in the query that should not be displayed - the user would see it. I think the code to output content should be explicit. having said that, it appears you want the output to be in a specific layout and not dynamic anyway. So, create a template using variables in the applicable fields. I can't tell from your code what the field names are since you are dynamically outputting the fields. But, here is an example with how it could look pulling a record using PDO <?php $query = 'SELECT invoice_no, paid, amount_paid, colour, size, print, embroidery, sew, supplier, customer, acknowledged From table_name WHERE invoice_no = ?'; $stmt = $pdo->prepare($query); $stmt->execute([$invoiceNo]); $record = $stmt->fetch(PDO::FETCH_ASSOC); ?> <table class="custom-data" cellspacing="0" cellpadding="4" width="100%" border="0"> <tr><td colspan="4" class="headline flush-left"><?php echo $form->getTitle(); ?></th></tr> <tr> <th>Invoice Number:</th><td><?=$recod['invoice_no']?></td> <th>Paid</th><td><?=$recod['paid']?></td> </tr> <tr> <th>Amount Paid:</th><td><?=$recod['amount_paid']?></td> <th>Colour</th><td><?=$recod['colour']?></td> </tr> <tr> <th>Size:</th><td><?=$recod['size']?></td> <th>Print</th><td><?=$recod['print']?></td> </tr> <tr> <th>Embroidery:</th><td><?=$recod['embroidery']?></td> <th>Sew</th><td><?=$recod['sew']?></td> </tr> <tr> <th>Supplier:</th><td><?=$recod['supplier']?></td> <th>Customer</th><td><?=$recod['customer']?></td> </tr> <tr> <th>Acknowledged:</th><td><?=$recod['acknowledged']?></td> <th> </th><td> </td> </tr> </table>
-
The modification I posted two responses up should fix that. I was looking at the CSS and it could do with some clean-up, but I'm not the best person for that.
-
OK, so you want the "active' element to turn bright red (like the inactive elements) when hovered over?
-
I just found a problem. Changing the 'active' class definition above applied the dark red background to ALL the anchors in that group - even the child elements. Use this instead to only apply it to the parent element (which will have the dropbtn class) li.active a.dropbtn { background-color: #990000; }
-
Then that means $webpage does not equal 'testcss.php'. I don't know how you are defining that variable. But, if you use the working example I posted above - you can set $webpage to the href value of an element in the array it will be shown as selected. So, you need to look at how you are defining $webpage. EDIT: In the createMenu() function, I defined the second parameter with a default value so it is not required. Depending on how $webpage is defined, it may not "known" which page you are on when it first loads (?). If so, you can define the default value in the function parameter to match the href for the home link.
-
OK, I gave you a lot of information, so let's take it one step at a time. 1. Your main problem was that the function Active() was either applying the 'dropdown' class OR the 'active' class. The dropdown class is the one that applied the styles which create the dropdown affect. So, if you only apply the 'Active' class you lose the dropdown affect. You can apply multiple classes to the same element by separating them with spaces. So, you want to always apply the 'dropdown' class to all of the relevant element and add the 'active' class only to the one where it applies. 2. Even if you were to properly apply the classes per #1 (Inactive class="dropdown" or Active class="dropdown active"), the definition for the 'active' class would do nothing because it is applied to the <li> element. The background colors you are seeing are due to styles applied to the anchor tags (<a></a>) not the <li> tags. That can be easily fixed, by changing the definition for active in the stylesheet to: li.active a { background-color: #990000; } What that means is for any <li> elements with the 'active' class, find any anchors (<a></a>) and apply the formatting. Those two things alone will directly fix your problem. But, your HTML follows a predictable format. Rather than copy/paste code and change labels, hrefs, etc. - create the content with a function. That way you know you won't have any copy/paste errors. This is especially helpful when you need to make changes to the format. So, I suggest creating an array that defines the menu (the parent links and the child links), then creating a function to produce the HTML output. This way you can easily add/edit/modify the menu links by just changing the array - which you can use as an include file. You would not have to modify core code to change the menu. Or, if you want to change the menu structure you just need to change the function. So, I provided an array for the current menu items you had as well as a function to create the menu - as well as fix the above issues. Here is a working script with all the pieces <?php //hardcoded $webpage value for testing purposes $webpage = "drivers.php"; //definition of available menu $menuLinks = array( 'Home' => array( 'href' => 'menu.php' ), 'Territory Manager' => array( 'href' => 'tms.php', 'children' => array ( 'Add TM' => '#', 'Search TM' => 'search.php?search=TM' ), ), 'Sales' => array( 'href' => 'sales.php', 'children' => array ( 'Add Sales Person' => '#', 'Search Sales' => 'search.php?search=sales' ), ), 'Drivers' => array( 'href' => 'drivers.php', 'children' => array ( 'Add Driver' => '#', 'Search Drivers' => 'drivers.php' ), ), 'Passengers' => array( 'href' => 'passengers.php', 'children' => array ( 'Add Passenger' => '#', 'Search Passengers' => 'search.php?search=passengers' ) ) ); //Function to create html content for menu function createMenu($menuLinks, $webpage=false) { $menuLinksHtml = ''; foreach($menuLinks as $parentLabel => $parentLink) { //Determine link if parent is active or not $active = ($webpage == $parentLink['href']) ? ' active' : ''; $menuLinksHtml .= "<li class=\"dropdown{$active}\">\n"; //Determine if parent link has children if(!isset($parentLink['children'])) { //No child elements $menuLinksHtml .= "<a href='{$parentLink['href']}'>{$parentLabel}</a>\n"; } else { //Has child elements $menuLinksHtml .= "<a href=\"javascript:void(0)\" class=\"dropbtn\">{$parentLabel}</a>"; $menuLinksHtml .= "<div class=\"dropdown-content\">\n"; foreach($parentLink['children'] as $childLabel => $childLink) { $menuLinksHtml .= "<a href=\"{$childLink}\">{$childLabel}</a>\n"; } $menuLinksHtml .= "</div>\n"; } $menuLinksHtml .= "</li>\n"; } //Return HTML content return $menuLinksHtml; } ?> <html> <head> <style> /***** Begin Menu CSS *****/ ul { width: 100%; list-style-type: none; margin: 0; padding: 0; overflow: hidden; background-color: #333; } li { float: left; } li a, .dropbtn{ display: inline-block; font-size: 15px; color: white; text-align: center; padding: 14px 16px; text-decoration: none; border-right: 1px solid #bbb; } /* Color of the main menu text when hovering */ li a:hover { background-color: red; } /* Once the mouse has moved off the main menu button and is now highlighting a sub menu button, this defines what that main menu button color is */ .dropdown:hover{ background-color: red; } /* Color of main menu button when not selected */ .dropbtn { background-color: 333; } li .dropdown { position:relative; display: inline-block; } li:last-child { border-right: none; } .dropdown-content{ display: none; position: absolute; background-color: #f9f9f9; min-width: 160px; box-shadow: 5px 7px 5px 0px rgba(0,0,0,0.2); z-index: 1; } /* Links inside the dropdown */ .dropdown-content a{ color: black; padding: 12px 16px; text-decoration: none; display: block; text-align: left; background-color: #f6f6f6; /* Sets background color of the drop down menu (not selected) */ } /* Change color of dropdown links on hover */ .dropdown-content a:hover {background-color: #ccc} .dropdown:hover .dropdown-content{ display: block; } /* I have no idea what this does as it appears nothing... li a:hover:not(.active) { background-color: #blue; } */ li.active a { background-color: #990000; } .active dropdown-content{ display: none; position: absolute; min-width: 160px; box-shadow: 5px 7px 5px 0px rgba(0,0,0,0.2); z-index: 1; } .active dropdown-content a{ color: black; padding: 12px 16px; text-decoration: none; display: block; text-align: left; } /***** End Menu CSS *****/ </style> </head> <body> <ul> <?php echo createMenu($menuLinks, $webpage); ?> </ul> </body> </html> EDIT: Removed the Active() function that is not used in my code.
-
OK, the code below will fix your problem and make the code easier to maintain and ensure consistency. However, the 'Active' class is being applied to the LI element and is not 'doing' anything because the colors you see are due to styles applied from the to the anchor elements - not the LI elements. You can fix that by changing the 'active' definition in the CSS to this. li.active a { background-color: #990000; } Then change the PHP code to define an array for the menu items and a function to generate the menu HTML content as follows //definition of available menu $menuLinks = array( 'Home' => array( 'href' => 'menu.php' ), 'Territory Manager' => array( 'href' => 'tms.php', 'children' => array ( 'Add TM' => '#', 'Search TM' => 'search.php?search=TM' ), ), 'Sales' => array( 'href' => 'sales.php', 'children' => array ( 'Add Sales Person' => '#', 'Search Sales' => 'search.php?search=sales' ), ), 'Drivers' => array( 'href' => 'drivers.php', 'children' => array ( 'Add Driver' => '#', 'Search Drivers' => 'drivers.php' ), ), 'Passengers' => array( 'href' => 'passengers.php', 'children' => array ( 'Add Passenger' => '#', 'Search Passengers' => 'search.php?search=passengers' ) ) ); //Function to create html content for menu function createMenu($menuLinks, $webpage=false) { $menuLinksHtml = ''; foreach($menuLinks as $parentLabel => $parentLink) { //Determine link if parent is active or not $active = ($webpage == $parentLink['href']) ? ' active' : ''; $menuLinksHtml .= "<li class=\"dropdown{$active}\">\n"; //Determine if parent link has children if(!isset($parentLink['children'])) { //No child elements $menuLinksHtml .= "<a href='{$parentLink['href']}'>{$parentLabel}</a>\n"; } else { //Has child elements $menuLinksHtml .= "<a href=\"javascript:void(0)\" class=\"dropbtn\">{$parentLabel}</a>"; $menuLinksHtml .= "<div class=\"dropdown-content\">\n"; foreach($parentLink['children'] as $childLabel => $childLink) { $menuLinksHtml .= "<a href=\"{$childLink}\">{$childLabel}</a>\n"; } $menuLinksHtml .= "</div>\n"; } $menuLinksHtml .= "</li>\n"; } //Return HTML content return $menuLinksHtml; } Now you can change the menu by just changing the array. Lastly, change the HTML to just this <ul> <?php echo createMenu($menuLinks, $webpage); ?> </ul> No need to create a table (that's so 1980's). If needed you could wrap it in a div.
-
The CSS class name 'dropdown' is what applies the properties to make the functionality happen. However, your logic is either applying THAT class or the other class 'active'. The active class does not have the applicable properties to make that functionality happen. The easiest solution is to always use the 'dropdown' class and ADD the active class when needed. Also, you are making this more difficult than needed by reproducing code for the elements. Create an array with the links needed and create them dynamically.
-
Concat multidimensional array with normal array
Psycho replied to luiggicc's topic in PHP Coding Help
I have no idea what you are asking. The code you posted doesn't seem to have any correlation to what you are asking. You state you have an multi-dimensional array with "5 positions". Not sure what that mean: is that 5 parent elements or that each parent element has five child elements? Regardless, the sample code you posted shows arrays with much more than "5 positions". How about you provide a sample of the two arrays and what you want the result to be? -
Here is what I believe is happening: At the end of the second foreach() loop you have a "$field" variable that is a reference. Then on the first iteration of the third loop the "$fields as $field" within the foreach is taking the first value of the array $fields and setting it as the value of the variable $field - which is still a reference to the second element in the array. So, on that third foreach loop, I think it is actually displaying the value for the second element on both iterations - but you are seeing the first value because it was overwritten on the first instance. Think of it this way for the logic on the last foreach loop: Take the next value from the $fields array and assign it to the 2nd element of $fields. Then display the value of the 2nd element.
-
Queries equal same amount of rows but should not
Psycho replied to mbrown's topic in PHP Coding Help
I'm making some assumptions here, but I would think that a vote should indicate a vote for or against the issue. But, your logic seems to imply that votes are only to indicate a "for" vote and all users must for for in order for it to pass. That seems like odd logic. Even if a unanimous decision is required, you should have some allowance for when someone doesn't cast a vote. Plus, you can easily determine 1) How many voters there are, 2) How many users have votes, and 3) The results of the vote with a single query. You don't state whether the votes table has an identifier for the user who casts a vote - but it should. Query SELECT COUNT(u.user_id) as users, COUNT(v.vote_id) as votes, (COUNT(u.user_id)=COUNT(v.vote_id)) as passed FROM votes v RIGHT JOIN users u ON v.user_id = u.user_id AND v.motion_id = :motion_id Results would look something like this (3 of 5 users have voted) users | votes | passed 5 3 0 Or this (5 of 5 users have voted) users | votes | passed 5 5 1 -
// doesn't work when put here. //echo $_SERVER['LOGON_USER'] //echo $_SERVER['AUTH_USER'] //echo $_SERVER['REDIRECT_LOGON_USER'] //echo $_SERVER['REDIRECT_AUTH_USER'] I assume you have error reporting off, because the above lines will cause an error (when they are not commented out) because they are not terminated with semi-colons. 1. Turn on error reporting when developing so you can see and fix errors. error_reporting(E_ALL); ini_set('display_errors', 1); 2. Add a semi-colon to the above lines if you want to output them to the page // doesn't work when put here. echo $_SERVER['LOGON_USER']; echo $_SERVER['AUTH_USER']; echo $_SERVER['REDIRECT_LOGON_USER']; echo $_SERVER['REDIRECT_AUTH_USER']; EDIT: I would suggest doing #1 first and then just un-commenting those lines and executing the script. That way you can verify that the error is reported and understand what it would look like.
-
Good point. A header to perform a redirect should (almost) always be followed by an exit() statement. Otherwise, depending on the structure of the logic flow, there could be additional logic that is being unnecessarily processed on that script.
-
I would suggest separating your logic (PHP) from the presentation (HTML) as much as possible. The code you have makes it difficult to debug because it switches back and forth so much. Looking at what you have, it appears the the "selected" options would end up having 'selected' put into the LABEL between the opening and closing tags as opposed to putting the selected parameter into the opening tag. So, if you are not seeing 'selected' in the drop-down list, it is because none of the DESCRIPTIONS match $info['size']. I would assume you would be saving the option VALUE and not the DESCRIPTION. So, you may also be comparing $info['size'] to the wrong value. I prefer to create a function for creation my option tags that I can use for all the select fields. Here is a quick and dirty solution. This assumes you are storing the tshirt size ID for selected values and not the description (as you should be). <?php //Put all of this code at the top of your script - before you output any HTML function createOptions($optionsAry, $selectedValue) { $options = ''; foreach($optionsAry as $optionValue => $optionLabel) { $selected = ($optionValue==$selectedValue) ? ' selected="selected"' : ''; $options .= "<option value='{$optionValue}'{$selected}>{$optionLabel}</option>\n"; } return $options; } //Convert db results into array and creation otpions HTML content $tshirtOptionsAry = array(); while ($row = mssqlfetchassoc($tres)) { $tshirtOptionsAry[$row['ts_id']] = $row['tsdescription']; } $tshirtOptionsHtml = createOptions($tshirtOptionsAry, $info['size']); ?> <!-- HTML content AFTER the logic is processed --> <select name="size" id="size"> <?php echo ; ?> </select>
-
Change echo "$row<br>"; To echo "{$d[$row][0]}<br>";
-
modify date('W') range from specific day of a week
Psycho replied to misiek's topic in PHP Coding Help
This is ugly, but it works. I would likely go through and refactor make it more efficient. I'm sure it could be done in a simpler fashion, but I had to change direction multiple times. It works on the same logic as the ISO logic. For any weeks that span Dec/Jan, the week will belong to the prior year or the next year based on which year has the most days in that week (i.e. at least 4). Note; There is debugging code at the bottom that shows the results for the days at the end/beginning of each year to validate the results <?php function weekNo($dateTs) { //Create return variable and set initial 'year' value $result = array(); $result['year'] = date('Y', $dateTs); //Get Jan 1 for the provided timestamp and the DOW $janFirst = strtotime(date("1/1/Y", $dateTs)); $janFirstDow = date('N', $janFirst); //Determine first day of first week if($janFirstDow == 3) { //First day of first week is Jan 1 $firstDayOfFirstWeek = $janFirst; } elseif(in_array($janFirstDow, [3,4,5,6])) { //First day of first week is Wed prior to Jan 1 $firstDayOfFirstWeek = strtotime('last Wednesday', $janFirst); } else { //First day of first week is Wed following Jan 1 $firstDayOfFirstWeek = strtotime('next Wednesday', $janFirst); } //Calculate number of weeks since first day of first week $startDate = new DateTime(date('m/d/Y', $firstDayOfFirstWeek)); $currDate = new DateTime(date('m/d/Y', $dateTs)); $daysDiff = $currDate->diff($startDate)->format("%a"); //Calculate the Week NO $result['week'] = ceil( ($daysDiff+1) / 7); //Handle the first three days or last three days of the year //if they should fall in the adjoining year's first/last week //If selected date is Jan 1 - 3 if(date('m', $dateTs)==1 && date('j', $dateTs)<=3) { //If Jan 1st falls on Sun/Mon/Tue AND selected date is on Sun/Mon/Tue if(in_array($janFirstDow, [7,1,2]) && in_array(date('N', $dateTs), [7,1,2])) { //Get year/week no for the last week of prior year $result = weekNo(strtotime(date("m/d/Y", $dateTs).' -3 days')); //Increment year & set to week 1 } } //If selected date is Dec 29 - 31 if(date('m', $dateTs)==12 && date('d', $dateTs)>=29) { //If 12-31 falls on Wed/Thu/Fri AND selected date is on Wed/Thu/Fri if(in_array(date('N', strtotime(date('12/31/Y', $dateTs))), [3,4,5]) AND in_array(date('N', $dateTs), [3,4,5])) { //Increment year & set to week 1 $result['year']++; $result['week'] = 1; } } //Return result return $result; } //Debugging code echo "<pre>"; for($year=2005; $year<=2015; $year++) { $startDate = "12/15/{$year}"; $noOfDays = 30; echo "<h1>{$year}</h1>"; for($day=0; $day<$noOfDays; $day++) { $timeStamp = strtotime("{$startDate} + {$day} days"); //$isoWeek = date("W", $timeStamp); $weekNo = weekNo($timeStamp); $dow = date('N',$timeStamp); if( date('N',$timeStamp) == 3 ) { echo "<br>\n"; } echo "<b>" . date('D, m/d/Y', $timeStamp) . "</b> -- Year: {$weekNo['year']}, Week: {$weekNo['week']}\n"; } } echo "</pre>"; ?> -
modify date('W') range from specific day of a week
Psycho replied to misiek's topic in PHP Coding Help
Without determining the FIRST week of the year, you cannot know the logic for determining the "week" for any other dates in the year. I've already got a solution - except it doesn't handling the "remaining" days at the end of the year that should belong to week one. Should have a complete solution shortly. -
modify date('W') range from specific day of a week
Psycho replied to misiek's topic in PHP Coding Help
I think that would cause scenarios where the "first week" of the year, will be mis-calculated. Take the following example where Jan 1 starts on a Friday Mon Tue Wed Thu Fri Sat Sun DEC 28 29 30 31 1 2 3 JAN 4 5 6 7 8 9 10 - First week For a standard ISO week, the first week of the year is the one beginning on Jan 4, because it has at least four days in the current year. Using the logic above, the 4th and 5th of January would be counted as the last week of the previous year. For a Wed - Tue week, the first week for that same year should begin on Dec 30th (of the prior year). Wed Thu Fri Sat Sun Mon Tue DEC 30 31 1 2 3 4 5 - First week JAN 6 7 8 9 10 -
modify date('W') range from specific day of a week
Psycho replied to misiek's topic in PHP Coding Help
OK, how will the first week of the year be determined and how are you going to determine how many weeks there are in a year (hint: it is not always 52)? You can't simply "shift" the results of "W" to get the right answer (well depends on what your rules are I guess). The "W" format is for specifying the ISO-8601 week number. Here are the "rules" for determining the first and last week for that model So, determine your rules for determining how you will decide the first and last week - THEN we can help write code for it. -
Here's a class to get the duration of an MP3 file from the header information. http://www.zedwood.com/article/php-calculate-duration-of-mp3
-
Using file size of a bunch of MP3 files to determine the total play length seems a bit clunky. How many files are there? Why not get the actual play length of the files directly from the file headers?