I have a table of customers. Each customer has a first and a last name. The two text fields of the table are editable. So users can update the information when they press Save. The problem is that I cannot get the specific row information,I only get the first row results
I tried to match to the names with the input field but I had no success.
<?php foreach($customer as $each){ ?>
<td class="first_name" id="first" contenteditable="true"><?php echo
$each['first_name']; ?></td>
<td class="last_name" id="last" contenteditable="true"><?php echo
$each['last_name']; ?></td>
<td > <button type="button" onclick="save('<?php echo $each['first_name'];?
>','<?php echo $each['last_name'];?>');" >Save</button></td>
<? } ?>
<script type="text/javascript">
function save(first,second) {
<?php foreach($customer as $each){?>
var first_name = "<?php echo $each['first_name']?>";
var last_name = "<?php echo $each['last_name']?>";
if (first_name==first && last_name == second){
var fname = document.querySelectorAll(".first_name");
console.log(fname[0]);
}
<?php } ?>
}
</script>
You would have to use a different query selector. Assign a classname or an attribute to the elements you want to select (e.g name for querying with .name) then querySelectorAll method will return an array of the elements that matched your query.
The main problem that I see is that you create unnecessary foreach loop inside a javascript function using php.
You can dynamically create your table and the contents inside it, that's fine. But the javascript does not care about that and you should not create javascript with php. So I would do it this way.
I wrap the td's in tr's cause i'm assuming you are putting that data in tr.
<?php foreach($customer as $each){ ?>
<tr class="customer-row">
<td class="first_name" contenteditable="true"><?php echo
$each['first_name']; ?></td>
<td class="last_name" contenteditable="true"><?php echo
$each['last_name']; ?></td>
<td><button type="button" class="save">Save</button></td>
</tr>
<? } ?>
Then outside the php foreach loop i would create my script.
<script type="text/javascript">
var saveBtn = document.querySelectorAll(".save");
for(var i = 0; i < saveBtn.length; i++) {
// attach click event to every button.
saveBtn[i].addEventListener("click", function() {
var _this = this;
var _tr = _this.closest(".customer-row");
var fname = _tr.querySelector(".first_name").innerText;
var lname = _tr.querySelector(".last_name").innerText;
console.log("Name: ", fname + " " + lname");
// below you can implement your check name logic...
}
}
</script>
I'm not 100% sure if my js will not throw errors, but it should give you an indication that you should separate your server-side from client-side logic.
Related
I need to update a row of a table. So when I click on a cell, I want it to be transformed into text box, so I used this:
<td contenteditable></td>
And then, when the content of a <td> is changed, I need to send it through AJAX to update it in the server without clicking on a button, so it will use the .change(function()).
I tried to get the content changed into a variable:
$("TD").change(function()
{
//Here I want to set the row ID:
var rowid = '<?php echo $row['id'] ?>';
var name = $("#emp_name").val();
var position = $("#position").val();
var salary = $("#salary").val();
$.ajax
({
url: 'update.php',
type: 'POST',
data: {dataId: rowid, data1: name, data2: position, data3: salary},//Now we can use $_POST[data1];
dataType: "text",
success:function(data)
{
if(data=="success")
{
//alert("Data added");
$("#before_tr").before("<tr><td>"+emp+"</td><td>"+pos+"</td><td>"+sal+"</td></tr>");
$("#emp_name").val("");
$("#position").val("");
$("#salary").val("");
}
},
error:function(data)
{
if(data!="success")
{
alert("data not added");
}
}
});
});
The problem is how to know which row is changed to send it via AJAX ? I am not getting any errors even when data not updated.
Here is the update.php code:
try
{
$rowid = $_POST['dataId'];
$emp_name = $_POST['data1'];
$pos = $_POST['data2'];
$sal = $_POST['data3'];
$upd = "UPDATE emp SET name = :emp_name, position = :pos, sal = :sal WHERE id = :rowid";
$updStmt = $conn->prepare($upd);
$updStmt->bindValue(":rowid", $rowid);
$updStmt->bindValue(":emp_name", $emp_name);
$updStmt->bindValue(":pos", $pos);
$updStmt->bindValue(":sal", $sal);
$updStmt->execute();
echo "success";
}
catch(PDOException $ex)
{
echo $ex->getMessage();
}
HTML:
<tbody>
<?php
$sql = "SELECT * FROM employee";
$stmt=$conn->prepare($sql);
$stmt->execute();
$res=$stmt->fetchAll();
foreach($res as $row){
?>
<tr id=""<?php echo $row['id'] ?>"">
<td contenteditable><?php echo $row['emp_name'] ?></td>
<td contenteditable><?php echo $row['position'] ?></td>
<td contenteditable><?php echo $row['salary'] ?></td>
</tr>
<?php } ?>
When loading your data with PHP you need to keep the row id in your html:
<tr id="<?php echo $yourList["id"]; ?>">
<td contenteditable></td>
</tr>
Then in your javascript you can catch it using the parent() jquery function
$("TD").change(function()
{
//Here I want to set the row ID:
var rowid =$(this).parent().attr("id");
......
UPDATE
Check this example, I have added listeners to detect contenteditable td changes, I think you shall add it too , refer to this contenteditable change events for defining proper change events on contenteditable fields.
Explanation:
The contenteditable does not trigger change events, this work around is used to detect the focus event of the td using jquery on method and event delegation. The original content is saved in the td jquery data object $this.data('before', $this.html()); . Then when the user leaves the field or triggers any of the events 'blur keyup paste input', the current content is compared to the content in the data object, if it differs, the change event of the td is triggered.
$(document).ready(function(){
$('table').on('focus', '[contenteditable]', function() {
var $this = $(this);
$this.data('before', $this.html());
return $this;
}).on('blur keyup paste input', '[contenteditable]', function() {
var $this = $(this);
if ($this.data('before') !== $this.html()) {
$this.data('before', $this.html());
$this.trigger('change');
}
return $this;
});
$("TD").change(function()
{
//Here I want to set the row ID:
var rowid = $(this).parent().attr("id");
$("#res").html(rowid);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table border="1" width="500px">
<tr id="1222">
<td contenteditable></td>
</tr>
<tr id="55555">
<td contenteditable></td>
</tr>
</table>
Row Id : <span id="res"></span>
<tr row_id="<?php echo $row['id'] ?>"> ></tr>
In Your Ajax
var rowid = $(this).attr('row_id');
I need help with a feature for my site. I just cant make the script work.
I have this site:
http://imgur.com/oMy69yx
As you can see, there is one "Edit" button for each row. The goal here is that when the user press one of those, the row gets editable (except for the subject name) and the button changes to "Save". Then the user can edit all he wants and save it. When he clicks "Save" I get all fields that were changed and update via SQL query.
PS:The number of rows is undefined because the user can input as many rows as he wants.
So I thought in some script like this:
var button = document.getElementByClassName("clicker");
var buttonclicked = function(){
button.textContent = "Save"; //And things get editable};
button.addEventListener("click", buttonclicked);
But this wont work because var button is an array of buttons, and the addEventListener wont work with that...
What can I do to solve this?
This is the HTML generating the table: (Might be a little bit messy)
<?php $i = 0;?>
<?php foreach ($rows as $row): ?>
<tr class="d1">
<td><?php echo $row["subject"] ?></td>
<td>
<?php
if($row["G1"] != -1)
echo $row["G1"];
?>
</td>
<td>
<?php
if($row["G2"] != -1)
echo $row["G2"];
?>
</td>
<td>
<?php
if($row["G3"] != -1)
echo $row["G3"];
?>
</td>
<td>
<?php
if($row["G4"] != -1)
echo $row["G4"];
?>
</td>
<td>
<?php
$round = round($row["normal"],2);
echo $round;
?>
</td>
<td><?= $row["creditos"] ?></td>
<td><?php echo $row["criteria"];?></td>
<td><?php echo "<button id = clicker.$i>Edit</button>"; ?></td>
</tr>
<?php $i++; ?>
<?php endforeach ?>
You can assign to each button via for loop:
var buttons = document.getElementsByClassName("clicker");
var buttonclicked = function(e){
e.target.textContent = "Save"; //And things get editable};
for(var i = 0; i < buttons.length; i++)
{
buttons[i].addEventListener('click', buttonclicked);
}
Also notice that I'm working on e.target in the buttonclicked function, rather than button, so that we get the right button each time.
The e is the event object that holds information about the onclick event. If you look at the buttonclicked variable you see it's assigned function(e) now instead of just function().
While loop creates rows, but below function only pick value of first row td and put in textbox, i want it pick the value of td which has been clicked. not first one. Please help
while($row = $result->fetch_assoc()){
<tr>
<td id='tbltd' onclick='getstock_id();'>",$row["stock_id"],"</td></tr>
}
<script>
function getstock_id() {
var myBox1 = document.getElementById("ab").innerHTML;
var result = document.getElementById('stk');
result.value = myBox1;
}
</script>
You should not have multiple id with same value in a document. In your case, first element is being selected in document.getElementById("ab").innerHTML
Try this:
<?php
while($row = $result->fetch_assoc()){
?>
<tr>
<td id='tbltd' onclick='getstock_id("<?php echo $row["stock_id"]; ?>");'><?php echo $row["stock_id"]; ?></td></tr>
<?php
}
?>
<script>
function getstock_id(val) {
var result = document.getElementById('stk');
result.value = val;
}
</script>
Try to passed in your function param the node reference like that:
while($row = $result->fetch_assoc()){
<tr>
<td id='tbltd' onclick='getstock_id(this);'>",$row["stock_id"],"</td></tr>
}
<script>
function getstock_id(refNode) {
document.getElementById('stk').value = refNode.innerHTML;
}
</script>
My script’s AJAX calls the following PHP file and prints a table with $attrib and text boxes.
Can somebody tell me how to collect the $attrib and text box in an array or something like that?
Code tried is giving values like "assetattrib%5B%5D=model". So please help me to correct this or show me a new way to do the same.
echo "<table border='1' cellspacing='12' cellpadding='4' style='border-collapse: collapse' width='700' id=addattrib >";
while ($row = mysql_fetch_assoc($results)) {
$attrib = $row['attrib'];
echo "<tr bgcolor='white'>
<td class='value'>$attrib</td>
<td class='value'><input type=text name=assetattrib[] value = '' </td>
</tr>";
}
echo "</table>";
echo "<input type=submit name='btnSaveAsset' id = 'btnSaveAsset' value='Save' >";
I tried the code below.
$(document).on("click", "#btnSaveAsset", function() {
$(document.getElementsByName('assetattrib[]')).each(function() {
var x = $(this).serialize();
alert(x);
});
});
IMPORTANT:
PHP mysql_ extension is deprecated and using it represents a major security issue. According to php.net
This extension is deprecated as of PHP 5.5.0, and has been removed as of PHP 7.0.0. Instead, either the mysqli or PDO_MySQL extension should be used.
Now the actual answer:
I suggest some changes in your HTML, if you can make them:
Wrap the table where the <input>s are into a <form> element
Give the generated <input>s the name attribute given by $attrib, for example <input name="user" />
If you cannot modify the PHP/HTML code let me know and we'll find a workaround
I updated your jsfiddle using this changes. Your PHP code should end up like this:
<form id="btnSaveAsset" onsubmit="return false;">
<table border='1' cellspacing='12' cellpadding='4' style='border-collapse: collapse' width='700' id='addattrib'>
<?php while ($row = mysql_fetch_assoc($results)) {
$attrib = $row['attrib']; ?>
<tr bgcolor='white'>
<td class='value'><?php echo $attrib; ?></td>
<td class='value'><input type='text' name='<?php echo $attrib; ?>' /> </td>
</tr>
<?php } ?>
</table>
<input type=submit name='btnSaveAsset' id='btnSaveAsset' value='Save' />
</form>
Then, you collect your data with one of this options:
$(document).on("click", "#btnSaveAsset", function () {
var data = $("#myForm").serializeArray();
console.log(data); // Array of objects
});
OR
$(document).on("click", "#btnSaveAsset2", function () {
var tempData = $("#myForm").serializeArray();
var data = {};
$.each(tempData, function () {
data[this.name] = this.value;
});
console.log(data); // Just an object
});
Here is the jsfiddle updated: http://jsfiddle.net/jormaechea/sy0wx8gb/1/
Check your JS console (Press F12 and go to Console tab) to see the results.
I have a simple table filled with rows from a MySQL database, the HTML part looks like this
<tbody>
<?php while($row = mysqli_fetch_row($result)){ ?>
<tr class="rows" id="<?php echo $row[0]; ?>"> // the id is an auto incremented int
<td id="col1"><?php echo $row[1]; ?></td>
<td id="col2"><?php echo $row[2]; ?></td>
<td id="col3"><?php echo $row[3]; ?></td>
<td id="col4"><?php echo $row[4]; ?></td>
<td id="col5"><?php echo $row[5]; ?></td>
</tr>
<?php } ?>
</tbody>
It gets the job done and I have a nice table. Now I want that if I click on a row, i get five variables with the values of the cells.
The problem what stopped me was to get the <td> element. This is what I tried in the external javascript file:
var rows = document.getElementsByClassName('rows');
for (var i=0; i<rows.length; i++){
rows[i].onclick = function(){
console.log(this.getElementById('col1')); // I tried to print it first
}
}
The console responded this: Uncaught TypeError: undefined is not a function.
Then I tried console.log(rows[i].getElementById(vonalkod));, but it responded Uncaught TypeError: Cannot read property 'getElementById' of undefined
If I only write console.log(this); then it prints what I expect, the whole row in html.
So my question is that what is the syntax to get those cells by ID?
What you can do to get the contents of a cell is
document.getElementById('col1').innerHTML
Now, having said that, it will only work if you have ONE col1: if you have more than one of these <tr>s each will have five tds like <td id=col1>, the same for the rest of the id-s. That's invalid HTML. Consider replacing those id-s with classes, or with additional PHP.
Or, better yet, you can forgo all these clumsy id-s entirely and use something like:
rows[i].onclick = function() {
console.log(this.childNodes[0].innerHTML); // col1
console.log(this.childNodes[1].innerHTML); // col2
// ... etc
}
It doesn't work because the object this is a HTMLTableRowElement (see http://www.w3.org/2003/01/dom2-javadoc/org/w3c/dom/html2/HTMLTableRowElement.html)
Here a library as jQuery comes very handy. Your script written using jQuery is as easy as
jQuery('.rows').click(function(){
alert(jQuery(this).children('#col1').text());
});