Hi,
I am having a bit of issue in getting a form field with AHAH property work when the form field is loaded via another AHAH callback.
Basically here is the scenario.
I have a Bio page where user's on the page can do inline edit's of person details such as Jobs, education etc.
When users click on "Add Job" button, they get a form to add Job details about the person. This job details form has two additional fields for "Save Job", "Close" .
Each of "Save Job and Close" again have AHAH callback's so that the form gets submitted within the wrapper without having to do page refresh.
As of now the "Add Job" callback works well and loads the Jobs form correctly. The issue with is with Save Job.
When Clicked on "Save job", instead of doing of doing inline submit of form and refreshing text within wrapper, the whole page gets submitted.
What i noticed is that drupal_render() , which i am using to render the jobs form is not rending "AHAH" fields.
Been stuck with this for a long time, Any help in this regard is greatly appreciated. Below is the code of the module i have been writing.
<?php
/**
* @file
* Personnel module,
*/
/**
* =============== <Drupal hooks> ================
*/
/**
* Implementation of hook_perm
*/
function pseps_jobs_perm(){
return array(
'Add jobs info'
);
}
/**
* Implementation of hook_theme
*/
function pseps_jobs_theme(){
return array(
'pseps_jobs' => array(
'arguments' => array('jobs'),
'file' => 'themes.inc',
),
);
}
/*
* Implementation of hook_menu
*/
function pseps_jobs_menu(){
$items['autocomplete/employers'] = array(
'title' => 'Jobs held by person',
'page callback' => '_employer_autocomplete',
'access arguments' => array('access content'),
'type' => MENU_LOCAL_TASK,
'weight' => -10,
);
$items['jobs/jobsform'] = array(
'title' => 'Jobs form',
'page callback' => 'quick_job_form',
'access arguments' => array('access content'),
'type' => MENU_LOCAL_TASK,
'weight' => -10,
);
$items['jobs/jobsform/save'] = array(
'title' => 'Jobs form save',
'page callback' => 'jobform_save',
'access arguments' => array('access content'),
'type' => MENU_LOCAL_TASK,
'weight' => -9,
);
return $items;
}
/**
* Implementation of hook_nodeapi
*/
function pseps_jobs_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL){
drupal_add_js(drupal_get_path('module','Drupal').'/misc/autocomplete.js');
if($op=='load'){
switch($node->type){
case 'pseps_people':
// Key to search Jobs table is by getting person information
$key = $node->person;
$result = db_query("SELECT employer, job_title,office,job_type from data.jobs where lower(employee) like lower('%s')",$node->person);
$jbr = "";
while($row = db_fetch_object($result)){
$jobs[] = $row;
// print_r($row);
}
$node->jobs = $jobs;
}
}
switch($op){
case 'load':
break;
case 'view':
// Loads a form that holds both Content of current jobs along with forms
$node->content['Jobs'] = array(
'#value' => drupal_get_form('person_jobs'),
'#weight'=> 2,);
break;
}
}
/**
* Quick job form , is displayed with AHAH quick edit
*/
/**
* Form that holds both Content of current jobs along with button to load new job form
*/
function person_jobs($form){
$nodeid = arg(1);
if(is_numeric($nodeid)&&(arg(0)=="node")){
$result = db_query("SELECT pseps_key from {pseps_nodes} where nodeid=%d",$nodeid);
if($result){
$contact = db_fetch_object($result);
}
}
$items = _get_jobs_by_contact($contact->pseps_key);
$form['add_jobs'] = array(
'#type' => 'image_button',
'#src'=> drupal_get_path('module','pseps')."/images/addjob.gif",
'#name'=>'Add job',
'#button_type'=>'button',
'#value' => t('Add job'),
'#ahah' => array(
'path' => 'jobs/jobsform',
'event'=>'click',
'wrapper' => 'jobs-wrapper',
'progress' => array('type' => 'bar', 'message' => t('Please wait...')),
'method' => 'replace',
'effect' => 'fade',
'#weight'=>-9,
),
);
$form['wrapper'] = array(
'#prefix' => '<div id="jobs-wrapper">',
'#suffix' => '</div>',
'#type'=>'item',
'#value'=> theme('pseps_jobs',$items),
'#weight' => 9,
);
return $form;
}
function _get_jobs_by_contact($contactid){
$sql = "SELECT employer,job_title,office,date_start,date_end from data.jobs where lower(employee) LIKE lower('%s')";
$result = db_query($sql,$contactid);
if($result){
return db_fetch_object($result);
}
return;
}
function quick_job_form(){
$form_element = job_form_elements();
drupal_alter('form', $form_element, array(), 'quick_job_form');
$form_state = array('submitted' => FALSE);
$form_build_id = $_POST['form_build_id'];
$form = form_get_cache($form_build_id, $form_state) ;
$form['jobsform']['jobs'] = $form_element;
form_set_cache($form_build_id, $form, $form_state);
$form += array(
'#post' => $_POST,
'#programmed' => FALSE,
);
// Rebuild the form.
$form = form_builder($_POST['form_id'], $form, $form_state);
unset ($form['wrapper']['#prefix'],$form['wrapper']['#suffix']);
$jobs_form = $form['jobsform']['jobs'];
$output = drupal_render($jobs_form);
drupal_json(array('status' => TRUE, 'data' => $output));
//return ; //drupal_json(array('data'=>$_POST['edit-contact']));
}
function job_form_elements(){
$form['employer'] = array(
'#type' => 'textfield',
'#title' => 'Employer',
'#value' => '',
'#autocomplete_path' => 'autocomplete/employers',
'#weight' => -10,
'#required' => true
);
$form['jobtype'] = array(
'#type' => 'textfield',
'#title' => 'Job type',
'#value' => '',
'#weight' => -9,
);
$form['jobtitle'] = array(
'#type' => 'textfield',
'#title' => 'Job title',
'#value' => '',
'#weight' => -8,
);
$form['startdate'] = array(
'#type' => 'date',
'#title' => 'Job start date',
'#value' => '',
'#weight' => -7,
);
$form['enddate'] = array(
'#type' => 'date',
'#title' => 'Job end date',
'#value' => '',
'#weight' => -6,
);
$form['save-job'] = array(
'#type' => 'button',
'#weight'=>0,
'#value'=>'Save',
'#attributes'=>array('class'=>'item'),
'#ahah' => array(
'path' => 'jobs/jobsform/save',
'wrapper' => 'jobs-wrapper',
'progress' => array('type' => 'bar', 'message' => t('Please wait...')),
'method' => 'replace',
'effect' => 'fade',
)
);
return $form;
}
/**
* Function to generate auto complete lists
*/
function _employer_autocomplete($str_contact){
$arr_peple = array();
$arr_contact['Add new contact'] = 'Add new contact';
if(strlen($str_contact)>2){
$result = db_query ("SELECT contact FROM data.contacts WHERE lower(contact) LIKE lower('%s%') AND is_old = false AND is_company = true order by contact",$str_contact);
while($rec = db_fetch_object($result)){
$arr_contact[$rec->contact] = check_plain($rec->contact);
}
}
if((count($arr_people) < 1)||(strlen($str_people) < 3)){
$arr_contact['Add new contact'] = 'Add new contact';
}
print drupal_to_js($arr_contact);
// drupal_json($arr_people);
}
function jobform_save(){
$form_state = array('storage' => NULL, 'submitted' => FALSE);
$form_build_id = $_POST['form_build_id'];
$form = form_get_cache($form_build_id, $form_state);
$args = $form['#parameters'];
$form_id = array_shift($args);
$form['#post'] = $_POST;
$form['#redirect'] = FALSE;
$form['#programmed'] = FALSE;
$form_state['post'] = $_POST;
drupal_process_form($form_id, $form, $form_state);
$form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
$qt_form = $form['qt_wrapper']['tabs'];
unset($qt_form['#prefix'], $qt_form['#suffix']); // Prevent duplicate wrappers.
$javascript = drupal_add_js(NULL, NULL, 'header');
drupal_json(array(
'status' => TRUE,
'data' => theme('status_messages') . 'Hello world',
'settings' => call_user_func_array('array_merge_recursive', $javascript['setting']),
));
}
Comments
Hey fella! Sorry been out
Hey fella! Sorry been out and about today...
There's an *awful* lot wrong with this code - it's not a matter of a simple fix, afraid it needs a whole host of tlc...
Have a good read of this; http://drupal.org/node/331941
I can't really do much without all the code to have a play with? Couple of things to note though, you've no submit handler pickup function and you've not set rebuild = TRUE in; $form_state = array('storage' => NULL, 'submitted' => FALSE); - Actually as well on that page, I see someone has mentioned the submitted => FALSE bit was causing problems.
Pobster
Fully confused
Yeah been reading through the documentation, Just about getting a bit of understanding on how the process works. Hopefully will be able to get my head around this soon.
BTW The code you see above is the whole module.
Julaboy
Is missing the .install file
Is missing the .install file for the db set up and the theme.inc file?!?! If you're still stuck tomorrow by tomorrow evening - send it over and I'll take a lookie at it.
Cheers!
Pobster
Almost there
Followed the lead of Quicktabs, Does seem that i am close, still can't figure out what i am missing.
Read it again! ;-)
Hi Julaboy,
you are not following Quicktabs' lead. The most important line in that handbook page that you need to grasp is this:
I wrote a blog post about this recently, which may help you with this: http://www.katbailey.net/blog/ahah-drupal-may-it-one-day-live-its-acronym.
In short, your submit handler should not be defining any form elements - only your form building function should do that. Your submit handler should just make a change to $form_state (e.g. adding $form_state['job_form] set to TRUE or something like that) which your form building function will react to when rebuilding the form and add the jobform elements. Hopefully that will make more sense once you've read the above post.
Katherine
Makes sense
I went through the blog and also went through the code of quick tabs & Poll modules.
Its all making a lot of sense to me now.
I changed my code and it follows the procedure outlined in you blog & Doing AHAH correctly in Drupal 6
I am still having issues in getting the form to work correctly.
There is something that i am doing wrong, just can't seem to understand what it is.
I will be grateful if you can look at the code below and help me understand where i am going wrong.
Don't bother about database
Mate don't bother about database and install files,
Here is what i am trying to achieve.
When user clicks on "Add Job", a new form is loaded with few fields. One of the fields is a "Save Job" button, when clicked needs to submit the form using AHAH callback. I just can't seem to figure out what is wrong with my code
hi there, did you manage to
hi there,
did you manage to archive what you wanted?
I am trying to build something similar - inline edit of simple string fields.
Fields are displayed in a table built and rendered by Drupal. Clicking on field should open the editable textbox field with save button.
Adding this to the ahah
Adding this to the ahah render function worked for me:
The whole function was:
Contact me to contract me for D7 -> D10/11 migrations.
Or anything really. I'm friendly, and open to work or conversation.
Solution
Did you ever find a solution for your problem?
I'm actually trying to do something similar and have issues returning new items to my form, but I have gotten other elements to work(changing amount of entries shown, date ranges) without reloading the page.