Salut les gars,
I have found the solution of my problem. As said Kenta Saito for the set_relation, you have to use a callback to replace the form field by it's (read-only) value. The difference is, when you write a callback for a 1-n relation, the id of the related field is a SQL field of the displayed table (for instance, the id of the country where a book was written). But in a n-n relation (for instance, a relation between "book" and "author" tables, through a "written_by" table), there is no SQL field in the "book" table to apply the callback. The solution is to declare by the meaning of the GroceryCrud fields() function, an HTML field, not related to any SQL field, which the callback would be applied.
For instance, if we have a "oeuvre" table with "titre" and "descriptif" fields, with a n-n relation with an "auteurs" table, throught a link table "ecrit_oeuvre", you would usualy write the following to display the "oeuvre" form :
public function oeuvre()
{
$crud = new grocery_CRUD();
$crud->set_table('oeuvre');
$crud->set_relation_n_n('auteurs', 'ecrit_oeuvre', 'personne', 'id_oeuvre', 'id_personne', 'nom', 'ordre');
$output = $crud->render();
$this->_prelib_output($output);
}
Now, if you want to display the "auteurs" field as read only, you could write the following :
public function oeuvre()
{
$crud = new grocery_CRUD();
$crud->set_table('oeuvre');
// Do not declare the read-only field by a set_relation_n_n
/// $crud->set_relation_n_n('auteurs', 'ecrit_oeuvre', 'personne', 'id_oeuvre', 'id_personne', 'nom', 'ordre');
$crud->callback_field('auteurs',array($this,'callback_field_auteurs'));
// Explicitly declare the read-only form field (note that this field has no equivalent in the database table, its only an HTML form field)
// in the contrary, the 'titre' HTML field is linked to a field in the 'oeuvre' MySQL table
// In this example, the read-only field is 'auteurs', 'titre' and 'descriptif' are the table 'oeuvre' fields
// as this read-only field has no equivalent in the SQL tables, you can name it a as you want.
// Since GroceryCrud has no function to add only one HTML field, you have to explicitely declare all the displayed fields with the fields() function
$crud->fields('titre','descriptif','auteurs');
$output = $crud->render();
$this->_prelib_output($output);
}
function callback_field_auteurs($value, $primary)
{
// ... my code here to retrieve the list of the authors in the database
return $liste_auteurs;
}
The problem with replacing a set_relation_n_n declaration by a callback, is that the "auteurs" field would not be diplayed in the list (i.e. columns) of the Å“uvres. One solution is to add a callback for the columns. The drawback is that you cannot sort the data by clicking the column title.
public function oeuvre()
{
$crud = new grocery_CRUD();
$crud->set_table('oeuvre');
// Do not declare the read-only field by a set_relation_n_n
/// $crud->set_relation_n_n('auteurs', 'ecrit_oeuvre', 'personne', 'id_oeuvre', 'id_personne', 'nom', 'ordre');
// Two differents callback functions (callback_field_auteurs and callback_column_auteurs) are necessary
// meannig, you can't use the same callback_auteurs() function for both callbacks (see further explanation)
/// $crud->callback_field('auteurs',array($this,'callback_auteurs'));
/// $crud->callback_column('auteurs',array($this,'callback_auteurs'));
$crud->callback_field('auteurs',array($this,'callback_field_auteurs'));
$crud->callback_column('auteurs',array($this,'callback_column_auteurs'));
// Explicitly declare the read-only form field (note that this field has no equivalent in the database table, its only an HTML form field)
// in the contrary, the 'titre' HTML field is linked to a field in the 'oeuvre' MySQL table
// In this example, the read-only field is 'auteurs', 'titre' and 'descriptif' are the table 'oeuvre' fields
// Since GroceryCrud has no function to add only a new HTML field, you have to explicitely declare all the displayed fields with the fields() and columns() functions
$crud->fields('titre','descriptif','auteurs');
$crud->columns('titre','descriptif','auteurs');
$output = $crud->render();
$this->_prelib_output($output);
}
// As explained in the examples of the callback_field() and the callback_column() functions, http://www.grocerycrud.com/documentation/options_functions/callback_column and
// http://www.grocerycrud.com/documentation/options_functions/callback_column
// the callback functions for the field and the column have not the same parameters.
// As they share the same code in common, callback_column_auteurs() only calls callback_field_auteurs() with
// the appropriate parameters ...
// Also notice that $row and $primary concern 'oeuvre', not 'auteur' ($primary contains id_oeuvre, not id_auteur).
function callback_column_auteurs($value, $row)
{
return $this->callback_field_auteurs($value, $row->id_oeuvre);
}
function callback_field_auteurs($value, $primary)
{
// ... my code here to retrieve the list of the authors in the database
return $liste_auteurs;
}