dynamically adding text boxes in drupal form api - api

I want to have a add more button on clicking which i can add dynamically, textboxes in a drupal form api.. can someone help on this?
Thanks in advance

Take a look at Adding dynamic form elements using AHAH. It is a good guide to learn AHAH with Drupal's form API.
EDIT: For an example, install the Examples for Developers module, it has an AHAH example you can use to help you learn.

Here is an example how to solve this with Ajax in Drupal 7(If anyone want I can convert it also to Drupal 6 using AHAH(name before it became Ajax)).
<?php
function text_boxes_form($form, &$form_state)
{
$number = 0;
$addTextbox = false;
$form['text_lists'] = array
(
'#tree' => true,
'#theme' => 'my_list_theme',
'#prefix' => '<div id="wrapper">',
'#suffix' => '</div>',
);
if (array_key_exists('triggering_element', $form_state) &&
array_key_exists('#name', $form_state['triggering_element']) &&
$form_state['triggering_element']['#name'] == 'Add'
) {
$addTextbox = true;
}
if (array_key_exists('values', $form_state) && array_key_exists('text_lists', $form_state['values']))
{
foreach ($form_state['values']['text_lists'] as $element) {
$form['text_lists'][$number]['text'] = array(
'#type' => 'textfield',
);
$number++;
}
}
if ($addTextbox) {
$form['text_lists'][$number]['text'] = array(
'#type' => 'textfield',
);
}
$form['add_button'] = array(
'#type' => 'button',
'#name' => 'Add',
'#ajax' => array(
'callback' => 'ajax_add_textbox_callback',
'wrapper' => 'wrapper',
'method' => 'replace',
'effect' => 'fade',
),
'#value' => t('Add'),
);
return $form;
}
function ajax_add_textbox_callback($form, $form_state)
{
return $form['text_lists'];
}
function text_boxes_menu()
{
$items = array();
$items['text_boxes'] = array(
'title' => 'Text Boxes',
'description' => 'Text Boxes',
'page callback' => 'drupal_get_form',
'page arguments' => array('text_boxes_form'),
'access callback' => array(TRUE),
'type' => MENU_CALLBACK,
);
return $items;
}

Related

Drupal 7 - get variables from hook_theme

I tried to pass a variable from a custom module to a tpl file.
In my custom module (named example)
1. I created a route with an argument via hook_menu :
function example_menu() {
$items['example/fancybox-photos/%'] = array(
'page callback' => 'example_display_fancybox_photos',
'page arguments' => array(2),
'type' => MENU_CALLBACK,
'access arguments' => array('access content'),
);
return $items;
}
2. I created my page callback function :
function example_display_fancybox_photos($nid) {
$nodePhoto = node_load($nid);
$field_photo = field_get_items('node', $nodePhoto, 'field_photo');
$photo = [
"field_photo" => $field_photo[0]['uri'],
....
];
return theme('example_fancybox_photos', array('infosPhoto' => $photos));
}
3 . I created a hook_theme
function example_theme() {
$themes = array();
$themes['example_fancybox_photos'] = array(
'template' => 'templates/example-fancybox-photos',
'variables' => array('infosPhoto' => NULL),
);
return $themes;
}
4 . I finally created a tpl named "example-fancybox-photos.tpl.php" in templates folder (in theme folder)
<pre><?php print var_dump($infosPhoto); ?></pre>
The result is NULL
I did some researchs but i dont understand why the variable is still NULL.
thanks for your help !
I finally managed to get the variable from the module to the tpl !
1. I created a route with an argument via hook_menu :
function example_menu() {
$items['example/fancybox-photos/%'] = array(
'page callback' => 'example_display_fancybox_photos',
'page arguments' => array(2),
'type' => MENU_CALLBACK,
'access arguments' => array('access content'),
);
return $items;
}
2. I created my page callback function :
function example_display_fancybox_photos($nid) {
$nodePhoto = node_load($nid);
$field_photo = field_get_items('node', $nodePhoto, 'field_photo');
$photos = [
"field_photo" => $field_photo[0]['uri'],
....
];
return theme('example_fancybox_photos', array('infosPhoto' => $photos));
}
3 . I created a hook_theme
function example_theme() {
$themes = array();
$themes['example_fancybox_photos'] = array(
'template' => 'templates/example_fancybox_photos',
'variables' => array('infosPhoto' => NULL),
);
return $themes;
}
4 . I finally created a tpl named "example_fancybox_photos.tpl.php" in templates folder (in MODULE (example) folder)
The problems were that:
- the tpl was not named in the same way and with dashes instead of underscore
- the tpl was in the template folder of the theme and not of the module
You have passed $photos but you have array as $photo. try to change that
Hope the below code helps you.
function example_menu(){
$items['example/fancybox-photos/%'] = array(
'page callback' => 'example_display_fancybox_photos',
'page arguments' => array(2),
'type' => MENU_CALLBACK,
'access arguments' => array('access content'),
);
return $items;
}
function example_display_fancybox_photos($nid){
$photos = 'value from example module!';
return theme('example_fancybox_photos',array('photos' => $photos));
}
function example_theme() {
$path = drupal_get_path('module', 'example');
return array(
'example_fancybox_photos' => array(
'variables' => array('photos' => null),
'template' => 'example_fancybox_photos',
'path' => $path,
),
);
}
Place your tpl file example_fancybox_photos.tpl.php in your module directory and inside it use the below code.
<?php print $photos; ?>
or
function example_theme() {
return array(
'example_fancybox_photos' => array(
'variables' => array('photos' => null),
'template' => 'example_fancybox_photos',
),
);
}
Place your tpl file example_fancybox_photos.tpl.php in your theme directory and inside it place the below code
<?php print $photos; ?>

Yiibooster TBSelect2 not displayed

In my view I have this code:
echo $form->select2Row($model, 'Zustelladresse', array(
'asDropDownList' => false,
'options' => array(
'placeholder' => "Zustelladresse",
'width' => '100%',
'closeOnSelect' => true,
'minimumInputLength'=>1,
'initSelection' => "js:function (element, callback) {
var selected_data = new Object;
selected_data.id = '123';
selected_data.text = 'Test';
callback(selected_data);
}",
'ajax' => array(
'url' => Yii::app()->createUrl('address/zustelladresse'),
'dataType' => 'json',
'data' => 'js:function(term,page) { if(term && term.length){ return { zustelladresse: term };} }',
'results' => 'js:function(data,page) { return {results: data}; }',
),
)));
Created html:
Why is created only label and hidden input?
YiiBooster widgets are quite tricky to debug, if anything is wrong they just don't show. If you still need the answer, I successfully displayed a select2 widget with this code:
$form->select2Row($model, 'attribute_name', array(
'data' => array('1'=>'value1,'2'=>'value2'),
'htmlOptions'=>array(
'style' => 'width:600px',
'multiple' => true,
),
'options'=>array('placeholder'=>'Please make a selection'),
));
I'd suggest you to start from this code and add up your options one by one, and see if anything breaks.

Yii select2 - returned data cannot be selected

I have been looking into select2 and yii and have managed to load data via json request/response.
The issue I'm faced with is when I try to select an entry of the returned data, I can not.
Where am I going wrong ? The data returnd by the action is json formatted as CustomerCode and Name
Widget code in form
$this->widget('bootstrap.widgets.TbSelect2', array(
'asDropDownList' => false,
'name' => 'CustomerCode',
'options' => array(
'placeholder' => 'Type a Customer Code',
'minimumInputLength' => '2',
'width' => '40%',
'ajax' => array(
//'url'=> 'http://api.rottentomatoes.com/api/public/v1.0/movies.json',
'url'=> Yii::app()->getBaseUrl(true).'/customer/SearchCustomer',
'dataType' => 'jsonp',
'data' => 'js: function (term,page) {
return {
term: term, // Add all the query string elements here seperated by ,
page_limit: 10,
};
}',
'results' => 'js: function (data,page) {return {results: data};}',
),
'formatResult' => 'js:function(data){
var markup = data.CustomerCode + " - ";
markup += data.Name;
return markup;
}',
'formatSelection' => 'js: function(data) {
return data.CustomerCode;
}',
)));
code snipped from controller action SearchCustomer
Yii::app()->clientScript->scriptMap['jquery.js'] = false;
$this->renderJSON(Customer::model()->searchByCustomer($term));
renderJSON function from base controller class
protected function renderJSON($data)
{
header('Content-type: application/json');
echo $_GET['callback'] . "(";
echo CJSON::encode($data);
echo ")";
foreach (Yii::app()->log->routes as $route) {
if($route instanceof CWebLogRoute) {
$route->enabled = false; // disable any weblogroutes
}
}
Yii::app()->end();
}
Appreciate any help on this
i try.
change
'dataType' => 'jsonp' to 'dataType' => 'json'
and check json format
https://github.com/ivaynberg/select2/issues/920

Zend - inputfilter get randomize name

Hello I'm trying ZF2 form with an input file.
I have a form with a file input and I want to insert the randomize name into my db.
How I can return the randomized name?
thanks.
This is the simple form class:
class OrdineForm extends Formhttp://stackoverflow.com/questions/ask
public function __construct($name = null)
{
parent::__construct('ordine');
$this->setAttribute('method', 'post');
$this->addElements();
$this->addInputFilter();
}
public function addElements(){
$this->add(array(
'name' => 'pdf',
'attributes' => array(
'type' => 'text',
'disabled' =>'true',
),
'options' => array(
'label' => 'PDF',
),
));
// FILE INPUT
$file = new File('file');
$file
->setLabel('PDF attach')
->setAttributes(array(
'id' => 'file',
));
$this->add($file);
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'Add',
'id' => 'submitbutton',
'class' => 'btn btn-success'
),
));
}
public function addInputFilter()
{
$inputFilter = new InputFilter\InputFilter();
$fileInput= new FileInput('file');
$fileInput->setRequired(false);
$fileInput->getFilterChain()->attachByName(
'filerenameupload',
array(
'target' => './public/tmpuploads/',
'randomize' => true,
"UseUploadname" => true,
)
);
$inputFilter->add($fileInput);
$this->setInputFilter($inputFilter);
}
}
After you have validated the form in your controller you can use $form->getData();
there should be a key 'file' as that is what you named your file element. Within that a key 'tmp_name'.
This will be the randomized name.
Eg:
public function uploadfileAction()
{
//get form and filter
$form = $this->getServiceLocator()->get('SomeModule\Form\UploadFileForm');
$filter = $this->getServiceLocator()->get('SomeModule\Form\UploadFileFilter');
$form->setInputFilter($filter->getInputFilter());
if ($this->getRequest()->isPost()) {
//merge files with post
$post = array_merge_recursive(
$this->getRequest()->getPost()->toArray(),
$this->getRequest()->getFiles()->toArray()
);
//set data in form
$form->setData($post);
//check is valid- form data will now contain new name
if ($form->isValid()) {
var_dump($form->getData());
}
}
}
The resulting array dump may look something like this:
array(13) {
["file"]=>
array(5) {
["name"]=>
string(14) "some-pdf.pdf"
["type"]=>
string(24) "application/pdf"
["tmp_name"]=>
string(46) "/public/tmpuploads/new-randomized-name.pdf"
["error"]=>
int(0)
["size"]=>
int(651264)
}
["submit"]=>
string(6) "Submit"
["csrf"]=>
string(32) "4df771bb2fb14e28992a408583745946"
}
You can then just do:
$formData = $form->getData();
$fileNewLocation = $formData['file']['tmp_name'];
//do what you want with $fileNewLocation

Drupal 7 Form Invalid foreach with tableselect EDIT - How to delete selected rows from tableselect

What I am trying to do is create a selectlist using the form API, where a user can select rows and press a delete button that deletes the selected rows from the database and reloads the table with a conformation that those selected had been deleted. With my current code, when I hit the delete button I get this error:
Warning: Invalid argument supplied for foreach() in form_execute_handlers() (line 1431 of C:\xampp\htdocs\amaware\includes\form.inc).
Here is the code:
/**
* Implements hook_menu().
*/
function smsfeed_menu() {
$items = array();
$items['admin/config/content/smsfeed'] = array(
'title' => 'SMS Messages and Newsletters',
'description' => 'Edit the Setting for the SMS Feed and Newsletter',
'page callback' => 'drupal_get_form',
'page arguments' => array('smsfeed_form'),
'access arguments' => array('access administration pages'),
'type' => MENU_NORMAL_ITEM,
);
$items['admin/config/content/smsfeed/settings'] = array(
'title' => 'Settings',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 1,
);
$items['admin/config/content/smsfeed/newsletter'] = array(
'title' => 'Newsletter',
'page callback' => 'drupal_get_form',
'page arguments' => array('newsletter_table_form'),
'access arguments' => array('access administration pages'),
'type' => MENU_LOCAL_TASK,
'weigth' => 2,
);
$items['admin/config/content/smsfeed/feed'] = array(
'title' => 'SMS Feed',
'page callback' => 'drupal_get_form',
'page arguments' => array('feed_form'),
'access arguments' => array('access administration pages'),
'type' => MENU_LOCAL_TASK,
'weight' => 3,
);
$items['admin/config/content/smsfeed/questions'] = array(
'title' => 'Questions',
'page callback' => 'drupal_get_form',
'page arguments' => array('questions_form'),
'access arguments' => array('access administration pages'),
'type' => MENU_LOCAL_TASK,
'weigth' => 4,
);
return $items;
}
/**
* Page callback: SMS Settings
*
* #see smsfeed_menu()
*/
function smsfeed_form($form, &$form_state) {
$form['response_time'] = array(
'#type' => 'textfield',
'#title' => t('Response Time (In Days)'),
'#default_value' => variable_get('response_time', 3),
'#size' => 2,
'#maxlength' => 2,
'#description' => t('The response time, in days, that users should expect.'),
);
$form['feed_keyword'] = array(
'#type' => 'textfield',
'#title' => t('Feed Keyword'),
'#default_value' => variable_get('feed_keyword', 'FEED'),
'#size' => 10,
'#maxlength' => 10,
'#description' => t('The keyword users should text to have their message moderated and added to the website feed.'),
);
$form['join_keyword'] = array(
'#type' => 'textfield',
'#title' => t('Join Keyword'),
'#default_value' => variable_get('join_keyword', 'JOIN'),
'#size' => 10,
'#maxlength' => 10,
'#description' => t('The keyword users should text to be added to the newsletter list.'),
);
$form['quit_keyword'] = array(
'#type' => 'textfield',
'#title' => t('Quite Keyword'),
'#default_value' => variable_get('quit_keyword', 'QUIT'),
'#size' => 10,
'#maxlength' => 10,
'#description' => t('The keyword users should text to be removed from the newsletter list.'),
);
return system_settings_form($form);
}
/**
* Page Callback Newsletter
*/
function newsletter_table_form($form, $form_state) {
$rows = array();
$header = array(t('User Name'), t('User Number'), t('User E-mail'),);
$query = db_select('sms_newsletter');
$query->fields('sms_newsletter', array('name', 'number', 'email',))
->orderBy('name', 'ASC');
$results = $query->execute();
foreach ($results as $line) {
$rows[] = array(
$line->name,
$line->number,
$line->email,
);
}
$form['table'] = array(
'#type' => 'tableselect',
'#header' => $header,
'#options' => $rows,
'#empty' => t('No users found'),
);
$form['delete'] = array(
'#type' => 'submit',
'#value' => t('Delect Selected'),
'#submit' => 'newsletter_table_form_delete'
);
return $form;
}
function newsletter_table_form_delete ($form, &$form_state) {
foreach ($form_state['values']['collections'] as $key => $value) {
if ($value) {
$delete = db_delete('sms_newsletter')
-> execute();
}
}
}
Any help is deeply appreciated.
EDIT:
I've edited my news_letter_table_form to read:
function newsletter_table_form_delete ($form, $form_state) {
foreach (($form_state['values']['table']) as $rows) {
//$delete = db_delete('sms_newsletter')
//-> execute();
drupal_set_message ('' . $rows . '');
//drupal_set_message ('' . $form_state['values']['table'] . '');
}
}
And the new output leaves me puzzled as to how I'd identify selected rows, and delete them from the database. Using the above newsletter_table_form_delete I get the following output:
If I select the top row nothing happens
If I select the second row the output is 1
If I select the third row the output is 2 and so on
If I select multiple rows the output is an unordered html list of the selected rows.
I'm curious now how I could take what I have now and change it so I can delete selected rows from the database.
Thanks again!
Try changing
$form['delete'] = array(
'#type' => 'submit',
'#value' => t('Delect Selected'),
'#submit' => 'newsletter_table_form_delete'
);
to
$form['delete'] = array(
'#type' => 'submit',
'#value' => t('Delect Selected'),
'#submit' => array('newsletter_table_form_delete') // <-- make this an array
);
Based on the additional info added in your question edit, I noticed that your tableselect is built without specifying array keys like:
foreach ($results as $line) {
$rows[] = array( // <-- No array keys specified here
$line->name,
$line->number,
$line->email,
);
}
Since there were no keys specified, the default by PHP is a 0-based index. That is why you are getting no results for the top row, 1 for the second row, and so on.
See the documentation for the tableselect element for an example.
I don't know what your database table structure looks like but you will probably need to query the Primary Key for the table and include it as array keys to your $rows array. That way, when you process the data in your delete function, you have the Primary Key of the row you want to delete and delete it.
For me this wasn't clear straight away so.
I would just like to add that in the end what nmc was saying is you should construct your rows like this, where you add a key to row.
foreach ($results as $line) {
$rows[$line->name] = array(
$line->name,
$line->number,
$line->email,
);