Hey guys

Has anyone implemented edit-in-place functionality with Drupal 5 profiles and can give me some idea on how to 'save' the fields? I know how to write the editing part, just now what/how to call an update to the database?

Comments

mokargas’s picture

I've added edit-in-place functionality using jQuery jEditable plugin, however I'm not sure on the drupal way of saving/overwriting a profile field with edited data?

Does anyone know how to save the edited field back to the database?

mokargas’s picture

Ok to answer my own question, I found a function in the api user_save (http://api.drupal.org/api/function/user_save/5).

Not being an expert, I don't know if it's possible to call this from javascript. Does anyone know how to do that? (Do I have to make a standalone php file?)

lum12’s picture

Hi denizengt, I'm interested in your integration of jeditable functionality in drupal. I'm trying and I've for now just html/javascript part working but I cannot understand the right way to save into db the field (in my case postgresql)

I did this,

this in a module.js file
------------------
$(document).ready(function() {
$(".editable").editable("http://gestionale.beopen/gestionale/jeditable", {
indicator : 'Only local images are allowed.',
}, {
style : "display: inline; width: 100px; text-align: right; font-weight: bold;"
});
});
------------------

this in module_menu()
------------------
$items['gestionale/jeditable'] = array( 'page callback' => '_updateValueJQ',
'access callback' => 'user_access', 'access arguments' => array('create entries'), 'type' => MENU_CALLBACK, );
------------------

this function
------------------
function _updateValueJQ($id, $value) {
$sql = "UPDATE {be_tributi} SET valore = %f WHERE idf24 = %d";
db_query($sql, $value, $id);

print stripslashes($_REQUEST['value']);
}
------------------

this php/html form
------------------
$output .= "

" . $saldo1 ."

";
------------------

For sure ther are several concept errors but I'd appreciate if you could give me an hint

thanks a lot

luca

luca marletta

mokargas’s picture

Hey mate

Sorry all I've been ridiculously busy! If memory serves me correctly Luca, there's a function in the Drupal 5 API called user_save. I'm pretty sure I used that with updated field information. I'll post what I used when I return from work.

Once again, apologies to all who've been camping on this thread!

mokargas’s picture

It's been a busy few months, but here's pretty much the code I've used in my 5.x install. It's not the best but that's because I haven't had time to revisit it and check it for bad stuff. Drupallers feel free to make it better as you see fit, but please post your improvements!

Ok first in my user-profile.tpl.php, I have a class called '.profField' attached to the times I want to be jEditable.

Here's an example field, using a custom defined profile text field called 'nickname':

<div class = "profField" id = "profile_nickname">
<? if($account->profile_nickname){
 print(check_markup($account->profile_nickname));
} else{ 
print("Ohh! ".$account->name." hasn't filled this in yet!");
} ?>
</div>

Also, in user-profile.tpl.php, I have this in my head code, a small peice of Javascript: ( Ideally this should be added with a module, using drupal_add_js(), but I did this a long time ago.)

<script src="<? print base_url().path_to_theme();?>js/jquery.1.2.1.pack.js" type="text/javascript"></script>
<script src="<? print base_url().path_to_theme();?>js/jquery.jeditable.pack.js" type="text/javascript"></script>
<script type="text/javascript">

$(".profField").editable("/user_saver/get_the_info",{
			indicator: "Saving...",
			onblur: 'submit'
			});	
</script>

That tells my module to pass the value of that field to the location '/user_saver/get_the_info'. That location is defined using a menu call back in my module. Take a look below:

file: user_saver.module:

function user_saver_menu($may_cache) {
  $items = array();
  if ($may_cache) {
    $items[] = array(
      'path' => 'user_saver/get_the_info',
      'access' => TRUE,
      'type' => MENU_CALLBACK,
      'callback' => 'user_saver_get_the_info'
     );
  }
  else {
// here is where you'd add the js to the module.
//say: user_saver_load_js();
  }
 
  return $items;
}

function user_saver_get_the_info() {
	global $user;
	$id = $_POST['id'];
	$output = $_POST['value'];

        //Get user's id
	$uIDx = $user->uid;

        //Retrieve users information via id.
	$userInfo = user_load(array('uid'=> $uIDx));

	//see what's changed
	if($userInfo->$id != $output){
		//something has changed
		//include changed value.
		$userInfo->$id = $output;
		
	}
	
	$userInfo = (array) $userInfo;
        //Hardcoded category because I know where my fields are, still naughty tho!
	$cat = 'Personal Information';
         
        //Save user's information using updated value
	$user = user_save($user, $userInfo, $cat);

        
	echo $output;
}


Ok, so user_saver_menu defines a path, which when visited, calls user_saver_get_the_info(). When we're in user_saver_get_the_info(), we get the value of the element's ID (that had a class of 'profField') that's being updated from our $_POST values array, and also retrieve the value that is inside that element.

Then, we load all the user's information, find the changed value, and then update our user using user_save. I've hardcoded the category there because I know what category my field belongs to, but ideally this should be determined programattically .

Perhaps the glaring issue with this is user_save is called for every single field update. At the time I couldn't see a way around it, so please feel free to improve!

I take no responsibility if something goes wrong with your site using this code, and it is rudimentary. Always back up your files, and remember you need jQuery 1.2.1 and jEditable as well. If you have questions, please ask and I'll get back to you.

Note: Currently this only handles text fields, but I intend to turn the code into a module to handle drop down lists and so on

mdowsett’s picture

Did you get this to work?

I have lots of questions (I'm a bit novice so I need lots of instructions):

- the "file: user_saver.module" part above...this is a module you created?

- when defining the first part of the code in the user_profile.tpl.php, what parts do you have to change to match the proper profile field? "nickname" to the proper field name?

I did that part and had something that field but it still showed the "Ohh!" message. I then changed the "account" parts to the category that field is actually in but that didn't make a difference.

I haven't even got to the AJAX part of things but thought that script should at least show the data entered or the Ohh! message...

- Head code....I don't have any HEAD section of my user_profile.tpl.php file (I have been using one to customize my user profiles for a while) - should I? What is the syntax for putting in a HEAD section?

- jQuery and jEditable - are these drupal modules?? jQuerey has no module attached and jEditable doesn't exist...or did you mean ajaxEditable for that part?

Can this coding work for other tpl.php files - like if I use the Bio module and have a template file to help theme that...?

MANY thanks - this will be fantastic if I can get this to work.

lum12’s picture

Sorry for delay mdowsett.
Yes I get jeditable working quite well in drupal but not for user module and I did it for drupal 6.x.

I did another module and I have a table with some fileds editable with double click.

It's not difficult also if I have not yet fixed some marginal problems.

so in brief:
load jeditable into drupal

  drupal_add_js(drupal_get_path('module', mymodule .'/js/jquery.jeditable.js');

create a general function in helpers.inc for instance, for load and reading from db the field

  function _readJedit($sql,$id) {
    // l'SQL deve ritornare un valore solo. Deve essere del tipo "SELECT valore FROM {be_tributi} WHERE nid = %d"
    $valore = db_result(db_query($sql, $id));
  return $valore;
}

and for any field type you can create a call back menu and a function related

    $items['gestionale/jmovvalore'] = array(   
                'page callback' => '_updateJmovvalore',
                'access callback' => 'user_access',
                'access arguments' => array('create entries'),
                'type' => MENU_CALLBACK, );
 

function _updateJmovvalore() {  // l'update è gestito nella singola funzione perchè è complicato passare l'SQL nell'url
  $sql = "UPDATE {be_movimenti}  SET valore = %f WHERE nid = %d";
  db_query($sql,  ereg_replace("[^0-9,-]", "", ereg_replace("\,(.*)", "", $_POST['value']) ), $_POST['id']); // here there are some strip of char
  (isset($_POST['value'])) ? print e($_POST['value']) : print e(0);
}

I hope it'll help you

luca

--
luca marletta

mokargas’s picture

Ok I have this working entirely, will post code shortly ! (just have to test)

jimbop’s picture

did the testing go OK? Interested...

drupalina’s picture

subscribing (I've been looking for something like this for a very long time)