In-place editing

Similar to Excel-like grid discussed in previous article this technique helps you to achieve similar goals. Instead of bringing up the whole edit page you can click that single field you need to edit, change its value and see your changes posted to the database automatically.

Live demo

Click any of fields that are enabled for inline editing. Text will turn into edit control, the way it were setup in PHPRunner, ASPRunnerPro or ASPRunner.NET. To exit editing hit Esc button on your keyboard or click anywhere outside of edit control. Changes will be saved automatically.

Note that this code is designed to work with tables that only have a single key column selected. While making it work with multiple key columns is possible we didn't want to over-complicate this example.

To make this happen select one or more fields to be editable inline and add the following code to List page: Javascript OnLoad event.

Code

PHPRunner

$(document).ready(function() {

	var $elem;
	var key;
	var field;
	var val;

	function cancelEditing() {
		if ($grid.data("editing")) {
			$elem.html(val);
			$grid.data("editing", false);
			$elem.closest("td").css("padding","5px 8px");
		}
	};


	$(document).keyup(function(e) {
		if (e.keyCode == 27) { 
			cancelEditing();
		}
	});


	$("span[id^=edit]").attr('title', 'Click to edit');

		$grid=$(document.body);
		$grid.on("click", function(e) {

		// click during editing outside of edited element 
		if ($grid.data("editing") && 
				!$(e.target).is(":focus")	) {
			cancelEditing();
			return;
		}

		// click  on one of editable elements?
		if( $grid.data("editing") ||
				!$(e.target).attr("id") ||
				!$grid.data("editing") && $(e.target).attr("id").substring(0, 4) != "edit"
			) {
			return;
		}

		$elem = $(e.target);
		// enter editing mode
		val = $elem.html();

		$grid.data("editing", true);
		
		var id = $elem.parent().attr("data-record-id");
		var res=$elem.attr("id").match(/[^_]+$/);
		field = res[0];

		var gridrows = JSON.parse(JSON.stringify(pageObj.controlsMap.gridRows));
		for (var i = 0; i < gridrows.length; i++) {
			if (gridrows[i].id==id) {
				key=gridrows[i].keys[0];
				break;
			}
		}

		// prepare request
		var data = { 
			id: id,
			editType: "inline",
			editid1: key,
			isNeedSettings: true
		};

		// get edit controls from the server
		$.ajax({
		type: "POST",
		url: "products_edit.php",
		data: data
		}).done(	function(jsondata) {
			var decoded = $('<div/>').html(jsondata).text();
			response = jQuery.parseJSON( decoded );
			
			// clear error message if any
			if ($elem.next().attr('class')=="rnr-error")
				$elem.next().remove();

			// cmake control as wide as enclosing table cell
			width = $elem.closest("td").width();

			$elem.html(response.html[field]);
			if (response.html[field].indexOf("checkbox")<0) {
				$elem.find("input,select").width(width-5).focus();
				$elem.closest("td").css("padding","1px 1px");
			}
			
		});

		});
	
$grid.data("editing", false);


 // save function
 $(document.body).on('change','input[id^=value],select[id^=value]',function() {

	var data = { 
		id: 1,
		editType: "inline",
		a: "edited",
		editid1: key	 
	};

	var type = $(this).attr('type');
	if (type)
		type=type.toLowerCase();
	else 
		type="text";
	
	// regular field or check box
	if (type!="checkbox") {
		data["value_"+field+"_1"]=$(this).val();
	} else {
		if($(this).is(":checked")) {
            val="on";
        }
		data["value_"+field+"_1"]=val;
		data["type_"+field+"_1"]="checkbox";
	}
	

	// clear error message if any
	if ($(this).next().attr('class')=="rnr-error")
			$(this).next().remove();

	// save data
	$.ajax({
	  type: "POST",
	  url: "products_edit.php?submit=1",
	  data: data
		}).done(	function(jsondata) {
			var decoded = $('<div/>').html(jsondata).text();
			response = jQuery.parseJSON( decoded );
			if (response["success"]==false) {
				$("<div class=rnr-error/>").insertAfter($elem).html(response["message"]);	
			}
			else {
				$elem.html(response["vals"][field]);
				$grid.data("editing", false);
				$elem.closest("td").css("padding","5px 8px");
			}
		});
    });
});

You will have to modify the Edit page URL accordingly to your project settings. Replace products_edit.php with corresponding name of your table i.e. tablename_edit.php.

ASPRunnerPro

Replace products_edit.php with corresponding name of your table i.e. tablename_edit.asp.

ASPRunner.NET

No changes are required. Code goes to List page: Javascript OnLoad event.

$(document).ready(function() {

	var $elem;
	var key;
	var field;
	var val;

	function cancelEditing() {
		if ($grid.data("editing")) {
			$elem.html(val);
			$grid.data("editing", false);
			$elem.closest("td").css("padding","5px 8px");
		}
	};


	$(document).keyup(function(e) {
		if (e.keyCode == 27) { 
			cancelEditing();
		}
	});


	$("span[id^=edit]").attr('title', 'Click to edit');

		$grid=$(document.body);
		$grid.on("click", function(e) {

		// click during editing outside of edited element 
		if ($grid.data("editing") && 
				!$(e.target).is(":focus")	) {
			cancelEditing();
			return;
		}

		// click  on one of editable elements?
		if( $grid.data("editing") ||
				!$(e.target).attr("id") ||
				!$grid.data("editing") && $(e.target).attr("id").substring(0, 4) != "edit"
			) {
			return;
		}

		$elem = $(e.target);
		// enter editing mode
		val = $elem.html();

		$grid.data("editing", true);
		
		var id = $elem.parent().attr("data-record-id");
		var res=$elem.attr("id").match(/[^_]+$/);
		field = res[0];

		var gridrows = JSON.parse(JSON.stringify(pageObj.controlsMap.gridRows));
		for (var i = 0; i < gridrows.length; i++) {
			if (gridrows[i].id==id) {
				key=gridrows[i].keys[0];
				break;
			}
		}

		// prepare request
		var data = { 
			id: id,
			editType: "inline",
			editid1: key,
			isNeedSettings: true
		};

		// get edit controls from the server
		$.ajax({
		type: "POST",
		url: "edit",
		data: data
		}).done(	function(jsondata) {
			var decoded = $('<div/>').html(jsondata).text();
			response = jQuery.parseJSON( decoded );
			
			// clear error message if any
			if ($elem.next().attr('class')=="rnr-error")
				$elem.next().remove();

			// cmake control as wide as enclosing table cell
			width = $elem.closest("td").width();

			$elem.html(response.html[field]);
			if (response.html[field].indexOf("checkbox")<0) {
				$elem.find("input,select").width(width-5).focus();
				$elem.closest("td").css("padding","1px 1px");
			}
			
		});

		});
	
$grid.data("editing", false);


 // save function
 $(document.body).on('change','input[id^=value],select[id^=value]',function() {

	var data = { 
		id: 1,
		editType: "inline",
		a: "edited",
		editid1: key	 
	};

	var type = $(this).attr('type');
	if (type)
		type=type.toLowerCase();
	else 
		type="text";
	
	// regular field or check box
	if (type!="checkbox") {
		data["value_"+field+"_1"]=$(this).val();
	} else {
		if($(this).is(":checked")) {
            val="on";
        }
		data["value_"+field+"_1"]=val;
		data["type_"+field+"_1"]="checkbox";
	}
	

	// clear error message if any
	if ($(this).next().attr('class')=="rnr-error")
			$(this).next().remove();

	// save data
	$.ajax({
	  type: "POST",
	  url: "edit?submit=1",
	  data: data
		}).done(	function(jsondata) {
			var decoded = $('<div/>').html(jsondata).text();
			response = jQuery.parseJSON( decoded );
			if (response["success"]==false) {
				$("<div class=rnr-error/>").insertAfter($elem).html(response["message"]);	
			}
			else {
				$elem.html(response["vals"][field]);
				$grid.data("editing", false);
				$elem.closest("td").css("padding","5px 8px");
			}
		});
    });
});

34 comments to In-place editing

  • Jerry

    This is way cool. Please keep this stuff coming :)

  • joey

    I am not following the asp.net instruction. where would I put the code?

  • Bob Dutil

    In-place editing and Excel like grid in PHPRunner applications are exactly what I keep hearing for request. Outstanding job! These tips that you produce is what make phpRunner number 1.

  • Marc

    Well done!!!!!!!!!!!!!

  • Mrcaseyman

    Great stuff!!! More More More!!!

  • Ausmonty

    Looks good, I know its not ready, but found a bug. :)

    Click on Unit price to edit. Click on Quantity to Edit. Update Unit price and click off. Quantity will update with the value put into Unit price, and Unit price will still be open for edit.

    But if you can get that fixed, this would be very handy.

    Especially, if its a check box field, one click will toggle it, that would make it really good. :)

  • admin

    @Ausmonty,

    you should not be able to open more than one edit control at the time. Click anywhere outside of edit control closes it.

    Just in case, what browser do you use? Cannot reproduce it.

  • Ausmonty

    I have tried it on both Edge and IE 1 on Win 10 :)

  • Ausmonty

    that should be IE 11. It the same on both.

  • Ausmonty

    And on Firefox 42, Chrome 46.0.2490.86 m on Win 8.1 :)

  • AJ

    var decoded = $(‘
    ‘).html(jsondata).text();
    response = jQuery.parseJSON( decoded );

    Getting a compilation error: Unterminated string constant in line 70

  • Ausmonty

    I don’t know if you have done anything, but it seems to be working fine now. I can only select one field at a time. Fantastic. :)

  • Ausmonty

    Seems I might have spoken to soon. Something wierd is happening, it is now broken again. :( I am doing this on the demo. Will ahve to give it a try in one of my apps.

  • Ausmonty

    Might have found something that is causing it. If I douple click to open it, the problem occures. If I single click, all is good. I do ahve a habit of double clicking things.

    Also have noted that when I put a price in for less than 20, it comes up with the message about minimum of 20, no probs. but when I then change it to above 20, it accepts it, but the message about needs to be above 20 remains.

  • AJ

    data: data
    }).done( function(jsondata) {
    var decoded = $(‘
    ‘).html(jsondata).text();
    response = jQuery.parseJSON( decoded );
    if (response[“success”]==false) {
    $(”
    “).insertAfter($elem).html(response[“message”]);
    }
    else {

    Errors in the above as well?!?

    Help

  • Paul

    Great Job. I have tried it and a dropdown works, but not a checked box, yet they are both selected on inline edit. I see on the live demo that the checkboxes show yes / no until you click on them, then they show a tick or not, maybe that is the difference? Could it be?

  • Don

    Where is the specific field identified? I see where we change the table name but where do you indicate the field that it is to be used on. I added it to the edit page and javascript section as indicated but I don’t see any inline editable that works like you example.

  • Mario

    Thats why I love PHPRunner !!

  • fantasmino

    Awesome
    Thanks

  • Andy

    Is there a way to edit an empty field?

  • admin

    @Don,

    editable fields are defined in the project itself. You just need to add this code to correct event, which is “List page: Javascript OnLoad”.

  • Paul

    @Don
    You copy and paste the code in the List Page – Javascript onload.
    There are two lines you need to change. As you can see above, search for products_edit.php which is in the code you copied. Then change the products for your own table name so it could be job_edit.php, or cars_edit.php.

    In the fields on you project, whatever you select as Inline edit will have the option to be editable from the list page.

  • sawan

    this is perfect…, great job guys!

  • ausmonty

    Yep agree with Paul, if the check box field is shown as a check box, it does not work. I changed my project to use Yes/No, and it works.

    Small issue, for a great enhancement.

  • Paul

    To get it working on a checkbox, I had to set the Edit as a Checkbox, but the View as Text. It displays Yes or No. Its no great deal, and it works, but I will have to re-size my columns now as I had 4 checkboxes in line for different status of jobs, but I am sure it will work and the customer will be happy with this mod, as now they can edit an engineer and select the job status all on the same page and not have to go into Edit, change it and save it and back to the list to print it. So Yes, I am more than happy with this bit of FREE code. Great job Xlinesoft

  • Mauricio Zea

    Excellent contribution. Implemented by example in one of my lists page, everything works except that does not save changes.

    Any suggestions?

    Thanks.

  • This is EXACTLY what I was looking for.

    Now, if only I could change the color of the text, the size and the font without writing it into the database – all would be perfect (when it writes it to the database, it messes with sorting and other problems).

    Mike

  • Chris

    I couldn’t get this to work on a form with only a single checkbox per row that is editable. I took the previous comments into account, changed the checkbox to text, and selecting it gets the editable checkbox. After that, the checkbox doesn’t have focus, the edit_link has focus, so clicking the checkbox to update it’s value causes the script determine that “something other than the current focus element has been clicked” and it cancels the edit before it can save. I’ve tried forcibly setting the focus but it still loses it before the next click.

    I’ve had to abandon it there for now.

  • Nitin Jain

    I am getting an error while implementing this code, when the field name contains “_”.
    Is there a work around available for this?

    Nitin

  • Justin

    I’m getting this error with the .net code
    Uncaught TypeError: Cannot read property ‘indexOf’ of undefined

  • Jacques

    any idea how to get it work for safari?

  • Jerry

    Doesn’t appear to work in ASPRunner.Net v.9.0

  • Jerry

    My bad. It does work in ASPRunner.Net v.9.0

  • mmakis2000

    Hi, does anybody know if it is applicable to master-details tables as well?
    If yes, what is the correct statement at line 130?
    e.g. if the details table is called product_details, then what is the correct statement on line 130?
    should it be
    url: “product_details_edit.php?submit=1”,

    thanks

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>