Drupal submitting a query that change a tableselect - php

I'm new on drupal, i've create a module that shows a form with select, button submit and i've got a tableselect that lists some records (from database). the tableselect works and it's listing all records, but i want to "filter" records on this tableselect by selecting what i want to see with select list (and submitting). when i choose something in the select list and i submit, the tableselect dont change but if i execute a dsm($form['tableselect']) it said that tableselect contains what the db_query returns.
here is my form :
function myBook_form ($form, &$form_state){
$form = array();
$form['options_state'] = array(
'#type' => 'value',
'#value' => array (
'all'=>t('All'),
'Valid'=>t('Valid'),
'published'=>t('published'),
'not published'=>t('not published')
)
);
$form['state_book'] = array(
'#type' => 'select',
'#title' => t('state :'),
'#options' => $form['options_state']['#value'],
);
// filter submit button
$form['filter'] = array(
'#type' => 'submit',
'#value' => t('filter')
);
}
$header = array(
'book_title' => t('title'),
'book_state' => t('state'),
);
$sql = db_select('field_data_field_title','ta');
$sql->join('field_data_field_state','st','st.entity_id = ta.entity_id');
$sql
->fields('ta', array('field_title_value','entity_id'))
->fields('st',array('field_state_value'));
$result = $sql->execute();
$rows = array();
foreach ($result as $res){
$rows [] = array(
'book_title' => l($res->field_title_value, 'node/'.$res->entity_id),
'book_state' => $res->field_state_value
);
}
$form['table1'] = array(
'#type' => 'tableselect',
'#header' => $header,
'#options' => $rows,
'#empty' => t('empty !'),
);
return $form;
here is my submit function :
function book_form_submit($form, &$form_state){
$cond = $form_state['values']['state_book'];
$header = array(
'book_title' => t('title'),
'book_state' => t('state'),
);
$sql = db_select('field_data_field_title','ta');
$sql->join('field_data_field_state','st','st.entity_id = ta.entity_id');
$sql
->fields('ta', array('field_title_value'))
->fields('st',array('field_state_value'));
$sql->condition('st.field_state_value', $cond, '=');
$quer = $sql->execute();
$rows = array();
foreach ($quer as $q){
array_push($rows, array(
'book_title' => $q->field_title_value,
'book_state' => $q->field_state_value,
));
}
$form['table2'] = array(
'#type' => 'tableselect',
'#header' => $header,
'#options' => $rows,
'#empty' => t('empty!')
);
}
Thanks

Related

Draggable table: drupal_render, render, both yield an empty string for "#weight" types

I am attempting to implement a draggable table in a Drupal 7 module. Whenever I invoke either render() or drupal_render on my element of type #weight, an empty string is returned. The table does render and I am able to drag the rows, but cannot see the weights. I cannot figure out what I am doing wrong: I've explored some core Drupal components that follow the same pattern (of invoking drupal_render on a #weight type element) and nothing is jumping out at me.
My form begins here:
$table_header = array_map(t, array('Order', 'Item', 'Manage'));
$form['table'] = array(
'#theme' => 'mymodule_kw_table',
'#header' => $table_header,
'#rows' => $my_rows // array(string)
);
hook_theme() is implemented as such:
function mymodule_theme()
{
return array(
'mymodule_kw_table' => array(
'render element' => 'form',
'function' => 'mymodule_table'
)
);
}
Finally, mymodule_table() looks like this:
function mymodule_table($variables)
{
$table_data = $variables['form'];
$table_id = uniqid('tb');
$rows = $table_data['#rows'];
for ($i=0; $i < count($rows); ++$i) {
$weight = array(
'#type' => 'weight',
'#title' => t('Order'),
'#default_value' => $i,
'#delta' => 1,
'#attributes' => array('class' => array($table_id . '-weight'))
);
$rows[$i] = array(
'data' => array_map(render, array($weight, $rows[$i], 'abcd placeholder')),
'class' => array('draggable')
);
}
$table = theme('table', array(
'header' => array_map(t, array('Order', 'Item', 'Manage')),
'rows' => $rows,
'attributes' => array('id' => $table_id)
));
$table .= drupal_render_children($table_data);
drupal_add_tabledrag($table_id, 'order', 'sibling', $table_id . '-weight');
return $table;
}

drupal 7 warning: Illegal offset type in isset or empty in element_info()

I have written the code with an idea of the core module named user, the role function.
my "user_admin_types" is like "user_admin_roles". If you take a brief look at "user.admin.inc" file you will understand that i have replaced my functions and variables on the basis of these:
"user_roles" = "user_types"
"role" = "type"
"rid" = "ut_id"
"name" = "ut_label"
Everything is that I've done is same as the Core has done but i have this warning in my page: Warning: Illegal offset type in isset or empty in element_info.
I have checked every line but i couldn't find the reason and the way i can disappear it.
`function user_admin_types($form, $form_state) {
$types = user_types();
$form['types'] = array(
'#tree' => TRUE,
);
$order = 0;
foreach ($types as $ut_id => $ut_label) {
$form['types'][$ut_id]['#type'] = (object) array(
'ut_id' => $ut_id,
'ut_label' => $ut_label,
'ut_weight' => $order,
);
$form['types'][$ut_id]['#weight'] = $order;
$form['types'][$ut_id]['weight'] = array(
'#type' => 'textfield',
'#title' => t('Weight for #title', array('#title' => $ut_label)),
'#title_display' => 'invisible',
'#size' => 4,
'#default_value' => $order,
'#attributes' => array('class' => array('type-weight')),
);
$order++;
}
$form['ut_label'] = array(
'#type' => 'textfield',
'#title' => t('User Type'),
'#title_display' => 'invisible',
'#size' => 32,
'#maxlength' => 64,
);
$form['add'] = array(
'#type' => 'submit',
'#value' => t('Add type'),
'#validate' => array('user_admin_type_validate'),
'#submit' => array('user_admin_type_submit'),
);
$form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => t('Save order'),
'#submit' => array('user_admin_types_order_submit'),
);
return $form;
}
/**
* Form submit function. Update the type weights.
*/
function user_admin_types_order_submit($form, &$form_state) {
foreach ($form_state['values']['types'] as $ut_id => $type_values) {
$type = $form['types'][$ut_id]['#type'];
$type->ut_weight = $type_values['weight'];
user_type_save($type);
}
drupal_set_message(t('The type order have been updated.'));
}
function user_types() {
$query = db_select('users_types', 'ut');
$query->addTag('translatable');
$query->fields('ut', array('ut_id', 'ut_label'));
$query->orderBy('ut_weight');
$query->orderBy('ut_label');
$result = $query->execute();
$types = array();
foreach ($result as $key => $type) {
switch ($type->ut_id) {
// We only translate the built in type names
case WEBNOVIN_CUSTOMER_UT_ID:
$types[$type->ut_id] = t($type->ut_label);
break;
case WEBNOVIN_PREFERRED_CUSTOMER_UT_ID:
$types[$type->ut_id] = t($type->ut_label);
break;
case WEBNOVIN_SALES_AGENT_UT_ID:
$types[$type->ut_id] = t($type->ut_label);
break;
default:
$types[$type->ut_id] = $type->ut_label;
}
}
return $types;
}`

Creating custom input form for a node using Ajax

Attached is an example screenshot of the form I'm using PHP and AJAX in Drupal 7.
By default, the form will display 10 fields. The form uses AJAX to enable users to add a potentially infinite number of input fields to the initial 10 in groups of 5. What I need it to do is upon retrieval, repopulate the fields as it was saved, with the same functionality available, should the user wish to edit.
I have on a previous attempt used $form_state in entries_form_add_five to add to the number of input boxes and returned using the ajax call but I couldn't get this to work when loading the data to edit. How can I rebuild the form with a new $node-->entries_form['term'] array which has been increased by 5?
<?php
function entries_form_form_entries_node_form_alter(&$form, &$form_state, $form_id) {
//trimmed
$node = $form['#node'];
$form["section"]["term"]["#tree"] = TRUE;
$items = $node->entries_form['term'];
foreach($items as $key => $item) {
$form["section"]["term"][$key] = array(
'#type' => 'textfield',
'#size' => 10,
'#attributes' => array(
'class' => array('left'),
),
'#value' => $item,
);
}
//trimmed
}
function entries_form_commands_add_callback($form, $form_state) {
return $form['section']['term'];
}
function entries_form_add_five($node, $form, &$form_state){
$node->entries_form['term'] = array_push($node->entries_form['term'],'', '', '', '', '');
$form_state['rebuild'] = TRUE;
}
function entries_form_node_prepare($node) {
if (empty($node->entries_form)) {
// Set default 10 empty values, since this only runs when adding a new node.
$node->entries_form['term'] = array_fill(0, 10, '');
}
}
function entries_form_node_load($nodes, $types) {
if($types[0] == 'entries'){
$result = db_query('SELECT * FROM {entries_form_node_form_alter} WHERE nid IN(:nids)', array(':nids' => array_keys($nodes)))->fetchAllAssoc('nid');
foreach ($nodes as &$node) {
$node->entries_form['term'] = json_decode($result[$node->nid]->term);
}
}
}
Any help very much appreciated.
Thanks!
I agree that there are no good examples of loading previously saved data into an unlimited values field. (I think this should have been in the examples module.
I wrote the code below to just manage a list of people. This list is stored in Drupal variable table, not as nodes, however the methodology should be similar, so hope should guide you in the right direction.
function people_list_form($form, &$form_state) {
$form['#tree'] = TRUE;
// load the list of names - here you could use node load instead
$names = variable_get('people_list', array());
if (empty($form_state['num_names'])) {
// store the number of names we have in $form_state
$form_state['num_names'] = count($names)>0 ? count($names) : 1;
}
$form['names_fieldset'] = array(
'#title' => 'List of People',
'#type' => 'fieldset',
'#prefix' => '<div id="names-fieldset-wrapper">',
'#suffix' => '</div>',
);
// loop for each name to add form elements
for ($i = 1; $i <= $form_state['num_names']; $i++) {
$form['names_fieldset']['name'][$i]['name'] = array(
'#type' => 'textfield',
'#title' => 'Name #'.$i,
'#default_value' => isset($names[$i-1]) ? $names[$i-1] : '',
);
}
$form['names_fieldset']['add_name'] = array(
'#type' => 'submit',
'#value' => t('Add another name'),
'#submit' => array('people_list_form_add_name'),
'#ajax' => array(
'callback' => 'people_list_add_more_callback',
'wrapper' => 'names-fieldset-wrapper',
),
);
if ($form_state['num_names'] > 1) {
$form['names_fieldset']['remove_name'] = array(
'#type' => 'submit',
'#value' => t('Remove last name'),
'#submit' => array('people_list_form_remove_name'),
'#limit_validation_errors' => array(),
'#ajax' => array(
'callback' => 'people_list_add_more_callback',
'wrapper' => 'names-fieldset-wrapper',
),
);
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Submit',
);
return $form;
}
function people_list_add_more_callback($form, $form_state) {
return $form['names_fieldset'];
}
function people_list_form_add_name($form, &$form_state) {
$form_state['num_names']++;
$form_state['rebuild'] = TRUE;
}
function people_list_form_remove_name($form, &$form_state) {
if ($form_state['num_names'] > 1) {
$form_state['num_names']--;
}
$form_state['rebuild'] = TRUE;
}
function people_list_form_submit($form, &$form_state) {
$names = array();
foreach($form_state['values']['names_fieldset']['name'] as $k => $v) {
$names[] = $v['name'];
}
variable_set('people_list', $names);
drupal_set_message('Names updated');
}

#autocomplete_path not working in Drupal 6

I am trying to create a form with a auto-complete textfield for a particular role type usersname. But it's not working. Though when I use "user/autocomplete" which is default path given in example over drupal.org it works...
This is for hook_menu ---
function scout_bucks_menu(){
$items = array();
$items['scouts/autocomplete'] = array(
'page callback' => 'scout_bucks_autocomplete',
'type' => MENU_CALLBACK,
'access arguments' => array('administer scout bucks'),
);
return $items;
}
This id for form --
function scoutbucks_add_bucks_form(&$form_state){
$form = array();
$form['scout_name'] = array(
'#type' => 'textfield',
'#title' => t('Scout Name'),
'#maxlength' => 60,
'#autocomplete_path' => 'scouts/autocomplete',
'#reguired' => TRUE,
);
$form['submit'] = array(
'#type' => 'submit',
'#title' => t('ADD BUCKS TO SCOUT PROFILE'),
'#prefix' => '<div class="submit-button-bucks">',
'#suffix' => '</div>',
);
return $form;
}
This is the function for auto-complete ---
function scout_bucks_autocomplete($string = '') {
$matches = array();
$userobj = db_fetch_object(db_query("SELECT users.name, users.uid FROM {users}, {users_roles} WHERE users.uid = users_roles.uid AND users_roles.rid = 7"));
while ($row = db_fetch_array($userobj)) {
$matches[$row['users.uid']] = $row['users.name'];
}
drupal_json($matches);
}
What can be the reason ?
You need to change drupal_json to drupal_to_js.
function scout_bucks_autocomplete($string = '') {
$matches = array();
$userobj = db_fetch_object(db_query("SELECT users.name, users.uid FROM {users}, {users_roles} WHERE users.uid = users_roles.uid AND users_roles.rid = 7"));
while ($row = db_fetch_array($userobj)) {
$matches[$row['users.uid']] = $row['users.name'];
}
drupal_to_js($matches); // the edited line.
}
Hope this works...
Sample from working autocomplete on one of my sites:
function module_menu() {
$items['app/autocomplete/%'] = array(
'title' => 'Some title',
'description' => '',
'page callback' => '_module_autocomplete',
'page arguments' => array(2),
'type' => MENU_CALLBACK,
);
}
function _module_autocomplete($param) {
$result = db_query('SELECT id,stuff FROM {table} WHERE a=%d', $param);
while ($row = db_fetch_object($result)) {
$ret[$row->id] = $row->stuff;
}
drupal_json($ret);
}
I've cut down as much as I feel safe to, but I do think it is bestif you define that % in the menu callback.

php mongodb '$or' regex search

i'm trying to query mongodb "videos" collection to find results by "title" or "tags" fields... it keeps returning 0 results even when i search for terms i know are in the title and/or tags... any help would be appreciated
<?php
$user_query = preg_replace("/[[:blank:]]+/"," ", $_GET['q']);
$arr_query = explode(' ', $user_query);
foreach ($arr_query as $q) {
$title[] = '/'. $q .'/i';
$tags[] = '/'. $q .'/i';
}
$who=array(
'$or' => array(
array('$in' => array('$regex' => $title)),
array('$in' => array('$regex' => $tags))
)
);
$vids=$videos->find($who);
?>
You need to specify some fields for your $in:
$who=array('$or' => array(
array('somefield' => array('$in' => array(new MongoRegex($title)))),
array('otherotherfield' => array('$in' => array(new MongoRegex($tags))))
));
So it works by saying saying: if some field is in a range of some values
http://docs.mongodb.org/manual/reference/operator/in/
Edit
That might still not work because of the embedded $regex. If this is the case then you can try:
$who=array('$or' => array(
array('somefield' => new MongoRegex($title)),
array('otherotherfield' => new MongoRegex($tags))
));
Edit
If either of those queries don't work you can do:
$who = array('$or' => array());
foreach($arr_query as $q){
$who['$or'][] = array('title' => new MongoRegex("/^$q/"));
$who['$or'][] = array('tags' => new MongoRegex("/^$q/"));
}
Something like that should work, again it is untested but if my memory serves me right that should do it.
Another edit
This works perfectly for me:
$mongo = new Mongo();
$db = $mongo->tstvid;
$videos = $db->videos;
$videos->insert(array('title' => 'test1', 'tags' => array('h','h')));
$videos->insert(array('title' => 'test2', 'tags' => array('h','h')));
$videos->insert(array('title' => 'test3', 'tags' => array('h','h')));
$videos->insert(array('title' => 'tst3', 'tags' => array('h','test')));
$user_query = preg_replace("/[[:blank:]]+/"," ", "test");
$arr_query = explode(' ', $user_query);
if (count($arr_query) > 1) {
$who = array(
'$or' => array()
);
foreach ($arr_query as $q) {
$who['$or'][] = array('title' => new MongoRegex("/^". $q ."/i"));
$who['$or'][] = array('title' => new MongoRegex("/^". $q ."/i"));
}
} else {
$regex=new MongoRegex("/^". $user_query ."/i");
$tregex=new MongoRegex("/^". $user_query ."/i");
$who=array(
'$or' => array(
array('title' => $regex),
array('tags' => $tregex)
)
);
}
$vids=$videos->find($who);
$results="";
$i=0;
foreach($vids as $vid){
$results .= "<li>".$vid['title']."</li>\n";
$i++;
}
if($i==0){
$results="<em>No results found</em>";
}
echo $results;
And it outputs:
test1
test2
test3
tst3
So I am unsure what is wrong but I would recommend double checking your script is breaking up the keywords right and the schema is being searched right by issuing these queries in the console as well.
It should be noted I also tried this with:
$user_query = preg_replace("/[[:blank:]]+/"," ", "test h");
And it worked as well.
$search_string = preg_replace("/[^A-Za-z0-9]/", " ", $_GET['q']);
$search_string = $search_string;
//Connecting mongoDB
$dbhost = 'localhost';
$dbname = 'yourdbname';
$port = '27017';
$m = new MongoClient();
$db = $m->$dbname;
if($m){
// select a collection
$videos = $db->videos;
// search for title and tags
$searchQuery = array(
'$or' => array(
array(
'title' => array(
'$regex' => $search_string,
),
),
array(
'tags' => array(
'$regex' => $search_string,
),
),
)
);
$cursor = $videos->find($searchQuery);
foreach ($cursor as $doc) {
var_dump($doc);
//or what ever you want
//var_dump($doc['title']);
}
else{
echo "Collection videos cant select :( <br>";die();
}
Thinks this will help. :D

Categories