How to resolve strange conflict between form post and ajax post? - php

On the one page, I am trying to use ajax to edit existing values. I am doing this by using jQuery Inline Edit and posting away the new data, updating the record and returning with success.
This is working fine.
Next I have implemented the ability to add new records, to do this I have a form at the end of the table, which submits post data then redirects back to the original page.
Each of them work individually, but after I have used the form to add a new record, the inline editing stops to work. If I close the webpage and reopen it, it works fine again until I have used the form and it goes of the rails again.
I have tried a number of solutions, clearing session data, giving the form a separate name, redirecting to an alternative page (which does work, but is not ideal as I want the form to redirect back to the original location ).
Here is a sample of the view form data:
<?php foreach($week->incomes as $income):?>
<tr>
<td><?php echo $income->name;?></td>
<td width="70" style="text-align:right;" class="editableSingle income id<?php echo $income->id;?>">$<?php echo $income->cost;?></td>
</tr>
<?php endforeach;?>
<?php echo form_open('budget/add/'.$week->id.'/income/index', 'class="form-vertical" id="add_income"'); ?>
<tr>
<td>
<input type="text" name="name" class="input-small" placeholder="Name">
<input type="text" name="cost" class="input-small" placeholder="Cost">
</td>
<td>
<button type="submit" class="btn btn-small pull-right"><i class="icon-plus "></i></button>
</td>
</tr>
<?php echo form_close(); ?>
This is the javascript initialisation code:
$(function(){
$.inlineEdit({
income: 'budget/update_income/',
expense: 'budget/update_expense/'
},
{
animate: false,
filterElementValue: function($o){
if ($o.hasClass('income')) {
return $o.html().match(/\$(.+)/)[1];
}
else if ($o.hasClass('expense')) {
return $o.html().match(/\$(.+)/)[1];
}
else {
return $o.html();
}
},
afterSave: function(o){
if (o.type == 'income') {
$('.income.id' + o.id).prepend('$');
}
if (o.type == 'expense') {
$('.expense.id' + o.id).prepend('$');
}
},
colors: { error:'green' }
});
});
If I can provide any more information to clarify what I have attempted etc, let me know.
Temporary Fix
It seems I have come up with a work around, not ideal as I still am not sure what is causing the issue.
I have created a method called redirect.
public function redirect(){
redirect('');
}
am now calling that after the form submit which has temporarily allows my multiple post submits to work.

please try and see by replacing the jquery sign.
$ should be replaced by jQuery then it will create new instance to work fine

I heard somewhere that jquery wont work if you put the form inside the table tag.
It need to be outside the table as in:
<form>
<table>
...
</table>
</form>
jQuery does not bring the contents of a form element if inside a table element on an ajax load
After testing it, i've discover that it is partialy true, (aka un-reliable)... It's the reason why i stopped using tables.

Related

PHP pass record id to another page without showing it in the URL

I'd like to know if there is a way to pass a record id to another page without showing in the URL (using $_GET).
This is my code:
<table class="table table-bordered">
<thead>
<tr>
<td>#</td>
<td>Sigla</td>
<td>Nome</td>
<td>Bilancio</td>
<td>Responsabile</td>
<td>Azione</td>
</tr>
</thead>
<tbody>
<?php foreach ($rows as $row): ?>
<tr>
<td><?=$row['id']?></td>
<td><?=$row['sigla']?></td>
<td><?=$row['nome']?></td>
<td><?=$row['bilancio']?></td>
<td><?=$row['responsabile']?></td>
<td class="actions">
<a href="update.php?id=<?php echo $row['id']; ?>" class="edit">
<i class="fas fa-pen fa-xs"></i>
</a>
<a href="delete.php?id=<?php echo $row['id']; ?>" class="trash">
<i class="fas fa-trash fa-xs"></i>
</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
As you can see for each record i create an <href> with the redirect to the "delete" or "update", so i will pass the id via $_GET.
Is there a way to not show the id in the URL?
You need AJAX or a form
Using a link to delete is VERY dangerous since once viist from a crawler and your database is corrupt
I suggest something like this
delegate the click to the container table
use data-attributes for the ID
Ajax using POST - I use fetch to do that here
let fetchData = {
method: 'POST'
}
const url = "delete.php";
document.querySelector("form").addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.classList.contains("trash") && confirm("Delete "+this.id+"?")) {
e.preventDefault();
fetchData["body"] = {
"id": this.getAttribute("data-id")
};
fetch(url, fetchData)
.then(function() {
console.log("deleted");
});
}
})
<a href="#" data-id="<?php echo $row['id']; ?>" class="trash">
<i class="fas fa-trash fa-xs"></i>
</a>
The id being shown in the URL is an absolute non-issue. That doesn't make the delete operation any more secure or insecure. What you have are one, perhaps two, other issues:
Any destructive operation must use POST requests. Normal links are free to be crawled by search engines, or preloaded by browsers. Which means, as soon as Google has crawled all your links, your database will be empty. That's why using POST is important, because every properly behaved HTTP client understands that POST is destructive.
If you're asking this question because you're afraid users can simply manipulate the id shown in the URL and delete other records they're not supposed to delete, then your real issue isn't in where you pass the id, but that you have no permission checking on your server.
For starters, use a form to create POST requests:
<form action="delete.php?id=<?php echo htmlspecialchars(urlencode($row['id'])); ?>"
method="post">
<input type="submit" value="Delete">
</form>
(Also note the proper way to URL-encode and HTML-encode the value, since you're embedding it in a URL in the context of HTML.)
On the PHP side, you'd process this something like this:
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$id = $_GET['id'];
// permission checking here
// delete record here
}
Instead of transporting the ID as a query parameter, you could also make it a form field:
<form action="delete.php" method="post">
<input type="hidden" name="id" value="<?php echo htmlspecialchars($row['id']); ?>">
<input type="submit" value="Delete">
</form>
On the server you'd then take the value from $_POST['id'] instead of $_GET['id'].
Note that this does not fundamentally change anything and is mostly a matter of taste.
You can customise that drab submit button in various ways, or perhaps switch to more interactive Javascript; but those are all just ways to pretty up this basic operation.
You can do it by something like this https://laravel.com/docs/5.8/encryption
At back-end you have to encrypt all your parameters like the following code:
$encryptedParameters = encrypt([
'id' => 132,
'something' => 'value',
'another_key' => 'another_value',
]);
and then send this value to your html template.
At front-end if you want to do it by GET do something like this and your users can't see what are you sending to your back-end because it is encrypted:
and if you want to do it by POST you can do it by Ajax or by generating a form and putting this value as a hidden input inside it. and then when user clicked on this link at back-end you have to decrypt it and use it's values like the following code:
$decryptedParameters = decrypt($_GET['s']);
$id = $decryptedParameters['id'];
$something = $decryptedParameters['something'];
$another_key = $decryptedParameters['another_key'];
Convert the GET request to a Post using a hidden form submission, a preferred method is to encrypt the record id when submitting the data.

HTML form acting as get instead of post

I'm pretty new to the whole PHP/HTML deal, and I've run into a problem that I don't know how to fix. It's a pretty simple form that lets you enter data into database. The PHP code is as following:
<?
include("../sqlcontext.php");
$foo = mysql_query("SELECT*FROM users WHERE checksum='".$_COOKIE['userCookie']."'");
if($_COOKIE['userCookie'] == '' || !mysql_num_rows($foo)){
echo 'Du er ikke logget ind :( log ind her';
}
else{
if($_POST['genreKnap']){
$nameGenre = $_POST['nameGenre'];
$textGenre = $_POST['textGenre'];
$succes = mysql_query("INSERT INTO genre VALUES('null','$nameGenre','$textGenre')");
if($succes){
echo 'Yay!';
}else {
echo 'Oh no';
}
}
?>
The form is as following:
<form name="form1" method="post" enctype="text/plain" action="">
<table>
<tr>
<td>Genre navn:</td>
<td><input type="text" name="nameGenre" id="nameGenre" style="width:100%; padding-right: 1px" /></td>
</tr>
<tr>
<td>Genre beskrivelse:</td>
<td><textarea name="textGenre" id="textGenre" style="width:100%; padding-right: 1px"></textarea></td>
</tr>
<tr>
<td></td>
<td><input type="submit" name="genreKnap" id="genreKnap" value="Go!"/></td>
</tr>
</table>
</form>
Whenever I press the submit button, it seems as though it acts as if it was a get method and not a post.
Aha!!!
You are not posting the form correctly.
Set the
action=""
to
action="code.php"
Assuming your php page is called code.php. Just change it to the name/path of the php page and the form will send the data to your php code to process.
When you leave action="" to blank, it posts the data to itself (the same page). It is not acting as GET, it is still acting as POST, but posting to the wrong place. I think you worded the title of the question wrong.
What do you mean it is acting like get instead of post.
Can you not read $_POST variables in your PHP?
remove the 'enctype="text/plain"' in your form code.
enctype="text/plain"
Take that out. It is provided for debugging purposes only and doesn't generate anything that is sane to parse with a machine.
Valid form enctypes:
application/x-www-form-urlencoded: This is the default content type
multipart/form-data
The content type "application/x-www-form-urlencoded" is inefficient
for sending large quantities of binary data or text containing
non-ASCII characters. The content type "multipart/form-data" should be
used for submitting forms that contain files, non-ASCII data, and
binary data.
Source: http://www.w3.org/TR/html401/interact/forms.html#h-17.13.3.4
You're all ignoring the primary question and focusing on irrelevent items.
First of all more than anything he's using a short php opener <? not <?php now not every web server accepts short openers first up check that.
Echo out your $_POST vars and see if they're returning the correct items
echo "POSTS BELOW<br />";
echo $_POST['nameGenre']."<br />";
echo $_POST['textGenre']."<br />";
echo "<br />GETS BELOW<br />";
echo $_GET['nameGenre']."<br />";
echo $_GET['textGenre']."<br />";
Put this block of code directly below your php opener see what data it returns.
Also this if($_POST['genreKnap']){ is generally a bad way of doing it as its user input the safest way is a hidden field <input type="hidden" name="action" id="action" value="dopost" /> and change your if clause to if($_POST['action']=="dopost && isset($_POST['action'])){
Also set your form action="" to the actual page name not blank
Give all that a try and if its still not working we'll try something different
If you are send normal data without any files by the form .
Then enctype is not always needed .
But even if you want to include it
The correct way is :
enctype="multipart/form-data"
Also give a url in the action method of the form : <form action='example.php'>
I hope it solves the problem .

While loop form to delete mysql_entry

I have this chunk of code, which is displayed on a user's journal page. They can add an entry and they have the option to delete an entry once it's on the page.
Ill show the code with some comments and then explain the problem.
// Figures out how many recent posts to display
$posts = $config_journalposts + 1;
if($noposts!=1) {
// Gets the data from the query
while(($row = mysql_fetch_array($journalquery)) && ($posts > 1)) {
// For each of the posts that were gathered, display the following:
echo '<table border="0" width="100%">
<tr>
<td colspan="2" style="vertical-align:bottom;">
// Display the title as a link to be used as a permalink
<p class="fontheader">'.$row['title'].'</p>
</td>
</tr>
<tr>
// Show the o-so-important content
<td width="100%" style="vertical-align:top;padding-left:10px;">
'.$row['content'].'
</td>
</tr>
<tr>
// Show the date
<td style="font-size:8pt;padding-top:10px;">'.$row['date_day'].'/'.$row['date_month'].'/'.$row['date_year'].'</td>';
// Checks if the current user is the owner of the journal or an admin
if($_SESSION['user']==$pageowner || $_SESSION['user_rank']=='Admin') {
echo '<td align="right">
// FOCUS POINT
<form method="POST" id="deljournal">
<input type=\'hidden\' name=\'delete_id\' value=\''.$row['id'].'\' />
// A delete button that executes a bit of Javascript
<button type="button" class="button" name="delete" value="Delete" onClick="delete_journal()" />Delete</button>
</form>
// END FOCUS POINT
</td>';
}
echo '</tr>
</table>
<hr>
';
$posts --;
}
Here is the Javascript that gets triggered on the button press
function delete_journal() {
var answer = confirm("Are you sure you want to delete this journal entry?")
if (answer){
// Submits the form
$("#deljournal").submit()
}
}
This javascript triggers the forum in the PHP code above which reloads the page and triggers this at the very top of the page, before the tag
if(($_POST['delete_id'])) {
// Gets the post ID from the hidden forum tag
$deleteid = addslashes(strip_tags($_POST['delete_id']));
// Deletes the row that has the ID of the hidden form
mysql_query("DELETE FROM `gamezoid_accounts`.`journal_$pageowner` WHERE `id`='$deleteid'");
}
Now, for the problem. In the while loop, this form gets repeated over and over. What happens is that upon pressing the delete button, it triggers the form that has the ID "deljournal". Since all of them have the ID "deljournal" it does the one at the top of the page. Trying to embed the post ID into the form ID breaks the code because the mysql_query doesn't know that the delete function has been triggered in the first place.
Any way around this?
Reason why I'm using Javascript as a trigger is for the confirmation popup in case anyone askes.
Anyways, thanks heaps for reading this far!
<input type=\'hidden\' name=\'delete_id[]\' value=\''.$row['id'].'\' />
then only u will get all the values as array when posted.
<input type=\'hidden\' name=\'delete_id[]\' value=\''.$row['id'].'\' />
then only u will get all the values as array when posted.
and on server side u should use
$delete_values= implode (',',$_POST['delete_id']);
Found a solution.
I have changed the form to be
<form method="POST" id="deljournal_'.$row['id'].'">
<input type=\'hidden\' name=\'delete_id\' value=\''.$row['id'].'\' />
</form>
<button type="button" class="button" name="delete" value="Delete" onClick="delete_journal_'.$row['id'].'()" />Delete</button>
by adding the journal entry ID into the ID of the form and the onClick function. The javascript is just below it outside the table cell and looks like:
<script type="text/javascript">
function delete_journal_'.$row['id'].'() {
var answer = confirm("Are you sure you want to delete this journal entry?")
if (answer){
$("#deljournal_'.$row['id'].'").submit()
}
}
</script>
where the entry ID has been added to the function name and form ID tag. By putting the Javascript into a while loop and not into an external file, it can be manipulated with the loop to have the same values.
It is a bit messy and will slightly increase load times + execution times but it was the quickest way that I could find.
Hope this helps anyone else who has been having a similar problem.

Adding array of textbox using javascript into html

Is something wrong with my code?
<script>
function add(){
/* Get your form */
form = document.getElementById("test");
/* Create your input element */
input = document.createElement("input");
input.type="text";
input.name="array['artists']";
/* Append to form */
form.appendChild(input);
alert("done");
}
</script>
<table>
<tr>
<td align="right">Artist/s:</td>
<td><form id="test" enctype="multipart/data-form" method="post">
<input type="text" name="artists"/>
<input type="button" onclick='javascript: add()'/></form></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Submit"></td>
</tr>
</table>
Im trying to add another textbox below another but nothing happened. What should i do?
Seems to be working for me too.
When I first put it into an html file, Internet Explorer wouldn't let me run the javascript because the html file was local to my computer. Try another browser if that's what you're using. Or just click yest to allow it in IE if that's the case.
Seems to be working - fiddle
I just put a call to add() inside a setTimeout so it would execute a second after the page loads.
Are you just missing the call to add()?
edit: I didnt originally see the onclick bound. new working fiddle2
Works for me as well. Try testing in another browser..
Your HTML-formatting is not right. This is why the input-box (TextBox) is added after the 'add'-button and not underneath it as you would like.
You can try the following code:
var table = document.getElementById("tableAddRows");
var row = document.createElement("tr");
var td1 = document.createElement("td");
var td2 = document.createElement("td");
td2.appendChild(input);
row.appendChild(td1);
row.appendChild(td2);
table.appendChild(row);
Add an id to the table (in the sample "tableAddRows").
Also, I added the Submit-button in a different table, like so (there are neater solutions):
<table>
<tr>
<td colspan="2"><input type="submit" value="Submit"></td>
</tr>
</table>
Also place the form-element around both tables.
I would also suggest to use JSRender or jQuery Templates to achieve your purpose.
Here's the sample code, if your still trying to figure it out.

Wordpress jQuery to PHP data transfer

everyone. I'm a relatively new developer with limited experience in jQuery AJAX and PHP. I'm working on a Wordpress plugin that is very much a learning exercise for me as well.
Basic description: On my plugin's admin page, I have a bunch of forms that will be displayed as modal windows (using jQuery UI) and when filled out, will submit their fields to a separate PHP file for processing. That file will accept the data and prepare it for insertion into the wpdb table I have set up.
Plugin Admin page (PHP):
<div id="form1" title="My Awesome Form">
<form id="frmNewCom">
<fieldset>
<table>
<tr>
<td><label for="name">Community Name</label>
<td><input type="text" name="newComName" id="newComName" />
</tr>
<tr>
<td><label for="lefthead">Left Column Header</label></td>
<td><input type="text" name="newComLefthead" id="newComLefthead" /></td>
</tr>
<tr>
<td><label for="righthead">Right Column Header</label></td>
<td><input type="text" name="newComRighthead" id="newComRighthead" /></td>
</tr>
</table>
</fieldset>
</form>
</div>
jQuery UI code for form ($pcal is my no-conflict thing):
$pcal('#form1').dialog({
autoOpen: false,
height: 275,
width: 400,
modal: true,
buttons: {
"Add Living Option": function() {
// Functionality for submit
},
Cancel: function() {
$pcal(this).dialog("close");
}
},
close: function() {
// close function
}
});
Now here's the problem. I'm not really sure what to do from this point. I've read a bunch of stuff about using .post() and .serialize(), and I've gotten myself very confused at this point.
Do you guys have some insight into the proper javascript/jQuery to PHP handling you could lend? I've asked this on the Wordpress forum as well, but I've always found good advice here, so thought I'd ask. Any and all help is appreciated.
A very simple example would be :
$pcal.post("test.php", $pcal("#frmNewCom").serialize(), function() {
// this will run once returned from PHP
alert('thanks');
$pcal(this).dialog("close");
});
This posts the form (id = frmNewCom) in a serialized format (newComName=1&newComLefthead=2&newComName=3 where 1,2 and 3 are the values entered in your form) using .post() and .serialize()
then in test.php you would access your values like this :
$newComName = $_POST['newComName'];
$newComLefthead = $_POST['newComLefthead'];
$newComName = $_POST['newComName'];
// insert into table
The above is a) untested and b) does not contain any prevention against SQL injection should you want to store this in a DB

Categories