I have one table which display data as from Dynamic Content in 1 column. I would like the content to move to a second column when the number of cell is >3. (ie. if there are 3 cells to display, it would be display in 1 col, and 4 cells or more it would be displayed in 2 columns. Note that the dynamic content will never go over 6 cells.
I have to say I can find my way with css and html but javascript is another issue... however I do realize it might be the only way.
Any Javascript , jQuery script available to get my result?
Data to be displayed like so:
| Col1 | | Col1 || Col2 |
--------- -----------------
| Data1 | ----> | Data1 || Data4 |
| Data2 | | Data2 | etc...
| Data3 | | Data3 |
Not sure if this would help but the Code calling for the dynamic content (and putting it in the table) is:
<table id="myTable">
<?php
$str1="";
$flag1=1;
while($rowReview1=mysql_fetch_array($resultReview1)){
$st1="";
$val=$rowReview1["ratingValue"];
$sName=$rowReview1["criteriaName"];
if($val>0){
for($ii=1;$ii<=$val;$ii++){
$st1.="<img src=\"$directory/images/orange.gif\" \>";
}
for($jj=$val;$jj<5;$jj++){
$st1.="<img src=\"$directory/images/gray.gif\" \>";
}
}else{
$st1="";
}
if($val > 0){
$str1.="<tr><td>$sName</td><td>$st1</td></tr>";
}else{
$str1.="<tr><td>$sName</td><td>N/A</td></tr>";
}
}
echo $str1;
?>
</table>
The page can now be seen live here: http://www.top10banques.com/avis/index2.php?item_id=1
The tables I'm trying to edit are the ones below the page break "l'evaluation des clients".
Thanks again for any help you could provide and Happy Holidays to all!
Assuming you're using standard table structure, first I would put all your data into one column, regardless of how many there are. Then I would move them dynamically:
EDIT
Here's a working sample of what you're trying to do. The problem was you have TWO div cells per row, I thought you only had one:
<html>
<head>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js">
</script>
</head>
<body>
<script type="text/javascript">
$(function(){
var allRows = $('#myTable tr');
if(allRows.length > 3) {
var extraData = $('#myTable tr:gt(2) td')
var j = 0;
for (i=0;i<extraData.length/2;i++) {
$(allRows[i]).append(extraData[j])
$(allRows[i]).append(extraData[j+1])
j=j+2;
}
$('#myTable tr:gt(2)').remove();
}
});
</script>
<table id="myTable">
<tr><td>Data1</td><td>Data11</td></tr>
<tr><td>Data2</td><td>Data21</td></tr>
<tr><td>Data3</td><td>Data31</td></tr>
<tr><td>Data4</td><td>Data41</td></tr>
<tr><td>Data5</td><td>Data51</td></tr>
<tr><td>Data6</td><td>Data61</td></tr>
</table>
</body>
</html>
NOTE the above solution will only work to your exact specifications. If you want this to be reusable (ie, takes any number of rows with any number of cells), you may have to do some additional tweaking.
WORKING UPDATE FOR MULTIPLE TABLES
See the code I posted here on Pastie: http://pastie.org/755963
Note that the tables are now referenced by classes instead of ids. Also, I want to say that I agree that this solution could (and maybe should) be handled server side, I am merely answering the question as the OP asked...
I would probably build a JSON object with this data in the PHP instead of injecting it into the DOM at ALL at first. This way, you don't have the overhead of the javascript restructuring existing data in the DOM, its just positioning it from scratch.
I would have thought this would be straightforward using CSS (but I'm no CSS expert).
Something like this deals with a more generic case in PHP:
function multi_columns($inp_array)
{
$max_cols=4;
$target_rows=3;
if (count($dyn)>$max_cols*$target_rows) {
// won't fit in this number of cols/rows
// add more rows
$rows=count($dyn)/$max_cols;
$target_rows= ($rows==(integer)$rows) ? $rows : $rows+1;
} elseif (count($dyn)>$max_cols*$target_rows) {
// reduce to number of cols needed
$cols=count($dyn)/$target_rows;
$max_cols= ($cols==(integer)$cols) ? $cols : $max_cols;
}
print "<table>\n";
for ($y=1; $y<=$target_rows; $y++) {
print "<tr>\n";
for ($x=1; $x<=$max_cols; $x++) {
print "<td>";
if (array_key_exists($y+$x*$target_rows, $inp_array)) {
print $inp_array[$y+$x*$target_rows];
}
print "</td>";
}
print "</tr>\n";
}
print "</table>\n";
}
This problem begs to be solved at the server and improve page performance by eliminating a JavaScript script.
Secondly, you can simplify life by not using a table, but rather div's.
Let us have a look first at a proposed data structure. We will hold all output in an array since you are using PHP.
$data=array[0...n];
That simply sorts the business logic generation.
Now let us look at the presentational logic, first visually the proposed divs!
$data_length=m
j=0 j=1 j=2 j=3 ..... j= x
i=0 [1] [4] [7] [10] []
i=1 [2] [5] [8] [11] []
i=2 [3] [6] [9] [12] []
y [] [] [] [] []
All divs will be floated left.
A clearing div will be printed once the row is completed.
Now we need to define the relationships of our data versus the position. A bit of observation of the table, shows that all horizontal positional values are separated by 3 and all vertical by one (i.e we need to iterate over our array $data in steps of three!), effectively floating our divs as follows:
j=0 j=1 j=2 j=3 ..... j= x
i=0 [1] [4] [7] [10] []
Pseudo algorithm
$imax=2; // spec
$number_cells = m/imax // total number of cells
$jmax=$number_cells/3 // check rounding etc left out at this stage
// you can use mod % to see if there are
// remainders etc.. on second script iteration
And now for the iteration
for ($i=0;$i<$imax-1;$i++){
for ($j=0;$j<$jmax;$j++){
$out.=wrap_in_div($data[($j*3)+(i+1)]);
}
}
Note that I have not bothered to define lay out the function wrap_in_div as is trivial.
Hope it helps Merry Christmas! Program was off my head so please translate the pseudo-code into real $! :)
Related
I'm generating dynamic form inputs based on table column field names with this simple code :
<form id="generate-user-register-form" type="POST">
<?php
$queryuser= "DESCRIBE users";
$resultstmt_queryuser= $conn->query($queryuser);
$fields = array();
while($row = $resultstmt_queryuser->fetch_assoc()) {
$fields[] = $row['Field'];
}
foreach($fields as $field): ?>
<div class="col-md-6">
<?php echo "$field: "; ?>
<input class="form-control" type="text" name="<?php echo $field; ?>" />
</div>
<?php endforeach; ?>
<input type="button" name="submit" value="submit"/>
</form>
Ok this works great but the first 10 fields are unnecessary and the first column id is autoincrement so it is definitely not needed as a form input. Is there a way for me to only generate specific fields without having to manually hard code something like the below code 10 times?
if($field !="id"){
//generate input
}
I think what you are trying to do might have different approaches considering how to decide if a field should be an input or not. For example.
Consider that your table would look like this:
+----+------------+-------------+-------------+------------+
| id | name_input | email_input | phone_input | created_at |
+----+------------+-------------+-------------+------------+
| 1 | John Smith | not#me.com | 888 333 444 | 2018-08-26 |
| 2 | Lila White | not#us.com | 412 322 555 | 2018-08-27 |
+----+------------+-------------+-------------+------------+
So, with this table you could easily find the keyword input in the columns and assign only them to the form:
while($row = $resultstmt_queryuser->fetch_assoc()) {
if (strpos($row['Field'], '_input') === false) {
continue;
}
$fields[] = $row['Field'];
}
Or, as #IdontDownVote pointed out in the comments above, you can use a count inside the loop and only add the fields if after some number or betweem some, or before another, like:
$count = 0;
while($row = $resultstmt_queryuser->fetch_assoc()) {
if ($count < 1 /* adding extra clauses here as && $count > 5 */) {
continue;
}
$fields[] = $row['Field'];
}someone
But I would advise against it. Why? you might ask.
Well, by nature, each field is different. The machine will certainly not know what is the label for a specific field, or what validation it should have, or what kind of information it should hold.
Most commonly, ids are integers, thought they might not be. But what about date fields? Or phone numbers? Or Postal Codes?
Generating dynamic inputs for each of them you might also have to read the name of the column as the label of each field, but still, some information you are bound to hardcoded at some point.
Validations of phone numbers, validations of postal codes, emails, websites.
Most of it will have to be hardcoded anyway in the backend before this information reach the database. So, if you are gonna have to write some specific rules for specific fields, why not specify this fields in the form as well?
It makes your life easier when trying to track down each field and you won't be entirely dependent on creating ignore rules for certain fields to be displayed like: created_at, created_by. When these fields are commonly updated by the system and not by the user (knowing who did what and when, of course).
But well, TL; DR; sometimes hardcoding is clearer and faster (on the long run) than the opposite.
[Edit]
Adding the count to the answer to be visible, if #IdontDownVote post this answer, please choose his answer.
I want to load contacts from a query, Whilst I have found ways to split by the amount of rows I want the result to be split into two columns as below as well as them being a sort of clickable button.Is it possible to display the query results as described below by the use of HTML or by the query itself? :
Contacts
------------------------------
Albert Smith | Ben Marshall
Benjamin Jones | Chris Jones
I have tried the code below
<?
$rowcount = mysql_num_rows($records);
echo "<div id='column1'>";
$i = 0;
while ($d = mysql_fetch_object($records)) {
echo $d->name;
$i++;
if ($i == floor($rowcount / 2)) {
echo "</div><div id='colums2'>";
}
}
echo "</div>";
?>
But this splits the columns by reaching half of the results in 1 column and the rest in another column
Albert Smith | Benjamin Jones
Ben Marshall | Chris Jones
This is not possible by query itself.
You must parse the result with an html <table>, every two results make a new <tr> and double <td>
I'm guessing you are conversant with coding:
Check this algorithm
get results
declare an even/odd check variable
loop through your result-set
List item
increment the counter in each loop
ii. check counter value in the loop
iii. if counter variable value is even give it a different class
To make them a clickable button, you can use bootstrap as (ie. give an tag the style of a button)
Let me know on how it works out.
Have fun coding.
I have bits of code I want to throw in to my site, and provisioned a space right after <body> using 'flairs' (divs) that sit outside the design. Here's the code:
//Add Flair Containers as needed
if($flairs>0){
echo "<!--Flair Graphics (if needed)-->\n";
while($fQty = --$flairs+1){ //-- subracts 1, +1 accounts for 1 being 0
$flair = array($flair1, $flair2, $flair3);
foreach($flair as $flairCode){
echo "<div id=\"flair-".$fQty++."\">".$flairCode."</div>\n";
};
};
};
It prints correctly, where content = $flair1, $flair2, and so on.
<div id="flair-1">Content1</div>
<div id="flair-2">Content2</div>
<div id="flair-3">Content3</div>
But if $flair2/$flair3 is empty, it still prints a div. How can I fix this?
Within your foreach loop you can check if the value is empty and continue (i.e. skip) to the next value if it is.
Like so:
if($flairs>0){
echo "<!--Flair Graphics (if needed)-->\n";
while($fQty = --$flairs+1){ //-- subracts 1, +1 accounts for 1 being 0
$flair = array($flair1, $flair2, $flair3);
foreach($flair as $flairCode){
if (empty($flairCode)) continue;
echo "<div id=\"flair-".$fQty++."\">".$flairCode."</div>\n";
};
};
};
I suspect that you could simply prepend if($flairCode) to your echo statement. That would make your inner loop:
foreach($flair as $flairCode){
if($flairCode) echo "<div id=\"flair-".$fQty++."\">".$flairCode."</div>\n";
};
Some points to note:
Since the $flair array will always be the same, construct it outside of the loop (this will let you evaluate the condition only once too.
Using $fQty++ is not enough to guarantee unique ID's, especially since every time it hits the while the value is reset. I suggest $fQty should not be part of the while condition and simply stay as an independent tally.
Stop using double-quotes. They're slow.
I am trying to create a button that will either say "Follow" or "Unfollow", depending on whether or not the current user follows another user.
If John followed Tim, but not Sarah, the web view would look as follows, according to John's view:
_________________________________
| | |
| Tim | (unfollow) |
|________________|______________|
| | |
| Sarah | (follow) |
|________________|______________|
Where (" ") denotes a button.
I have a database that indicates who follows whom, but how would I display the correct button based upon validation with said database?
Assuming you have three fields "name_id","name" and "followed" where "name_id" is the id of the person, "name" is a string signifying the name of the person, and "followed" is a boolean:
<script type="text/javascript">
function toggleFollowing(name_id) {
window.location = 'toggleFollowing.php?name_id='+name_id;
}
</script>
...
<?php
...
while ($row = $result->fetch_assoc()) {
echo '<tr>';
echo '<td>'.$row['name'].'</td><td><a href=""><button type="button" onclick="toggleFollowing('.$row['name_id'].')">'.($row['followed']==1 ? 'Unfollow':'Follow').'</button></td>';
echo '</tr>';
}
...
?>
You would have toggleFollowing.php receive the variable $_GET['name_id'] to toggle on the database and come back to this page. I'm assuming you have the current user's ID stored as a session variable or by other means since you would need that as a primary reference to update the record. If you're passing that from page to page by some other means, then you would want to pass that variable as well.
Apparently, this is more truncated code, but a better method would be to use AJAX to perform the toggling on the DB, and DOM manipulation (JQuery?) for a "real-time" update.
Hard to answer without examples of your code, but something like this?
<?php
if(follow){
echo '<input type="button" value="Follow" />';
} else {
echo '<input type="button" value="Unfollow" />';
}
?>
I got an XML file being echoed by PHP and all the code works fine but my problem is that inside a tag (exam and the attribute is chapter which is what's being echoed) there's more than one tag (ex, that's what is being echoed as exam #) and I am echoing the data to a table and I want it to display it like this:
| Chapter 1 | Chapter 2 |
|--Exam 1---|--Exam 1---|
|--Exam 2---|--Exam 2---|
| Chapter 3 | Chapter 4 |
|--Exam 1---|--Exam 1---|
But What I am getting is something like this: (I know why though)
| Chapter 1 |
|--Exam 1---|
| Chapter 1 |
|--Exam 2---|
| Chapter 2 |
|--Exam 1---|
It keeps on repeating the tag's attribute and I know why, because I am echoing the tag's attribute that I have as a variable in a table data. So the question is not why it is happening but how can I change it to display it the way I want it.
I guess maybe there's a way to delete the attribute if there's more than one (I know you can delete it but I don't know how to show it once and delete the others)
The code that I have is something like this:
In XML
<maintag>
<exam chapter="Chapter 1">
<ex id="1">Exam 1</ex>
<ex id="2">Exam 2</ex>
<ex id="3">Exam 3</ex>
</exam>
<exam chapter="Chapter 2">
<ex id="4">Exam 1</ex>
<ex id="5">Exam 2</ex>
</exam>
<exam chapter="Chapter 3">
<ex id="6">Exam 1</ex>
</exam>
<exam chapter="Chapter 4">
<ex id="7">Exam 1</ex>
<ex id="8">Exam 2</ex>
<ex id="9">Exam 3</ex>
<ex id="10">Exam 4</ex>
</exam>
</maintag>
The PHP
<?php
$xml = DOMDocument::load('examdata.xml');
$xpath = new DOMXPath($xml);
$exams = $xpath->query('//exam/ex');
$istyle = 1; //This is to add gray after every other row
echo " <table cellpadding=\"0\" cellspacing=\"3\" border=\"0\" width=\"60%\" align=\"center\">
<tr id=\"center\" bgcolor=\"#999\">
<td>Book</td>
<td>Exam</td>
<td>ID</td>
<td>Student's Exam Status</td>
</tr>
";
foreach($exams as $exams2) {
$chapter = $exams2->parentNode->getAttribute('chapter');
$examid = $exams2->getAttribute('id');
$examname = $exams2->nodeValue;
if ($examid < 5) { //where it says 5 there goes a php variable where it has the queried user's exam number from the database, again this is all finished no need to change this.
$exstatus = "You already took this exam.";
}elseif ($examid == 5) {
$exstatus = "This is your exam (exam link)";
}elseif ($examid > 5) {
$exstatus = "You are not yet on this exam";
}
echo "<tr id=\"center\"";
if ($istyle % 2 == 0)
echo " bgcolor=\"#ccc\"";
echo ">
<td>$chapter</td>
<td>$examname</td>
<td>$examid</td>
<td>$exstatus</td>
</tr>";
$istyle++;
}
echo "
</table>";
?>
Notice that the table structure is different than the way I said I want it and I was getting it above, I just changed it because I couldn't leave it the way it was.
Note that what I want to change is where it says chapter, I want it to display it once and below it to display exam 1 and below that exam2 ect. and next to the chapter put the next chapter (in this case chapter 2) and below that exam 1 and below that exam 2 ect. and after that create another table row below exam 2 and put two other chapters and below that the other exams.
Notice that the exams do not follow a pattern and this is an edited version of the file since there's hundreds of those and the values are different of what you see above.
The code above works, I just want to modify it so it could meet my requirements.
I've figured it out, it took me hours but I finally did it.
This is the code I used for the PHP, the XML stayed the same. I'll try to be as detailed as possible so it could help anyone with a similar problem or so they could extract info from it and modify it to their needs.
<?php
//self explanatory
$xml = DOMDocument::load('examdata.xml');
//again, self explanatory
$xpath = new DOMXPath($xml);
//looks for ex under exam in the xml I loaded above xml
$exams = $xpath->query('//exam/ex');
//I just put a number for testing purposes but it actually gets the user's exam id from the database
$studentexnum = "5";
//column counter, will be used to tell that after every 2 chapters, break the table data (td) and table row (tr) and create a new one
$_2chapters = 1;
//Opens the table and displays it to the client
echo "<table cellpadding=\"5\" cellspacing=\"5\" border=\"0\" width=\"25%\" align=\"center\">
<tr>"; //Opens the first table row and end the echoing
//starts the loop, for every exam, makes exam2 same as exam
foreach($exams as $exams2) {
//looks at my xml file for the tag ex (what I defined above) and gets the attribute called chapter from his parent (the tag above it)
$chapter = $exams2->parentNode->getAttribute('chapter');
//gets the attribute called id from the tag ex
$examid = $exams2->getAttribute('id');
//makes the tag ex a string so we could display it
$examname = $exams2->nodeValue;
////////////////////////////////////////Now for the Fun Part/////////////////////////////////////////////////////////////////////////////////
//conditional statement saying that if the variable chapter2 is set, display the conditions below, if it's not set (which is not when its starts the loop) do something else
if (isset($chapter2)){
//says if variable chapter defined above is equal to variable chapter 2 which is defined below do something. This is not true the first time but it is the rest of the loop, even is is a million.
if ($chapter == $chapter2) {
//variable chaptertd (which is called below) will equal to nothing if chapter equals to chapter2, this will happen at every exam (every ex tag in my xml file which is in the question above)
//this will avoid having repeated chapter, ie: chapter1 - exam one, chapter1 - exam 2, chapter1 exam 3, ect. will make it chapter 1, exam 1, exam 2, exam 3, ect
$chaptertd = "";
//if chapter does not equal to chapter2
}else {
//here we increment variable _2chapters that was 1 above, now is two, this is necessary so it could display two chapters side by side and break right before the third chapter, this will happen later
$_2chapters++;
$chapter2 = $chapter; //THIS PART IS EDITED, BUT NECESSARY
//Now we give a value to variable chaptertd, it was nothing before because I didn't want to repeat the title every time the loop found a new tag ex from my xml. This will only happen once in every chapter
$chaptertd = "
</td>
<td align=\"center\" valign=\"top\">$chapter2";//here we create the html that variable chaptertd will be displaying after a new name from the attribute chapter is found. This will display the name of the chapter to our table
}
//this else will only happen the first time the loop runs since only the first time is when the variable chapter2 is not defined, after this runs the variable chapter2 will have been defined
}else {
//chapter2 will be the same as chapter, if chapter equals to the string chapter1 so will chapter2.
$chapter2 = $chapter;
//here we create the same td as above since we want to display the name of the chapter the fist time it runs, if we don't do this the first chapter won't be display to the client
$chaptertd = "
<td align=\"center\" valign=\"top\">$chapter2";
}
//This part you don't have to concern yourself with it, I made this because I needed it to display different info depending whether the user was allow to see that exam.
//the variable examval is defined outside this code, that's on my html code which would do nothing here since it uses javascript and css. this gets the attribute id from our ex tag.
if ($examid < $studentexnum) {
$exval = "lessthan";
}elseif ($examid == 5) {
$exval = "equalto";
}elseif ($examid > 5) {
$exval = "greaterthan";
}
//here we say what happens when the variable _2chapters reaches the third attribute called chapter. we say if the remainder of variable _2chapters divided by 3 equals 0 do something
//else do nothing since we didn't define the else because we didn't needed it. this part will only happen at every third chapter, it will break from the previous chapter thus making
//it a new row right under the values of the tag ex which is under chapter 1 the third time the loops runs, but this will happen infinite amounts of time, after that it will be under
//chapter 3 and after that chapter 5 and so on.
if ($_2chapters % 3 == 0) {
//here we reset the count back to one because if we don't and there's more than one tag ex under chapter 3, it will be braking after every ex
$_2chapters = 1;
//here we echo the break from the previous chapter
echo "
</td>
</tr>
<tr id=\"center\">";
}
//here we echo the variable chaptertd which we gave different values to above depending whether the chapter's name has been declared already or not. If it has been declared, chaptertd
//won't show anything, if the chapter has never been declared it will create a new td and display the chapter's name and after that it will become nothing again
echo "$chaptertd<br />
$examname";//here we show the client what's the name of the exams under the given chapter, there could be one or one hundred of this and it will only display the chapter once and will display the rest
//of the exam names one after the other
//here we say that chapter2 equals to chapter, this way chapter2 will equal to the name of that loop, if the next time it repeats there's a new chapter the value of chapter will change
//thus making this statement false above and that will force it to create a new td with the new name until another name appears.
$chapter2 = $chapter;
}
//close the table to have a well formatted html file to display to the client.
echo "
</td>
</tr>
</table>";
?>
I actually figured it out a while ago, but this "smart forum" doesn't allow me to answer my OWN question before 8 hours because I don't have enough points or something. It's like as if it was trying to say that because I am new here I am dumb and can't find the solution to my problem on my own inside 8 hours. So I went to sleep. I just wanted to help other people that might come to this post in the future and hopefully the answer would answer some of their questions.
You probably meant...
foreach($exams as $exam)
...to get an item from the array, instead of...
foreach($exams as $exams)
BTW i would think of other names for the variables exam and ex, use names that describes what they are, maybe exam and chapter.