I am new to cake and mysql, and am trying to create a simple job tracking app. I want to have a dropdown box for each job with a list of the status' a job can be at. When a user changes the active item in the box I want to save this into the database.
Any help in how to handle this would be very much appreciated. Below is what I have tried so far:
How I create the set of forms in the view with the options taken from the enums in my database table:
<?php $id = count($jobs)-1; ?>
<?php for ($job = count($jobs)-1; $job >= 0; --$job): ?>
<tr>
<td>
<?php echo $this->Form->input('status'.(string)$id, array('type'=>'select', 'class' => 'statusSelect','label'=>'', 'options'=>$states, 'default'=>$jobs[$job]['Job']['Status'])); ?>
</td>
I am using a jquery script to set an on change listener for each dropdown and call an action in my controller:
$(".statusSelect").change(function(){
//Grab job number from the id of select box
var jobNo = parseInt($(this).attr('id').substring(6));
var value = $(this).val();
$.ajax({
type:"POST",
url:'http://localhost/projectManager/jobs',
data:{ 'id': jobNo,
'status':value},
success : function(data) {
alert(jobNo);// this alert works
},
error : function() {
//alert("false");
}
});
});
And I have this function in my controller:
public function changeState($id = null, $status = null) {
//I don't think the id and status are actually
//being placed as arguments to this function
//from my js script
}
Thank you!!!
You are POSTing to /projectManager/jobs, which corresponds to ProjectManagerController::jobs().
Your function is declared as public function changeState($id = null, $status = null). Assuming changeState(..) is a function within ProjectManagerController, this corresponds to /projectManager/changeState/$id/$status.
You need to switch the URL the AJAX is POSTing to. You can either do something like:
url:'http://localhost/projectManager/changeState/'+jobNo+'/'+value', remove the data {} and leave your function as is, or you can do
url:'http://localhost/projectManager/changeState', leave the data {}, change your function to changeState() and then use $this->request->data within changeState() to access the data.
I am guessing you have another function, jobs(), and that is why the AJAX is working properly and the alert is generating.
Related
I have some results from a fetch.php using json and I successfully brought all results to my bootstrap modal HTML screen.
When the Modal is being shown, I would like to run a MYSQL query using a value coming from the same json I used for the modal, however I can't put this value into a PHP variable to run the SQL query.
How can I get this?
I am trying to bring the same value I input into the HTML textbox (modal), but it is not working. I also tried to use the value from json '$('#PCR').val(data.PCRNo);)', but nothing happen.
This is the script to collect information from database using fetch.php file:
<script>
$(document).ready(function(){
$('#table').on('click', '.fetch_data', function(){
var pcr_number = $(this).attr('id');
$.ajax({
url:'fetch.php',
method:'post',
data:{pcr_number:pcr_number},
dataType:"json",
success:function(data){
$('#PCR').val(data.PCRNo);
$('#PCC').val(data.PCC);
$('#PCR_Creation').val(data.Creation_Date);
$('#PCR_Status').val(data.Stage);
$('#Required_Completion').val(data.Required_Completion);
}
});
});
});
</script>
This is the PHP code
<?php
//trying to get the value I have included on #PCR (textbox) which has ID='PCR' and name ='PCR' **
$PCR= $_POST['PCR'];
//running now the code to check if the database has the value and return the desired response to be shown **
$sql1 = mysqli_query($dbConnected,"SELECT * FROM change_management.tPCN");
while ($row1 = mysqli_fetch_array($sql1)) {
if ($row1['PCRNo']==$PCR){
echo $row1['PCNNo'];
echo "<br/>";
}else{
}
}
?>
I would like include value from this val(data.PCRNo) json return into the $PCR variable, so the MYSQL query is going to work
There are a number of quite basic logical issues with your code which are preventing it from working.
1) data: { pcr_number: pcr_number}- the name pcr_number doesn't match the value PCR which the server is searching for using $_POST['PCR'];. The names must match up. When making an AJAX request, the name you gave to the form field in the HTML does not matter (unless you use .serialize()) because you are specifying new names in the data parameter.
2) Your SQL query doesn't make sense. You seem to be wanting to read a single row relating to a PCR number, yet your query makes no usage of the input PCR value to try and restrict the results to that row. You need to use a SQL WHERE clause to get it to select only the row with that ID, otherwise you'll fetch all the rows and won't know which one is correct. (Fetching them all and then using an if in a PHP loop to check the correct one is very inefficient.) I wrote you a version which uses the WHERE clause properly, and passes the PCR value to the query securely using prepared statements and parameters (to project against SQL injection attacks).
3) Your output from the PHP also makes no sense. You've told jQuery (via dataType: "json" to expect a JSON response, and then your code inside the "success" function is based on the assumption you'll receive a single object containing all the fields from the table. But echo $row1['PCNNo']; echo "<br/>"; only outputs one field, and it outputs it with HTML next to it. This is not JSON, it's not even close to being JSON. You need to output the whole row, and then use json_encode() function to turn the object into a JSON string which jQuery can parse when it receives it.
Here's a version of the code containing all the above changes:
JavaScript:
$(document).ready(function(){
$('#table').on('click', '.fetch_data', function(){
$.ajax({
url: 'fetch.php',
method: 'post',
data: { pcr: $(this).attr('id'); },
dataType: "json",
success: function(data){
$('#PCR').val(data.PCRNo);
$('#PCC').val(data.PCC);
$('#PCR_Creation').val(data.Creation_Date);
$('#PCR_Status').val(data.Stage);
$('#Required_Completion').val(data.Required_Completion);
}
});
});
});
PHP:
<?php
$PCR = $_POST['pcr'];
$stmt = $dbConnected->prepare("SELECT * FROM change_management.tPCN WHERE PCRNo = ?");
$stmt->bind_param('s', $PCR);
$stmt->execute();
$result = $stmt->get_result();
//an "if" here will cause a single row to be read
if ($row = $result->fetch_assoc()) {
$output = $row;
}
else
{
$output = new StdClass();
}
$stmt->free_result();
$stmt->close();
//output the result
echo json_encode($output);
?>
N.B. I would potentially suggest studying some tutorials on this kind of subject, since this is a fairly standard use case for AJAX/JSON, and you should be able to find samples which would improve your understanding of all the different parts.
P.S. Currently the PHP code above will return an empty object if there is no matching row in the database. However, this is probably an error condition (and will cause your JavaScript code to crash due to trying to read nonexistent properties), so you should consider how you want to handle such an error and what response to return (e.g. 400, or 404, and a suitable message).
You need to first return json from php by using json_encode.
Inside this loop
while ($row1 = mysqli_fetch_array($sql1)) {
$data = array('PCRNo' => 'itsvalue', 'PCC' => 'itsvalue', 'Creation_Date' => 'itsvalue')
}
print json_encode($data)
store all the data in an associative array and then convert it into json using json_encode and return the json.
Use json data in you ajax file
$.ajax({
url:'fetch.php',
method:'post',
data:{pcr_number:pcr_number},
dataType:"json",
success:function(data){
var data = JSON.parse(data);
$('#PCR').val(data.PCRNo);
$('#PCC').val(data.PCC);
$('#PCR_Creation').val(data.Creation_Date);
$('#PCR_Status').val(data.Stage);
$('#Required_Completion').val(data.Required_Completion);
}
});
Below is the changed script to store different values in $PCR variable
<script>
$(document).ready(function(){
var i = 1;
$('#table').on('click', '.fetch_data', function(){
if(i == 1) {
var pcr_number = $(this).attr('id');
} else {
var pcr_number = $('#PCR').val();
}
$.ajax({
url:'fetch.php',
method:'post',
data:{pcr_number:pcr_number},
dataType:"json",
success:function(data){
$('#PCR').val(data.PCRNo);
$('#PCC').val(data.PCC);
$('#PCR_Creation').val(data.Creation_Date);
$('#PCR_Status').val(data.Stage);
$('#Required_Completion').val(data.Required_Completion);
i++;
}
});
});
});
</script>
So basically this little box section displays like recent uploads and a little status that is red for pending and green for uploaded. Right now I made it so when I click on the first red box it will update all the red ticks to green for completed.
How can I make it so that when I click on a single red box, it will only update that tables row to green?
Each upload has an id automatically generated in the Database.
Here is a picture of the box: https://i.gyazo.com/af895f24a2f002df588ca1863f7216fa.png
I have to manually edit the table status to green in order for it to change or I click on 1 and it updates all. I want it to only be on the specific one clicked like displayed in the photo.
Here is another example of it but using a .gif for better demonstration: https://i.gyazo.com/3e974f1a536ba37e71fcb60fc7f19c54.gif
Javascript:
$("#updateStatus").click(function(){
window.location.href = 'connections/updateStatus.php';
});
PHP:
public function redtoGreen(){
$query2 = "UPDATE uploads SET status = 'green'";
$this->conn->query($query2);
header('Location: '.'../index.php');
}
You can achieve through AJAX, sending the ID or wherever you identify your DIV, the code will be something like this:
$("#updateStatus").click(function(){
var id = $(this).attr('id');
$.ajax({
method: 'GET',
url: "connections/updateStatus.php?id="+id
});
});
and at your server side
public function redtoGreen(){
$id = $_GET['id'];
$query2 = "UPDATE uploads SET status = 'green'";
$this->conn->query($query2);
header('Location: '.'../index.php');
}
to change of color, take a look https://jsfiddle.net/k0ye49oh/
You should use AJAX for that (although it works with redirecting back and forth too...).
Do something like this instead:
$("#updateStatus").click(function(){
$.ajax({
url: "connections/updateStatus.php"
});
});
For it to update only a specific row, you have to pass on the ID of the row. Your update query will just update all rows in the table to "green". You can pass the ID on as a parameter and read it in PHP with $id = $_POST["id"] if you posted it by:
$.ajax({url: "connections/updateStatus.php", method: "POST", data: { id: 4 }});
You can read and update it in PHP like:
public function redtoGreen(){
$id = intval($_POST["id"]);
$query2 = "UPDATE uploads SET status = 'green' WHERE id = $id";
$this->conn->query($query2);
}
Another remark: consider using prepared statements for this. SQL queries like this are not good style. You'd rather want something like:
public function redtoGreen(){
$id = $_POST["id"];
$stmt = $db->prepare ("UPDATE uploads SET status = 'green' WHERE id = ?");
$stmt->execute($id);
}
You can also build on the ajax query to change the row color without reloading, doing something like:
$.ajax({
url: "connections/updateStatus.php",
method: "POST",
data: { id: rowno },
success: function (result) {
$("#myrow-" + rowno).css('background-color', 'green');
}
});
However, seeing that you only have one button (#updateStatus) to update ALL rows I think you have several issues with your approach here. If you have the buttons on each row, you have conflicting IDs.
To get both the rowno and the correct button references, you can define your buttons like this:
<button class="updateStatus" data-rowno="1"></button>
When building the table, you will have to put the row number where the 1 is.
Then you can do the javascript part like this:
$(document).ready(function () {
$(".updateStatus").click(function () {
var el = $(this);
var rowno = el.data("rowno");
$.ajax({
url: "connections/updateStatus.php",
method: "POST",
data: { id: rowno },
success: function (result) {
$(el).parent().css('background-color', 'green');
}
});
});
});
Tested and works with HTML like
<table>
<tr><td style="background-color:red;">Blah <button class="updateStatus" data-rowno="1">Update</button></td></tr>
<tr><td style="background-color:red;">Blah <button class="updateStatus" data-rowno="2">Update</button></td></tr>
<tr><td style="background-color:red;">Blah <button class="updateStatus" data-rowno="3">Update</button></td></tr>
<tr><td style="background-color:red;">Blah <button class="updateStatus" data-rowno="4">Update</button></td></tr>
<tr><td style="background-color:red;">Blah <button class="updateStatus" data-rowno="5">Update</button></td></tr>
</table>
You need to update your SQL query to something like below. The current query will set every row for status to 'green' in the uploads table.
UPDATE uploads SET status = 'green' WHERE somecolumn = somevalue
That somevalue needs to be sent from your javascript function call, something like
updatestatus.php?var=somevalue
and use the var as $_GET['var'] on the php page.
Alright, so after some thinking I figured this out.
I thought about changing the html to have divs labeled like this: Hello1 and Hello2. Here is some HTML:
<html>
<div id = "Hello1">
</div>
<div id = "Hello2">
</div>
</html>
You would put the content for each clickable box that you have.
I recommend using Jose Rojas's Javascript.
Here is some PHP to update them accordingly.
With my example, you would just using the $_GET global value instead of a $_POST
<?php
$div = $_GET['div'];
redToGreen($div);
function redToGreen($div) {
$query = "UPDATE uploads SET status = 'green' WHERE div = '{$div}'";
try {
$stmt = $this->conn->prepare($query);
$stmt->execute();
header('Location: ../index.php');
} catch (PDOException $e) {
header('Location: ../pages-500.html');
}
}
?>
If you have any questions, feel free to comment, and I will respond.
How my function works:
There are 2 buttons 'Accept' and 'Decline'. When user clicks on Accept, the text will change to 'Accepted' and both buttons will be disabled. Colour of text changes too. After this process, i need to update the database table column accordingly.
My current situation:
I'm showing more than one entry with this function.
Currently my codes only work when i have one entry and it doesn't stays the way it should be when I pressed on it after I refresh the page. When there are more than one entry, the button i clicked on the second entry somehow detects the first entry and changes the button in the first entry. And i have no clue on how to update the database accordingly.
Thank You so much in advance.
My Script:
<script>
function accept() {
document.getElementById("accept").disabled = true;
document.getElementById("decline").disabled = true;
document.getElementById("accept").innerHTML = 'Accepted';
document.getElementById("accept").style.color = "green";
}
function decline() {
document.getElementById("decline").disabled = true;
document.getElementById("accept").disabled = true;
document.getElementById("decline").innerHTML = 'Declined';
document.getElementById("decline").style.color = "red";
}
</script>
Accept Button:
<button id="accept" onclick="accept()">Accept</button>
Decline Button:
<button id="decline" onclick="decline()">Decline</button>
You need to learn how to use AJAX:
Using JQuery AJAX makes it much easier.
JS FILE:
$.ajax({
url: "/updateDatabase.php";
type: "POST";
data: {update: value},
beforeSend: function (){
//stuff you like to do before sending.
}
success: function (data){
//do something with return data
}
});
PHP FILE: updateDatabase.php
$var = $_POST["update"]; //make sure this is the same name for the data{} json string
//update database.
echo "Put return value here for JS success data var."
Remember Button state:
<?php if(databaseValue == Accepted) { ?>
<button>Format Button Disabled for accepted</button>
<?php } else { ?>
<button>Format button for enabled</button>
<?php } ?>
Why are you writing two functions if 50% of the operations of the functions are same. I suggest you to write only one function and put a conditional statement in it which checks which button was clicked. It is efficient programming!
Regarding your question can you share a screenshot here, as what exactly is displayed when the operation is performed.
I am making a simple web chat application using ajax,php,javascript and mysql.
What I am trying to do here is to avoid fetching the whole database after an interval of 1 sec(which is normally done in basic chat application ) but rather I want to fetch and display(by appending) also those chats which have been newly entered into the database by any user.
To implement this ,First when the user first opens the chat screen the whole database is loaded in the chat window(not shown in this code snippet),and then I am using the variable msgid to fetch the latest value of MSg_ID (which is the auto-increment primary key in my chat table) through an ajax request to the page 'Msg.php' which returns the required value of msg_id.
Now using this value of msgid and comparing it with the max value of Msg_ID every second in the database through the ajax request to the page 'Chat3.php'.
If the Max value of Msg_ID has changed the required rows are returned . After this I m updating the value of 'msgid' using the same earlier ajax request to the page 'Msg.php'
The pages Msg.php and Chat3.php are working perfectly ,as I have tested them thoroughly.
My question here is what is the problem in my code , why is not working?
Can we use an ajax request inside a ajax call back function or not?
What else can be a probable source of error?
Any input will be valuable :)
If you have any problem in understanding the code,leave a comment.
'#yyy' and '#zzz' are random div elements which i am using to test the data value of ajax callback function.
I can even post the rest of the code if it helps.
<script type"text/javascript">
$(document).ready(function() {
var dept = '<?php echo $deptId; ?>';
$.ajax({
url: 'scripts/php/Msg.php',
data: {dept:dept},
success: function(data) {
$('#yyy').html(data);//this displays the correct value
var msgid=data;
}
});
var interval = setInterval(function() {
$.ajax({
url: 'scripts/php/Chat3.php',
data: {dept:dept,msgid:msgid},
success: function(data) {
if(data!='bad'){
//$('#messages').prepend(data);
$('#zzz').html(data);//does not display any value although Chat3.php is returning the correct value.
//below ajax request to update the value of msgid
$.ajax({
url: 'scripts/php/Msg.php',
data: {dept:dept},
success: function(data) {
var msgid=data;
$('#zzz').html(data); //not displaying anything although above one is was displaying
}
});
}
}
});
}, 1000);
});
</script>
Here is my Msg.php
<?php
require '../../includes/database/connect.db.php';
function get_msg($dept){
$query= "SELECT Msg_ID,Sender, Message ,Time_stamp FROM chat WHERE Dept_ID='$dept' ORDER BY Msg_ID DESC" ;
$run=mysql_query($query);
$messages =array();
while($message=mysql_fetch_assoc($run)){
$messages[] =array('msgid'=>$message['Msg_ID'],
'sender'=>$message['Sender'],
'message'=>$message['Message'],
'time_stamp'=>$message['Time_stamp']);
}
return $messages;
}
$dept=$_GET['dept'];
$messages = get_msg($dept);
$x=count($messages);
if($x){
foreach($messages as $message) {
if($x==count($messages)){
echo $message['msgid'];
}
$x--;
}
}
?>
Here is my Chat3.php
<?php
require '../../includes/database/connect.db.php';
function get_msg($dept,$msgid){
$query1= "SELECT MAX(Msg_ID) as msg_id FROM chat" ;
$run1=mysql_query($query1);
$row = mysql_fetch_assoc($run1);
$result =$row['msg_id'];
$messages =array();
if($result>$msgid)
{
$query= "SELECT Sender, Message ,Time_stamp FROM chat WHERE Dept_ID='$dept' AND Msg_ID>'$msgid' ORDER BY Msg_ID DESC" ;
$run=mysql_query($query);
while($message=mysql_fetch_assoc($run)){
$messages[] =array('sender'=>$message['Sender'],
'message'=>$message['Message'],
'time_stamp'=>$message['Time_stamp']);
}
return $messages;
}
else
{
return $messages;
}
}
$dept=$_GET['dept'];
$msgid=$_GET['msgid'];
$messages = get_msg($dept,$msgid);
if(count($messages)){
foreach($messages as $message) {
echo '<strong>'.$message['sender'].' Sent</strong><br>';
echo $message['message'].' <i><small><div align="right">'.$message['time_stamp'].'</i></small></div>';
}
}
else {
echo 'bad';
}
?>
The problem is the msgid
In your first AJAX Request you are setting the variable var msgid=data; which is in local scope.
I think you are trying to access that variable in the second AJAX request while sending the datas
url: 'scripts/php/Chat3.php',
data: {dept:dept,msgid:msgid}, // Trying to access the local variable of previous ajax request
EDIT:
Try removing the var from var msgid=data; in your first AJAX request. Removing var will make the variable GLOBAL, Although its not good to pollute the global scope, but you can definitely try out this for the time being
I was trying to figure out how to check if the value entered in text box is existing in
database or no as soon as it is entered or on tab event using cakePHP and javascripts. I am new so please can someone help?
Thanks,
Create a validation for Unique on the field. It will check the value of the field before it saves it. If it exists, it will tell the user that the value already exists.
assumptions:
table: posts
model:Post
controller:Posts
and the field about which you need notification of pre-existence is post_title
Now do something like this
In view:
let id of text field for post_title is PostPostTitle
$('#PostPostTitle').bind({
blur:function(){
var newTitle = $(this).val();
if(newTitle){
$.ajax({
url:'Posts/checkTitle/',
type:'POST',
data:{title:newValue},
dataType:'JSON',
success:function(data){
if(data.ok==1){
//dont show any error and let the user submit
}else {
//show error notification in desired format
}
}
})
}
}
});
Now in your controller make an action with name checkTitle
controller code will be like this
public function checkTitle(){
//fetch the vlaue of title from appropriate key of the controller class
//variable $this->params (in cake v<2) or from $this->reuest (cake v2.x+)
$this->layout = 'ajax';//or json or null what ever you prefer
$this->autoRender = false;
//assumig that you have fetched value of newTitle in $newTitle from requestVar
//make a database query to post table
$response = array('ok'=>0);
$data = $this->Post->find('count',array('conditions'=>array('post_title'=>$newTitle)));
if($data==0) {
$response['ok']=1;
}
echo json_encode($response);
exit;
}