Bootstrap Modal - How to provide data from php (database) - javascript

This is probably very simple, but am learning PHP, Javascript as I go. I find it easier to learn using real examples than the contrived examples given online.
I am creating an attendance register page, based on selecting a class, then all members of that class ordered by Surname and Firstname.
The table row has it's id set, by PHP, as the record's mem_id, and contains just forename+" "+surname, and some checkboxes.
All this is working fine, but now I have been asked to add a link so that clicking on it brings up a modal containing related data for the person selected. The extra data is already in the $a_fetch array.
Have added a glyphicon link for every row and clicking it displays a modal alright, and by having a javascript function I know I can get the row index and row id
<tbody>
<?php
while($g_fetch = $a_query->fetch_array()) {
$checked = array();
$memid = $g_fetch['mem_id'];
$name = $g_fetch['firstname'].' '.$g_fetch['lastname'];
$attendences = explode(",",$g_fetch['attend']);
for ($x = 0; $x <= 12; $x++) {
if ($attendences[$x]!="0") {
$checked[$x] = 'checked = "checked"';
}
else $checked[$x] = '';
}
echo "<tr id='".$memid."'>";
echo "<td>".$name."</td>";
echo "<td align='center'><div id='".$memid."' class='glyphicon glyphicon-info-sign' onclick='getId(this.id)' style='cursor:pointer' data-toggle='modal' data-target='#ModalCentre'></div>";
for ($y = 0; $y <= 12; $y++) {
echo '<td align="center"><input type="checkbox" value = "" '.$checked[$y].'></td>';
}
}
unset($checked);
unset($attendences);
?>
</tbody>
</table>
I am at a loss as how to proceed - is it even possible to pass data to the modal to display related data?
If it is would I need to run a new query (SELECT), or as the row is the same index as the data in the $A_fetch, and the row id has the correct mem_id is it possible to get the data from the existing $a_fetch array using either of those, or would I need to run a new SELECT?
Many thanks

There are multiple ways to provide data to the modal - and (in my opinion) it depends on how much data you need to pass to your modal and how many rows you have.
I want to describe you two ways:
Light+Easier Solution
If you don't want to display a lot of data and you have just a few rows.
The idea is to add the data directly to each div.glyphicon (as data attributes) and then use it in the modal
In your foreach add it to your model like that:
<div id='".$memid."' class='glyphicon glyphicon-info-sign' onclick='getId(this.id)' style='cursor:pointer' data-toggle='modal' data-target='#ModalCentre' data-link='".$g_fetch['additional_link'] ."' data-moreInfo='".$g_fetch['moreInfo']."'></div>
You haven't posted the modal's HTML or your JS code, but you wrote you are using bootstrap, so stick to
https://getbootstrap.com/docs/4.0/components/modal/#varying-modal-content
and fetch/set the relevant data (related clicked glyphicon) as it's described.
More complex solution
For more data / more rows. The additional data is not provided in the inital loaded HTML page - Therefore not all data needs to be loaded in the beginning.
Instead the additional data is loaded via ajax when clicking on one row.
For that you need to provide an additional endpoint (php) which provides the modal content for one row.
Check out second answer in Bootstrap 3 - How to load content in modal body via AJAX?
Basically you have a php file (e.g. getAdditionalData.php)
In this file you access the mem_id via GET
$mem_id = $_GET['mem_id'];
fetch the additional data from database
and print/render out the modal content (full html like in the second answer)
And in JS (inital page) you load the modal content onClick (fetched from php with provided mem_id as parameter)
var clicked = $(e.relatedTarget);
$(this).find(".modal-body").load("%PATH%/getAdditionalData.php?mem_id="+clicked.attr("id"));
I hope it will help you solving your problem and if you need additional infos just let me know. There are more ways to archive your goal but I think this 2 possibilities are enough in the beginning :-)

Related

How to pull a PHP echoed button's text into Javascript, whose value will be used in another PHP Sql query?

I have a PHP sql query that returns a table.
while($row = $result->fetch_assoc()) {
echo "<tr><td id=\"cst\"><button type=\"submit\" id=\"click\" onClick=sendData(this)>".$row["Name"]</button></td></tr>";
The table is output correctly. My next step is using vanilla Javascript to pull the HTML text value associated with $row["Name"] from the button in the output table (when the button is clicked). I call the function onClick=sendData(this)
Now, in Javascript I'm attempting to access the text value like so:
function sendData(name) {
var text = name.innerText;
}
However, this isn't working. Can anyone explain why?
There are multiple problem with how you are using both PHP and JavaScript here to solve this problem.
Let me break them down, and how best we can solve them.
Your ID's are the same : When you're iterating through the rows in your table, you're not setting a unique id for them. This means if you try to reference them later on in any capacity via JavaScript you won't be able to. Instead, you can change this to something like, <td id=\"cst_$row['row_id']\".
Your PHP is prone to SQL Injection : The method you're using to query your database is most likely prone to SQL Injection based on how I see you are returning your values. You'd be best to read up on Prepared Statements and PDO.
You don't have quotation marks around your onclick : because you haven't wrapped your function in quotation marks, it actually won't even be sending correctly. However, there is a better solution anyway. Remove the on-click from your button, and add an event listener.
Your button type is of submit : because you've set your button type to submit, the default behavior is to refresh the page. If you want to keep this, you'd have to specify not to use the default behavior, or simply change the button type, to button.
To solve all of these issues (except SQL Injection because this would require more information than was provided), your code could be changed to the following :
PHP :
while($row = $result->fetch_assoc()) {
echo "<tr><td id=\"cst_$row['row_id']\"><button class=\"test_buttons\"type=\"button\" id=\"btn_$row['row_id']\"".$row["Name"]</button></td></tr>";
In the above example, "row_id" is your unique identifier in your database table. Change this to "id" or whatever you have called it in your table.
JavaScript :
window.onload = function() {
let buttons = document.getElementsByClassName("test_buttons"); // Get all buttons you want to search for
for (let i = 0; i < buttons.length; i++) {
buttons[i].addEventListener("click", function(event) { // On click of these buttons
event.preventDefault(); // This is required only if you want to keep the button type of submit
let text = this.textContent;
alert(text);
});
}
}
<td><button type="button" class="test_buttons">Test 1</button></td>
<td><button type="button" class="test_buttons">Test 2</button></td>
The yet another variant is to improve formatting of your HTML output by taking advantage of HEREDOC syntax that suits well for complex formatting
while($row = $result->fetch_assoc()) {
echo <<<HTML
<tr>
<td class="cst"> <!-- class instead `id` -->
<button
type="button" <!-- `button` type instead of `submit` -->
class="btn-click" <!-- class instead `id` -->
data-name="{$row["Name"]}">
{$row["Name"]}
</button>
</td>
</tr>
HTML;
And using vanilla JS it is possible to make smth. similar to the result snippet below.
document.addEventListener('click', function(event) {
var target = event.target;
// If the clicked element doesn't have the right selector, bail
if (!target.matches('.btn-click')) {
return;
}
var name = target.getAttribute('data-name');
alert('Button `data-name` is "' + name + '"');
// sendData logic goes further ...
}, false);
<tr>
<td class="cst">
<button type="submit" class="btn-click" data-name="Coockaracha">Reveal my name</button>
</td>
</tr>
The approach of using global click listener is called event delegation and has some advantages. You can read about it here.
Also keep in mind that id should be unique across the page, so it is not correct to iterate using id. class attribute suits nicely and allows multiples.

jQuery responds with html table containing a (form in each row plus jquery code to edit each row) newly created forms ignore submit()

Three days and I cannot find an answer to this or a solution. I am far from being a jQuery guy.
User arrives at a php page that shows a form to choose the language code and submit. Form gets submitted and the jQuery response builds a table in a div container in the original page. So far so good. The resulting table contains hundreds of rows where the language variables can be edited. On clicking the edit button, I get nothing, no errors in console, nothing. If I use on click, I can fire an alert. On submit, bind, and many others do not work.
I am attempting to load the table, perform basic editing, submit the edits to the db, and refresh the div.table.row with the edited results. I have not gotten to the part where I refresh the rows with the edited data, still stuck trying to submit the dynamic form in each row.
One interesting thing that happens when I use on click, it works with just the first button I click on, it somehow disables all the other rows. I need to be able to submit a row for changes, have that row refresh and move on to the next row all without redirecting. Is this too much to ask? Or should I just move them from page to page?
The ajax php page returns the table using the following code:
if(!empty($_POST['edit_language']) && $_POST['edit_language'] == 1){
edit_language($_POST['lang']); //call function to edit language
} else {
echo "You got here but no variables<br>"; //testing
print_r($_POST); //testing
}
function edit_language($lang){
//query table to get language vars list
$sql = "SELECT lang_site.lid, lang_codes.iso_code, lang_codes.`language`, lang_varnames.varid, lang_varnames.varname, lang_site.varval FROM lang_codes LEFT JOIN lang_site ON lang_site.langid = lang_codes.langid LEFT JOIN lang_varnames ON lang_site.varid = lang_varnames.varid where lang_codes.iso_code = '" . $lang . "'";
$result = db_query($sql);
//generate report table
echo "<table cellspacing='0' border='1'><tr><th>Count</th><th>Language</th><th>Variable Id</th><th>Variable Name</th><th>Variable Value</th><th>Edit</th></tr>";
$a=1; //count the rows to number the rows for easy viewing
while($data = db_fetch_assoc($result)){
//create form in each tr
echo "<form name='edit_" . $data['lid'] . "' id='edit_" . $data['lid'] . "' action=''><tr><td>" . $a++ . "</td><td>" . $data['language'] . "</td><td>" . $data['varid'] . "</td><td>" . $data['varname'] . "</td><td><textarea class='form-control' name='varval' id='varval' cols='100' wrap='virtual'>" . $data['varval'] . "</textarea></td><td id='editresponse'><button type='submit' class='button' type='submit' id='but_" . $data['lid'] . "'>Edit</button></td></tr></form>";
?>
//jquery to post edits
<script language="javascript">
$(document).ready(function()
{ //using $.ajax() function
//alert("document ready"); //this alerts each row
//this function will not work, no errors, simply nothing
$(document).on("submit", "#edit_<?php echo $data["lid"]; ?>", function(e)
{
//alert("button clicked"); //this does not work
var data = $("#edit_<?php echo $data["lid"]; ?>").serialize();
$.ajax({
type : "POST",
url : "/lang/ajax_langs.php",
data : data,
success : function(response)
{
{
$("#editresponse").html(response);
};
}
});
e.preventDefault();
});
});
</script>
<?php
}
echo "</table>";
}
?>
How do I get the jQuery to submit the individual form in each row to effect an edit and then refresh each row individually as languages are edited? I need to add another form to each row to delete an entry then remove the row dynamically, but I am stuck here without being able to submit any of these forms.
I should add that this generated form shows well in the website, but is not shown in view source. Using chrome browser. I'm open to any suggestions. Thanks in advance for reading. I seriously hope I can find a solution here. Otherwise, I'm back to the 90's on this software.
It's not working because you are only submitting one id. You need to make each of your forms be of the same class. Therefore, any form clicked will be processed. Like
<form class="myForm" .....
Then, the Jquery would look like this
$(".myForm").submit(function(e){
var inputToChange = this.varval; // saw input varVal, but use whatev
var dataToChange = inputToChange.value;
// then send the data to php for processing using ajax or post
Then, use inputToChange.value = whatever new value you want to put into the form input or other div/td etc. you want to change. If you want to change data that isn't in an input, just make that td a text input and disable it from being edited by the client
<input type="text" name="lname" disabled>
then on callback send new data to this.lname.value = (many other ways to do this as well)
Don't forget, if you send through ajax you want to stop the form itself from submitting so use e.preventDefault()

How to dynamically generate a link with query

Hi fellow developers,
I want to integrate affiliate program for my website, to earn commissions from bookings made via my links.
Since, I have those properties on my site as well, I need a user to be able to click "book it" and get redirected to a page on booking.com with that particular place highlighted.
So the link has this params, which I need:
http://www.booking.com/searchresults.html?city=-2900142&aid=814610&checkin_monthday=25&checkin_month=3&checkin_year=2017&checkout_monthday=30&checkout_month=3&checkout_year=2017&no_rooms=1&group_adults=1&highlighted_hotels=2197459
City = I have custom field for it,so wordpress can pick it with
get_post_meta(CityID)
Highlighted_hotels = makes this particular object highlighted if it's available, also I have it in custom field, so I can take it with
get_post_meta(HotelID)
But how do I take date values from dropdowns? And how do I make a link afterwards? with
<?php echo '<a href="http://www.booking.com/searchresults.html?';
echo $city;
echo $highlighted;
echo $dates;
Is this a correct method to create a link on wordpress?
Btw, I'm using an official booking.com plugin right now, but it's broken and doesn't fill my needs, I want to change it with above custom code, but you can take a look at what I want to achieve on my site here for example (russian language) :
http://sochi.asp.sale/nedvizhimost/chvizhepse/posutochno/kompleks-zolotoj-kashtan/
Form is on the right side bottom.
Any help much appreciated!
Use Javascript to take the values from the dropdown like so:
var e = document.getElementById("DROPDOWN_NAME");
var strUser = e.options[e.selectedIndex].text;
Now to build a URL just use the variable created called strUser.
var url = "http://www.booking.com/searchresults.html?" + strUser;
I hope that is clear and helps.
EDIT:
If you want to use php to build the link, append the values to the url variable:
<?php echo '<a href="http://www.booking.com/searchresults.html?' . $city . '&' . $highlighted . '&' . $dates;
That will echo the completed url with all the variables added onto the end of it.

How to update a table without changing the onscreen data displayed

I need to display a simple list of hundreds of items which are on a MySQL table, review the list onscreen and click on a link beside each unwanted item to delete it from the table. This is an internal management procedure; no outside user is involved. I do not need the item to disappear from the list immediately; I will refresh the list periodically so items deleted from the table are no longer listed. I do not need any message to confirm that the item has been deleted. The important thing is that I don't want to lose sight of the list each time I delete an item and have to click on a "go back" button to return to the list.
The table uses MySQL. All my coding to date has been in PHP. So I am using php to display the list of items, on a non-html screen. This is the code for each item:
echo $item." <a href='item_delete.php?id=".$item."'>Delete item</a><br />";
This is the code for item_delete.php:
<?php
require ('connect.php'); // To define connection $con
$id = $_POST['id'];
mysqli_query($con, "DELETE FROM `items_table` WHERE `id` = $id");
?>
The item is deleted correctly but a blank screen is (understandably) displayed.
I have done a lot of searching but most people needing help want to do more advanced things and - because I have so far managed to avoid learning JavaScript, jQuery and AJAX - I can't even work out which of those technologies I need to update a table without changing the screen.
I get the impression that each PHP script always takes "focus" with it, so maybe I need a little JavaScript script to do this ?
If so:
- can I just change item_delete.php to item_delete.js or do I have to define the non-html list as an html one ?
- what js code is needed in item_delete.js ?
I have read about using: header("location:javascript://history.go(-1)");
or: header('Location: ' . $_SERVER['HTTP_REFERER']);
but they don't go back to the onscreen list.
I don't think I want the js script to perform a virtual "go back" because the list is originally produced by using (about 20) $_POST parameters, so I still seem to have to refresh it each time.
So I'd like a solution to remain with the list - rather than leave it and return to it. Thanks.
It would make a lot of sense to do the deletion asynchronously using javascript. However, the simplest and messiest way to achieve what you want, is to add target="_blank" to the links, (which will leave you with a open blank tab for each delete request you do).
echo $item." <a href='item_delete.php?id=".$item."' target='_blank'>Delete item</a><br />";
Or you can solve it by adding checkboxes in front of every item, check the items you want to delete and submit them as form parameters to the delete script.
If you want to delete to row in the onscreen table after the actual PHP code has run you can use the following implementation:
The HTML structure for the link requires a unique class name, such as:
echo 'Delete item'
Note the item id is stored inside a HTML5 data attribute. I have also added an onclick event handler which returns false to avoid the link refreshing the page.
The javascript used to delete the item use the JQuery AJAX method and binds to the specified class, which is: item-delete. The implementation requires Jquery version >= 1.9.0
(function(){
$('.item-delete').click(function(event) {
var target = $(event.target);
var id = target.data('item-id');
$.ajax({
url: 'item_delete.php',
method: 'POST',
data: {
id: id
},
}).done(function() {
target.remove();
}).error(function(err) {
console.error('Could not delete item with ID: ' + id);
console.error(err);
});
});
}())
The event listener is defined inside a self-executing function, which is automatically executed when the page-load completes and avoids poluting the global namespace.
You can delete the item directly on the same page without moving to another
page by passing the id through a hyperlink and then get it to finally delete
the unwanted item. CHECK THIS OUT, and please let me whether or not is what you
wanted :-)
// connection
mysql_connect("host", "user", "password");
mysql_select_db("your database name");
// select all the items from table.
$selectQuery = mysql_query("SELECT * FROM table_name" );
// use while loop to list all the items...
while( $row = mysql_fetch_array($selectQuery) )
{
// list the items as a hyperlink, passing their id through the URL.
?>
<?php echo "delete " . $row["item_name"]; ?>
<?php
}
// Below is the code to delete the item.
if( isset( $_GET["id"] ) )
{
$itemId = $_GET["id"];
// query to delete item
$deleteQuery = mysql_query("DELETE FROM table_name WHERE id = '$itemId' ");
//-----------THE MOST IMPORTANT PART. >>>
// redirect if delete is successfull.
if( $deleteQuery )
{
// reload the page to get the items minus the deleted one...
// let's say your sript name is delete.php
header("Location:delete.php");
}
}
?>
</code>

PHP multiple records insert

I am attempting to reword my issue.
I have a datatable that can return thousands of records, each with multiple columns. There is a checkbox in the first column that, once the user checks it, they then click a button, and the CONTAINER_NUMBER that is associated with the row is sent to a modal window to be used in a form.
Here is the code for the checkbox:
echo "<tr><td><input type=\"checkbox\" id=\"{$Row[CONTAINER_NUMBER]}\" name=\"checkMr[]\" /></td>";
This is the javascript that retrieves the CONTAINER_NUMBER and sends it to the modal window:
<script type="text/javascript">
$(function()
{
$('a').click(function()
{
var selectedID = [];
$(':checkbox[name="checkMr[]"]:checked').each(function()
{
selectedID.push($(this).attr('id'))
});
$(".modal-body .containerNumber").val( selectedID );
});
});
</script>
This is the section of the modal window that displays the CONTAINER_NUMBER:
<div class="modal-body">
<form action="" method="POST" id="serviceModalForm" name="serviceModalForm">
<input type="text" name="containerNumber" id="containerNumber" class="containerNumber">
Here is the section of PHP that takes the id="containerNumber" and converts it to a PHP variable. After that, there is an INSERT statement that inserts the containerNumber into a database table:
<?php
$container = $_POST['containerNumber'];
if(isset($_POST['submit'])){
$container = mysql_real_escapse_string(stripslashes($container));
$sql = "INSERT INTO myTable (container_num) VALUES ('$container')";
if(mysql_query($sql)){
echo "Insert complete";
}
else {
echo "Insert was not completed";
}
?>
This code is fine. It works good. It does what it's supposed to do...for when the user checks ONE checkbox. It DOES NOT work when the user checks multiple checkboxes.
Basically, from what I've been researching is that I need to separate the records from the variable $container, as there can be multiple containers in that variable, which is why the query does not work when there are more than one container numbers selected.
I need to be able to separate the container numbers and store them in an array or something. The query will read each record separately and generate multiple INSERT statements for each record.
I've tried several times to create an array and get the sql statement to recognize it, but have been unsuccessful. I'm not sure if I'm placing the array in the right place. I'm not sure if this has to be done in the javascript before the container gets sent to the modal window.
I know I need to utilize a FOREACH loop to go through the array, but like I said, I'm not sure where the array needs to go in my code.
Please help. I know I need to learn PDO or MYSQLI. I will be sure to utilize PDO or MYSQLI on my next application. Until then, please help me with this issue.
Thank you, and sorry for so much wording.
Your containerNumber will be posted as a converted string from a js array. Something like id1, id2, id3[...]
In your php code, convert the $container back to an array ($containerArray = explode(",", $container)) and construct the sql dynamically to add all the rows in a single query so that the statment becomes something like
INSERT INTO myTable (container_num) VALUES ('$containerArray[0]'), ('$containerArray[1]')[...]

Categories

Resources