I'm making a mail icon which could send emails of different contents stored in arrays.
the problem is, the contents are isolated using a loop:
foreach ($table as $data) {
echo '<a id="email-content" href="mailto:?body='.$data->content.'"><i class="icon-envelope" ></i></a>';
echo "<div class='search-tmp-div' style='display:none;'><pre class='search'>$data->content</pre></div>";
}
I was wondering if there is anyone I can use the function without the envelope icon printing out a bunch of times. I want it to print only once?
$count = 0;
foreach ($table as $data) {
echo "<a id="email-content" href="mailto:?body='.$data->content.'">";
if($count == 0){ echo '<i class="icon-envelope"></i>';}
echo "</a><div class='search-tmp-div' style='display:none;'><pre class='search'>$data->content</pre></div>";
$count++;
}
This just adds a counter initially has a value of 0, thus printing <i class...></i> on the first loop (where $count == 0).
Yes there are many, an example of an alternative way would be:
create the icon button
create an html table
in each row, you put a column with a checkbox or radio box (for selection)
upon clicking on the icon button, you get the selected row(s) and send the requested email(s)
Edit:
An example of what you need would be:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#btn").click(function () {
selector = "content-"+$("input[type=radio]:checked").val();
location.href = "mailto:?body="+$("#"+selector).text();
});
});
</script>
<?php
$table = array( array( "id" => 1, "content"=>"content 1") , array( "id" => 2, "content"=>"content 2"), array( "id" => 3, "content"=>"content 3"), array( "id" => 4, "content"=>"content 4") );
echo '<img id="btn" src="http://cdn1.iconfinder.com/data/icons/Primo_Icons/PNG/128x128/email_send.png" width="40px" style="cursor:pointer;" />';
foreach ($table as $data) {
echo "<div class='search-tmp-div' style='display:block;'>";
echo "<input type=\"radio\" name=\"content\" value=\"{$data['id']}\">";
echo "<pre class='search' id=\"content-{$data['id']}\">{$data['content']}</pre></div>";
}
Related
I am creating a php email form with a foreach loop which creates a checkbox with several other checkboxes and input fields within the foreach loop. The loop might repeat several times, creating several sets of checkboxes, however I only want to include the checked checkbox and associated fields, not all of those within every loop. Only those selected would then be included in the 'servicelist' array and email.php.
My code below is incorrect as it is gathering all of the data from every loop. I understand this is because the input fields are populated with data, so the data is added to the array.
I think I need to add an 'if' statement to my jQuery, but I'm not sure how? I have tried changing the jQuery line 'if (checkbox.is(":checked"))' with the below line of code without success.
if ($("input[data-name='servicetitle[]'").prop(":checked")) {
PHP Form:
foreach ( $order->get_items() as $item_id => $item ) {
// Main checkbox to check if selected
echo '<div data-name="sup-checkbox-title[]">';
echo '<label for="servicetitle">Service:</label><br>';
echo '<input type="checkbox" id="servicetitle" data-name="servicetitle[]" value="' . $item->get_name() . '"><span>' . $item->get_name() .'</span><br>';
echo '</div><br>';
// Sub checkboxes and input fields to include in array if above checkbox checked
echo '<div data-name="sup-input[]"><br>';
echo '<label for="weightallowance">Weight Allowance Per Bin:</label><br>';
echo '<input type="text" id="weightallowance" value="Weight1" ><br>';
echo '</div><br>';
echo '<div data-name="sup-input-date[]">';
echo '<label for="servicestartdate">Service Start Date:</label><br>';
echo '<input type="date" id="servicestartdate" class="sup-required"><br>';
echo '</div><br>';
echo '<div data-name="sup-checkbox[]">';
echo '<label for="routenumberAln1">Route Number:</label><br>';
echo '<input type="checkbox" id="routenumberAln1" value="Aln1" >Aln1<br>';
echo '</div><br>';
echo '<div data-name="sup-input-costs[]">';
echo '<label for="supplierpriceperlift">Supplier Price Per Lift:</label><br>';
echo '<input type="text" id="supplierpriceperlift" value="£16.75"><br>';
echo '</div><br>';
}
echo '<div name="submit" class="button btnAction" onClick="sendSupplierForm();">Send Email</div>';
jQuery:
function sendSupplierForm() {
let values = [];
$("div[data-name='sup-checkbox-title[]'], div[data-name='sup-input[]'], div[data-name='sup-input-date[]'], div[data-name='sup-checkbox[]'], div[data-name='sup-input-costs[]']").each(function() {
const label = $(this).find('label');
const checkbox = $(this).find('input[type="checkbox"]');
const input = $(this).find('input[type="text"]');
const date = $(this).find('input[type="date"]');
if (checkbox.is(":checked")) {
values.push(label.html(), checkbox.val());
}
if (input.val()) {
values.push(label.html(), input.val());
}
if (date.val()) {
values.push(label.html(), date.val());
}
});
var data = {
servicelist: values,
};
jQuery.ajax({
url: "email.php",
data: data,
dataType:'text',
type: "POST",
success:function(data){
$("#EmailStatus").html(data);
},
error:function (){}
});
}
email.php
$mailto = "info#******.com";
$subject = "Test";
$headers = "From: info#******.com\nMIME-Version: 1.0\nContent-Type: text/html; charset=utf-8\n";
$serviceinfo = implode("<br>",array_map(function($i){
return implode(" ",$i);
},array_chunk($_POST['servicelist'],2)));
$message = "
<html>
<head>
<title>Form Details</title>
</head>
<body>
<p>" . $serviceinfo . "</p>
</body>
</html>
";
// PHP MAILER FUNCTION
$result1 = mail($mailto, $subject, $message, $headers);
// PHP MAILER MESSAGE
if ($result1) {
print "<div id='EmailStatusSuccess'>SUCCESS!!! The details have been sent.</div><br>";
} else {
print "<div id='EmailStatusFail'>ERROR... Sorry there is a problem sending the details. Please check and retry.</div><br>";
}
-----------------------------------------
EDIT: SOLUTION
-----------------------------------------
Thanks to the answer from #knetsi, I was able to create the following code which fixed my issue. Basically the code looks for a div with the class of ".service-row-items" and then looks for all checkboxes named "servicelist[]". All labels & inputs (text, date, checkbox etc) are then gathered and used in the array.
let values = [];
$(".service-row-items").each(function() {
const checkboxtitle = $(this).find('input[name="servicelist[]"]');
if (!checkboxtitle.is(":checked")) {
return;
}
$(this).find("span").each(function(){
const label = $(this).find('label');
const checkbox = $(this).find('input[type="checkbox"]');
const input = $(this).find('input[type="text"]');
const date = $(this).find('input[type="date"]');
const number = $(this).find('input[type="number"]');
const textarea = $(this).find('textarea');
if (checkbox.is(":checked")) {
values.push(label.html(), checkbox.val());
}
if (input.val()) {
values.push(label.html(), input.val());
}
if (date.val()) {
values.push(label.html(), date.val());
}
if (number.val()) {
values.push(label.html(), number.val());
}
if (textarea.val()) {
values.push(label.html(), textarea.val());
}
});
})
I would suggest having unique IDs for your inputs. But with small adaptation to your code you can achieve what you want. Even though would be nice to know what your end goal is so we could guide you to a better solution.
to begin with you can wrap each group of inputs under a single <div> let's call it <div class='row-item'>
foreach ( $order->get_items() as $item_id => $item ) {
echo '<div class="row-item">';
.... // rest of the code
echo '</div>';
}
then you could use a similar to this jQuery code
let values = [];
$(".row-item").each(function() {
const checkbox = $(this).find('input[type="checkbox"]');
if (!checkbox.is(":checked")) {
return;
}
$(this).find("div").each(function(){
const val = $(this).find("input").val();
if (!val){
return;
}
values.push($(this).find("label").html(), val);
});
what does this code do?
It loops through the newly added div then find the checkbox in that div and skips the processing if the checkbox is not checked.
Then I noticed that what you tried to do is to basically push in an array the combination of label and value. So you could simply go through each <div> element under the .row-item and add the label and val combinations.
I also created a small example for you in JSFiddle that has hardcoded the HTML instead of the PHP code.
https://jsfiddle.net/yjLqseax/5/
You must utilize the unique id of each item.
Below is the code (I used test data):
<?php
$data = array(
1 => array(
'name' => 'Jack'
),
2 => array(
'name' => 'John'
),
3 => array(
'name' => 'Josh'
),
);
foreach ( $data as $item_id => $item ) {
echo "-----------------------------------------------------------------";
// set the id of this item
echo '<div data-name="sup-checkbox-ids[]">';
echo '<input type="hidden" name="item_id" value="'.$item_id.'" >';
echo '</div>';
// Main checkbox to check if selected
echo '<div data-name="sup-checkbox-title[]">';
echo '<label for="servicetitle">Service:</label><br>';
echo '<input type="checkbox" id="servicetitle_'.$item_id.'" data-name="servicetitle[]" value="' . $item['name'] . '"><span>' . $item['name'] .'</span><br>';
echo '</div><br>';
// Sub checkboxes and input fields to include in array if above checkbox checked
echo '<div data-name="sup-input[]"><br>';
echo '<label for="weightallowance">Weight Allowance Per Bin:</label><br>';
echo '<input type="text" id="weightallowance" value="Weight1" ><br>';
echo '</div><br>';
echo '<div data-name="sup-input-date[]">';
echo '<label for="servicestartdate">Service Start Date:</label><br>';
echo '<input type="date" id="servicestartdate" class="sup-required"><br>';
echo '</div><br>';
echo '<div data-name="sup-checkbox[]">';
echo '<label for="routenumberAln1">Route Number:</label><br>';
echo '<input type="checkbox" id="routenumberAln1" value="Aln1" >Aln1<br>';
echo '</div><br>';
echo '<div data-name="sup-input-costs[]">';
echo '<label for="supplierpriceperlift">Supplier Price Per Lift:</label><br>';
echo '<input type="text" id="supplierpriceperlift" value="£16.75"><br>';
echo '</div><br>';
}
?>
<button id="select_values">Select values<button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
let values = [];
$("#select_values").click(function(){
var current_id = 0
$("div[data-name='sup-checkbox-ids[]'], div[data-name='sup-checkbox-title[]'], div[data-name='sup-input[]'], div[data-name='sup-input-date[]'], div[data-name='sup-checkbox[]'], div[data-name='sup-input-costs[]']").each(function() {
const id = $(this).find('input[name="item_id"]');
const label = $(this).find('label');
const checkbox = $(this).find('input[type="checkbox"]');
const input = $(this).find('input[type="text"]');
const date = $(this).find('input[type="date"]');
if(id.val()){
console.log('Current id is:'+id.val());
current_id = id.val();
}
if($('#servicetitle_'+current_id).is(':checked')){
if (checkbox.is(":checked")) {
values.push(label.html(), checkbox.val());
}
if (input.val()) {
values.push(label.html(), input.val());
}
if (date.val()) {
values.push(label.html(), date.val());
}
}
});
console.log(values); // Print the selected values, based upon the checkbox
values = []; // empty values
})
</script>
I hope it helps.
The code I have posted below shows a child row when you click on the value inside of a row, in this example with colindex of 2.
I was wondering what way I could make the same thing happen but when you click anywhere on the row. I am not sure on how to do this. The way I am creating my table is by using tablesorter and a php query. The display of the table works fine, I am just having issues finding documentation on displaying the child row when a row is clicked not the value.
My PHP:
<?php
foreach($report_tabs as $report) {
$tag=$report["tag"];
$title=$report["title"];
$hcols=$report["hdrcols"];
$cols=$report["datacols"];
$db_query=$report["dbquery"];
echo "<div id='my_test_table_tab' class='tab-pane active'>";
echo "<table id='test_table' class='table table-hover tablesorter'>";
echo "<thead>";
echo "<tr>";
// removed the hard coded column headers and took the ones from our query
global $hcols;
foreach($hcols as $column_header) {
echo "<th>$column_header</th>";
}
echo "</tr>";
echo "</thead>";
echo "<tbody>";
//Use queried data to create each row of the table
$rowcount=0;
//Creating checker health table & filling with data
if ( isset($db_query)) {
while($row = mysqli_fetch_array($db_query)) {
$rowcount++;
// removed the hard coded column set and made it driven off of the array below
echo "<tr>";
$colindex = 0;
foreach( $cols as $column_name ) {
$val = $row[$column_name];
if ($colindex == 2) {
echo "<td style='text-align: left; width: 1pt;'><a href='#' class='toggle' onClick='drawChart(\"$val\");'>$val</a></td>";
$tempval = $val;
} else {
echo "<td style='width:100pt; text-align='right'>$val</td>";
}
$colindex++;
}
echo "</tr>";
echo "<tr class='tablesorter-childRow'>";
echo "<td colspan='3'>";
echo "<div id='$tempval' style='height: 400px;'></div>";
echo "<div id='fail$tempval' style='height: 400px;'></div>";
echo "</td>";
echo "</tr>";
}
}
echo "</tbody>";
echo "</table>";
echo "<h4>$rowcount rows retrieved</h4>";
echo "</div>";
}
?>
My TableSorter function to open based on value click:
<script>
// Table Sorter Options
$(document).ready(function(){
// Turns all tables with the 'tablesorter' class into tablesorter tables with the given widgets
$(".tablesorter").tablesorter({
// stickyHeaders - Keeps headers always visible when scrolling down
// filter - Adds filter boxes to each column
cssChildRow : "tablesorter-childRow",
widgets: ['stickyHeaders','filter'],
widgetOptions: {
stickyHeaders_offset : 50,
filter_placeholder : {search : ''},
filter_saveFilters: true,
pager_output: '{startRow} - {endRow} / {filteredRows} ({totalRows})',
pager_removeRows: false,
filter_childRows : true,
filter_cssFilter : 'tablesorter-filter',
filter_startsWith : false,
filter_ignoreCase : true
},
});
// Clear buttons
add_clear_buttons();
var table = $( '#my_test_table_tab' );
// hide child rows
table.find( '.tablesorter-childRow td' ).addClass( 'hidden' );
// Toggle child row content (td), not hiding the row since we are using rowspan
table.delegate( '.toggle', 'click' ,function() {
// use "nextUntil" to toggle multiple child rows
// toggle table cells instead of the row
$( this )
.closest( 'tr' )
.nextUntil( 'tr.tablesorter-hasChildRow' )
.find( 'td' )
.toggleClass( 'hidden' );
return false;
});
// Toggle filter_childRows option
$( 'button.toggle-combined' ).click( function() {
var widget_options = table[0].config.widgetOptions,
options = !widget_options.filter_childRows;
widget_options.filter_childRows = options;
$( '.state1' ).html( options.toString() );
// update filter; include false parameter to force a new search
table.trigger( 'search', false );
return false;
});
});
</script>
All you'd need to do is change the delegate function (why are you using such an old version of jQuery?), to point to the row instead of the link.
table.delegate( '.tablesorter-hasChildRow', 'click' ,function() {
I set up this demo, which is using a newer version of jQuery - the delegate function has been deprecated, so use on instead:
$table.on('click', '.tablesorter-hasChildRow', function() {
I have used the following php+mysql code to generate a list of check boxes which are having names of employees and their employee ID as value of that particular check box.
<?php
while($row = mysqli_fetch_array($run_qry))
{
echo "<input type='checkbox' name='emply[]'
value='91".$row['empid']."'>".$row['fname']." ".$row['lname'];
echo "<br>";
}
?>
with this code segment, I'm getting list of employees, now I want a search box above this list for search through the generated list, so I can easily select particular employee.
Help me with this issue.
Thanks in advance.
Well, to solve this at client-side, you need a JS solution.
Just substitite the array example by the result set from BD.
<script>
// the function searches in elements with class 'class_searh' the string 'string_searh'
function search(class_searh, string_searh) {
//get elements
var class_searh_elements = document.getElementsByClassName(class_searh);
//get string
var string = string_searh.toString();
//loop for each element
for (var i = 0; class_searh_elements.length > i; i++) {
//get the data on child element on 'class_searh_elements'
var text_data = class_searh_elements[i].childNodes[0].data;
//if maches add the class wich hides the element
if (text_data.search(string) < 0) {
class_searh_elements[i].classList.add('hidden');
//if don't maches remove the class wich hides the element
} else {
class_searh_elements[i].classList.remove('hidden');
}
}
}
</script>
<!--class that hides -->
<style>
.hidden { display: none; }
</style>
<?php
//array example
$run_qry = [
['empid' => 1, 'fname' => 'john', 'lname' => 'john'],
['empid' => 2, 'fname' => 'mary', 'lname' => 'anne'],
['empid' => 3, 'fname' => 'mc', 'lname' => 'donalds'],
];
echo "<input type='text' name='string_seach' id='string_search' value='' onkeydown='search(\"elements_class\",this.value)' /> <hr>";
foreach ($run_qry as $row) {
echo "<label class='elements_class'>" . $row['fname'] . " " . $row['lname'] . "<input type='checkbox' name='emply[]' value='91" . $row['empid'] . "' /><br></label>";
}
?>
I have a new question about a project I had been working on. I was designing a grid with different colored cells. it has a hidden div which shows when a cell is clicked, however I realized that only one cell(the last one of it's type) will show. i.e. if I have 2 objects with the column "objaffinity" as 0 ("enemy") it will show both red cells on the grid, however only the last one will actually work.
how can I make it so that it will show the proper information for each cell?
here's my code:
mapgen.php:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="cellinfo.js"></script>
<script src="cmenu.js"></script>
<?php
require("sql.php");
$sql = <<<SQL
SELECT *
FROM `maps`
WHERE `objpresent` = 1
SQL;
if(!$result = $db->query($sql)){
die('There was an error running the query [' . $db->error . ']');
} // ran the query
//$xobj = array();
//$yobj = array();
$otype = array();
$oname = array();
$xyobj = array();
while($row = $result->fetch_assoc()){
$xyobj[$row['x']][$row['y']] = true;
$otype[$row['id']]=$row['objaffinity'];
$oname[$row['id']]=$row['object'];
}
// get the rows
$cellid=1;
//find whether the row is obstructed
for ($y = 0; $y < 20; $y++) {
echo '<tr>';
for ($x = 0; $x < 25; $x++) {
echo "<td>";
//Detect what type of object it is
if (isset($xyobj[$x][$y])) {
if($otype[$cellid] == 2)
{
echo "<a href='#'> <div class='foe'> </div><div class='foepopup'>";
echo $oname[$cellid];
echo "</div></a>";
}
elseif($otype[$cellid] == 1)
{
echo "<a href='#'><div class='friend'></div><div class='friendpopup'>";
echo $oname[$cellid];
echo "</div></a>";
}
else
{
echo "<a href='#'> <div class='neutral'></div><div class='neutralpopup'>";
echo $oname[$cellid];
echo "</div></a>";
}
$cellid++;
}
echo '</td>';
}
echo '</tr>';
}
?>
Cellinfo.js:
$(document).ready(function(){
//initially hide all popups
$(".foepopup").hide();
$(".neutralpopup").hide();
$(".friendpopup").hide();
//foebutton selected
$(".foe").on("click",function(e){
$(".friendpopup").hide();
$(".neutralpopup").hide();
$(".foepopup").show();
});
//close foe when selected
$(".foepopup").on("click",function(e){
$(".foepopup").hide();
});
//neutral button pressed
$(".neutral").on("click",function(e){
$(".foepopup").hide();
$(".friendpopup").hide();
$(".neutralpopup").show();
});
//close neutral
$(".neutralpopup").on("click",function(e){
$(".neutralpopup").hide();
});
//friend button pressed
$(".friend").on("click",function(e){
$(".foepopup").hide();
$(".neutralpopup").hide();
$(".friendpopup").show();
});
//close friend
$(".friendpopup").on("click",function(e){
$(".friendpopup").hide();
});
});
In your functions you use selectors, so for the script it does not matter which div was clicked.
Let me show you some examples:
$(".foepopup").on("click",function(e){
$(".foepopup").hide();
});
It should be something like this rather:
$(".foepopup").on("click",function(e){
$(this).hide();
});
And another example:
$(".neutral").on("click",function(e){
$(".foepopup").hide();
$(".friendpopup").hide();
$(".neutralpopup").show();
});
Rewrite it like this:
$(".neutral").on("click",function(e){
var td_tag = $(this).parent().parent();
td_tag.children(".foepopup").hide();
td_tag.children(".friendpopup").hide();
td_tag.children(".neutralpopup").show();
});
Rewrite other code on your own. this is the element on which click was triggered. td_tag will contain parent cell of a div clicked. After that, children method will allow you to find needed elements already inside specific cell.
Good luck!
Basically by clicking the "comment" link the last result of the query should show and by clicking again it should be hidden. I have tried Rocket's code as well but I get an error message in the bottom of the browser and when I click "comments" it just takes me to the top of the page. I would apprieciate some advice on this
$i = 1; // ID Counter
while($row = mysql_fetch_array($result))
{
echo "<h1>$row[title]</h1>";
echo "<p class ='second'>$row[blog_content]</p> ";
echo "<p class='meta'>Posted by .... • $row[date] • Comments<div id='something$i' style='display: none;'>$row[comment]</div>";
$i++; // Increment counter
}
This is a loop, echoing the same thing over and over, thus making all the divs have the same ID, something2.
IDs need to be unique, you gonna have to make unique IDs for each div.
Something like: <div id='something$i' style='display: none;'> (remembering to increment $i).
Also, you're gonna to escape the quotes in your onclick attribute.
<a href='#' onclick=\"toggle_visibility('something$i');\">
The code should look something like this:
$i = 1; // ID Counter
while($row = mysql_fetch_array($result))
{
echo "<h1>$row[title]</h1>";
echo "<p class ='second'>$row[blog_content]</p> ";
echo "<p class='meta'>Posted by .... • $row[date] • Comments<div id='something$i' style='display: none;'>$row[comment]</div>";
$i++; // Increment counter
}
Escape the quotes :
$blah = "onclick='toggle_visibility(\"something2\");'>Comments</a>"
There is an easier way to hiding / showing the next sibling ....
try this
<div style="display:none">some hidden content</div>
function toggle(el,ev) {
ev.preventDefault(); // prevent the link from being followed
el = next(el); // get the next element
if (el.style.display == "none") { // toggle the display
el.style.display = "block";
} else {
el.style.display = "none";
}
}
/*
Credit to John Resig for this function
taken from Pro JavaScript techniques
*/
function next(elem) {
do {
elem = elem.nextSibling;
} while (elem && elem.nodeType != 1);
return elem;
}
Working example
You can throw in a counter into your code as the while loop is executing to dynamically generate unique id's for each comment div. Or, you can pull a unique field out of the query result for the id's, as long as you hook up to it appropriately later if it ends up being used and remain consistent in the rest of the code.
either
$count = count($result);
...
while (...){
$count--;
echo '... id="something'. $count .'" ...'
}
or...
while (...){
echo '... id="something'. $row['ID'] .'" ...'
}