How to click on a button in PHPUnit (Symfony2) - symfony

Hi, I'm writing a functional test and I want to know how to perform a simple click on a button, I have a hidden form that is shown after the button click
I tried doing a normal click like that :
$button = $crawler->filter('button:contains("Add")');
$crawler = $client->click($button);
but it seems the click() function take a Link Object not a Crawler Object.
how can I do something like that ?

I assume you use JS to show your hidden form.
This will not work since the crawler doesn't support JS, you better look up CasperJs or some other crawler if you want to test the click and visibility of your form.
Symfony2 Functional Testing - Click on elements with jQuery interaction
Otherwise if testing the submit of the form is what you want to achieve, then you can use :
$form = $crawler->filter('button#idofyourbutton')->form(array(
'firstname' => 'Blabla',
'lastname' => 'Blabla',
'address' => 'BlablaBlablaBlablaBlabla',
'zipcode' => '302404',
'phone' => '30030130269'
),'POST');
$client->submit($form);

From the docs it says to convert to a link object you would do the following
$button = $crawler
->filter('button:contains("Add")') // find all buttons with the text "Add"
->eq(0) // select the first button in the list
->link() // and click it
;
And then you can click it like before..
$crawler = $client->click($button);
I haven't used this though so I'm not sure if it would work with a button.

Related

Conditionally disable validation for embedded form

I have an embedded form (for Address) which has its own validations for various properties. I embed this form in a parent form (for Person), and I have a checkbox on the parent form that says something like "Person has an address?"
When the checkbox is left unchecked, I want to disable all the validation for the embedded Address form. Or, better yet, if I can just remove the embedded form from being submitted completely that would be OK too.
I looked at using validation groups, but the use case doesn't match my own.
OK, figured this out. When adding the AddressType embedded form in my form builder, I just pass in the option for validation groups like so:
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$form = $event->getForm();
$form->add('address', new AddressType(), array(
'label' => 'Address',
'validation_groups' => function (FormInterface $form) {
if ($form->getParent()->get('toggleAddress')->getData() === false) {
return array();
}
return array('Default');
}
));
});
Within the validation group function, a check is made to see if the toggle to enable Address is off. If so, return a blank array, with removes all validation groups, including the "Default" one.
You try to fix your issue with validation group which will not cover your use case (it can but it will be tricky because en empty Address object will be linked to your Person object).
Basically, you embed your Address form everytime whereas it should only be embed when the checkbox is checked. IMHO, you should rely on dynamic form as explained here.
With this solution, you will need extra JS code in order to update you form when you click the checkbox in order to update the whole form accordingly. Then, there will be no issue about validation because the Address object will only be created when the form is embed.
Additionally (just for information), you can add/edit validation groups according to the submitted data as explained here.
Hope my answer is helpfull!

Drupal Hook_Block_View perform action on button click

I am learning drupal and am trying to add some extra features to a module I've made following a tutorial
I have one block 'History' which shows the last x pages you've viewed.
Now I've made a second block with a button 'clear history', but I can't figure out how to make the set_value('trails_block_history','0') happen when my button is clicked (which would clear my history in the database)
anybody who can help me out here?
My blocks:
function trails_block_info() {
$blocks['history'] = array(
'info' => t('History'),
'cache' => DRUPAL_NO_CACHE,
);
$blocks['clearHist'] = array(
'info' => t('Clear history'),
'cache' => DRUPAL_NO_CACHE
);
return $blocks;
}
hook block save:
function trails_block_save($delta = '', $edit = array()) {
variable_set('trails_block_num', $edit['trails_block_num']);
variable_set('trails_block_granularity',$edit['trails_block_granularity']);
}
and the problem:
function trails_block_view($delta = '') {
...
case 'clearHist' :
{
$block['subject'] = 'Clear History';
$block['content'] = '<button>clear history</button>';
} break;
...
Still a student and reaaally new to this (started the module-coding this morning) so sorry if this seems like a stupid question (which it most probably is) but I just can't find it..
Have made another extra feature on the module allready, so I want this one to work as well!
You should use Forms API to create a form with submit button. Then clear your history when form is submitted. More info here and some example code here

Drupal: Dynamic View using Arguments

For a current project i need to setup a specific view to display a gallery detailpage. It should work like this:
1. User clicked a node (costum-post-type: gallery)
2. User received an overview page with linked images
3. User clicked an image
4. User received the gallery page (gallerific view)
Step 1-3 are done. But how can I get Drupal to build a detail page using the data of the overview page?
For Example something like this: http://example.com/gallery-1/detail or http://example.com/gallery-2/detail.
/gallery-n is the overview page with linked images and detail is the detailpage of /gallery-n.
Hope you'll understand what i mean?!
EDIT
On the overview page i have a bunch of thumbails which each are linked to the detail gallery (jquery galleriffic) page.
If I'm correct understand your problem you should do this things.
1. Create view1 for page with linked images. It should be page display with http://example.com/images/%nid
where %nid is nid argument of gallery.
2. Create view2 for gallery detailed page. it should be page display with http://example.com/%nid/detail
3. Theme that views as you want.
4. For view1 for image field use override output in field settings to make it links to %nid/detail
P.S. Use relationships where needed. If description is not clear, fill free to ask.
You can try something like this, in a custom module you make (or maybe already have):
where you set the path to the page you want in the menu and set it as a callback that calls a function and then you can render whatever you want, or call whatever you want.
function MODULENAME_menu() {
$items = array();
$items['gallery/%/detail'] = array(
'title' => 'Gallery Detail',
'page callback' => 'MODULENAME_gallery_detail_page',
'page arguments' => array(1),
'access callback' => TRUE,
'type' => MENU_CALLBACK
);
return $items;
}
function MODULENAME_gallery_detail_page($gallery_id) {
// Here you can render the view as a page, using the gallery
// id which you passed as a parameter to this function.
// So Change MYCUSTOMVIEW to the view you want to render
$view = views_get_view('MYCUSTOMVIEW');
print views_build_view('page', $view, array(), false, false);
}
Just change MODULENAME with the name of your module. You might need to do some work when calling the views_build_view, but it should be a start, you can ask some more questions if you like and I'll help out.

Drupal 6 passing variables from Forms to Content, how to?

I created a BLOCK (left) with this simple form.
Now I want to PROCESS and DISPLAY results on PAGE (center)
How can I do it ?
inputs:
name = James
surname = Bond
output I want :
<div style="color:red">Welcome, James Bond</div>
here is a BLOCK which i wrote and works.
<?php
echo drupal_get_form('myForm');
function myForm($form_state) {
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('Name'),
'#size' => 20,
'#maxlength' => 10
);
$form['surname'] = array(
'#type' => 'textfield',
'#title' => t('Surname'),
'#size' => 20,
'#maxlength' => 10
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save')
);
return $form;
}
function myForm_submit($form,&$form_state)
{
//??
};
Now I need to display the output :).
Please don't suggest to use VIEWS or any other addon.
I want to learn Drupal from Inside out. Not the other way around ;)
Well, it depends a bit on how you want to do things. Since you are learning how to make a drupal module, you might want to start with an implementation of hook_menu(). This hook is used to define menu items, which basically means that you can register urls with that function. Going that route you can:
Implement hook_menu()
A general way of handling redirects is using drupal_goto(). However, in this case it is much more fitting to use the $form_state['redirect'] as Henrik explained in his comment.
For the url you are redirecting to, you should have a call back function which is where you put your logic, the way you setup the hook_menu and the callback function will determine how you get your variables available. You probably want to look into the arg() function which is what generally is used to get the values from the url.
Run the user input through a filter to make sure that they haven't posted nasty stuff like script tags ect, use check_plain
return a theme function, alternatively make your own, look at theme() and hook_theme()
There are quicker ways to do this, but doing it this way, you will generate urls for every search result that drupal can cache, which is nice. Also not being dependent on the post parameters people can bookmark the search results
Another thing is that you might want to put some basic validation to your form. That would be a good practice to learn. That would look something like this:
/**
* Validation handler for myForm.
*/
function myForm_validate($form, &$form_state) {
$name = $form_state['values']['name'];
// do some checks to $name.
if ($error) {
form_set_error('name', t('error message to be displayed, showing the value of the field: #name', array('#name' => $name);
}
};
You could implement AHAH in your form, and specify an element inside your page's content area as the 'wrapper' (the element in which the results of the callback function will be placed). But, you would need to understand the excellent advice of Mr. Opel before you even attempt it.
How about using drupal_set_html_head() to write a string of script to the head section of the page? I am doing this on specific pages (getting user latitude and longitude and passing them into my gMap function), but I am interested in dong the same thing directly from hook_form_submit(). I have made a few tries at it, and I am obviously outputting the script string but calling the function from submit doesn't seem to work.
if the submit function creates a page full of html output; what is the best way to pass this to a page callback? i doubt that passing as an arg on the url would work.
i stuffed into a session var but maybe a better way?

Drupal Views2 Exposed Form how to change

I have a View with an exposed form . I am trying to a few things on it. Ideally I would like to have a dropdown that fires the form with no button. If that is not possible then I would like to have the button text something different than apply.
I hacked it for now and change views_form in views.module but that does not seem like the right way to do it. I only have one exposed form right now, but what if I add more?
Please see http://www.wiredvillage.ca/News for my example.
I am poking around drupal.org and seeing others with the same problem but no solutions so far. Not sure where the best place to get Drupal help is.
Here is the change I made so far:
function views_exposed_form(&$form_state) {
// Make sure that we validate because this form might be submitted
// multiple times per page.
$form_state['must_validate'] = TRUE;
$view = &$form_state['view'];
$display = &$form_state['display'];
$form_state['input'] = $view->get_exposed_input();
// Let form plugins know this is for exposed widgets.
$form_state['exposed'] = TRUE;
$form['#info'] = array();
if (!variable_get('clean_url', FALSE)) {
$form['q'] = array(
'#type' => 'hidden',
'#value' => $view->get_url(),
);
}
// Go through each filter and let it generate its info.
foreach ($view->filter as $id => $filter) {
$view->filter[$id]->exposed_form($form, $form_state);
if ($info = $view->filter[$id]->exposed_info()) {
$form['#info']['filter-' . $id] = $info;
}
}
// I CHANGED The VALUE OF THIS SUBMIT BUTTON TO GO
$form['submit'] = array(
'#name' => '', // prevent from showing up in $_GET.
'#type' => 'submit',
'#value' => t('go'),
);
$form['#action'] = url($view->get_url());
$form['#theme'] = views_theme_functions('views_exposed_form', $view, $display);
$form['#id'] = views_css_safe('views_exposed_form-' . check_plain($view->name) . '-' . check_plain($display->id));
// $form['#attributes']['class'] = array('views-exposed-form');
// If using AJAX, we need the form plugin.
if ($view->use_ajax) {
drupal_add_js('misc/jquery.form.js');
}
views_add_js('dependent');
return $form;
}
Or, you could use a preprocess function to alter the form even before it is build. I wanted to change the text on the button, so I did this:
function MYTHEME_preprocess_views_exposed_form(&$vars, $hook) {
// only alter the jobs search exposed filter form
if ($vars['form']['#id'] == 'views-exposed-form-jobs-search-page-1') {
// Change the text on the submit button
$vars['form']['submit']['#value'] = t('Search');
// Rebuild the rendered version (submit button, rest remains unchanged)
unset($vars['form']['submit']['#printed']);
$vars['button'] = drupal_render($vars['form']['submit']);
}
}
If you want the drop-down to fire, I'd use JavaScript instead of hacking the module as Eaton suggests.
Basically, you can modify the text with hook_form_alter as Eaton suggests, then use in the same hook_form_alter, add a call to drupal_add_js with your custom JS which hides the button and submits the form on the onChange handler of the select drop-down. You want that submit button there for those 10% of users for whom the JS fails.
Both of the above are fine but I found out that altering the form might not always lead to desirable results, mainly because exposed filters are themed using a specifc theme template. The proper way of changing the theme would be to override the views-exposed-form.tpl file in your theme's folder. Bear in mind that this will apply to all exposed filter forms, to theme a specific one, you will need to use a different name for that filename, like:
views-exposed-form--TITLE--DISPLAY.tpl.php
views-exposed-form--TITLE.tpl.php
and some others, you can check the Theme: Information section of your views for template naming conventions.
This module provides an auto-submit among other things http://drupal.org/project/views_hacks
This module is great to improving exposed filters http://drupal.org/project/better_exposed_filters
You should be able to use hook_form_alter() (http://api.drupal.org/api/function/hook_form_alter) to change the form as it's built, modifying the fields in question when that particular view is being displayed. You can nuke the submit button, add a #theme function that calls the drupal_add_js() function, and so on.
As long as the GET params come in the way views expect them, everything will work fine -- it was designed that way to allow bookmarking of pages with exposed filter settings, etc. The important part is to make sure you're doing the form mangling in your own module's hook_form_alter() function, so that it won't make other views driven stuff choke.

Resources