I'm trying to add feature to our corporate website (this module called 'userpasswords2' searches database of local mailsystem passwords). I'm using AJAX autocomplete and modification of the form.
I cannot submit the form by enter key. AJAX autocomplete works fine, but when I choose the user, the form can only be submitted by submit button.
I would like it to work like here https://api.drupal.org/api/drupal - user enters for example 'hook', chooses for example hook_menu, hits enter, then hits enter again and get the result!
So again - clicking submit button works fine, hitting 'enter' key doesn't work.
Googled a lot, the workarounds I've found doesn't work for me. Please help.
function userpasswords2_menu() {
$items = array();
$items['userpasswords2'] = array(
'title' => 'User passwords',
'page callback' => 'drupal_get_form',
'page arguments' => array('userpasswords2_form'),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['userpasswords2/ajax_username_autocomplete_callback2'] = array(
'page callback' => 'ajax_username_autocomplete_callback2',
'type' => MENU_CALLBACK,
'access callback' => TRUE,
);
return $items;
}
function userpasswords2_form($form, &$form_state) {
$form = array();
$form['user'] = array(
'#type' => 'textfield',
'#title' => t('Enter username'),
'#autocomplete_path' => 'userpasswords2/ajax_username_autocomplete_callback2',
'#executes_submit_callback' => 'TRUE',
);
$form['box'] = array(
'#type' => 'markup',
'#prefix' => '<div id="box">',
'#suffix' => '</div>',
'#markup' => '<br>',
);
$form['actions']['submit'] = array(
'#type' => 'submit',
'#ajax' => array(
'callback' => 'userpasswords2_callback',
'wrapper' => 'box',
),
'#value' => t('Submit'),
);
return $form;
}
function ajax_username_autocomplete_callback2($string = "") {
$matches = array();
if ($string) {
$result = db_select('my_domain_passwords')
->fields('my_domain_passwords',array('fullname','password'))
->condition('fullname', db_like($string) . '%', 'LIKE')
->range(0,10)
->execute();
foreach ($result as $user) {
$form['custom']['username'] = $matches[$user->fullname] = check_plain($user->fullname);
$form['custom']['password'] = check_plain($user->password);
}
}
drupal_json_output($matches);
}
function userpasswords2_form_validate($form, &$form_state) {
$username = $form_state['values']['user'];
$matches = array();
// select from database by fullname
$result = db_select('my_domain_passwords')
->fields('my_domain_passwords', array('fullname'))
->condition('fullname', db_like($username), 'LIKE')
->range(0,1)
->execute()
->fetchField();
if (!empty($username)) {
$form_state['custom']['username'] = $result;
$password = db_select('my_domain_passwords')
->fields('my_domain_passwords', array('password'))
->condition('fullname', db_like($username), 'LIKE')
->range(0,1)
->execute()
->fetchField();
$form_state['custom']['password'] = $password;
}
return $form;
}
function userpasswords2_callback($form, &$form_state) {
if ( (!empty($form_state['custom']['username'])) && (!empty($form_state['custom']['password'])) ) {
$output_string = $form_state['custom']['username'] . " : " . $form_state['custom']['password'];
} else {
$output_string = "No such user: " . $form_state['values']['user'];
}
$username = $form_state['custom']['username'];
$password = $form_state['custom']['password'];
$element = $form['box'];
$element['#markup'] = $output_string;
return $element;
}
If you remove your autocomplete, you can be able to submit by press enter. So the issue is in the autocomplete function. You need to patch the misc/autocomplte.js. Following is the patch, check out the link for more details.
case 13: // Enter.
case 27: // Esc.
this.hidePopup(e.keyCode);
if (e.keyCode == 13 && $(input).hasClass('auto_submit')) {
input.form.submit();
}
This could be help you https://www.drupal.org/project/drupal/issues/309088
Related
I am at beginner level of drupal trying to Overriding the third party uc_cart_uc_cart_pane function into my own custom function custom_session_uc_cart_pane but it is duplicating the form or result
Here is sample functions
/**
* Implements hook_uc_cart_pane().
*/
function uc_cart_uc_cart_pane($items) {
$body = array();
if (!is_null($items)) {
$body = drupal_get_form('uc_cart_view_form', $items) + array(
'#prefix' => '<div id="cart-form-pane">',
'#suffix' => '</div>',
);
}
$panes['cart_form'] = array(
'title' => t('Default cart form'),
'enabled' => TRUE,
'weight' => 0,
'body' => $body,
);
return $panes;
}
function custom_session_uc_cart_pane($items){
$iframe = multi_domain_iframe();
// echo "<pre>";
// print_r($items);
// exit;
$pre_suf_fix = array(
'#prefix' => '<div id="cart-form-pane1">',
'#suffix' => '</div>'.$iframe,
);
$body = array() + $pre_suf_fix;
if (!is_null($items)) {
$body = drupal_get_form('custom_session_view_form', $items) + $pre_suf_fix;
}
$panes['cart_form'] = array(
'title' => t('Default cart form'),
'enabled' => TRUE,
'weight' => 0,
'body' => $body,
);
return $panes;
}
any thing which i am missing.
if you want to change some thing specifically for a form you can use
hook_form_alter
you do not need to override the function.
Thanks
i have this form:
function tax_assistant_form_alter(&$form, $form_state, $form_id) {
//questa funzione รจ usata per alterare la disposizione del form originale
//contenuto in un altro modulo (linkableobject)
if ($form_id == 'linkableobject_node_form') {
$vid=26;
$query=taxonomy_get_tree($vid);
//Creo funzione per array name vocabulary
foreach($query as $rec){
$form["prova"]= array(
'#type'=> 'select',
'#title'=> t($rec->name),
'#options'=>array(get_vid($vid)),
'#ajax' => array(
'callback'=>'get_synonyms',
'wrapper'=>'area_sinonimi',
'replace'=>'TRUE',
),
);
}
//form dei sinonimi
$form['sinonimi'] = array(
// '#type' => 'hidden',
'#title'=> t('Sinonimi'),
'#prefix' => '<div id="area_sinonimi">Qui andrebbero i sinonimi',
'#suffix' => '</div>',
);
}
and recall with ajax this function get_synonyms
function get_synonyms() {
$form_build_id = $_POST['form_build_id'];
$form_state = array('submitted' => FALSE);
$form = form_get_cache($form_build_id, $form_state);
$output="";
$synonyms = '';
$vid=26;
$tid = $_POST['prova'];
$result = db_query('SELECT name FROM {taxonomy_term_synonym} where tid=:tid', array(':tid'=>$tid));
//print_r($result);
$voc = get_vocabolario($vid);
if ($tid > 0)
$synonyms .= "<b>Synonyms for $voc:</b></br>";
foreach ($result as $rec) {
$synonyms.= "<i>'" . $rec->name . "';</i> ";
$keywords[$rec->name] = $rec->name;
}
$form['sinonimi'] = array(
'#type' => 'item',
'#description' => t("In order to facilitate the cataloging of your learning object,
try to make use of these terms for its description"),
'#value' => $synonyms,
);
$synonyms.='</br>';
form_set_cache($_POST['form_id'], $form, $form_state);
$form = form_builder($_POST['form_id'], $form, $form_state);
$output.=drupal_render($form['sinonimi']);
drupal_json_encode(array('status' => TRUE, 'data' => $output));
exit;
}
but give me this error Recoverable fatal error: Argument 1 passed to drupal_array_set_nested_value() must be of the type array, null given, called in /var/www/html/glorep/includes/form.inc on line 2532 and defined in drupal_array_set_nested_value() (line 6598 of /var/www/html/glorep/includes/common.inc).
I think the probles is ajax, i have upgrade this from D6 when there is D6, but i can understand how modify, can someone help me?
Please read this https://drupal.org/coding-standards and update your code.
You're adding form element ($form["prova"]) with the same name in loop. So each iteration will replace existing element with new one.
Check value of $tid = $_POST['prova']; because it depends from which options was set for this select box. I expect that you didn't set the keys for options.
Check arguments of drupal_array_set_nested_value() function.
Install and configure xdebug and will be able to find a bug in 1 minute.
I'm trying to get the user to return to the page they were on after logging in. Right now, it takes them to the current page. I'm logging in though my universities LDAP so drupal modules don't work. Here is my user.module code that takes users to the lpad login instead of the drupal login block:
function user_login($form, &$form_state) {
global $user;
// If we are already logged on, go to the user page instead.
if ($user->uid) {
drupal_goto('user/' . $user->uid);
}
header("Location: https://www.cvrc.virginia.edu/login/pc"); /* Redirect browser */
/* Make sure that code below does not get executed when we redirect. */
exit;
// Display login form:
$form['name'] = array('#type' => 'textfield',
'#title' => t('Username'),
'#size' => 60,
'#maxlength' => USERNAME_MAX_LENGTH,
'#required' => TRUE,
);
$form['name']['#description'] = t('Enter your #s username.', array('#s' => variable_get('site_name', 'Drupal')));
$form['pass'] = array('#type' => 'password',
'#title' => t('Password'),
'#description' => t('Enter the password that accompanies your username.'),
'#required' => TRUE,
);
$form['#validate'] = user_login_default_validators();
$form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Log in'));
return $form;
}
Any thoughts? Thanks.
(If i understood). Thinking,you need use $_SERVER["HTTP_REFERER"] for returning user back. Try it:
drupal_goto($_SERVER["HTTP_REFERER"]);
first instead of
if ($user->uid) {
drupal_goto('user/' . $user->uid);
}
user either user_is_logged_in() or $user->uid >0 . your current logic will also work for anonymous users which is uid 0
also from the looks of it the code for your form will never get executed.
if you are trying to redirect the user after login i believe you should do this
// If we are already logged on, go to the user page instead.
if (user_is_logged_in()) {
drupal_goto('user/' . $user->uid);
}else{
// Display login form:
$form['name'] = array('#type' => 'textfield',
'#title' => t('Username'),
'#size' => 60,
'#maxlength' => USERNAME_MAX_LENGTH,
'#required' => TRUE,
);
$form['name']['#description'] = t('Enter your #s username.', array('#s' => variable_get('site_name', 'Drupal')));
$form['pass'] = array('#type' => 'password',
'#title' => t('Password'),
'#description' => t('Enter the password that accompanies your username.'),
'#required' => TRUE,
);
$form['#validate'] = user_login_default_validators();
$form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Log in'));
return $form;
}
{pseudocode on success form redirect }
header("Location: https://www.cvrc.virginia.edu/login/pc"); /* Redirect browser */
/* Make sure that code below does not get executed when we redirect. */
exit;
something like that
I am writing custom module in drupal.
Aim is to :
1. Upload a csv file
2. Display its content in a tabular layout.
3. On confirmation, save it in database.
Problem I am facing:
I am unable to upload any file. I am not getting any thing in $_FILES, even if I upload or not. >> SOLVED
How do I split the process ? Suppose I succeed in uploading file [with your help indeed ;) ], and I save the file, suppose in drupal6/uploaded_data directory. How do I redirect to next page where I can read from file and show tabular data for confirmation.
Codes :)
menu hooks and all
function productsadmin_menu() {
$items['admin/settings/product-administration'] = array(
'title' => 'Product Administration',
'description' => 'Upload products data',
'page callback' => 'productsadmin_form',
'access arguments' => array('access content'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
function productsadmin_form() {
return drupal_get_form('productsadmin_my_form');
}
This function is passed to drupal_get_form()
function productsadmin_my_form() {
$form['#attributes'] = array('enctype' => "multipart/form-data");
$form['csv'] = array(
'#type' => 'file',
'#title' => 'Product Catalog',
'#description' => 'Product catalog in specified csv format',
'#required' => FALSE,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Submit',
);
return $form;
}
Validation (The part which is not working is commented)
function productsadmin_my_form_validate($form, &$form_state) {
if($form_state['values']['csv'] == "") {
form_set_error('csv', t('Please input product catalog csv data'));
}
/* // Check if file is uploaded (Not working)
if ($_FILES['files']['name']['csv'] == '') {
form_set_error('csv', t('Please upload product catalog' . $rahul_vals));
}
*/
}
Submit action
function productsadmin_my_form_submit($form, &$form_state) {
/*
1. Move File to uploaded_dir
2. Change the header so that it is redirected to new page
*/
}
you shouldn't use $_FILES in drupal,use drupal api
I made this example for you to explain how to work with cvs
/**
* Form function
*/
function _form_cvs_import($form_state) {
$form['#attributes'] = array('enctype' => "multipart/form-data");
$form['container'] = array(
'#type' => 'fieldset',
'#title' => t('CVS UPLOAD') ,
);
$form['container']['cvs_file'] = array(
'#type' => 'file' ,
'#title' => t('CVS FILE') ,
'#description' => t('insert your cvs file here') ,
) ;
$form['container']['submit'] = array(
'#type' => 'submit' ,
'#value' => t('SEND') ,
) ;
return $form ;
}
/**
* form validate
*/
function _form_cvs_import_validate($form, $form_state) {
$validators = array(
'file_validate_extensions' => array('cvs'),
);
if(!file_save_upload('cvs_file', $validators)) { // the file is not submitted
form_set_error('cvs_file', 'Please select the cvs file') ;
}else{ // the file is submitted another validation for extension
$file = file_save_upload('cvs_file', $validators, file_directory_path()) ;
if($file->filemime != 'application/octet-stream' ) {
form_set_error('cvs_file', 'Extensions Allowed : cvs') ;
}
}
}
/**
* form submit
*/
function _form_cvs_import_submit($form, $form_state) {
$file = file_save_upload('cvs_file', $validators, file_directory_path()) ; // this is the cvs file in the tmp directory
$file_handler = fopen($file->filepath, 'r') ; // open this cvs file
$line_num = 0 ;
$fields = array() ;
while(!feof($file_handler)) {
$line_num++ ;
$line = fgets($file_handler) ; // this is the line/row
$line_array = explode(",", $line); // array of row fields
$field_num = 0 ;
foreach($line_array as $field) {
$field_num++ ;
$fields[$line_num][$field_num] = str_replace('"', '', $field ); // E.g you can access second row and third field by $fields[2][3]
}
}
fclose($file_handler);
unlink($file->filepath);
}
I am using fancy box iframe to display my page which has the file upload button. when i click form submit i got the "File exceeds the defined ini size". i checked some of links under google and stackoverflow. But not able to find. I have enctype="multipart/form-data" in my form. Following is my code
public function createForm($data = array())
{
$this->setMethod(Zend_Form::METHOD_POST);
$this->setEncType(Zend_Form::ENCTYPE_MULTIPART);
$this->setAttrib('id', 'createsub');
$this->setAction(
$this->getView()->getHelper('url')->url(array(
'controller' => 'test',
'action' => 'create'
))
);
$this->setDecorators(array(
'Description',
'FormElements',
'Form'
));
$fnameNotEmpty = new Zend_Validate_NotEmpty();
$fnameNotEmpty->setMessage('Name cannot be empty.');
$fnameStrlen = new Zend_Validate_StringLength(1, 20);
$name = new Zend_Form_Element_Text('name', array(
'label' => 'Name:',
'value' => '',
'class' => 'text-size text',
'tabindex' => '1',
'required' => true,
'validators' => array(
array($fnameNotEmpty, true),
array($fnameStrlen, true)
),
'decorators' => $this->requiredElementDecorators,
'description' => '<img src="../../'.$baseurl.'/images/star.png" alt="required" />',
'filters' => array('StringTrim')
));
$this->addElement($name);
.... ..... .....
$brochure = new Zend_Form_Element_File('brochure', array(
'label' => 'Brochure:*',
'value' => '',
'class' => 'text-size text',
'tabindex' => '3',
'required' => true,
'filters' => array('StringTrim')
));
$this->addElement($brochure);
$submit = $this->createElement('button','addtbtn',array('class'=>'Test','label'=>'Create'));
$submit->setIgnore(true);
$this->addElement($submit);
return $this;
}
Also if i did not use iframe, I can able to upload my image...Very Strange.
I make the validation using Ajax by following code ,
<script type="text/javascript">
var Path="<?php echo $this->eurl; ?>"
$(function()
{
vReg=0
$("#addtbtn").click(function()
{
if(vReg == 1)
{
return true;
}
else{
var url = 'validateform';
var data = {};
$("input").each(function()
{
data[$(this).attr('name')] = $(this).val();
});
$("select").each(function()
{
data[$(this).attr('name')] = $(this).val();
});
$("textarea").each(function()
{
data[$(this).attr('name')] = $(this).val();
});
$.post(url,data,function(resp)
{
vError=""
for(id in resp){
oResp=resp[id];
for(key in oResp){
vError +=oResp[key]+"\n"
}
}
if(vError == ''){
vReg=1
$("#createform").attr('target','_top');
$("#createform").submit();
return true;
}
else{
$("#createform").attr('target','_self');
alert(vError)
return false;
}
},'json');
}
});
});
</script>
Also Has the following function in my controller
public function validateformAction()
{
$this->_helper->viewRenderer->setNoRender();
$this->_helper->getHelper('layout')->disableLayout();
$p = new Admin_Model_DbTable_Test();
$p = $p->getData();
foreach($p AS $k => $v)
{
$p[$v['catid']] = $v['name'];
}
$form = new Admin_Model_Form_SubTest();
$f = $form->createForm(array('parents' => $p));
$f->isValid($this->_getAllParams());
$json = $f->getMessages();
echo Zend_Json::encode($json);
}
So this will call the function which i gave on the top of the post and do the validation and return the error.But here i always getting "File exceeds the defined ini size " What I done wrong this code.
Kindly help me on this.
Check the upload_max_filesize setting in your .ini file(s). That's where this error comes from.
When you call .val() on your file input, you get the path of the file you have selected, while your validator will be expecting the file itself, hence the strange error. Most people opt to skip file inputs when doing ajax validation, and just check it on submit.