I have a web page that allows authorized users to update or delete rows in a MySQL table. The table has the columns id (INT), label (VARCHAR), details (VARCHAR), templateId (INT), and auditable (TINYINT, either 0 or 1). This table is displayed as HTML on the front end, with "Label", "Details", "Auditable?" and "Edit/Delete" columns showing.
Clicking the "Edit" button on a row, changing some data in the resulting Bootstrap modal form, and clicking "Save Changes" works fine. The problem occurs when I click "Edit", click "Cancel" on the form, and then click another row (say, for example, I accidentally clicked the wrong row). When I click the button to execute the edit on that newly clicked row, both that row and the initially clicked row will be affected. The Chrome console shows that two JavaScript objects are being sent via $.post(), though I cannot figure out why from the logic I wrote (see below). I looked in MySQL and the duplicate results are there, confirming the page accurately reflects the update. Is there some $.get or $.post cache behavior in jQuery I am not aware of? (This also occurs with the delete functionality, but I'm limiting the question for brevity's sake).
Main page (GUI):
// The 'edit this row' button that brings up the modal form
$(".edit-action").click(function() {
// Clear any previously set values in form
$("#editActionLabel").val('');
$("#editActionDetails").val('');
$(".radio-edit-action").prop("checked", false);
// All edit button id's in GUI table will be "edit-action-[`id` in database]"
// Grab number out of there and convert from string to number
var actionId = $(this).attr("id");
actionId = parseInt(actionId.slice(12));
// Grab data from database to populate fields
$.get("data.php?a=actionData&actionId=" + actionId, function(d) {
// Returning a JSON encoded array isn't working,
// so I'm sending back a comma-separated string instead
var response = d.split(",");
var label = response[0];
var details = response[1];
var auditable = parseInt(response[2]);
$("#editActionLabel").val(label);
$("#editActionDetails").val(details);
if (auditable == 1) {
$("#editAuditableNo").prop("checked", false);
$("#editAuditableYes").prop("checked", true);
} else if (auditable == 0) {
$("#editAuditableYes").prop("checked", false);
$("#editAuditableNo").prop("checked", true);
}
// Only reset `auditable` variable if selection was changed
$(".radio-edit-action").change(function() {
auditable = $(this).val();
auditable = parseInt(auditable);
});
// User clicks "Save Changes" instead of "Cancel"
$("#executeEdit").click(function() {
var label = $("#editActionLabel").val();
var details = $("#editActionDetails").val();
var obj = {
"operation": "edit",
"actionId": actionId,
"label": label,
"details": details,
"auditable": auditable
};
console.log("The object passed to 'edit' this row:");
console.log(obj);
$.post("data.php", obj, function(r) {
// Confirm success or failure to user
$("#crudResult").html(r);
});
}); // end click
});
}); // end 'edit action'
data.php (called via AJAX to execute the UPDATE in database. Only relevant code shown):
$debug = false;
$operation = $_POST['operation'];
$action_id = (isset($_POST['actionId']) ? $_POST['actionId'] : '');
$label = (isset($_POST['label']) ? $_POST['label'] : 'NULL');
$details = (isset($_POST['details']) ? $_POST['details'] : 'NULL');
$auditable = (isset($_POST['auditable']) ? $_POST['auditable'] : 'NULL');
switch ($operation) {
case 'edit':
$query = "
UPDATE actions
SET label='$label',
details='$details',
auditable=$auditable
WHERE id=$action_id
LIMIT 1";
// DB connection not shown. Yes, I know I should be using PDO...
$result = mysqli_query($db_conn, $query);
// PHP echoes out the result; let the calling JavaScript figure out where to place it
if ($result) {
echo '<p class="text-success">Action successfully updated!</p>';
} else {
echo '<p class="text-warning">There was an error and the action could not be edited.</p>';
// Don't show error to user in production, when $debug should be false
if ($debug) {
echo '<p><b>Error:</b> ' . mysqli_error($db_conn) . '</p>';
}
}
break;
/* case 'delete': ... */
}
The modal form, which follows Bootstrap's template HTML, is simply a collection of fields and a couple buttons (no <form> wrapped around it). Please let me know if I can clarify anything.
How many times is the request to server occurs? I Bet it is twice.
The problem is on the client side.
For each edit click you have made, a new save click function has been created.
You do not need to add this for every edit click, take it out from the edit click function.
Hope it helps.
Related
I have a page with several buttons whose values and names are retrieved from the database. I'm trying to run an insert query on any button clicked, my code so far:
<?php
$sqlGetIllness = "SELECT * FROM illnissesandconditions ";
$resultGetIllness = $conn->query($sqlGetIllness);
while ($rowGetIllness= mysqli_fetch_array($resultGetIllness)){
echo "<div class='col-md-3'style='margin-top:20px;'><button onclick='insert(".$rowGetIllness['illness'].");' class='button button1' style=' color:white;' value='".$rowGetIllness['illness']."'>".$rowGetIllness['illness']."</button></div>";
}
function insert($value) {
$value='';
$sqlGetId = "SELECT commonID from common group by commonID DESC LIMIT 1 ";
$resultGetId = $conn->query($sqlGetId);
$r=mysqli_fetch_array($resultGetId);
$id=$r['commonID'];
$sqlGetIllness = "INSERT INTO medicalrecords (CommonID,Medical_Condition) VALUES (".$id.",'".$value."')";
$resultGetIllness = $conn->query($sqlGetIllness);
}
The value passed to the function inside onclick is correct when I inspect it in the browser, however nothing happens. I have a database connection on already, what could be wrong? Is it possible to do it like that in php without refreshing the page? Or do I need to use a client side lang like AJAX? Please note that I've never worked in AJAX btw.
New EDIT:
<script>
$("button").click(function(e) {
e.preventDefault();
$.ajax({
type: "POST",
data: {
condition: $(this).val(), // < note use of 'this' here
},
success: function(result) {
alert('Condition Inserted!');
},
error: function(result) {
alert('error');
}
});
});
</script>
Solution:
I got it worked out, after writing the script, i retrieved the variable value on top of the page
if (isset($_POST['condition'])) {
$value=$_POST['condition']; }
inside $_SERVER['REQUEST_METHOD'] == 'POST' ) and now it inserts the value when ever any button is clicked, my next step is to give the clicked button a background color
Solution is in the post under Solution, was my first time trying ajax and it did work indeed, gave the button an id, and took its value ( any button clicked ) through this.val and sent via post, retrieved and used the value in a variable for the insert query.
I have used same form for adding and edtting data. Adding and Editting is done successfully and I am refreshing after editing and adding. But I need some solution which is below
My jquery code is below
$(".update_vehicle_info").click(function(){
var hdn_id = $(this).attr('data-hdn_id');
$("#vehicle_form_div").find("#hdn_id").val(hdn_id);
var post_url = "<?php echo base_url();?>index.php/spc_con/get_vehicle_info_data/" + hdn_id;
$('#hdn_id').empty();
$.getJSON(post_url, function(response){
document.getElementById('financial_year_id').value = response.financial_year_id;
document.getElementById('vehicle_id').value = response.vehicle_id;
document.getElementById('brand_id').value = response.brand_id;
document.getElementById('country_id').value = response.country_id;
document.getElementById('reg_no').value = response.reg_no;
document.getElementById('capacity').value = response.capacity;
document.getElementById('running').value = response.running;
document.getElementById('serviceable').value = response.serviceable;
document.getElementById('condemned').value = response.condemned;
});
$("#vehicle_form_div").dialog("open");
});
I have screen shoot which is below
If i click edit button, if i don't edit now and if click Add Vehicle Info then edit field value has stayed but
I need when i click edit and click cross without editing. Then Page will be refresh/reload which if i click Add Vehicle Info then every field Data won't stay it.
How to solve it, Please help me.
UPD:
give to each of your tr some unique id, for example <tr id="tr_pk_23">...</tr> where 23 is a primary key of the row in you databse.
<button onClick="showModalForm(this,23);">EDIT</button>
function showModalForm(button,id){
var $tr = $(button).closest('tr');
/*
* Send ajax request to your php script /myScript.php?id=23
* Find data in database by id, and generate modal form with php, send it back to browser append to body and show it to user.
*/
}
Update button in modal form must be an ajaxButton. So onClick should be assigned as function
<button onClick="saveDataAndUpdateRow(this,23);">UPDATE</button>
JavaScript:
function saveDataAndUpdateRow(button,id){
var $form = $(button).closest('form');
var data = $form.serialize();
/*
* Send data to another script, save your data in DB and generate a new <tr> with updated values
*/
var $new_tr = #ajaxresponse;
var $old_tr = $('#tr_pk_'+id);
$old_tr.after($new_tr);
$old_tr.remove();
}
Feel free to ask me any questions about this concept.
The attached picture shows the results page of the search engine that I'm building. For each return result, the user may click on the result (i.e. "Food Science") and it will expand out accordion-style to reveal information about that particular result.
I want to log each time the user clicks on a result (for learning/intelligence purposes) and store it in a database table that I have created which stores the session ID, the query, the position of the result, and the order in which the user clicked the item.
Using JQuery, I already have a function that will pull the title of the result that was clicked, and I have it set where I want to log the click, but I don't know how to do it since JQuery is client side and PHP is server side.
How can I use the JQuery to trigger a PHP function so that I can query the database to insert the click logs into my table?
Below is the JQuery function.
$(document).ready(function() {
$('.accordionButton').click(function(e) {
if($(this).next().is(':hidden') == true) {
$(this).addClass('on');
$(this).next().slideDown('normal');
$(this).next().slideDown(test_accordion);
// SEND CLICK ACTION TO LOG INTO THE DATABASE
alert($(this).find('h3:last').text()); // displays the title of the result that was just clicked
}
else {
$(this).removeClass('on');
$(this).next().slideUp('normal');
$(this).next().slideUp(test_accordion);
}
});
}
You can do something like this (untested):
Define a javascript variable to track the order of the clicks, outside your click function:
var order = 0;
Add this into your click function, at the bottom:
order++;
var sessionID = $("input[name='sessionID']").val(); // assuming you have sessionID as the value of a hidden input
var query = $("#query").text(); // if 'query' is the id of your searchbox
var pos = $(this).index() + 1; // might have to modify this to get correct index
$.post("logClick.php", {sessionID:sessionID, query:query, pos:pos, order:order});
In your php script called "logClick.php" (in the same directory):
<?php
// GET AJAX POSTED DATA
$str_sessionID = empty($_POST["sessionID"]) ? '' ; $_POST["sessionID"];
$str_query = empty($_POST["query"]) ? '' ; $_POST["query"];
$int_pos = empty($_POST["pos"]) ? 1 ; (int)$_POST["pos"];
$int_order = empty($_POST["order"]) ? 1 ; (int)$_POST["order"];
// CONNECT TO DATABASE
if ($str_sessionID && $str_query) {
require_once "dbconnect.php"; // include the commands used to connect to your database. Should define a variable $con as the mysql connection
// INSERT INTO MYSQL DATABASE TABLE CALLED 'click_logs'
$sql_query = "INSERT INTO click_logs (sessionID, query, pos, order) VALUES ('$str_sessionID', '$str_query', $int_pos, $int_order)";
$res = mysql_query($sql_query, $con);
if (!$res) die('Could not connect: ' . mysql_error());
else echo "Click was logged.";
}
else echo "No data found to log!";
?>
You can add a callback function as a third parameter for the $.post() ajax method if you want to see if errors occured in the script:
$.post("logClick.php", {sessionID:sessionID, query:query, pos:pos, order:order},
function(result) {
$('#result').html(result); // display script output into a div with id='result'
// or just alert(result);
})
);
EDIT: If you need the value of the order variable to persist between page loads because you paginated your results, then you can pas the value of this variable between pages using either GET or POST. You can then save the value in a hidden input and easily read it with jQuery. (Or you could also use cookies).
Example (put this in every results page):
<?php
$order = empty($_POST["order"]) ? $_POST["order"] : "0";
$html="<form id='form_session' action='' name='form_session' method='POST'>
<input type='hidden' name='order' value='$order'>
</form>\n";
echo $html;
?>
In your jQuery, just change var order = 0; to
var order = $("input[name='order']").val();
Then, when a user clicks on a page link, prevent the default link action, set the order value and the form action, and then submit the form using javascript/jQuery:
$("a.next_page").click(function(event) {
event.preventDefault();
var url = $(this).attr("href");
$("input[name='order']").val(order);
$("#form_session").attr('action', url).submit();
});
All the 'next' and 'previous' pagination links must be given the same class (namely 'next_page' (in this example).
EDIT: If your pagination is as follows:
<div class='pagination'>
<ul><li><a href='page1.url'>1</a></li>
<li><a href='page2.url'>2</a></li>
</ul>
</div>
then just change this:
$("div.pagination a").click(function(event) {
etc.
This one is pretty easy, you need a PHP-Script to handle AJAX requests which are sent from your Search page.
In your search page you'll need to add an .ajax to create an AJAX request to your Script.
Everything you need to know about AJAX can be found here: http://api.jquery.com/jQuery.ajax/
In your PHP-Script you'll handle the Database action, use GET or POST data to give the script an ID over Ajax.
Use Ajax. Write a simple php-script that writes clickes to the database. I don't know how you log the clicks in the database exactly, but you can send the clicked item unique identifier to a php script with ajax, for example via POST variables.
A little example, on click:
$.post(
'count_click.php',
{ id: "someid" },
function(data) {
// data = everything the php-script prints out
});
Php:
if (isset($_POST['id'])) {
// add a click in the database with this id
}
Send a request to a PHP page using jQuery AJAX. See here for more info (it is really simple):
http://api.jquery.com/jQuery.ajax/
In this particular case, as you do not need to return anything, it may be better to just use the POST or GET methods in jQuery:
http://api.jquery.com/jQuery.post/
http://api.jquery.com/jQuery.get/
Something like:
$.ajax({
type: "POST",
url: "some.php",
data: "name=John&location=Boston"
success: function(data){
alert('done');
});
I'm building a site which allows users to log on to it, and uses jquery to dynamically update the page to show all users who are currently on.
I want to have a button beside each users name that would let another user select that person (a game match-making service, if you will.)
Currently I'm generating the names with a combination of jquery and php.
Jquery does long polling:
function waitForMsg(){
$.ajax({
url: "tictac_code1.php",
type: 'POST',
data: 'longpoll=1',
async: true, /* If set to non-async, browser shows page as "Loading.."*/
cache: false,
timeout:10000, /* Timeout in ms */
success: function(data){ /* called when request to barge.php completes */
$('#loggedinnames').empty();
$('#loggedinnames').append(data);
setInterval(waitForMsg, 10000);
//setTimeout(
// 'waitForMsg()', /* Request next message */
// 1000 /* ..after 1 seconds */
//);
},
error: function(XMLHttpRequest, textStatus, errorThrown){
//alert("error in waitformsg.");
addmsg("error", textStatus + " (" + errorThrown + ")");
setInterval(waitForMsg, 10000);
//setTimeout(
// 'waitForMsg()', /* Try again after.. */
// "15000"); /* milliseconds (15seconds) */
}
});
};
$(document).ready(function(){
waitForMsg(); /* Start the inital request */
});
PHP does the sql queries and returns data to the jquery to be displayed.
if (isset ($_POST['longpoll'])) {
if (filter_input(INPUT_POST,'longpoll') == '1') {
$name = $_SESSION['name'];
$result = mysql_query("select name from tictac_names where logged_on='1' AND name!='$name'", $db);
$rowCheck = mysql_num_rows($result);
if ($rowCheck > '0') {
while ($row = mysql_fetch_assoc($result)){
foreach ($row as $val){
$spanid = 'sp_' . $val;
$buttonid = 'b_' . $val;
//echo "<br><span id=\"$spanid\">$val</span></br>";
//<input type ="button" id="nameButton" value ="OK"/><br>
echo "<br><span id=\"$spanid\">$val <input type =\"button\" id=\"$buttonid\" value =\"Button!\"/> </span></br>";
//echo "<br><p><span id=\"$spanid\">$val</span>Click here to play a game with this player.</p></br>";
}
}
} // end rowcheck
}
} //////////// end of the LONGPOLL if
So it successfully puts out the name and a button, but the button's ID is not unique. If I want it to be clickable, I'm sure that the ID will have to be unique, but then there will need to be additional jquery to catch the button click.
How can I make this work?
Should I take a different approach, perhaps names with radio buttons, and a single "Match us!" button?
An alternative to #Craig M 's answer would be to use the built in delegate features in jQuery.
$('#loggedinnames').delegate('span','click',function(){
alert($(this).text());
});
It does the same thing but you can use any selector, not just tag name, and you don't need to code all of the boiler plate delegation code.
You could remove the buttons, and use event delegation to figure out which username the person clicked on. Then do what you need to do with it in the click handler.
To do this, set a click handler on #loggedinnames like so:
$('#loggedinnames').click(function(e) {
if ($(e.target).is('span')) { //e.target is the element that was actually clicked.
alert($(e.target).text());
}
});
The advantage of this approach is that you only have one click handler and don't need to bind an event every time the list of logged in users changes.
What I usually do in this situation is to build the button in JavaScript rather than on the server. Then you can just keep a global variable that serves as a counter, increment it each time you add a button, and use that to put together your unique button ID.
I've used this approach in a lot of situations, and 90% of the time, it works every time.
Give all of your buttons the same class and unique ids. Write an event handler in JQuery using live() for your class where you get the id of this and use it in your code. This way the code works for ALL buttons (including new ones) and you do not have to duplicate any code.
$('#loggedinnames .button').live('click', function() {
someMethod($(this).attr('id')); //run your code here
});
I know this is a topic where you can find tons of answers for... I spent now quite some time to search for the solution I am looking for.
I have a PHP file with a form. This PHP file uses a JavaScript for a drop down pre-selection.
Means: If a user selects a value in drop-down1 then there is a limited selection in drop-down2.
This JavaScript definitely needs to reload the PHP file for changing the values of the second drop-down2 list.
The question is now: How can I keep the entered values of the user in the form, after the JavaScript has been executed. Currently all entered data get lost.
One option would be to set all values into the URL and grab them with GET. Yes.. that would be an option but as I am using 13 values, the URL would look not too nice. I don't want to user to take notice of what happens.
I cant use the POST, as I don't push the posting button.. it's just the JavaScript that gets executed and reloads the page.
I thought about filling the Session with the entered data but that is not directly possible as JavaScript is on the client side and the session is on the server side.
Do you have any suggestions?
Form Example:
First Name (text box) Last Name (text box) Age (drop-down) Sex (drop-down)
Province (JS drop down) District (JS drop down) Commune (JS drop down) Village (JS drop down)
Transf.from (drop down) Health Center (text box) Ambulance (drop-down) Self.transferred (drop down) SEND BUTTON
dynmicoptionlist.js code:
//Set parameters for provinces selection
function reload1(form) {
var val1=form.provinces.options[form.provinces.options.selectedIndex].value;
//Get the current URL
var url1=window.location.href;
//Check if the current URL has the search term in it (-1 means it is not in it)
if(url1.search("&provinces=") != -1) {
//Now that the search term was found, cut the search term from the URL so that it can be replaced
//This is necessary for multiple selections in the same drop down box
var url2 = url1.substr(0,url1.search("&provinces="));
//If the user has selected "Please select", then dont add the provinces parameter
if(val1 == "") {
//Create the new URL
self.location= url2
}
else {
//Create the new URL
self.location= url2 + "&provinces=" + val1 ;
}
}
else {
//The search term was not found, so just add the provinces
self.location= url1 + "&provinces=" + val1;
}
}
//Set parameters for districts selection
function reload2(form) {
var val1=form.provinces.options[form.provinces.options.selectedIndex].value;
var val2=form.districts.options[form.districts.options.selectedIndex].value;
//Get the current URL
var url1=window.location.href;
//Check if the current URL has the search term in it (-1 means it is not in it)
if(url1.search("&districts=") != -1) {
//Now that the search term was found, cut the search term from the URL so that it can be replaced
//This is necessary for multiple selections in the same drop down box
var url2 = url1.substr(0,url1.search("&districts="));
//If the user has selected "Please select", then dont add the provinces parameter
if(val2 == "") {
//Create the new URL
self.location= url2
}
else {
//Create the new URL
self.location= url2 + "&districts=" + val2 ;
}
}
else {
//The search term was not found, so just add the districts
self.location= url1 + "&districts=" + val2;
}
}
//Set parameters for communes selection
function reload3(form) {
var val1=form.provinces.options[form.provinces.options.selectedIndex].value;
var val2=form.districts.options[form.districts.options.selectedIndex].value;
var val3=form.communes.options[form.communes.options.selectedIndex].value;
//Get the current URL
var url1=window.location.href;
//Check if the current URL has the search term in it (-1 means it is not in it)
if(url1.search("&communes=") != -1) {
//Now that the search term was found, cut the search term from the URL so that it can be replaced
//This is necessary for multiple selections in the same drop down box
var url2 = url1.substr(0,url1.search("&communes="));
//If the user has selected "Please select", then dont add the provinces parameter
if(val3 == "") {
//Create the new URL
self.location= url2
}
else {
//Create the new URL
self.location= url2 + "&communes=" + val3 ;
}
}
else {
//The search term was not found, so just add the communes
self.location= url1 + "&communes=" + val3;
}
}
On behalf of JohnP's suggestion here are my changes so far:
I've added the onload function to fill the hidden field with a value:
<body onload=\"setValue()\">
The JavaScript filling the value looks like this:
<script type=\"text/javascript\">
function setValue() {
document.getElementById(\"dyndrpdwnhidden\").value=\"createPatient\";
}
</script>
In my form I've added the hidden field:
<input type=\"hidden\" id=\"dyndrpdwnhidden\">
To get the values out of the form's input fields in my JavaScript dynmicoptionlist.js above I've used as an example:
var entry_date = form.entry_date.value;
Maybe you try to use SESSION? The session data will not disappear even on page refresh or redirect.
To keep any data:
session_start();
$_SESSION['data']=$_POST['data_from_previous_page'];
To read it at any page:
session_start();
$_SESSION['data'];
To clear all session data:
unset($_SESSION);
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), '', time()-42000, '/');
}
session_destroy();
Why not just make your JS submit the form? That will make the variables available, and you can activate the second dropdown by looking at the post data instead of the $_GET data that the JS sends.
use localStorage https://www.w3schools.com/jsref/obj_storage.asp
Storage Object
The Storage object of the Web Storage API provides access to the session storage or local storage for a particular domain. This allows you to read, add, modify, and delete stored data items.