Zend Zend_Form Layouting - zend-form

i have an input-Element, that should be layouted through a css-class:
class="ok", default or when there is no error by validating this field
and
class="error", when there is an error by validating this field.
How can i achieve that?
Fesp

Easiest solution is to foreach through the form elements after you've called isValid and add the class name to each element based on its hasErrors status.
Another solution would be to add a Decorator to the form decorators, which will do the same.

Related

How to locate an element by both class name and accessibility ID?

I am automating a windows application through a desktop session using Appium and Windows Application Driver. Certain elements I want to interact with don't have unique accessibility IDs but the combination of their class names and IDs does seem to be unique.
How can I first get a list of elements by their class name and then fetch one of them with certain ID?
I am aware that the second line of code provided is not correct, I'm just showing it to demonstrate what behavior I need.
Below is through class name:
class_elements = driver.find_elements_by_class_name("some_class_name")
Below is through an accessibility id:
specific_element = class_elements.find_element_by_accessibility_id("some_id")
specific_element.click()
Is there a way to put both of these together in a loop?
Thank you #Moshe Slavin for your suggestion
I tried the following piece of code
#pytest.mark.trial
def test_trial():
className = "UIProperty"
class_elements = ds.find_elements_by_class_name("UIProperty")
for elm in class_elements:
print(elm.get_attribute('id'))
if elm.get_attribute('id') == "System.ItemNameDisplay":
elm.click()
I decided to print the IDs as well. I got the following results:
None
None
None
...
I'm quite confused as to why this is happening. I'm using the Windows Inspect tool from SDK to gather properties of the UI elements and there definitely is and element present that matches both the class name and the ID.
It should look something like:
class_elements = driver.find_elements_by_class_name("some_class_name")
for elm in class_elements:
if elm.get_attribute('accesibilityID') == "some_id":
elm.click()
EDIT:
As #Bill Hileman has pointed out the attribute OP was looking for is accesibilityID not just id.
Thanks Bill
Hope this helps you!
Moshe Slavin answer works, but you can try like this also.
Suppose you have some class name and you are storing it in some variable like below :
className = "some class name"
then you can get all the matching class names using the below line and you are aware of that :
driver.find_elements_by_class_name(className)
Instead of finding all the elements and storing the values, store the accessibility id that you want to check in some variable like below :
accessibilityID = "some accessibility id"
Then you can search for an element which contains both the class name and accessibility id(is just for an indicative purpose, so use app related attribute which identifies required field) using the below xpath without performing any looping :
element = driver.find_element_by_xpath("//*[#class='"+className+"' and #accesibilityID='"+accessibilityID +"']");
I hope it works too...

Capybara: Find element by attribute containing something NOT

I am having the following issue in my Capybara environment:
I need to search for an element. This element contains an attribute, which is unique. The attribute is changed asynchronously.
I need the content of this attribute, but when I just search for the attribute I am getting a nil.
I could wait until the attribute has the property, but since this is Capybaras job, I thought there might be a possible selector, which can search for something like:
find('button[uniqueattribute] != nil')
Any ideas how to do this?
Thanks already!
If the attribute is being added to the button element (didn't have the attribute originally) then you can just do
find('button[attribute_name]')
which will wait (up to Capybara.max_default_wait_time seconds for a button element with that attribute to be on the page - https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors. To wait and then get the contents/value of that attribute you could do
find('button[attribute_name]')['attribute_name']
If you just want to wait until the attribute is either not there or not blank then you can do
find('button:not([attribute_name=""])')
If you need to ensure the attribute is there, but isn't blank it would be
find('button[attribute_name]:not([attribute_name=""])')
I found a possible solution:
You can check the length of an element by Xpath (which is awesome) with string-length.
So in my case the solution was:
find(:xpath, ".//button[#unique_attribute_name[string-length() != 0]]")
Now Capybara waits until the attribute has a value. If there are more pretty solutions, just tell me.

Sylius - Overriding CartItemType breaks the Product show view

Sylius 1.0.0-dev
I'm trying to modify the Quantity field of CartItemType.
Following the old docs I have created a new FormType on my Bundle and extends from original in Symfony/Bundle/CartBundle/Form/Type/CartItemType.
My custom CartItemType shows like this:
use Sylius\Bundle\CartBundle\Form\Type\CartItemType as BaseType;
use Symfony\Component\Form\FormBuilderInterface;
class CartItemType extends BaseType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->remove('quantity')
->add('quantity', 'hidden', [
'attr' => ['min' => 1, 'max' => 1],
'data' => '1',
'label' => 'sylius.form.cart_item.quantity',
])
->setDataMapper($this->orderItemQuantityDataMapper);
}
}
I want you can't buy more than one product quantity per order.
My config seems liike this:
sylius_cart:
resources:
cart_item:
classes:
form:
default: Dinamic\Bundle\SyliusRibBundle\Form\Type\CartItemType
When I open some product view i'm getting this error:
The option "product" does not exist. [...] in #SyliusShop/Product/Show/_inventory.html.twig at line 4
Any idea about why this is happening?
Instead of extending CartBundle CartItemType extend using this:
use Sylius\Bundle\CoreBundle\Form\Type\CartItemType as BaseType;
The CoreBundle CartItemType class extends the CartBundle CartItemType, so if you extend the wrong class it will break everything
Don't extend Symfony form types that way - extend Symfony\Component\Form\AbstractType instead, and implement getParent() in your custom type:
public function getParent()
{
return BaseType::class;
}
That way, the parent's options will be available to your custom type as well, and everything will be properly rendered/initialized.
Edit:
Technically, both approaches should work. However, using inheritance will completely override the parent form's behavior, while using getParent() will add your custom behavior to the parent's form.
getParent() will tell Symfony to build the form defined in that method first, and then use that as the base for your own implementation. So when using that, the FormBuilder in your buildForm() method will already contain the complete parent form, ready for your own modifications, the OptionsResolver in your configureOptions() method will already have the parent form's options and defaults defined, etc. which appears to be exactly what you want (otherwise your call to $builder->remove() makes very little sense). When using inheritance, you'll have to take care to do everything the parent form does which you want to do as well, which might very well break when the parent form changes.
Another difference is in Symfony's form extensions. When implementing getParent(), any form extensions applied to the parent form will be applied to your custom form as well. When using inheritance, that won't be the case.
The first point is easy to work with (parent::buildForm() will ensure you have the correct fields, for instance), but the second is not as easy. Generally you want these extensions to apply to your custom form type as well - in this case there's actually a decent chance the error is caused by a form extension not being applied to your custom type.
So basically, use getParent() whenever possible. Use inheritance for form types only if you want to completely override behaviour or you explicitly want form extensions not to apply to your custom type.

zend framwwork 2 inArray element validator boring

How to disable the inArray validator of Zend\Element\Select ?
I can not remove this standard validator select element.
Edit:
What I'm trying to do is populate a select element so dynamic with ajax. So that way the inArray loses the reference field value.
Does anyone know what is the right way to populate this element with ajax?
It actually does not look like it is possible at this point in time to disable the validator; however, you can override the select element to be able to remove the validator for this specific case:
use Zend\Form\Element\Select;
class MySelect extends Select {
public function getValidator() {
return $this->validator;
}
}
Basically the key issue with the current select element is that if the validator does not exist; it will create it. The other option you have here is to set a validator manually; which you should likely be doing is manually creating an InArrayValidator and populating it with the potential options that would be coming from your AJAX call. In which case you would need to add a setter above.
Since version 2.2, Zend Framework provide the ability to disable inArray validator calling:
$element->setDisableInArrayValidator(false);
or passing option to an element:
'disable_inarray_validator' => false

OpenErp: Update form fields

I would like to update form fields "on-fly" after button press that triggers python function.
Something like onchange that allows to return field values, but I need to do it after button press.
The situation is, to create module, that will allow to search for company information in public company register based on entered company registration ID.
The best would be, to show up some popup window with updated fields list and user has to confirm, wether to update fields values or not.
Thank you.
You can create a wizard (osv.osv_memory class) to simulate a dynamic popup window.
To populate this wizard, you can use the returned action descriptor of your python function, like this :
return {'res_model':'your.osv.memory',
'view_mode':'form',
'view_type':'form',
'target':'new',
'context':{...},
}
Thanks to your algorythm that get public company information, you just have to put you're fields values on the context, like you would do in a write() method.
Override your default_get() method of your osv_memory, which receives your context, and populate your wizard like you want.
I think a simple text fields on your wizard will be efficient to display fields updated values, and 2 buttons : cancel and OK (which will call the write method to apply fields values, always using your context).