I'm writting a report in which I have two radiobuttons of the group 'tab'. Depending on their value, I must set some screen fields to no-display, else, display them correctly.
I can make it work perfectly by using the event at selection-screen output. , but it refuses to work when using at selection-screen on radiobutton group tab -to test one, I comment out the other.
The code in both is exactly the same, so could someone help me understand the difference in the two events so I get why only one works?
events below, only the second one works.
at selection-screen on radiobutton group tab.
go_controller->modify_screen( ).
at selection-screen output.
go_controller->modify_screen( ).
They both call the same method
method modify_screen.
loop at screen.
case screen-group1.
when 'TAB'.
if use_otab = abap_false.
screen-invisible = 1.
screen-active = 0.
screen-input = 0.
p_int = abap_false.
p_nat = abap_false.
free p_table[].
else.
screen-active = 1.
screen-invisible = 0.
screen-input = 1.
endif.
modify screen.
endcase.
endloop.
endmethod.
Via debug, I see that both of the events are reached correctly, nevertheless, only the second one works.
Because it is designed like this: AT SELECTION-SCREEN ON... is a "process after input" (PAI) event. PAI is designed to react on user actions. At the end of PAI, the next dynpro is determined (even if it may be the same as the actual), and then the "process before output" (PBO) of the dynpro is processed. This is the preparation of the screen elements for the user. Only in PBO, the modification of the SCREEN table has an influence on the visibility or editability of the screen elements.
So, in reporting you are supposed to use at selection-screen output. to influence the visibility or editability of the parameters and select-options.
Related
I'm getting ready to create a communications widget for use in a Jupyter application. I'm trying to understand when the widget's "value" property can be accessed ... it looks like the "value" can be read anytime, but won't match the widget model "value" until cell execution stops (i.e., the widget's browser state isn't updated back to the widget's kernel state).
To test this, I tried creating a small slider widget, waiting for 10 seconds, and then reading the widget "value" property ... all in the same cell. In the 10 seconds, the user (i.e., me) has time to change the slider to something like "5".
Here's a small test that can be run in a cell. When the sleep() happens, I move the slider to value "5".
from ipywidgets import *
import time
slider = IntSlider(
value=7,
min=1,
max=10.0,
step=1,
description="Input:",
)
display(slider)
time.sleep(10) # move slider to 5
print("done " + str(slider.value))
I expected "done 5" but got "done 7", implying to me that "value" is updated only after the cell completes.
Is this always true? And is there a way to force synchronization between the widget's browser state and its state in the kernel?
(I do get the expected "done 5" if I move the print() to the following cell.)
Thanks!
There is basically at present no way to automatically force code running in a cell
to wait for an event or change in a widget. Things like time.sleep(3) will only
freeze the cell and a slider created in the same cell will not display until the
sleep is complete.
The user could create a slider in cell 1 and then execute a sleep in cell 2 and then adjust the slider and the code in cell 2 may see the change after the sleep
but in this case the synchronization is directed by the user and is not automatic.
You can also start Python code from a widget event, but the Python code does not "run in a cell" and the "prints" will not go to the standard cell output area but
the output can be captured in other ways,.
In the following screenshot I use the "Output" widget to capture output from a widget event
The basic problem is that all communication between widgets and kernels is via
one-way messages -- there are no "return values" or "acknowledgements" of any kind.
Please see https://github.com/AaronWatters/jp_proxy_widget/blob/master/notebooks/Tutorial.ipynb for more discussion.
As it turns out, there does seem to be a library that uses something like asyncio to achieve an inline wait. It's called jupyter-ui-poll at https://github.com/Kirill888/jupyter-ui-poll. The author says it's available on PyPI at https://pypi.org/project/jupyter-ui-poll/
Very promising! ... otherwise, I'm forced to agree with you.
I was developing an app that in the first state you choose a date range using dataFields then you press a button to go to another state and generate a datagrid showing an employee list and another scrollable datagrid with its columns generated dynamically having the worked hours for every employee in every date.
The step sequence to get the error message is:
You choose a date range for example: from 01/01/2013 to 01/31/2013
You press generate button (The app change the currentState = "EmployeeList" and all is OK)
You press the back button (you return to initial state and all is OK)
If you change the date range having more days than before date range then all is OK
If you change the date range having less days than before date range then next error is reached
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at mx.controls.dataGridClasses::DataGridBase/http://www.adobe.com/2006/flex/mx/internal::columnHeaderWordWrap()
at mx.controls.dataGridClasses::DataGridItemRenderer/validateProperties()
at mx.managers::LayoutManager/validateClient()
at mx.controls.dataGridClasses::DataGridHeader/updateDisplayList()
at mx.core::UIComponent/validateDisplayList()
at mx.managers::LayoutManager/validateDisplayList()
at mx.managers::LayoutManager/doPhasedInstantiation()
at mx.managers::LayoutManager/doPhasedInstantiationCallback()
and if you google it then some results take to visit apache bug reporting site
https://issues.apache.org/jira/browse/FLEX-22108
And there is no more...
But I found how to solve it!
To solve it first of all I was googling a lot and i looks like no one got this error and I discover that is a Flex Bug reported to Apache. And I was analyzing the original code from DataGrid.as and DataGridColumn.as to think about a possible solution and I was making some tests and nothing work.
What I did and I hope it will be useful to someone
when you click the back button, inside the backbutton_clickEventLister() and before currentState="";
I just set columns array to new Array();
protected function bttnBack_clickEventHandler(event:Event) : void {
// This code line solved it
dtGrdWorkedHours.columns = new Array();
// Make sure of code it before state change stament
currentState = "";
}
I have a panel Profiles List on a web page. It contains multiple small panels, like a list of items contains lines. The items here are profiles. Each profile is actually a small panel SingleProfile with checkbox inside. Checkbox is the core here, because it has an ID, which is used to find the same items.
On this page there is also another similar big panel. I should add to the second panel only those items, which do not exist in the first one. So, the task is to show in the second panel only those profiles, which are not presented in the first panel. This is checked using IDs of the checkboxes in both lists.
To check if a newly added profile in the second panel already exists in the first panel, I try to access the ID property of each item in the first panel through Controls[] property. I do it in the cycle:
if (ProfilesPanel1.Controls.Count > 0)
{
for (int i = 0; i <= ProfilesPanel1List.Controls.Count - 1; i++)
{
//label1.Text += " "+Convert.ToString(sqlReader["chain_id"]); //Bug #2 - see Stored Procedure description
cbx1 = new CheckBox();
cbx1 = (CheckBox)ProfilesPanel1List.Controls[i].Controls[1]; //Bug #1 - here the Exception occurs
if (cbx1.ID == Convert.ToString(sqlReader["chain_id"])) //if profile already exists in the first panel
{
//Do not add this profile to the second panel
}
}
}
The exception "System.ArgumentOutOfRangeException" occurs in the line marked with "Bug #1".
I use sqlReader which takes IDs from a stored procedure. Stored procedure works fine in the Sql Server. But, when I output values of the sqlReader into a label on a web page (see comments in the code), each value is doubled, like "1 1 2 2 3 3 4 4 5 5".
Solution to BUG #1
Check number of controls and its names from quickwatch in debug mode and see, is ProfilesPanel1List.Controls[i] a panel or some other control. Choose your index correctly after checking it in debug mode.
And also you don't need to use cbx1 = new CheckBox(); line of code. Its next line of code is enough to initialize that Checkbox.
Your sqlReader code is not enough to get the actual cause of 2nd error.
For Bug#1, there is a chance that there might be no nested controls existing underneath 'Controls[i]'. So to guard against the bug, you can first check if there are any nested controls underneath the current element and then checking the type of control before type casting.
if(ProfilesPanel1List.Controls[i].Controls.Count>1 && ProfilesPanel1List.Controls[i].Controls[1] is CheckBox) //Iff you are double sure about layout structure and assured that it is not going to
//change. If changes are anticipated then again doing a foreach(..) over nested 'Controls' and type
//checking is much better.
{
//Do the type conversion etc., as per your requirement.
}
For Bug#2, what do you exactly mean by 'each value is doubled'? As I can see that you are appending to the same Label (with ID: Label1) inside the loop so, there is a chance for the text to be concatenated on every iteration. Also, please be sure as per your requirement, whether you need to manipulate same label's text or label inside nested controls of the parent panel.
Take a standard web page with lots of text fields, drop downs etc.
What is the most efficient way in webdriver to fill out the values and then verify if the values have been entered correctly.
You only have to test that the values are entered correctly if you have some javascript validation or other magic happening at your input fields. You don't want to test that webdriver/selenium works correctly.
There are various ways, depending if you want to use webdriver or selenium. Here is a potpourri of the stuff I'm using.
Assert.assertEquals("input field must be empty", "", selenium.getValue("name=model.query"));
driver.findElement(By.name("model.query")).sendKeys("Testinput");
//here you have to wait for javascript to finish. E.g wait for a css Class or id to appear
Assert.assertEquals("Testinput", selenium.getValue("name=model.query"));
With webdriver only:
WebElement inputElement = driver.findElement(By.id("input_field_1"));
inputElement.clear();
inputElement.sendKeys("12");
//here you have to wait for javascript to finish. E.g wait for a css Class or id to appear
Assert.assertEquals("12", inputElement.getAttribute("value"));
Hopefully, the results of filling out your form are visible to the user in some manner. So you could think along these BDD-esque lines:
When I create a new movie
Then I should see my movie page
That is, your "new movie" steps would do the field entry & submit. And your "Then" would assert that the movie shows up with your entered data.
element = driver.find_element(:id, "movie_title")
element.send_keys 'The Good, the Bad, the Ugly'
# etc.
driver.find_element(:id, "submit").click
I'm just dabbling in this now, but this is what I came up with so far. It certainly seems more verbose than something like Capybara:
fill_in 'movie_title', :with => 'The Good, the Bad, the Ugly'
Hope this helps.
I'm creating a spinbox in R using rtcltk with:
from <- tkwidget(leftFrame, type="spinbox", from=0, to=0.1,
inc=0.001, textvariable=freqFrom,
command = function(){updatePlot()})
This works as intended (updatePlot is called) when I use the arrows of the spinbox, but does not work if I just type something in manually.
How do I catch the "value changed" event?
By default it does not change in this case in case you type in an illegle value (like deleting the last digit), or if the update is time consuming then you would not want it to update between every keystroke when typing in a 3 or 4 digit number.
You can add an update button than calls updatePlot when clicked so that the user would type in the number and when they know they are finished would click the button.
If you really want the update to occur with every keystroke then you can use the tkbind function to call updatePlot (something like tkbind(*spinbox*, "<Key>", updatePlot) where spinbox is the variable pointing to the spinbox).