briandaly40 Posted December 3, 2009 Share Posted December 3, 2009 Hi all, I need to create a table whereby a user can click on a cell to edit its contents in PHP. Once entered, the rest of the cells in that row should recalcuate depending on what value was entered. I am hoping to prevent the page from loading everytime a change is made so I am trying to use AJAX. I have been working on it for some time but can't figure out a solution. My approach is as follows: When a user opens the page first, a few arrays are created to store the default values of the table. This is then stored in the Session. I then create the table putting the correct array value from the session in the <td> </td>. In each <td> I use Moo Tools to allow editable content on click as follows: <td class="editable" rel="0">Content</td> Moo Tools picks up the "editable" class and allows users to edit inline. It then sends a request to a php page with parameters (which array, index to update, content to insert) that allow it to update the session. When this succeeds an AJAX method is called to loop through the arrays and echo out a table with the new, updated data. This table is then inserted in the div where the old table was. This approach works very well but once I make a change to a cell and the new table overwrites it I cant edit another cell. Its as if Moo Tools lost its event handlers for the "editable" class even though the updated table inserts the class into its <td> 's. Can anyone help me with this issue. Or is there a better way of achieving the same result. Im starting to think it is beyond my programming skills. All help welcome, Thanks in advance, briandaly40 Quote Link to comment https://forums.phpfreaks.com/topic/183848-editing-table-cell-inline/ Share on other sites More sharing options...
Deoctor Posted December 3, 2009 Share Posted December 3, 2009 the funny thing is that me too looking for the same kind of stuff.. Quote Link to comment https://forums.phpfreaks.com/topic/183848-editing-table-cell-inline/#findComment-970483 Share on other sites More sharing options...
briandaly40 Posted December 3, 2009 Author Share Posted December 3, 2009 the funny thing is that me too looking for the same kind of stuff.. Okay, so now there are two people with the same problem. If anyone has any ideas, and I mean any, please let us know. I am pulling my hair out trying to figure it out. Quote Link to comment https://forums.phpfreaks.com/topic/183848-editing-table-cell-inline/#findComment-970492 Share on other sites More sharing options...
premiso Posted December 3, 2009 Share Posted December 3, 2009 Not really sure how this is a PHP issue, but on the AJAX call back are you setting the table class attribute to editable? If not try to do that and see if it works, as it may need to have that attribute reset since it is a new field. Without seeing any code, especially the code that generates the returned table cell, it will be hard to provide quality help. Either way I fail to see how this is PHP and moving it to AJAX forum. Quote Link to comment https://forums.phpfreaks.com/topic/183848-editing-table-cell-inline/#findComment-970620 Share on other sites More sharing options...
JustLikeIcarus Posted December 3, 2009 Share Posted December 3, 2009 MooTools is not constantly watching the dom for elements with the editable class. It reads it in when it loads so it doesnt see your new/updated elements. You need to look for a MooTools plugin like the jQuery livequery plugin which should fix your issue. The other solution would be to run the MooTools function after the table is added to the dom each time. Quote Link to comment https://forums.phpfreaks.com/topic/183848-editing-table-cell-inline/#findComment-970659 Share on other sites More sharing options...
briandaly40 Posted December 4, 2009 Author Share Posted December 4, 2009 @premiso: My apologies, I should of posted in the Javascript forum. The AJAX callback had the class="editable" in it. @JustLikelcarus: Thanks for your response, you sent me on the right track. I looked for a MooTools version of LiveQuery but I was unable to find one. I then came across Event Delegation. This is where you attach events to a parent (and subsequently, its children) instead of assigning them to each element individually. Attaching the event to the parent means if any elements are injected into the page, they will get attached also. My only problem now is combining my original way and the new way: Original way: window.addEvent('domready', function() { //find the editable areas $$('.editable').each(function(el) { //add click and blur events el.addEvent('click',function() { //store "before" message var before = el.get('html').trim(); //erase current el.set('html',''); //replace current text/content with input or textarea element if(el.hasClass('textarea')) { var input = new Element('textarea', { 'class':'box', 'text':before }); } else { var input = new Element('input', { 'class':'box', 'value':before }); //blur input when they press "Enter" input.addEvent('keydown', function(e) { if(e.key == 'enter') { this.fireEvent('blur'); } }); } input.inject(el).select(); //add blur event to input input.addEvent('blur', function() { //get value, place it in original element val = input.get('value').trim(); el.set('text',val).addClass(val != '' ? '' : 'editable-empty'); //save respective record var request = new Request({ method:'get', url:'sessionupdater.php', onSuccess: function() { showResults(); } }).send('section=' + el.get('section') + '&i=' + el.get('rel') + '&content=' + el.get('text')); }); }); }); }); New method: window.addEvent('domready', function() { $('#results').click(function(event) { var $tgt = $(event.target); if ($tgt.is('td')) { // Do work here... } }); }); I tried combining the two as follows: window.addEvent('domready', function() { $('#results').click(function(event) { var $tgt = $(event.target); if ($tgt.is('td')) { $$('.editable').each(function(el) { //add click and blur events el.addEvent('click',function() { //store "before" message var before = el.get('html').trim(); //erase current el.set('html',''); //replace current text/content with input or textarea element if(el.hasClass('textarea')) { var input = new Element('textarea', { 'class':'box', 'text':before }); } else { var input = new Element('input', { 'class':'box', 'value':before }); //blur input when they press "Enter" input.addEvent('keydown', function(e) { if(e.key == 'enter') { this.fireEvent('blur'); } }); } input.inject(el).select(); //add blur event to input input.addEvent('blur', function() { //get value, place it in original element val = input.get('value').trim(); el.set('text',val).addClass(val != '' ? '' : 'editable-empty'); //save respective record var request = new Request({ method:'get', url:'sessionupdater.php', onSuccess: function() { showResults(); } }).send('section=' + el.get('section') + '&i=' + el.get('rel') + '&content=' + el.get('text')); }); }); }); } }); }); But with this, when someone clicks on a <td> it then adds a click event to each element with an .editable class. Which is like a bad way of implementing on double click. Can someone point out a better solution? Quote Link to comment https://forums.phpfreaks.com/topic/183848-editing-table-cell-inline/#findComment-971087 Share on other sites More sharing options...
JustLikeIcarus Posted December 4, 2009 Share Posted December 4, 2009 There isnt a need to combine them. Just when a click occurs check that it is a 'td' and has the class editable. Sorry I should have mentioned event deligation before. It is indeed the best way and requires only one bind instead of one for every td. Quote Link to comment https://forums.phpfreaks.com/topic/183848-editing-table-cell-inline/#findComment-971179 Share on other sites More sharing options...
briandaly40 Posted December 7, 2009 Author Share Posted December 7, 2009 There isnt a need to combine them. Just when a click occurs check that it is a 'td' and has the class editable. Sorry I should have mentioned event deligation before. It is indeed the best way and requires only one bind instead of one for every td. Cheers JustLikeIcarus, But I am still having trouble with the moo tools event handler. If you look at the code I posted above. I have the original way, which uses "$$('.editable').each(function(el)" where you can then use el to access methods and properties. For instance in the code I use "el.hasClass('textarea'))". But as I dont use the each method using event delegation I cant use el in my code. In the new method, i say "var $tgt = $(event.target);" to access the element but I need the el for methods such as el.set() or el .hasClass() Does anyone have an idea how I can get this to work. My mootools/js skill are not up to scratch. Thanks! Quote Link to comment https://forums.phpfreaks.com/topic/183848-editing-table-cell-inline/#findComment-972730 Share on other sites More sharing options...
JustLikeIcarus Posted December 7, 2009 Share Posted December 7, 2009 Im a jQuery man myself however I am sure its the same in MooTools that when using .each() the element is referenced via $(this). instead of an argument in the function. Quote Link to comment https://forums.phpfreaks.com/topic/183848-editing-table-cell-inline/#findComment-972771 Share on other sites More sharing options...
briandaly40 Posted December 7, 2009 Author Share Posted December 7, 2009 Im a jQuery man myself however I am sure its the same in MooTools that when using .each() the element is referenced via $(this). instead of an argument in the function. Again, thanks for the reply. But I dont want to use .each() anymore as I am now using event delegation. Or am I going about this is the completely wrong way, using the $(this) reference here is what I've got but it doesnt work: window.addEvent('domready', function() { $('#results').click(function(event) { var $tgt = $(event.target); if ($tgt.is('td')) { //store "before" message var before = $(this).get('html').trim(); //erase current $(this).set('html',''); //replace current text/content with input or textarea element if($(this).hasClass('textarea')) { var input = new Element('textarea', { 'class':'box', 'text':before }); } else { var input = new Element('input', { 'class':'box', 'value':before }); //blur input when they press "Enter" input.addEvent('keydown', function(e) { if(e.key == 'enter') { this.fireEvent('blur'); } }); } input.inject($(this)).select(); //add blur event to input input.addEvent('blur', function() { //get value, place it in original element val = input.get('value').trim(); $(this).set('text',val).addClass(val != '' ? '' : 'editable-empty'); //save respective record var request = new Request({ method:'get', url:'sessionupdater.php', onSuccess: function() { if (($(this).get('rel') <= 5)) { showResults(0); } else if(($(this).get('rel') >= 6) && ($(this).get('rel') <= 18)) { showResults(1); } else if(($(this).get('rel') >= 19) && ($(this).get('rel') <= 25)) { showResults(2); } else if(($(this).get('rel') >= 26) && ($(this).get('rel') <= 32)) { showResults(3); } else if(($(this).get('rel') >= 33) && ($(this).get('rel') <= 36)) { showResults(4); } else { showResults(0); } } }).send('section=' + $(this).get('section') + '&i=' + $(this).get('rel') + '&content=' + $(this).get('text')); }); } }); }); A JS error is given in IE8, "Object doesnt support this property or method". Its line number is wrong though as it there is no JS on that line. I get no error in firefox but it does not work. Please have a look and tell me where I am going wrong. Thanks in advance! Quote Link to comment https://forums.phpfreaks.com/topic/183848-editing-table-cell-inline/#findComment-972835 Share on other sites More sharing options...
JustLikeIcarus Posted December 7, 2009 Share Posted December 7, 2009 I notice your using an id as the selector for results. There is only one element with the id=results correct? As they can not be duplicated. I could throw together a version of what you want in jQuery if you think that would help. Quote Link to comment https://forums.phpfreaks.com/topic/183848-editing-table-cell-inline/#findComment-972843 Share on other sites More sharing options...
JustLikeIcarus Posted December 7, 2009 Share Posted December 7, 2009 oh and input.inject($(this)).select(); is missing a ) Quote Link to comment https://forums.phpfreaks.com/topic/183848-editing-table-cell-inline/#findComment-972845 Share on other sites More sharing options...
briandaly40 Posted December 7, 2009 Author Share Posted December 7, 2009 I notice your using an id as the selector for results. There is only one element with the id=results correct? As they can not be duplicated. I could throw together a version of what you want in jQuery if you think that would help. Yes, I have a div (id=results) which holds a table with <td class="editable"> in it. I would be most greatful if you could have a go because I am pulling my hair out with it. Quote Link to comment https://forums.phpfreaks.com/topic/183848-editing-table-cell-inline/#findComment-972855 Share on other sites More sharing options...
JustLikeIcarus Posted December 7, 2009 Share Posted December 7, 2009 Ok heres a really quick example. would have been easier with your html but should work. $(document).ready(function(){ $('#results').click(function(e){ if($(e.target).is('td.editable')){ if($(e.target).hasClass('textarea')){ $(e.target).html('<textarea class="box">'+$(e.target).text()+'</textarea>'); }else{ $(e.target).html('<input type="text" class="box" value="'+$(e.target).text()+'" />'); } $(e.target).find('.box').keypress(function(k){ if(k.which == 13){ var data = $(this).val(); $(this).parent().text(data); /// save your data or whatever else. } }); } }); }); Quote Link to comment https://forums.phpfreaks.com/topic/183848-editing-table-cell-inline/#findComment-972874 Share on other sites More sharing options...
briandaly40 Posted December 7, 2009 Author Share Posted December 7, 2009 Ok heres a really quick example. would have been easier with your html but should work. $(document).ready(function(){ $('#results').click(function(e){ if($(e.target).is('td.editable')){ if($(e.target).hasClass('textarea')){ $(e.target).html('<textarea class="box">'+$(e.target).text()+'</textarea>'); }else{ $(e.target).html('<input type="text" class="box" value="'+$(e.target).text()+'" />'); } $(e.target).find('.box').keypress(function(k){ if(k.which == 13){ var data = $(this).val(); $(this).parent().text(data); /// save your data or whatever else. } }); } }); }); Thanks a million JustLikeIcarus! I adapted and extended your code to suit my needs, thanks a bunch!!! One last question (I swear), You will see from my code below that on blur the data is saved. $(document).ready(function(){ $('#results').click(function(e){ if($(e.target).is('td.editable')){ if($(e.target).hasClass('textarea')){ $(e.target).html('<textarea class="box">'+$(e.target).text()+'</textarea>'); }else{ $(e.target).html('<input type="text" class="box" value="'+$(e.target).text()+'" />'); } $(e.target).find('.box').select(); $(e.target).find('.box').blur(function(){ var data1 = $(this).val(); $(this).parent().text(data1); $.get("sessionupdater.php", { section: $(e.target).attr("section"), i: $(e.target).attr("rel"), content: data1 }, function(data) { if (($(e.target).attr("rel") <= 5)) { showResults(0); } else if(($(e.target).attr("rel") >= 6) && ($(e.target).attr("rel") <= 18)) { showResults(1); } else if(($(e.target).attr("rel") >= 19) && ($(e.target).attr("rel") <= 25)) { showResults(2); } else if(($(e.target).attr("rel") >= 26) && ($(e.target).attr("rel") <= 32)) { showResults(3); } else if(($(e.target).attr("rel") >= 33) && ($(e.target).attr("rel") <= 36)) { showResults(4); } else { showResults(0); } } ); }); }});}); I also want it to be when a user hits enter. I saw from you example you use k.which == 13 method. I tried to use the following so that when a user hits enter it fill fire the blur event and save my data .But it does not work, I have but it before the blur event and after it but to no avail. This is the last bit I need to do, please help me. $(e.target).find('.box').bind('keypress', function(e) { if(e.keyCode==13){ $(e.target).find('.box').fireEvent('blur'); } }); Quote Link to comment https://forums.phpfreaks.com/topic/183848-editing-table-cell-inline/#findComment-972913 Share on other sites More sharing options...
JustLikeIcarus Posted December 7, 2009 Share Posted December 7, 2009 Try it this way.. Also you can help yourself out alot by inserting alert()'s in places where you cant tell if something is firing right. making it alert to let you know it atleast got that far. Since you bound the event to something when it occurs "this" is the element that invoked it. $(e.target).find('.box').bind('keypress', function(e) { if(e.keyCode==13){ $(this).blur(); } }); Quote Link to comment https://forums.phpfreaks.com/topic/183848-editing-table-cell-inline/#findComment-972923 Share on other sites More sharing options...
briandaly40 Posted December 8, 2009 Author Share Posted December 8, 2009 Try it this way.. Also you can help yourself out alot by inserting alert()'s in places where you cant tell if something is firing right. making it alert to let you know it atleast got that far. Since you bound the event to something when it occurs "this" is the element that invoked it. $(e.target).find('.box').bind('keypress', function(e) { if(e.keyCode==13){ $(this).blur(); } }); Absolutely spot on. Thanks very much for your help. I'd be completely lost without this forum and the help I got from you. Cheers, briandaly40 Quote Link to comment https://forums.phpfreaks.com/topic/183848-editing-table-cell-inline/#findComment-973314 Share on other sites More sharing options...
JustLikeIcarus Posted December 8, 2009 Share Posted December 8, 2009 Good deal. Happy I was able to help. Quote Link to comment https://forums.phpfreaks.com/topic/183848-editing-table-cell-inline/#findComment-973343 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.