With custom module, display result , - drupal

function searchsong_block($op='list',$delta=0){
$block = array();
switch($op){
case "list":
$block[0][info] = t('Search song');
return $block;
case "view":
$block['subject']='THIS IS SONG SEARCH MODULE';
$block['content']=drupal_get_form('custom1_default_form');
return $block;
}
}
function custom1_default_form () {
$form = array();
$form['txt_name'] =
array('#type' => 'textfield',
'#title' => t('Please enter your name'),
'#default_value' => variable_get('webservice_user_url',''),
'#maxlength' => '40',
'#size' => '20',
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save Details'),
);
return $form;
}
function custom1_default_form_validate (&$form, &$form_state) {
if(($form_state['values']['txt_name']) == '') {
form_set_error('user_webservice', t('Enter a name'));
}
}
function custom1_default_form_submit ($form_id, $form_values) {
$GET_TXT_VAL = $_POST['txt_name'];
$result = db_query('SELECT title FROM {node} WHERE type = "%s" AND title LIKE "%%%s%%"', 'song', $GET_TXT_VAL);
$output='';
while ($row = db_fetch_object($result)) {
// drupal_set_message($row->title);----IF I ENABLE THIS LINE THEN MY SEARCH RESULT DISPLAYING IN THE GREEN BLOCK, YES I KNOW THIS FUNCTION SOMETHING LIKE ECHO JUST FOR TESTING PURPOSE WE SHOULD USE
$output .=$row->title;
}
$block['content'] = $output;
}
How to print my output ,
Above module does not display anything , even error also,
i thing i should use theme('itemlist') somthing , but i am not sure how to use this , and where i should use this ,
So what i want is , i want to display my search result , in the content region ,
Please find my question picture view below..

Validate and submit are not for outputting data.
You should show your results in custom1_default_form:
Add in submit $_SESSION['search_text'] or use multistep "storage" (learn drupal form api for this).
But let's look how to work via sessions:
Add in custom1_default_form:
// Here is your form code, so form will appear on the top
// ...
if (isset($_SESSION['search_text'])) {
//add here your code from submit that output searching result
$form['result'] = array(
'#type' => 'item',
'#value' => $output,
);
unset($_SESSION['search_text']); // don't forget clear session
}
Your submit function should be like this:
function custom1_default_form_submit($form, &$form_state) {
$_SESSION['search_text'] = $form_state['values']['txt_name'];
// this will store text field into session, then reload page,
// so you drupal_get_form will see entered values.
}
This is all.
Tips:
if(($form_state['values']['txt_name']) == '') {
form_set_error('user_webservice', t('Enter a name'));
}
This code is not needed, if you do:
$form['txt_name'] = array(
... // other properties
'#required' => true,
);
Read please about form api here: http://api.drupal.org
Other way to use block, just call function that output result and form via drupal_get_form, so:
...
$block['content']='custom1_default_result';
...
function custom1_default_result () {
$output .= drupal_get_form('custom1_default_form');
...
$output .= //search result if session filled/
}

Related

How to wrap field in custom markup?

Situation
I have a custom module that is using hook_field_formatter_info() to add an "fancy" option to the image field in the manage display of a content type. When this option is chosen I want to be able to surround the ENTIRE field in custom divs and markup. I want the solution to be a hook in my custom module and not a template override.
Process
A user wants the display of an image field to be the "fancy" option. They check it in the drop down and click save from the content types Manage Display admin page. Now on that content type node there should be custom markup surrounding the entire field even if there are multiple images, the new markup should surround ALL the images and not each individual image.
hook_field_formatter_view
hook_field_formatter_view seems to demand it's output be an array and I can't seem to be able to wrap the output in a div.
Template overrides
I can't just make a field.tpl.php for the specific field because like I initially mentioned I need to be able to switch themes and the module still work like normal. Unless there is a way to get my module to override any field where said field has hook_field_formatter_info() set specifically.
/**
* Implements hook_field_formatter_view().
*/
function bootstrap_modal_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array();
foreach ($items as $delta => $item) {
if ($index === NULL || $index === $delta) {
$element[$delta] = array(
'#theme' => 'bootstrap_modal_image_formatter',
'#item' => $item,
'#entity_type' => $entity_type,
'#entity' => $entity,
'#node' => $entity, // Left for legacy support.
'#field' => $field,
'#display_settings' => $display['settings'],
'#delta' => $delta,
);
}
}
// $element = '<div id="CUSTOMDIVSTUFF">' . $element . '</div>';
return $element;
}
And here is the #theme function:
function theme_bootstrap_modal_image_formatter($variables) {
$item = $variables['item'];
$entity_type = $variables['entity_type'];
$entity = $variables['entity'];
$field = $variables['field'];
$settings = $variables['display_settings'];
$image = array(
'path' => $item['uri'],
'alt' => isset($item['alt']) ? $item['alt'] : '',
'title' => isset($item['title']) ? $item['title'] : '',
'style_name' => $settings['bootstrap_modal_node_style'],
);
if (isset($item['width']) && isset($item['height'])) {
$image['width'] = $item['width'];
$image['height'] = $item['height'];
}
if (isset($item['attributes'])) {
$image['attributes'] = $item['attributes'];
}
// Allow image attributes to be overridden.
if (isset($variables['item']['override']['attributes'])) {
foreach (array('width', 'height', 'alt', 'title') as $key) {
if (isset($variables['item']['override']['attributes'][$key])) {
$image[$key] = $variables['item']['override']['attributes'][$key];
unset($variables['item']['override']['attributes'][$key]);
}
}
if (isset($image['attributes'])) {
$image['attributes'] = $variables['item']['override']['attributes'] + $image['attributes'];
}
else {
$image['attributes'] = $variables['item']['override']['attributes'];
}
}
$entity_title = entity_label($entity_type, $entity);
if ($style_name = $settings['bootstrap_modal_image_style']) {
$path = image_style_url($style_name, $image['path']);
}
else {
$path = file_create_url($image['path']);
}
$caption = 'some value';
$gallery_id = 'some value';
return theme('bootstrap_modal_imagefield', array('image' => $image, 'path' => $path, 'title' => $caption, 'gid' => $gallery_id));
}
Been working on this for days, I'm drowning here.
This is possible via HOOK_process_field(). Use this hook to define a new template file for your field by adding it to theme_hook_suggestions array (place the template file in your module directory, because you wanted to change the theme -as you mentioned-). More info about field template suggestions.
Then, you will need to add the module path to drupal theme registry, so it picks up the template file. Demo.
I found out it was:
function bootstrap_modal_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array(
'#prefix' => '<div class="wrapper">',
'#suffix' => '</div>',
);

Drupal 7: custom module: display custom contentTypy in custom block

I'm new at Drupal 7, so I have a question.
I have my own content type Writers that includes such fields as Title, Years of life, Photo, Description.
I have a task to display 3 random Writers at page. Actual I've done it with help of Views module, but I want to do it myself.
So I created my own module random_content like that:
<?php
function random_content_help($path, $arg) {
switch ($path) {
case "admin/help#random_content":
return '<p>'. t("Displays random content") .'</p>';
break;
}
}
function random_content_block_info() {
$blocks['random_content'] = array(
'info' => t('Random content'),
'cache' => DRUPAL_CACHE_PER_ROLE,
);
return $blocks;
}
function random_content_contents() {
$query = db_select('node', 'n')
->fields('n', array('nid', 'title'))
->condition('type', 'writers')
->orderBy('rand()')
->range(0,3)
->execute();
return $query;
}
function random_content_block_view($delta = '') {
switch($delta){
case 'random_content':
$block['subject'] = t('Random content');
if(user_access('access content')) {
$result = random_content_contents();
$items = array();
foreach ($result as $node){
$items[] = array(
'data' => l($node->title, 'node/' . $node->nid) . '</br>',
);
}
if (empty($items)) {
$block['content'] = t('No data availible.');
} else {
$block['content'] = theme('item_list', array(
'items' => $items));
}
}
}
return $block;
}
As you can see, I've learned only to add links to particular content. But how can I display full information including Title, Years of life, Photo and Description?
To display the full node, or parts of it you need to load the node. E.g.
$my_node = node_load($nid);
$render_array = array();
$render_array['title'] = array(
'#type' => 'markup',
'#markup' => $my_node->title
);
$author = field_get_items('node', $my_node, 'field_author','und');
$render_array['author'] = array(
'#type' => 'markup',
'#markup' => $author[0]['safe_value']
);
// or as some like to do it
$render_array['author'] = array(
'#type' => 'markup',
'#markup' => $my_node->field_author['und'][0]['value']
);
echo drupal_render($render_array);
Note the 'und' constant means the language is undefined. If you have translation/language enabled and different content for different languages you would have to use 'en', 'de' etc. for the appropriate language.
You can also let drupal render the node and then manipulate or retrieve individual items. Like this
$my_node = node_load($nid);
$build = node_view($my_node,'full');
$build['body'][0]['#markup'] = $build['body'][0]['#markup'].' some addition';
$build['field_author'][0]['#markup'] = $build['field_author'][0]['#markup'].' my favorite';
echo drupal_render($build);
The advantage of using this latter method is that then the whole themeing engine kicks in, and all hooks that are set to act on the content etc. Of course, if you only want to retrieve values you don't need that.
Note also, I assume your author field is named field_author. You should check that in the field edit window for the content type.

drupal ajax form change

I'm working on a drupal 7 module, where I wish to print out infos on a page (MENU_LOCAL_TASK node/%node/something), with ajax filters.
I created a form and added 2 checkboxes, 1 is on default other is not. I want to show to the user the information according to wich checkbox is checked. 1 is on table row 1 is displayed, 2 is on table row 2 is displayed. If some of it is off, than that table row is off. Did I mentioned, that I want to solve it without submit and reload, only ajax.
I added to the two 'checkbox'es the following 'ajax' => array('callback' => 'my_module_callback')
. Here is the rest of the code, simplefied.
function my_module_callback($form, $form_state) {
$data = array();
$nid = 1;
if ($form_state['values']['checkbox1']) {
$data += load_data($nid, "checkbox1");
}
if ($form_state['values']['checkbox1']) {
$data += load_data($nid, "checkbox2");
}
$commands[] = ajax_command_html("#here", my_module_table($data));
return array('#type' => 'ajax', '#commands' => $commands);
}
function my_module_table($data){
//do some stuff with the data in a foreach
return theme("my_module_fancy_table",array("data" => $data));
}
function theme_my_module_fancy_table($data){ //registered with my_module_theme()
// putting html into $output in a foreach
return $output;
}
function my_module_page_callback_from_menu_function($nid){
$output = drupal_render(drupal_get_form('my_module_custom_ajax_form'));
$output .= "adding other stuffs including div#here";
return $output;
}
First of all is this the 'good way' to do this, cause I kind of lost confident:)
Second question, how to show the data on page load, rigth now one checkbox needs to be changed to see some infos.
Thanks and sorry for the short description :)
You should not really be doing the processing in the callback, it should be done in the form building function. The callback usually only returns the part of the form that has changed. Also, I don't think there is not need for setting commands[] in this case as returning part of the form will automatically replace the content set by 'wrapper'.
function my_module_form($form, $form_state){
$data = array();
$nid = 1;
if ($form_state['values']['checkbox1']) {
$data += load_data($nid, "checkbox1");
}
if ($form_state['values']['checkbox2']) {
$data += load_data($nid, "checkbox2");
}
$form = array();
$form['checkbox1'] = array(
'#type' => 'checkbox',
'#ajax' => array(
'callback' => 'my_module_callback'
'wrapper' => 'mydata',
'event' => 'change',
),
);
$form['checkbox2'] = array(
'#type' => 'checkbox',
'#ajax' => array(
'callback' => 'my_module_callback'
'wrapper' => 'mydata',
'event' => 'change',
),
);
$form['mydata'] = array(
'#prefix' => '<div id="mydata">',
'#suffix' => '</div>',
'#markup' => my_module_table($data),
);
return $form;
}
function my_module_callback($form, $form_state){
// $form_state['rebuild'] = true; may have to be set because the form has not been submitted and wont be rebuilt...I think, I cant remember for sure.
return $form['mydata'];
}
To show the data on page load, you just have to change the logic of setting data in the form build function.
Also, fyi, there is a stack site specifically for drupal at: http://drupal.stackexchange.com

how can i extract node title and node content for ajax manipulation before node submit?

I need to perform some operations by ajax before a node is submitted. So, how can I capture the node content and title which has been filled in by the user and pass it onto my ajax callback ?
Ok so here is the code-
So for this you need to specify "hello" as your callback function for the element for which the ajax attribute is being set.
For example if you want to call this by a button press-
$form['test'] = array(
'#type' => 'button',
'#value' => t("Testing"),
'#ajax' => array(
'callback' => 'hello_ajax',
'wrapper' => 'newtable_div',
'effect' => 'slide',
),
);
then your callback function should be-
function hello_ajax($form, $form_state) {
$output = '';
$values = $form_state['values'];
$title = $values['title'];
$body = '';
foreach ($values['body'][$values['language']] as $info) {
$body .= $info['value'];
}
$content = check_plain($title) . ' ' . $body;
}
$content variable now holds the node title as well as node content, which you can use for further manipulations. cheers !! :)

Drupal hook_form_alter anonymous user can't see the fields

I created a small module for altering forms called "form_mods". The form I'm altering is the "user_profile_form". I added a category for extra fields called "Profile".
I created a select field in the Drupal admin called "profile_state" and I'm altering it in my module to have a key => value list of states and It's working for me when logged in as an admin but an anonymous user that's trying to register sees an empty states select field. Is there a permissions issue here? I tried to add 'access' => user_access('access content') to the field but that didn't work. Here is my code:
function form_mods_form_alter($form, $form_state, $form_id) {
switch ($form_id) {
## user_profile_form ###################################################################################
case 'user_profile_form': // This is our form ID.
//echo '###'.$form['_category']['#value'].'###';
if($form['_category']['#value'] == 'Profile'){
// Modify the states dropdown list
$states = load_states_list();
$form['Profile']['profile_state'] = array(
'#type' => 'select',
'#title' => t('State'),
'#options' => $states,
'#required' => TRUE,
'#default_value' => isset($form['Profile']['profile_state']['#default_value']) ? $form['Profile']['profile_state']['#default_value'] : '',
'#element_validate' => array('profile_state_validate')
);
}
####################################################################################
break;
}
}
function load_states_list() {
$states = array('' => '-- Select a state'); // add a default empty value
$results = db_query("SELECT * FROM {states_list} ORDER BY name ASC");
while ($state = db_fetch_array($results)) {
$states[$state['code']] = $state['name'];
}
return $states;
}
Thanks
First of all, are you sure you're function ever gets run? Having the function named the way you do, I don't think it is. If the module name is "form_mods", your function should be called
function form_mods_form_alter
Or...since you're only modifying the user_profile_form form, you could use the function name
function form_mods_user_profile_form_alter
Now, the reason it isn't working is because you don't have the & in front of the $form in the parameter list. The & basically passes the variable as reference, and so any changes you make to the $form variable will be saved and passed back to the calling function. So, your function should look like
function form_mods_form_alter(&$form, &$form_state, $form_id) {
OR
function form_mods_user_profile_form_alter(&$form, &$form_state) {
Reference: http://api.drupal.org/api/drupal/developer--hooks--core.php/function/hook_form_alter/6
Thank you mikesir87 for the reference link. I figured out my problem.
There are 2 different forms that are using those fields I created. They have different form id's. I have to look for "user_profile_form" and "user_register" form id's.
Here is my new code that works:
function form_mods_form_alter($form, $form_state, $form_id) {
if( (($form_id == 'user_profile_form') && ($form['_category']['#value'] == 'Profile')) || ($form_id == 'user_register') ){
// Modify the states dropdown list
$states = form_mods_load_states_list();
$form['Profile']['profile_state'] = array(
'#type' => 'select',
'#title' => t('State'),
'#options' => $states,
'#required' => TRUE,
'#default_value' => isset($form['Profile']['profile_state']['#default_value']) ? $form['Profile']['profile_state']['#default_value'] : ''
);
}
}
thanks

Resources