How to pass dynamic file location in Form API? - drupal-7

my requirement is to upload files to specific folders. How can I achieve this by using form api.
How can I modify below code such that upload_location should be dynamic. Uploaded file should save into the Folder name provided by the user.
#submit element is not calling custom_document_submit function.
$form['folder_name'] = array(
'#type' => 'textfield',
'#title' => t('Folder Name'),
);
$form['document'] = array(
'#type' => 'managed_file',
'#upload_validators' => array('file_validate_extensions' => array('xml')),
'#upload_location' => 'public://',
'#submit' => array('custom_document_submit'),
);
function custom_document_submit($form, &$form_state){
$destination = $form_state['values']['folder_name'];
$validators = array();
$file = file_save_upload('document', $validators, 'public://'.$destination);
}

The #submit property cannot be declare on a managed_file form object...
Instead, you have to add or to modify a submit action on your form (or button).
$form['#submit'][] = 'custom_document_submit';
If you don't want to modify the submit method of your form, you can also simply add a validator (with the #validate property), witch will modify the '#upload_location' property of your document depending on the folder_name value.
Both, #submit and #validate properties have to be added to the form itself.

<?php
define('IMPORT_DIRECTORY_PATH', 'public://import');
$form['folder_name'] = array(
'#type' => 'textfield',
'#title' => t('Folder Name'),
);
form['document'] = array(
'#title' => t('Upload .xml'),
'#type' => 'managed_file',
'#upload_validators' => array(
'file_validate_extensions' => array('xml'),
),
'#process' => array('import_document_element_process'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Upload'),
'#submit' => array('custom_document_submit'),
);
function custom_document_submit($form, &$form_state){
// Validate extensions.
$validators = array(
'file_validate_extensions' => array('xml'),
);
$file = file_save_upload('document', $validators, FALSE, FILE_EXISTS_RENAME);
// If the file passed validation.
if ($file) {
// Rename uploaded file to prevent cache from remembering name file.
$directory = SCHEDULES_IMPORT_DIRECTORY_PATH;
if (file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {
$uri = $directory . '/xml_' . $file->uid . '_' . $file->timestamp . '.xml';
if ($file = file_move($file, $uri)) {
$form_state['values']['document'] = $file;
}
else {
form_set_error('document', t('The file could not be uploaded.'));
}
}
else {
form_set_error('document', t('The directory is not writable.'));
}
}
else {
form_set_error('document', t('The file extension is not correct.'));
}
// dpm($form_state['values']['document']);
// var_dump( $form_state['values']['document']);
}
/**
* Removing the upload button in managed files.
*/
function import_document_element_process($element, &$form_state, $form) {
$element = file_managed_file_process($element, $form_state, $form);
$element['upload_button']['#access'] = FALSE;
return $element;
}

Related

Drupal form api file upload with auto compression

I have written a module with form api which can upload image with dynamic file name. I want to upload that file with auto compression. I cannot understand how will I achieve this. How can I implement this in submit callback.
Below my code:
function MYMODULE_registration_form() {
$form['name'] = array(
'#title'=> t('Name'),
'#type' => 'textfield',
'#required' => TRUE,
'#size' => 40,
'#attributes' => array('placeholder' => t('Enter your name'),),
);
$form['personal_info']['upload_pic'] = array(
'#title' => t('Upload Photo'),
'#type' => 'file',
'#description' => t('Upload a file, allowed extensions: jpg, jpeg, png, gif, bmp'),
);
$form['submit'] = array(
'#value' => t('Submit'),
'#type' => 'submit',
);
$form['#attributes']['enctype'] = 'multipart/form-data';
return $form;
}
function MYMODULE_registration_form_submit($form, $form_state) {
$name = $form_state['values']['name'];
$count = 1;
$original_username = $name;
while (user_load_by_name($name)) {
$name = $original_username . $count++;
}
$validators = array(
'file_validate_extensions' => array('png gif jpg jpeg bmp')
);
$uploadCheck = file_save_upload('upload_pic', $validators);
if($uploadCheck) {
$parts = pathinfo($uploadCheck->filename);
$imagename = str_replace(' ', '_',$original_username.'_'. $count . '.'. $parts['extension']);
$target = "public://attorneys/".$imagename;
file_move($uploadCheck, $target, FILE_EXISTS_REPLACE);
$picture_fid = $uploadCheck->fid;
}
}
After a lot of R&D I have come to this conclusion and it is working fine:
Implement gulp package and install image optimisation plugin.
Take ref from this url : https://www.tutorialspoint.com/gulp/gulp_optimizing_images.htm

Drupal 7 custom form module

My form using custom module is not appearing on my contact us page.I created my .module file and .info file and then active the module as well. Following is the code I had included in my .module file
function custom_form_module_form($form,&$form_state) {
$form['name'] = array(
'#type' => 'textfield',
);
$form['company'] = array(
'#type' => 'textfield',
);
$form['phone'] = array(
'#type' => 'textfield',
);
$form['email'] = array(
'#type' => 'textfield',
);
$form['message'] = array(
'#type' => 'textfield',
);
return $form;
}
and in my template.php file
function custom_form_module_form_theme($existing, $type, $theme, $path) {
$items['custom_form_module_form'] = array(
'render element' => 'form',
'template' => 'page--contact-us',
'path' => drupal_get_path('theme', 'escorts').'/templates');
return $items;
}
and in my page--contact-us.tpl.php I used the following line to call separate fields of a form but its not working.
<?php echo drupal_render($form['name']); ?>
"here custom_form_module=my module name and page--contact-us.tpl.php=my template file and escorts=my theme name"
To print the form in the contact page, you may not use template.php.
Simply:
$my_form = drupal_get_form('custom_form_module_form');
print drupal_render($my_form);
Update
Change the form markup from from your template.php
function theme_my_form_1($form) {
$vars['element'] = $form;
$markup = '';
$markup .= '<div id="form-name-wrapper">'
. drupal_render($form['name'])
. '</div>';
// continue altering the markup
$vars['element']['#children'] = $output;
return theme_form($vars);
}
Then, in your .tpl.php file:
$my_form = drupal_get_form('custom_form_module_form');
print theme_my_form_1($my_form);

Updating and deleting data in D7

I have made a form in D7 using form API, registered some users and retrieved their registered data from database;now what i want is to add an edit and a delete link in front of every row in the retrieved table;i have done that in PHP but how to implement same in Drupal?;anybody having any idea how to do that?
My retrieval code is:
function form_data_menu() {
$items['formdata'] = array(
'title' => 'Form Data',
'page callback' => 'form_data_form',
'access callback' => TRUE,
);
return $items;
}
function form_data_form()
{
$results = db_query('SELECT * FROM {drupal}');
$header = array(t('Id'),t('Name'),t('College'),t('Education'),t('Percentage'),t('Application'));
$rows = array();
foreach($results as $result) {
$rows[] = array(
$result->id,
$result->name,
$result->college,
$result->education,
$result->percentage,
$result->application,
);
}
return theme('table',array('header'=>$header,'rows'=>$rows));
}
I can add links though but the main problem is how to run update and delete queries in D7?
Any help will be appreciated. Thank you!
Start with the example module "dbtng_example.module".
https://www.drupal.org/project/examples
This will give an example of how to set up a module to save to the database. I used this recently to create a custom module to save data to a new database table within drupal. To figure out how to set up the hook_schema, you can look at ".install" files within the drupal core and contributed codebase.
Then to create an edit or delete link, you need to alter your hook_menu to pass in the unique id for that element:
$items['admin/structure/nates-custom-page/update/%'] = array(
'title' => 'Update entry',
'page callback' => 'drupal_get_form',
'page arguments' => array('nates_module_form_update', 5),
'weight' => -5,
'access arguments' => array('administer DFP'),
);
$items['admin/structure/nates-custom-page/delete/%'] = array(
'title' => 'Delete entry',
'page callback' => 'drupal_get_form',
'page arguments' => array('nates_module_form_delete', 5),
'access arguments' => array('administer DFP'),
);
Above is an example where I added the argument (indicated by the percentage sign in the array key, ("%"), that will represent the unique id for that item I want to edit or delete.
Then alter the edit form to load the item you want to edit by the id.
And add a delete form.
Here's an example of a delete form:
function nates_module_form_delete($form, &$form_state) {
$entry = nates_module_entry_load_by_pid(arg(5));
$form = array();
$form['pid'] = array(
'#type' => 'value',
'#value' => arg(5),
);
$output = "";
foreach($entry as $key => $value) {
$output .= "<p><strong>$key</strong>: $value</p>";
}
$form['markup'] = array(
'#type' => 'markup',
'#markup' => $output,
);
return confirm_form(
$form,
t('Are you sure you want to delete this item? '),
'example/list',
t('This action cannot be undone.'),
t('Delete'),
t('Cancel')
);
return $form;
}
Notice I return a confirmation form first.
And here's the submit handler function that processes it after they submit the request:
function nates_module_form_delete_submit($form, &$form_state) {
global $user;
nates_module_entry_delete($form_state['values']['pid']);
drupal_set_message(t("Deleted entry"));
}
Then, edit your listing page to add the edit links and delete links:
function nates_module_list() {
$output = '';
// Get all entries in the dfp_amobee2 table.
if ($entries = nates_module_entry_load_all()) {
$rows = array();
foreach ($entries as $entry) {
// Sanitize the data before handing it off to the theme layer.
$entry->editlink = l('edit','admin/structure/nates-custom-page/update/' . $entry->pid, array('query' => array('destination' => 'admin/structure/nates-custom-page')));
$entry->deletelink = l('delete','admin/structure/nates-custom-page/delete/' . $entry->pid, array('query' => array('destination' => 'admin/structure/nates-custom-page')));
unset($entry->pid);
if(!empty($entry->tid)) {
$entry->alias = l($entry->alias, 'taxonomy/term/'.$entry->tid);
}
else if(isset($entry->pages)) {
if(drupal_valid_path($entry->pages)) {
$entry->alias = l(drupal_lookup_path('alias', $entry->pages),$entry->pages);
} else {
$entry->alias = check_markup($entry->pages);
}
} else {
$entry->alias = "";
}
unset($entry->pages);
if(!$entry->tid) {
$entry->tid = "";
}
$rows[] = (array) $entry;
}
// Make a table for them.
$header = array(t('path'), t('tid'), t('dfp tag machine_name'),t('amobee_as'), '', '');
$output .= '<p>' . t('If the "tid" is filled in, amobee_as will be used on taxonomy pages and on node pages (where the main term id matches). If the path is filled it, will be used on that path. Path supercedes "tid" when there is a conflict.') . '</p>';
$output .= theme('table', array('header' => $header, 'rows' => $rows));
}
else {
drupal_set_message(t('No entries have been added yet.'));
}
return $output;
}

drupal 7 form theme function not being called

I'm trying to register a theme function for a simple form in a custom module, but the theme function is not being called. I just get the basic form.
Here's my hook_theme():
function kss_membership_theme($existing, $type, $theme, $path){
$items = array();
$items['kss_membership_payment_form'] = array(
'render element' => 'form',
);
return $items;
}
for this form:
/**
* Returns the form for the second page of the payment process
*/
function kss_membership_payment_form($form, &$form_state) {
$form['description'] = array(
'#type' => 'item',
'#title' => t('We currently accept Paypal payments'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
'#submit' => array('kss_membership_payment_form_submit'),
);
$form['#theme'] = array('theme_kss_membership_payment_form');
return $form;
}
and here is the theme function:
function theme_kss_membership_payment_form($variables) {
// Isolate the form definition form the $variables array
$form = $variables['form'];
$output = '<h2>' . t('Please enter your information below') . '</h2>';
$output .= '<div id="personal_details">';
$output .= drupal_render($form['description']);
$output .= drupal_render($form['submit']);
// Additional template output goes here....
$output .= '</div>';
$output .= drupal_render_children($form);
return $output;
}
You are very near to solution, Only one problem is there.
theme calling is wrong
$form['#theme'] = array('theme_kss_membership_payment_form');
you are required to call
$form['#theme'] = array('kss_membership_payment_form');
After that You must required to clear the cache from the admin => configuration => Performance => Clear Cache button.
/**
* Returns the form for the second page of the payment process
*/
function kss_membership_payment_form($form, &$form_state) {
$form['description'] = array(
'#type' => 'item',
'#title' => t('We currently accept Paypal payments'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
'#submit' => array('kss_membership_payment_form_submit'),
);
$form['#theme'] = array('kss_membership_payment_form');
return $form;
}

Can I create a Drupal autocomplete textfield in a block?

I want to create an auto-complete form in my custom module that will be loaded in a block. Drupal doesn't seem to be loading the necessary Javascript libraries to work properly. How do I know what needs to be loaded and how/where do I tell Drupal to load these libraries?
hook_block_view:
function my_module_block_view($delta = '') {
//The $delta parameter tells us which block is being reqested.
switch ($delta) {
case 'my_module_my_block':
$block['subject'] = t('Block Subject');
$block['content'] = drupal_get_form('my_module_my_form');
break;
}
return $block;
}
Form code:
function my_module_my_form($form, &$form_state) {
$form = array();
$form['term'] = array(
'#type' => 'textfield',
'#autocomplete_path' => 'my-module-autocomplete'
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Add',
);
return $form;
}
The form loads, the field is there, but auto-complete isn't working :(
If I call the my-module-autocomplete path I do get a valid response back when compared with a Content Type edit form. The ajax spinner in the input field never appears so the ajax isn't being called. Realistically all I want is the autocomplete field...the submit will be handled manually.
It's probably because you're reseting $form to an empty array at the beginning of the function. In Drupal 7 there's a bunch of stuff added to that element before it's passed through to your form function (that's why $form is passed to your function whereas in Drupal 6 it wasn't).
Just remove $form = array(); and it should work, other than that your code looks perfect.
the following should work;
function mymodule_block_info() {
$blocks['mymodule'] = array(
// The name that will appear in the block list.
'info' => t('My Module'),
// Default setting.
'cache' => DRUPAL_NO_CACHE,
);
return $blocks;
}
function mymodule_block_view($delta = ''){
switch($delta){
case 'mymodule':
if(user_access('access content')){ //good idea to check user perms here
$block['subject'] = t('My Module');
$block['content'] = 'Hi :)';
$block['content'] = drupal_get_form('mymodule_form');
return $block;
}
break;
}
}
function mydmodule_menu() {
$items['module/autocomplete'] = array(
'page callback' => 'mymodule_autocomplete',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK
);
return $items;
}
function mymodule_form($form, &$form_state) {
$form['greenentry'] = array(
'#type' => 'textfield',
'#title' => t('Enter'),
'#autocomplete_path' => 'mymodule/autocomplete',
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
return $form;
}
function mymodule_autocomplete($string) {
$matches = array();
// Some fantasy DB table which holds cities
$query = db_select('cities', 'c');
// Select rows that match the string
$return = $query
->fields('c', array('city'))
->condition('c.city', '%' . db_like($string) . '%', 'LIKE')
->range(0, 10)
->execute();
// add matches to $matches
foreach ($return as $row) {
$matches[$row->url] = check_plain($row->url);
}
// return for JS
drupal_json_output($matches);
}
this code is so pretty to add an auto-complete filed in block. But i just found a tiny notice here. if someone get an error
An ajax error occurred. http result code 200
then just add
exit();
after the line
drupal_json_output($matches);
hence fix the issue.

Resources