Solved

update field on focusout

Posted on 2016-11-20
15
61 Views
Last Modified: 2016-11-20
I seem to have 2 problems here. Firstly, the updating... text shows on the first row of the table always, instead of showing on the row where I am actually editing the textfield.

Secondly, the edit works the first time around but if I go back to the page and edit again, then go back to the page ,it has copied the record above it for some reason. I don't understand why.

$(document).ready(function(){
			
			$(document).on('focus', '.data[name="category"]',function() {
				var tr = $(this).closest('tr');
				var id = $(this).attr('id');
				var category = $(this).val();
				
				$(document).on('focusout', '.data[name="category"]', function(){
					var newName = $(this).val();
					if(newName!=category){
						$.ajax({
							
							url: "updatecat.php",
							type: "POST",
							data: {
								id: id,
								newName: newName
							},
							beforeSend: function() {
								$('#status').html("updating...");
							},
						});
						
					} 
					 

				});
				   
			}); 
				
		}); 

Open in new window




if($_POST['newName'] && $_POST['id']) {
	
	$stmt = $link->prepare("UPDATE `voucher_categories` SET `category_name` = ? WHERE `cat_id` = ? LIMIT 1");
	$stmt->bind_param("si", $_POST['newName'], $_POST['id']);
	$stmt->execute();
	$stmt->close();
	}

Open in new window

0
Comment
Question by:Black Sulfur
  • 6
  • 5
  • 4
15 Comments
 
LVL 109

Expert Comment

by:Ray Paseur
ID: 41894788
Please post the HTML markup associated with this question, thanks.

As a general rule, when you have a jQuery question, it helps if we can see HTML, CSS, and JavaScript at the same time.
0
 

Author Comment

by:Black Sulfur
ID: 41894795
Apologies,

html:

<tr>
<td id="status"><input id="{$pid}" class="data" type="category" name="category" value="{$categoryName}"></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td><a> <i class="pe-7s-trash" id='$pid'></i> </a></td>
</tr>

Open in new window


The css is just to hide the borders around the textfields:

input[type=category] {
	border: none;
	width: 300px;
	background: none;
}

Open in new window


      
		$(document).ready(function(){
			
			$(document).on('focus', '.data[name="category"]',function() {
				var tr = $(this).closest('tr');
				var id = $(this).attr('id');
				var category = $(this).val();
				
				$(document).on('focusout', '.data[name="category"]', function(){
					var newName = $(this).val();
					if(newName!=category){
						$.ajax({
							
							url: "updatecat.php",
							type: "POST",
							data: {
								id: id,
								newName: newName
							},
							beforeSend: function() {
								$('#status').html("updating...");
							},
							
							  success: function(result) {
							 swal("Updated!", "Category successfully updated.", "success");
							  },
						});
						
					} 
					 

				}); 
				   
			}); 
				
		}); 

Open in new window

0
 
LVL 109

Expert Comment

by:Ray Paseur
ID: 41894824
Feels like we are still working with fragments of an application here.  Example:
$('#status').html("updating...");

Open in new window

This line of code tells jQuery to find the div with id="status" and replace its HTML with "updating..." but there is no <div id="status" /> tag in the HTML.

Maybe if you can just tell us in plain language what you're trying to do, we could help find an example that demonstrates the design.
0
How Do You Stack Up Against Your Peers?

With today’s modern enterprise so dependent on digital infrastructures, the impact of major incidents has increased dramatically. Grab the report now to gain insight into how your organization ranks against your peers and learn best-in-class strategies to resolve incidents.

 
LVL 109

Expert Comment

by:Ray Paseur
ID: 41894827
Or, check that... Maybe the <td id=status" is what jQuery will find.

In any case, unless the value in newName does not equal the value in category, the AJAX request will not run.
0
 
LVL 109

Accepted Solution

by:
Ray Paseur earned 250 total points
ID: 41894831
This combination seems to show the interaction of the client and server-side scripts.

First the server - just a reflector to show what the client sent.
<?php // demo/temp_blacksulfur_server.php
/**
 * https://www.experts-exchange.com/questions/28984270/update-field-on-focusout.html
 */
ini_set('display_errors', TRUE);
error_reporting(E_ALL);

// REFLECT THE POST REQUEST VARS
die( 'POST: ' . var_export($_POST, TRUE) );

Open in new window

Next the client - with a few console.log() statements mixed in to help visualize the JS variables.
<?php // demo/temp_blacksulfur_client.php
/**
 * https://www.experts-exchange.com/questions/28984270/update-field-on-focusout.html
 */
error_reporting(E_ALL);


// MAKE SURE THAT PHP WORKS WITH UTF-8
mb_internal_encoding('UTF-8');
mb_regex_encoding('UTF-8');


// USE PHP (AND/OR MAYBE MySQL) TO CREATE VARIABLES FOR OUR HTML
$pid = 3;
$categoryName = " Murray #$pid";


// CREATE OUR WEB PAGE IN HTML5 FORMAT, USING HEREDOC SYNTAX
$htm = <<<HTML5
<!DOCTYPE html>
<html dir="ltr" lang="en-US">
<head>
<meta charset="utf-8" />
<meta name="robots" content="noindex, nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<style type="text/css">
input[type=category] {
	border: none;
	width: 300px;
	background: none;
}
</style>

<script src="https://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).ready(function(){

    $(document).on('focus', '.data[name="category"]',function() {
        var tr = $(this).closest('tr');
        var id = $(this).attr('id');
        console.log(id);
        var category = $(this).val();
        console.log(category);

        $(document).on('focusout', '.data[name="category"]', function(){
            var newName = $(this).val();
            console.log(newName);
            if(newName != category){
                $.ajax({
                    url: "temp_blacksulfur_server.php",
                    type: "POST",
                    data: {
                        id: id,
                        newName: newName
                    },
                    beforeSend: function() {
                        $('#status').html("updating...");
                    },
                    success: function(result) {
                        alert(result);
                    }
                });
            }
        });
    });
});
</script>

<title>HTML5 Page With jQuery in UTF-8 Encoding</title>
</head>
<body>

<noscript>Your browsing experience will be much better with JavaScript enabled!</noscript>

<tr>
<td id="status"><input id="{$pid}" class="data" type="category" name="category" value="{$categoryName}"></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td><a> <i class="pe-7s-trash" id='$pid'></i> </a></td>
</tr>

</body>
</html>
HTML5;


// RENDER THE WEB PAGE
echo $htm;

Open in new window

0
 

Author Comment

by:Black Sulfur
ID: 41894833
status in the html I posted in my previous post in this line:

<td id="status"><input id="{$pid}" class="data" type="category" name="category" value="{$categoryName}"></td>

Open in new window



What I am trying to do is list a set of records which I am doing with php looping through records in the database. I am using heredoc to display them:

$showcat = <<<EOD
		
<tr>
<td id="status"><input id="{$pid}" class="data" type="category" name="category" value="{$categoryName}"></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td><a> <i class="pe-7s-trash" id='$pid'></i> </a></td>
</tr>
		
EOD;
echo $showcat;

Open in new window


All the records are in text fields but I am hiding the borders with css so that they don't look like text fields. If I click on any text of the displayed records I can obviously type something else in or edit the text because they are in fact text fields. When i click outside of the text field or press tab on my keyboard the record should update. The word "updating..." must also show when you perform this action. The sweet alert then shows up once completed and that particular record should be updated in the database.
0
 

Author Comment

by:Black Sulfur
ID: 41894835
Thanks for the console log. Something strange is happening. If I edit a record and hit tab on the keyboard it works okay as long as it's the last record and it can't tab into another field. It also works if I click out of all the fields somewhere else on the page. If I click on any other field though after altering text in a field, console log shows that the record I initially tried to update copies the data from whatever field I click into next, and then gets stuck in some sort of loop as every time I close the alert, it does it again and again and again.
0
 
LVL 82

Expert Comment

by:leakim971
ID: 41894851
you create a new onfocus each time you focus the object, it's not good.
change your logic, for example save initial/last value of your textbox and compare it when focusout/blur
Else, the easy fix would be to use jQuery.one instead jQuery.on for your focusout part :
$(document).ready(function(){

	$(document).on('focus', '.data[name="category"]',function() {
		var tr = $(this).closest('tr');
		var id = $(this).attr('id');
		var category = $(this).val();

		$(document).one('focusout', '.data[name="category"]', function(){ // We use jQuery.one instea jQuery on
			var newName = $(this).val();
			if(newName!=category){
				$.ajax({
					url: "updatecat.php",
					type: "POST",
					data: {
						id: id,
						newName: newName
					},
					beforeSend: function() {
						$('#status').html("updating...");
					},
					complete: function() {
						$('#status').html(""); // fire after success or error, what do you think ?
					},
					success: function(result) {
						swal("Updated!", "Category successfully updated.", "success");
					}
					error: function() {
						swal("Error!", "Category NOT updated!!!!", "error"); // also three lines to save time :D
					}
				});
			} 
		}); 
	}); 

}); 

Open in new window

0
 

Author Comment

by:Black Sulfur
ID: 41894859
Okay, great! Using one instead of on helped with my problem but only if I changed it on my code. If I copy and paste your code nothing works. The database record is not updated, the status message doesn't show and sweet alert never fires. My code is working now expect that the updating text still always shows in the first record row instead of the row I am actually updating.

      
	$(document).ready(function(){

    $(document).on('focus', '.data[name="category"]',function() {
        var tr = $(this).closest('tr');
        var id = $(this).attr('id');
        console.log(id);
        var category = $(this).val();
        console.log(category);

        $(document).one('focusout', '.data[name="category"]', function(){
            var newName = $(this).val();
            console.log(newName);
            if(newName != category){
                $.ajax({
                    url: "updatecat.php",
                    type: "POST",
                    data: {
                        id: id,
                        newName: newName
                    },
                    beforeSend: function() {
                        $('#status').html("updating...");
                    },
                    success: function(result) {
                       swal("Updated!", "Category successfully updated.", "success");
                    }
                });
            }
        });
    });
});

Open in new window

0
 
LVL 82

Expert Comment

by:leakim971
ID: 41894863
cool, for a sure typo in mine as I write it on the fly...
0
 

Author Comment

by:Black Sulfur
ID: 41894866
So, the million dollar question is...

How do I get this to show on the actual row I am updating?

 $('#status').html("updating...");

Open in new window

0
 
LVL 82

Assisted Solution

by:leakim971
leakim971 earned 250 total points
ID: 41894879
Sir Paseur was right, you're overwriting your textbox with : html("updating...")
this one add a bit of code  :
$(document).ready(function(){

	$(document).on('focus', '.data[name="category"]',function() {
  	var td = $(this).closest("td");
		var tr = $(this).closest('tr');
		var id = $(this).attr('id');
		var category = $(this).val();

		$(document).one('focusout', '.data[name="category"]', function(){
			var newName = $(this).val();
			if(newName!=category){
				$.ajax({
					url: "updatecat.php",
					type: "POST",
					data: {
						id: id,
						newName: newName
					},
					beforeSend: function() {
						$('input',td).hide();
            $('<span>updating...</span>').appendTo(td);
					},
					complete: function() {
              $('span',td).remove();
              $('input',td).show();
					},
					success: function(result) {
						swal("Updated!", "Category successfully updated.", "success");
					},
					error: function() {
						swal("Error!", "Category NOT updated!!!!", "error");
					}
				});
			} 
		}); 
	}); 

}); 

Open in new window

0
 
LVL 109

Expert Comment

by:Ray Paseur
ID: 41894943
Seems like the tab key would trigger Out-of-focus for the current position and In-to-focus for the next position, right?

How many fields have id="status" after you've created the record display with HEREDOC.  If it's more than one, the outcome is probably unpredictable.
0
 

Author Comment

by:Black Sulfur
ID: 41894965
Okay, it's working now! :)

Not sure how to split the points though because you were both really helpful.
0
 
LVL 82

Expert Comment

by:leakim971
ID: 41895023
I believe Sir Paseur pointed the issue from the beggining (the fact you're overwritting the textbox) so why not 50/50 ?
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
What's wrong with this PDO query? 5 27
IFrame in MVC 2 23
Extracting store locations from Google maps or site 2 22
JS Event Does not Trigger From File 2 24
Introduction A frequently asked question goes something like this:  "I am running a long process in the background and I want to alert my client when the process finishes.  How can I send a message to the browser?"  Unfortunately, the short answer …
Introduction If you're like most people, you have occasionally made a typographical error when you're entering information into an online form.  And to your consternation, the browser remembers the error, and offers to autocomplete your future entr…
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

840 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question