hi,
i need to dynamically generate form that i put inside a table with some other data. so my question is how can i use form_render correctly?
i've tried to follow this example http://drupal.org/node/93218 but i get some wired warnings like this warning: implode(): Bad arguments. in /includes/form.inc on line 309. so i started digging and i've found this: http://drupal.org/node/78467 - well, great - i should not use form_render... there was something mentioned about #parents... ok i did some more digging and found this http://drupal.org/node/48643 - well, not much of a help - i have no clue how this #parents should be used, and the forms api does not say much about it, frankly it says nothing.
finally i've found this: http://drupal.org/node/47582 and thought that my problems will end... but NO! it all comes to the fact that my form is mixed with some other data inside a table. so theming my form won't do anything, cause to print the table i need that additional data. so again i ended up with nothing :(
basically i've started to experiment with #parents so i can kinda manually render my form inside a table using form_render. as soon as i got rid of the mentioned above warning, i've found out that:
- yes my form is rendered inside a table as i wish BUT...
- despite specifying the '#default_value' property value of my textfield remains empty
- name and id field of my [input ... ] tags are empty so i can't reference them after they are submitted
- all my [input ...] tags rendered using form_render are placed outside the [form] tags that are generated later by the drupal_get_form function. this is rather obvious because first i output the result of form_render($my_form_element) and then i call the drupal_get_form.
any ideas how to solve this? what is the 'right' approach when i need to mix dynamic data and forms? here is part of my code that i'm trying to use:
$requests = GetRequestsFromSomewhereInDB();
foreach($requests as $row) {
$form[$row->rid.'+count'] = array(
'#parents' => array('PMRequests'),
'#type' => 'textfield',
'#default_value' => 0,
'#maxlength' => 2,
'#size' => 2
);
$rows[] = array(
$row->date,
$row->client_comment,
$row->price,
form_render($form[$row->rid.'+count']),
);
}
$content .= drupal_get_form('PMRequests',$form);
$content .= theme('table', $header, $rows);
Comments
Hmm.. it's been a while
Hmm.. it's been a while since I've been in Drupal 4.7, but the issue here is you'd be better off using a theme function. So, you'd want to just construct the form by itself in that function. Call drupal_get_form('PMRequests', $form); and let that get themed by a separate function defined like so:
The tips for using #tree is so that you can use foreach(element_children($form['...'])) later on. I don't have the time to go into it now, but maybe someone else can carry on here... basically, in the theme function you'll run that foreach loop and have it build your rows there. Then that function would return the output of theme_table($header, $rows)...
Hope that helps. If no one responds by tonight, I'll try to finish this explanation.
Look at the QuickStart Guide for forms by going to http://api.drupal.org and clicking the 4.7 link. It's there. Or, search the docs there for info on tree/parents, and element_children in the 4.7 API.
----------------------
Current Drupal project: http://www.ubercart.org
I guess let me know if this
I guess let me know if this was helpful or not and what needs to be clarified, and I'm happy to answer.
no luck
i'm afraid that this is not the way for me. i've also tried this approach, but there is a problem, that my table also needs additional dynamic data that is generated alongside with form. so passing the form itself to drupal_get_form to let the theme generate the table is not enough, because the theme does not have the necessary data to fill in the table. i've tried 'smuggling' this data inside my $form array hoping to have it available when it arrives to the function in theme that is supposed to generate the table. but i had no luck. maybe i did something wrong? if you can, please post some code that could be a hint for me.
my scenario looks like this:
i need to generate something that may be called a table of user orders for some items - one item per row (these are not exactly orders but it does not matter right now). now the trick is that each row needs to have a textbox that allows user to input the quantity for each item. all the data is pulled from database and it needs to be done only once. that means - i can not pull some data while creating a form and then the rest of the data when the form is themed. i need to pull that data in one call to db. so all i struggle with is how to theme that form when i haven't got all the necessary data during theming. after some misfired attempts i decided i'll try to render the form myself into a table but as you cold see i've run into some problems too.
Just to see if this is what
Just to see if this is what you're talking about, I'd like you to follow the Ubercart link in my sig and go to the livetest site. Add some stuff to your cart and go look at the cart screen... For the shopping cart, it seems like I've done exactly what you described, and I've had no problems using Drupal's Forms API to do it, gathering the data in the form builder function and theming it in the theme function into a table. If that's what you're looking to do, I'm happy to post the code or at least pseudo-code to make that happen.
----------------------
Current Drupal project: http://www.ubercart.org
ubercart
that's exactly what i need. in fact i've just managed to do it this way:
as you can see i've injected some data to may form array. earlier when i've been trying to do it this way i could not make it work. probably because my injected data was named like this: "_date", "_price" and so on. i couldn't make it work. it looks like the only thing i had to do was to add '#' char to my names ("#_date", "#_price") and now it works. i have no idea why this makes a difference, but hey it works :)
let me know if there is a better way to do it.
Example code...
Ok, looking at your code, I can understand a little of your frustration. You're trying to pass in just normal text to display in the form by hijacking the textfield for the quantity entry. Instead, you can define those as markup elements in the form. This is achieved by making other members of the array w/o setting a type (or optionally setting '#type' => 'markup') and setting the value to be what you want displayed. Here's a pseudo-code example, untested, using your code:
The only reason this might not work is if I've included 5.0 specific code, but I don't think I have. Hope that does it for you! Let me know how it goes... (Notice the use of #tree and element_children(). This eliminates the need for your substr check.)
----------------------
Current Drupal project: http://www.ubercart.org
damn docs!
oh man, this can be so simple?! i've tested this and i works great. thank you!
if i could have found this in docs... @$#* i've lost 2 damn days fighting this and the solution turned out to be so simple :(
i don't know... am i so blind or these drupal docs really suck :/ ??
Addenum
See http://api.drupal.org/api/HEAD/file/developer/topics/forms_api_reference...
Note that markup elements are not escaped or filtered in any way: you need to call check_plain / theme('placeholder') or the relevant filter (via check_markup or even filter_xss) on user supplied data yourself.
(edit: spelling)
--
The Manual | Troubleshooting FAQ | Tips for posting | How to report a security issue.
Thanks for the heads up,
Thanks for the heads up, Heine! I'm using this in a module and hadn't yet added in the filter. :)
frankly i've seen that. i've
frankly i've seen that. i've run through that page several times but didn't figured out that it is possible to use form api this way to pass only text (or markup) as a pseudo form element. i thought that i can only create form elements that are real form elements ie textarea, checkbox and so on. i just needed a clear example, message or just a note, that form api can be used this way.
oh well, maybe i'm just blind or something... or maybe i got used to msdn docs that are just incredible :/
Tips
Feel free to add to http://drupal.org/node/36900, until we can give the section an overhaul.
--
The Manual | Troubleshooting FAQ | Tips for posting | How to report a security issue.
Happy to help
Happy I could help. ; )
It's in the docs, but you really need to know the docs and understand how to put 2 and 2 together to make 5. hehe I learned by a combination of example, trial and error, and beating my head against the desk. It still confuses me sometimes!
That said, I am of the opinion that the docs need a good update, especially now with 5.0. Some stuff is just wrong, and like your case points out... there's nothing showing concept, just what exists in the code.
Good thing about these forums is this concept is now "documented" in our thread. ; )