0

I try to construct a field and I wonder how should I implement this process via Field API:

  1. User enter some data to the field. Let's say, the data entered is a node title.
  2. User hits the "Save" button, but what is actually saved in the database is the node ID of the node whose title has been entered by the user.

Something like this happens with the Entity Reference module: I enter the title of the entity (as I 'm getting assistance through autocomplete), but the module saves target_id, not the title I have actually entered.

How can I gain such behavior?

10
  • You means title not saved in databae?
    – Yuseferi
    Commented Sep 20, 2012 at 4:38
  • Yes, drupal should search for the node that have the same title and save its nid (target_id). Node's title shouldn't be saved.
    – DimG
    Commented Sep 20, 2012 at 4:55
  • This is strange, drupal work by nid, if you be in edit page of node,any change updated the node ,not add another node
    – Yuseferi
    Commented Sep 20, 2012 at 5:04
  • Mm. I don't know how to paraphrase it. Consider this example: in the widget user selects his location by typeing coordinates but what is saved in database is the name of the city. Or this one: User enters the integer but drupal wants to save it's "word representation": entered 2 is saved as "two", entered 3 is saved as "three". All this stuff requires some process function and the question is basically if Drupal can save not entered data but the processed data that possibly hav different data type.(i.e. "int" is saved as "string")
    – DimG
    Commented Sep 20, 2012 at 5:15
  • @DimsG, ok, I understand what is your problem, this is not issue and its big feature(realated to database engineering conception and realationship conceptition ). What do you intend?
    – Yuseferi
    Commented Sep 20, 2012 at 5:32

2 Answers 2

1

Create a module for example module name is rose. In that module implement hook_node_validate

function rose_node_validate($node, $form, &$form_state) {
       //Check to see if this is the node form data you want to change
    if ($form['#form_id'] == 'contentType_node_form') {
        //based on the value provided in 
        $form_state['input']['field_name']['und'][0]['value'];
        $new_info_data = 'some logic'; //get the data you would like to save .
        variable_set('new_info', $new_info_data); //Save the data in a variable.
    }
}

Then implement a hook_node_presave. As per our example

function rose_node_presave($node) {
    //check if the node type is the one you want to change the value
    if ($node->type == 'content_type') {
        $new_info = variable_get('new_info'); //get the value which was set in validation variable_set()
        $node->field_name['und'][0]['value'] = $new_info;
    }
}

I have implemented this on Drupal 7. A user enters instagram user name and I get the instagram id from instagram api and save it. Let me know if more explanation is required.

In this implementation users enters only address I get the Lat and Lng based on the address provided and save it in the database. enter image description here

enter image description here

6
  • Yes, that is exactly what I meant. However it seems to be really strange. Please tell me, if I got it right: Drupal requires for field-edit-form (widget) to have one input for one column (in db)? I.e. there is no Drupal way to form the data structire I want it to be? Because your solution is a kind a crutch to fix Drupal's inability.
    – DimG
    Commented Sep 20, 2012 at 5:24
  • By the way, how to implement it in the opposite direction, i.e. in your example, when user tries to edit the node he sees instagram name, not the id (i.e. to "process id back" to username)
    – DimG
    Commented Sep 20, 2012 at 5:26
  • In my case to solve "opposite direction" problem I used username filed data to get the user id and populated it in another filed and saved both.
    – 15dk51
    Commented Sep 20, 2012 at 5:30
  • I also used a similar approach where a user enters an address in some fields, based on info in these fields I send a request to google's map api and get the lat and lng for that address and save it in additional fields database.
    – 15dk51
    Commented Sep 20, 2012 at 5:35
  • @dkiscool,your answer maybe worked but it is irregular.
    – Yuseferi
    Commented Sep 20, 2012 at 5:37
1

ok.let's suppose your entity ref field name is field_entity_ref
you should to create anther field (text) field , name it field_book_title
in you custom module hook_form_alter

  function custommodule_form_alter($form, &$form_state,$form_id) {
     if ($form_id == 'yourcontetntpe_form_node') {
        $form['#submit'][] ='mycustom_function';
        // we must hide shadow field in view 
        // first check #access=false if not work comment it and use hide
         $form['field_book_title']['#access'] = false;
        // or you can hide it
        // hide($form['field_book_title']);
       }
   }

and in mycustom_function function get nid of refrenced node , load node and save it's title in field_book_title.

function mycustom_function(form,&$form_state) {
  $node = node_load($form_state['values']['field_entity_ref']['und'][0]['target_id']);
  $form_state['values']['field_book_title']['und'][0]['value'] = $node->title; 
 }

And finally in view of node (in your tpl or in views) use field_book_title instead of field_entity_ref

I hope this be useful for you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.