Below is a simplified example that demonstrates the problem I am having. One hundred percent of code is posted below.
Three files work together: testa.php, testb.php, and testc.js. (FWIW, testa.php could function as the index.php, but this is just a demo)
OVERVIEW:
TESTA.PHP
When user clicks anchor tag, sends value to testb.php
Receives ajax response from testb.php into div #reportstable, within FORM structure
Form is submitted to itself, so it prints $_POST data -
TESTB.PHP
receives value from TESTA.PHP, via ajax
outputs table that corresponds to received values
(In this example, I removed how received value is used, but still retained this structure as it affects the jQuery in testc.js)
TESTC.JS
the jQuery that makes it (partially) work
PROBLEM 1: If user adds more than one "document" (i.e. row), only data for the last document appears in the POST data..
PROBLEM2: DocTitle and FileName IDs (dt1, fn1) are not POSTED as they appear in the DOM. In the DOM, their IDs are incremented properly (dt11, dt12, dt13, etc) but when POSTed only one comes through and it has not been incremented. (Use firebug to inspect table elements after adding a couple of documents.
PROBLEM3: First click doesn't "take" when clicking the "choose file" anchor when adding a new document. Any thoughts on this one?
TESTA.PHP
<?php
If (empty($_POST)===false) {
echo '<pre>';
print_r($_POST);
echo '</pre>';
die();
}
?>
<html><body>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="jquery-custom-file-input.js"></script>
<script type="text/javascript" src="testc.js"></script>
<br />
Project*:<br />
Click Me
<form action="" method="post">
<div id="reportstable">
</div>
</form>
</body></html>
TESTB.PHP
<?php
$project_id = $_POST['project_id'];
if ($project_id == 5) {
echo '
<table id="DocTable">
<tr>
<th width="150">Document Title</th>
<th width="150">File Name</th>
</tr>
<tr name="tr2" id="tr2" style="display:none;">
<td><input type="text" name="dt1" id="dt1"></td>
<td>
<input type="hidden" name="fn1" id="fn1">
<span id="sp1">choose file<span>
</td>
</tr>
</table>
<br />
add document<br />
<br />
<input type="submit" name="submit" id="submit_it" value="Submit">
';
}
TESTC.JS
$(function(){
var count = 1;
//*******************************************************************
$('#project_pick').click(function(e) {
$(this).hide();
$.ajax({
type: "POST",
url: "testb.php",
data: "project_id=5",
success:function(data){
$('#reportstable').html(data);
}
});
});
//*******************************************************************
$(document).on('click','#ah11',function() {
$(this).file().choose(function(e, input) {
$('#fn11').val(input.val());
$('#sp11').html(input.val());
$('#sp11').css('color','grey');
});
});
//*******************************************************************
$(document).on('click','#ah12',function() {
$(this).file().choose(function(e, input) {
$('#fn12').val(input.val());
$('#sp12').html(input.val());
$('#sp12').css('color','grey');
});
});
//*******************************************************************
$(document).on('click','#ah13',function() {
$(this).file().choose(function(e, input) {
$('#fn13').val(input.val());
$('#sp13').html(input.val());
$('#sp13').css('color','grey');
});
});
//*******************************************************************
$(document).on('click', '#add_row', function() {
$("table#DocTable tr:nth-child(2)")
.clone()
.show()
.find("a, input, span, tr").each(function() {
$(this)
.val('')
.attr('id', function(_, id) {
return id + count;
});
})
.end()
.appendTo("table");
count++;
if (count == 4) {
$('#add_row').prop('disabled', 'disabled');
}
}); //end fn add_row
//*******************************************************************
$(document).on('click', '#submit_it', function() {
alert('This will be submitted now');
});
//*******************************************************************
});
It seems in your javascript that you are changing the values of the id attribute only. However, when you post a form, the id attribute is irrelevant and not posted, you need the name attribute instead.
So where you are changing id's, you really should be changing names (and id's to if you really need them as they need to be unique).
However, a far easier solution would be to use arrays for names, like:
<input type="text" name="dt[]">
If you copy / clone elements with these names and post the form, you will get an array in your $_POST['dt'].
Related
I have a problem with my code. I have a php script where i, in a while, i write a table in html with html name and html value attr with the data of database, like the printscreen above
My table was assembled with input inside the TDs, to be able to "edit" directly in the table, without MODAL or redirection
</thead>
<tbody id="corpoTabela">
<?php
$i = 1;
while ($row = mysqli_fetch_array($result)) :;
?>
<tr>
<form name="presencaForm" id="presencaForm" method="POST">
<input type="hidden" id="idcrmmedico" name="idcrmmedico" value="<?php echo $row['id']; ?>"></input>
See that the opening of the form tag is inside the while, that is, for each row of the table, for each TR, I have a form (all with the same name)
The end of the form tag still inside php while. The Button, who receives the ID referring to the record in the DB, has the same name of the form
<td><button id="d" name="presencaForm" value="<?php echo $row['id'] ?>" class="btn btn-sm btn-info">Atualizar</a></td>
<td>
<button type="submit" id="" name="deletamedico" class="btn btn-sm btn-danger">Excluir</button>
</td>
</form>
</tr>
<?php
endwhile;
}
?>
</tbody>
This is my ajax script, which updates the data in the database without refreshing the page and returning me a success message.
<script>
$(document).ready(function() {
$('#presencaForm').on('submit', function(event) {
event.preventDefault();
$("#alert").css('display', 'none');
console.log("Botão Clicado!");
$.ajax({
url: "DAO/medico/update.php",
method: "POST",
data: $(this).serialize(),
dataType: "json",
success: function(data) {
if (data[0] == true) {
$("#success").html('Médico ' + data[1] + ' atualizado com sucesso');
$("#success").show();
setTimeout(function() {
$("#success").hide();
}, 5000);
}
}
})
});
});
</script>
The problem is that if i try to refresh the second line, the page just refreshes.
I used the code below to check, and I saw that all buttons return only the first record in the LOG.
Is there any way to update the data as I want, right in the table?
$(document).ready(function() {
$("button[name='presencaForm']").on("click", function(event) {
event.preventDefault();
for (var i = 1; i < document.getElementById("dataTable").rows.length; i++) {
console.log($('#idcrmmedico').val());
}
var val = document.getElementById('d').value;
var x = document.getElementById("dataTable").rows.length;
});
id is unique,if you want to control a group of form,you can use class.
For example:
<form class="presencaForm" method="POST">
Then in your javascript:
$('.presencaForm').on('submit', function(event) {
<script type="text/javascript" src="../js/jquery-1.4.1.min.js"></script>
<script type="text/javascript">
$("#submit").click(function (){
var name =$("#name").val();
var mobile =$("#mobile").val();
var email =$("#email").val();
$.get('new.php',{name : name, mobile: mobile, email: email},function (data){
$("#res").html(data);
});
$("#name").val("");
$("#mobile").val("");
$("#email").val("");
$("#res").hide(10000);
});//submit.click end here!!!!!!!
$("#view").click(function(){
var view='view';
$.post('new.php',{view: view},function(data){
$("#viewdata").html(data);
});
$("#viewdata").toggle("slow");
});//to display data in table!!!!!!!
$("#add").click(function(){
$("#addnew").toggle("slow");
});//toggel button for record table!!!!!
$("body").on('click','',function(){
var iddata =this.id.split('-');
var id = iddata[1];
alert(id);
});
</script>
if(isset($_POST['view']))
{
$query="select * from userdetail";
$res=mysql_query($query);
echo "<table border=1>
<tr><th>name</th><th>Mobile</th><th>Email</th><th>Delete</th><th>Update</th></tr>";
while($row=mysql_fetch_array($res))
{
echo "<tr><td>".$row[1]."</td><td>".$row[3]."</td><td>".$row[4]."</td>";
echo "<td><div class='del' id='id-".$row[0]."';>Delete</div></td>";
echo "<td><a href='#'>Update</a></td>";
}
echo"</table>";
}
<body>
<div id="addnew" style="width:500px; float:left;">
<div style="width:200px; float:left;">
<form name="frm" id="frm">
<input type="text" id="name"></br>
<input type="text" id="mobile"></br>
<input type="text" id="email"></br>
<input type="button" id="submit" value="submit"/></br>
</form>
</div>
<div id="res" style="width:300px; float:left;">
</div>
</div>
<button id="add">Add New</button>
<button id="view">View</button>
<div id="viewdata">
<table border=1>
<tr>
<th>name</th><th>Mobile</th><th>Email</th><th>Delete</th><th>Update</th>
</tr>
</div>
</body>
I'm new in jquery and trying to learn crud function with jquery and php. I'm working on a code where I can add data through jquery as well as I can retrieve it from database, now I have placed a delete field to delete record from that table but I'm stuck here because I don't know how to get id from that table so I can use it to delete that record from table. I have tried .on and delegate in jquery to get that id but still not getting the result what I want, so please help me to solve this error.
So your html output is going to be something like this for your delete cell
<td>
<div class='del' id='id-1'>Delete</div>
</td>
Within JQuery you can do this:
$('.del').on('click',function() {alert(this.id)});
Result: id-1
Check it out here http://jsfiddle.net/54nptrkd/
By placing id inside while loop, I can fetch it using bellow code
in html page.
I can use
$<'#viewdata'>.on('click','.del',function(){
alert(this.id);
})
It will popup the result like id-31 or id-1 (whatever is selected).
Now you can use that id to delete the record.
.del is a class where id is stored in php file
e.g
< class='del' id=$row['id']>delete
"ok i'm trying and can you refer me some stuff or link to learn delete and update using jquery and php"
Your SQL statement will be something along the lines of
Delete from *TABLE* where id = ?
You most likely will have a Delete.php file that you can run your sql queries the same as you did in your New.php. Delete.php will either listen to a $_POST or $_GET variable
Your JQuery will have an ajax call like this if you are using $_POST in your php
$.ajax('Delete.php?id='+id,{
success: function() {
alert('it worked!')
}
});
or like this if you are using $_GET in your php
$.ajax('Delete.php', {
id: id,
success: function() {
alert('it worked!')
}
});
id will be defined in your JS like I mentioned before
$('.del').on('click',function() {
alert(this.id)
var id = this.id;
//$.ajax call goes here
});
I have a php script that fetches items from database and allows users to vote for them, I give each one of those fetched items a (html form) with one (input text field) and a (submit button) to submit an entered score when clicked, and I have a jQuery script in the very same page that inserts the score via that form to the database without refreshing the page, everything seems to be working just fine except the script has one.
This script allows only the very first (html form) in the loop to submit and this first (html form) affects item that does not follow it in the loop, how to make every form attributed to its item?
Alongside this I also want the script to return a notification for the user who submits the score to inform them whether the data is successfully inserted or failed and when success I want to the score that the user submitted to appear for them after the submission
Any help is appreciated, here is my code:
<body>
<div id="items-wrapper">
<?php //function where i fetch items/records from database $items=g et_items_function($page_id); if(!$items){ echo 'There are no items in this page yet!'; }else{ ?>
<div id="item">
<?php //looping the fetched items/records foreach($items as $item){ $_itemid=$ item[ 'item_id']; $_name=$ item[ 'item_name']; $item_file='path/to/items/name-' .$_name. '-id-'.$_itemid. '.jpg'; ?>
<ul id="responds">
<!--i want to append data here-->
</ul>
<img src="<?php echo $item_file; ?>" />
<form action="setItemScore.php?itemPass=<?php echo $_itemid.'&pagePass='.$_pageid; ?>" method="POST">
<input type="text" name="content_txt" id="contentText" placeholder="Enter score" />
<button id="FormSubmit">Add Score</button>
<img src="images/loading.gif" id="LoadingImage" style="display:none" />
</form>
<?php } ?>
</div>
<?php } ?>
</div>
<script type="text/javascript">
$(document).ready(function() {
//Ajax request to setItemScore.php
$("#FormSubmit").click(function(e) {
e.preventDefault();
if ($("#contentText").val() === '') {
alert("Please enter some text!");
return false;
}
$("#FormSubmit").hide();
$("#LoadingImage").show();
var myData = 'score_value=' + $("#contentText").val();
jQuery.ajax({
type: "POST",
url: "setItemScore.php?itemPass=<?php echo $_itemid.'&pagePass='.$_pageid; ?>",
dataType: "text",
data: myData,
success: function(response) {
$("#responds").append(response);
$("#contentText").val('');
$("#FormSubmit").show();
$("#LoadingImage").hide();
},
error: function(xhr, ajaxOptions, thrownError) {
$("#FormSubmit").show();
$("#LoadingImage").hide();
alert(thrownError);
}
});
});
});
</script>
</body>
Issue #1
You should always use the .submit() method when a form is being submitted rather than the submit button onclick() for two reasons. 1) When using inputs you can hit enter and submit the form bypassing the entire method. 2) .submit() uses the form allowing you to get children items for that form.
With that in mind I would add a class name to the forms that you know are being submitted through ajax like:
<form class="ajax-form" action="setItemScore.php?itemPass=<?php echo $_itemid.'&pagePass='.$_pageid; ?>" method="POST">
...
</form>
Then instead of using .onclick() you can use:
$('.ajax-form').submit(function(e){
...
});
Issue #2
In your AJAX request you are using the following line:
url: "setItemScore.php?itemPass=<?php echo $_itemid.'&pagePass='.$_pageid; ?>",
This is always going to set $_itemid to the last iteration from your above foreach() loop instead of the action from the form.
If you use the method mentioned above in issue #1 then you could simply use the forms action property:
url: $(this).prop('action')
Whereas $(this) is the form.
I'm trying to display multiple checkboxes and then submit the selected checkboxes as HTTP GET (i.e. as parameters in URL string) to the same script:
Here is my simplified test code - test.php:
<html>
<head>
<style type="text/css" title="currentStyle">
#import "http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/redmond/jquery-ui.css";
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>
<script type="text/javascript">
$(function() {
$('#name').dialog({ autoOpen: false, modal: true });
});
</script>
</head>
<body>
<form>
<p><input type="button" value="Select name"
onclick="$('#name').dialog('open');"></p>
<div id="name" title="name">
<?php
$NAMES = array(
'project one',
'project two',
'project three',
);
foreach ($NAMES as $name) {
printf('<p><label><input type="checkbox" name="name" value="%s">%s</label></p>',
urlencode($name),
htmlspecialchars(substr($name, 0, 120))
);
}
?>
</div>
<input type="submit">
</form>
</body>
</html>
But for some reason, when I select the first 2 checkboxes click the "Submit" button (sorry for the non-English name in the screenshot), then the script http://myserver/test.php? is being submitted and not http://myserver/test.php?name=project+one&name=project+two as I would expect.
If I get rid of all JQuery UI stuff, then it works.
What am I doing wrong? (besides using name="name" which is because that's a database table column name and doesn't seem to be the reason for this problem anyway)
UPDATE:
In my real program (not the above test case) I actually have several such dialogs and would like to set some settings in each dialog and only after that that click a Submit button. So the Submit button must be outside the dialog(s).
Thank you!
Assuming all the form inputs are checkboxes you can use the following to compile and submit the details as a GET.
using your original code add the following function
function compileInputs(){
var string = '';
var inputs = new Array();
//loop through all checkboxes
$(':checkbox').each(function(){
if($(this).is(':checked')){
inputs.push($(this).attr('name')+"="+$(this).val());
}
});
string = "?"+inputs.join("&");
window.location.replace(string);
}
you will need to change the names of the inputs from name='name' to name='name[]'
then change the submit to a button as follows:
<input type="button" onClick='compileInputs()' value='submit'>
you will no longer need the <form> tags
for a more selective approach:
//get all checkboxes from div#name
$('div#name :checkbox').each(function(){
if($(this).is(':checked')){
inputs.push($(this).attr('name')+"="+$(this).val());
}
});
//get all checkboxes from div#appsversion
$('div#appsversion :checkbox').each(function(){
if($(this).is(':checked')){
inputs.push($(this).attr('name')+"="+$(this).val());
}
});
//get all checkboxes from div#osversion
$('div#osversion :checkbox').each(function(){
if($(this).is(':checked')){
inputs.push($(this).attr('name')+"="+$(this).val());
}
});
You may need to wrap the whole form in a div and then dialog the new div in the dialog rather than just the div #name
Try this:
$("#submitButton").click(function(){
$("#formId").submit();
});
Should you not do name="name[]" . Then on the form submit (however you submit it (AJAX or non AJAX), you can get the "name" array as your post variable and handle it as you may wish. Correct me if I am wrong
Assuming the dialog is actually the problem, you may have to have your dialogs populate some hidden fields on the page to actually submit.
Here is a very simple sample to get you started.
http://jsfiddle.net/jUH9g/
When you click ok in the dialog it populates the 'names' textbox inside the form that actually gets submitted. In your real code you would change input type="textbox" to input type="hidden"
$("#dlg").dialog({autoOpen: false,
buttons: {
"OK": function () {
var names = "";
$("input:checkbox").each(function () {
if (this.checked) {
names += $(this).val() + ",";
}
});
$("#names").val(names);
}
}
});
I have working script that the user completes inputs on a form and when they submit the form and the content of the form inputs are entered as a table row.
Is there any way of, I think within the JS to make each row have a unique ID and add a delete button to the last colum of each row so the user can delete an individual row.
Thanks for saving a life!!!!
HTML Form
<form id="my_form" action="table_form.php" method="post">
<div style="width:10%; float:left;">
Quantity<br />
<input name="field_1" type="text" id="field_1" size="3" />
</div>
<div style="width:20%; float:left;">
Part Number<br />
<input type="text" id="field_2" name="field_2" />
</div>
<div style="width:30%; float:left;">
Notes<br />
<input name="field_3" type="text" id="field_3" size="45" />
</div>
<div style="width:20%; float:left;">
Unit Price<br />
<input type="text" id="field_4" name="field_4" />
</div>
<div style="width:20%; float:left;">
<br />
<input type="submit" value="Add Row" />
</div>
</form>
<!--
Here we create our HTML table.
Note the ID of the table. This will be used in our javascript file
Our table only contains a header row. All other content will be added dynamically
--><? $rowid = 1; ?>
<table width="100%" id="my_table">
<tbody id="my_table_body">
<tr>
<th width="5%"><div align="left">Qty</div></th>
<th width="19%"><div align="left">Part Number</div></th>
<th width="46%"><div align="left">Notes</div></th>
<th width="15%"><div align="left">Unit Price</div></th>
<th width="15%"><div align="left">Row Total</div></th>
</tr>
</tbody>
</table>
JS
window.addEvent('domready', function(){
$('my_form').addEvent('submit', function(e){
e.stop();
this.set('send', {
onComplete: function( response ){
var data = JSON.decode(response);
inject_row( $('my_table_body'), data );
}
});
var valid_form = true;
$$('#my_form input').each(function(item){
if( item.value == '' ) valid_form = false;
});
if( valid_form ) {
this.send();
} else {
alert('Fill in all fields');
}
});
var inject_row = function( table_body, data ){
var row_str = '<tr width="100%">';
data.each( function(item, index){
row_str += '<td>'+item+'</td>';
});
row_str += '<td><input type="submit" name="deleterow" id="deleterow" value="Delete" /></td></tr>';
var newRow = htmlToElements( row_str );
newRow.inject( table_body );
}
var htmlToElements = function(str){
return new Element('div', {html: '<table><tbody>' + str + '</tbody></table>'}).getElement('tr');
}
});
PHP
<?php
/**
* If nothing is being posted to this script redirect to
* our HTML page.
*/
if( ! $_POST ){
header('Location: newquote.php');
}
// create an empty array for our results
$results = array();
/**
* Stick the values from _POST into our results array
* while also stripping out any html tags
*
* This is where you would perform any required processing
* of the form data such as server side validation or updating
* a database.
*/
foreach( $_POST as $field ){
$results[] = strip_tags( $field );
}
// Echo our results as a JSON encoded string.
echo json_encode( $results );
?>
I agree with J-P, it sounds like you don't need an unique id here.
Since the question is tagged "jquery" I suggest using the live event binding, e.g.
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready( function() {
$(".deleterow").live("click", function() {
$(this).parents("tr:first").remove();
});
});
function foo(id) {
$("#"+id).append('<tr><td>'+(new Date()).getSeconds()+'</td><td>x</td><button class="deleterow">delete</button></td></tr>');
}
</script>
</head>
<body>
<table id="t1">
<tr><td>a</td><td>A</td><td><button class="deleterow">delete</button></td></tr>
<tr><td>b</td><td>B</td><td><button class="deleterow">delete</button></td></tr>
<tr><td>c</td><td>C</td><td><button class="deleterow">delete</button></td></tr>
</table>
<button onclick="foo('t1')">add</button>
</body>
</html>
The function passed to $(document).ready() is invoked when ...well, as the name states, when the document (dom) is ready.
$(".deleterow").live("click", ... : Whenever a click event occurs on an element with the css class "deleterow" the function passed as second parameter is invoked. In this case
function() {
$(this).parents("tr:first").remove();
}
When the function is invoked the this-context is the element where the event occurred. parents("tr:first") returns the first/"nearest" tr element in the ancestor-axis of the current element. remove() is probably self-explaining...
edit: ok, now that the jquery tag is gone....
http://www.jaycarlson.net/blog/2009/04/06/live-events-in-mootools/ shows a live-event binding for mootools. Using that the "new" solution is quite similar to the jquery script
window.addEvent('domready', function() {
// add an onclick handler for all current and future button elements
// within the table id=t1
$('t1').addLiveEvent('click', 'button', function(e){
// a button in t1 has been clicked, this=button element
// get the "nearest" tr in the parent/ancestor-axis
// and remove it
$(this).getParent("tr").dispose();
});
});
This should be unique enough for this project:
var newDate = new Date;
var id = newDate.getTime();
Then it would just be a matter of adding it the row in your loop and linking it to your delete button.
I always use the php function uniqid(). It generates a unique id based on the time in microseconds. PHP Documentation.
You could loop through your results in PHP and add the result from uniqid() to each result before using json_encode().