Selecting a field whose label is repeated in subsections - react-testing-library

I have a form that has some labels repeated, but in different subsections. Here's an example of part of my form:
I want to be able to choose, for example, the Days from Section A and also the Days from Section B independently. To that end, I've tried using the getByLabelText method:
it('should display correct value for days field', async () => {
const {getByLabelText} = render(<MyForm/>);
const daysElement = await waitForElement(() =>
getByLabelText(/Days/i) as HTMLInputElement
);
expect(daysElement.value).toEqual('0');
});
I'm using htmlFor on the label for Days and a matching Id on the associated input element. Each section has a context provided to disambiguate the otherwise matching Ids (e.g. for days). For example:
<Field label={i18n.days} htmlFor={`${name}_days`} value = {<NumberControl name='days' id={`${name}_days`} value={this.state.days}}/>
In this code, ${name} would resolve to something that is different for section A vs section B. (Field and NumberControl would ultimately create label and input elements, setting htmlFor and id values appropriately).
When I use getByLabelText as illustrated above, it obtains the value for Section A. But I also need to obtain the value for Section B. How would I do this?

You have different options depending on your DOM structure.
If you have a way to query your section—for example with a data-testid—you could use within:
within(getByTestId('id-for-section-A')).getByLabelText('Days')
within(getByTestId('id-for-section-B')).getByLabelText('Days')
within gives you all the query helpers that are returned by render but they are limited to the children of the node you pass to them.
If you can't add a data-testid to your section but you're always sure about the order in which the fields appear on the page you can use getAllByLabelText:
const [firstInput, secondInput] = getAllByLabelText('Days')
Lastly, if none of the above works, you could use the id attributes since they are unique. renderd returns a container element which is just a DOM Node. You can use the regular DOM methods on it:
const { container } = render(<YourForm />)
container.getElementById('section_A_days')
container.querySelector('#section_A_days')
How you query within your container depends on your DOM structure.
I personally would go with within but it very much depends on your use-case.

Related

Creating an array for multiple instances targeting IDs with non static members

I am trying to automate text boxes to fill with a certain value, however the text boxes names are not static so they will always change. I am looking to find a way to always populate them even though they do not have a static name and how to find the second, third, fourth etc instance of the boxes and be able to also fill them without overwriting the previous text boxes
i have tried using the _collect function in sahi pro but could not find how to target the class correctly
I expect to be able to populate any textbox using the same class name without overwriting the first instance of this class.
I am using Sahi pro.
The sahi documentation on _collect seems to be you exactly what you are looking for
// Collect all textboxes matching any identifier, in table "listing".
// Note the use of match all regular expression "/.*/"
var $textboxes = _collect("_textbox", "/.*/", _in(_table("listing"));
// Iterate and set values on all textboxes
for (var $i=0; $i<$textboxes.length; $i++) {
_setValue($textboxes[$i], "value");
}
If this does not solve your problem, please provide an example of the html and of your _collect code

How to retrieve the rows which are selected in the list report page of smart templates

This is the List Report type of Smart Template application
Here I have selected 2nd and 5th row, I also have a button named Send Requests in the section part which is highlighted. If I click this button it calls a javascript controller function which is defined in the extensions of the application. In this js function how can I retrieve the selected rows that are selected?
I have enabled the checkboxes in this page by mentioning this code
"settings": { "gridTable": false, "multiSelect": true } in the manifest.json
As it was recommended by this link https://sapui5.netweaver.ondemand.com/#docs/guide/116b5d82e8c545e2a56e1b51b8b0a9bd.html
I want to know how can I retrieve the rows which got selected?
There is an API that you can use for your use case. It is described here: https://sapui5.netweaver.ondemand.com/#docs/guide/bd2994b69ef542998becbc69ab093f7e.html
Basically, you just need to call the getSelectedContexts method. Unfortunately you will not be able to really get the items themselves, only the binding contexts (which point to the data entities which are selected). Excerpt from the documentation:
After you have defined a view extension, you can access and modify the
properties of all UI elements defined within these extensions (for
example, change the visibility). However, you cannot access any UI
elements that are not defined within your view extensions.
In this type of table there is way.
var myTable=sap.ui.getCore().byId("your table id");
get all rows:
var myTableRows=myTable.getRows();
now get selected Indices
var selectedIndeices=myTable.getSelectedIndices(); //this will give you array of indeices.
now run loop on indeices array. And get particular row item;
// get binding path
var bindingpath=myTableRows[2].getBindingContext().sPath; // this will return eg:"/ProductCollection/2"
// now get Binding object of that particular row.
var myData=myTableRows[2].getModel().getObject(bindingpath); // this will return binding object at that perticular row.
// once your loop is over in the end you will have all object of selected row. then do whatever you want to do.
If you use smart template create an extension.
This is the standard event befor the table is rebinding:
onBeforeRebindTableExtension: function (oEvent) {
this._table = oEvent.getSource().getTable();
}
In your action function (or where you want) call the table and get the context :
this._table.getSelectedContexts();

Adding a form filter

I'm currently working on a form in Microsoft Dynamics AX.
The form consists of a grid with about 10 fields from 4 different tables.
As the form is now it returns too many values so I need to include some sort of filter, it doesn't need to be dynamic, just a static filter saying only show the lines with value X in column Y.
Has anyone here got some experience with this sort of thing? Where do I start?
I must say I'm not experienced with Microsof AX at all, I've been working with it for about a month now.
I've tried to follow this guide: How to: Add Filter Controls to a Simple List Form [AX 2012]
But I got stuck at the second part (To add a control to the custom filter group) Step 2: I dont know which type of control to chose, and ik i pick lets say a ComboBox i cant get Step 3 to work because I dont see the 'Override Methods' they mention.
Well, I usually do it this way:
In ClassDeclaration, create as many QueryBuildRanges variables as fields to filter. Let's name them Criteria1, Criteria2, etc (name them properly, please, not as here)
QueryBuildRange criteria1, criteria2;
In each Datasource you need to filter, override method Init, an add code similar to this:
super();
criteria1 = this.query().datasource(tablenum(tableofdatasource)).addQueryRange(fieldNum(fieldtofilter))
//criteria1.status(RangeStatus::locked); //optional - this way you can hide filter field to user, have it readonly for users, etc
Create a control of type StringEdit or ListBox in form to be used as filter. Change their AutoDeclaration property to Yes. Override modified() method. In it, I use to put something similar to:
super();
element.changeFilters();
In form, add method changeFilters();
range rangeFromStringControl = StringEditControlName.text(); //Put in rangeFromStringControl the string to be used as filter, as a user would write it
range rangeFromListBoxControl;
criteria1.value(rangeFromStringControl);
switch (listBoxControl.Selection())
{
case NoYesAll::All:
rangeFromListBoxControl = ''; //Empty filter string - No filter at all
break;
case NoYesAll::No:
rangeFromListBoxControl = QueryValue(NoYes::No); //Or whatever string filter value you want
break;
//Etc
}
//We have all filter strs done; let's filter for each main DataSource required with new filters
DataSource1.executeQuery();
//If there is other datasources joined to this one, it's usually no necessary to call their executeQuery;
//If there are others with filters and not joined to it, call their executeQuery()
If you need this filter to be applied when form is open, set appropiate initial values to controls, and then in form's run() method:
run();
element.changeFilters();

How can I get the Zend_Form object via the Zend_Form_Element child

I've built a Zend_Form_Decorator_Input class which extends Zend_Form_Decorator_Abstract, so that I could customize my form inputs -- works great. I ran into a problem in the decorate class, in trying to get the form name of the element, so as to built a unique id for each field (in case there are multiple forms with identical field names).
There is no method like this: Zend_Form_Element::getForm(); It seems Zend_Form_Decorator_Abstract doesn't have this ability either. Any ideas?
I don't think changing the id from the decorator is the right approach. At the time the decorator is called the element already has been rendered. Thus changing the id would have no effect to the source code. Additionally, as you already have pointed out, the relation between a form and its elements is unidirectional, i.e. (to my best knowledge) there is no direct way to access the form from the element.
So far the bad news.
The good news is, that there actually is a pretty easy solution to your problem: The Zend_Form option elementsBelongTo. It prevents that the same ID is assigned to two form elements that have the same name but belong to different forms:
$form1 = new Zend_Form(array('elementsBelongTo' => 'form1'));
$form1->addElement('Text', 'text1');
$form2 = new Zend_Form(array('elementsBelongTo' => 'form2'));
$form2->addElement('Text', 'text1');
Although both forms have a text field named 'text1', they have different ids: 'form1-text1' and 'form2-text1'. However, there is a major drawback to this: This also changes the name elements in such a way that they are in the format formname[elementname]. Therefore $this->getRequest()->getParam('formname') will return an associative array containing the form elements.

Drupal 7 Views add list of authors as exposed filter

I have a view with a number of exposed filters that I want to add an exposed filter for the author, so that the user can limit a list of nodes by the creator of the node (in addition to a number of other filters).
What I've done so far:
I've added an exposed filter of the author and set the operator to "contains any word" (so the usernames could just be a + separated list)
This is by default a text field, but I would like it to appear as a list of checkboxes (similar to taxonomy)
Using hook_form_alter I've added the following code to change it to a list of checkboxes (harcoded for now but I'll fix shortly)
$form['name']['#type'] = "select";
$form['name']['#size'] = "3";
$form['name']['#multiple'] = TRUE;
$form['name']['#options'] = array(
'admin' => 'admin',
'tyler' => 'tyler',
'test' => 'test'
);
$form['name']['#theme'] = "select_as_checkboxes";
When this form is submitted it changes the url to &name[]=tyler&name[]=admin, what I would like to do is combine these with a foreach so that url would look like &name=tyler+admin, but I'm really not sure how exactly to achieve this in the API.
I tried adding a function to $form['#submit'], and changing the value of the field in there, but that still didn't change the output.
Any advice?
Quick Edit
For the time being I have switched this to use radios instead of checkboxes, which solves the issue that I was having.
To break down the issue I was having a bit further, the names of the checkboxes where getting set to name[]= instead of name= because of the multiple inputs. The name filter in Views does not know how to handle multiple values for the name field.
For now I will see if this flies with the client, but if anybody has an answer for the original question of adding checkboxes for all authors to an exposed filter that would be awesome!
Use Better Exposed Filters module.