cancel
Showing results for 
Search instead for 
Did you mean: 

Can't fill input fields for TableView - HELP!!!!

Former Member
0 Kudos

Hi,

I know this is probably a stupid question, but...

I've created a value node and bound it to a table making all of the entries "InputField." When I change the value and click into other cells, the original values re-appear!

What am I doing wrong? What I want to do is be able to change any cell, insert new rows. When I'm done, I will press the Save button and process all my values.

Any ideas?

Thanks,

Andrew

Accepted Solutions (0)

Answers (3)

Answers (3)

Former Member
0 Kudos

Hi,

It seems that you have somewhere <b>singleton</b> node on context path to "table" node -- try to revisit this.

VS

Former Member
0 Kudos

Hi,

My Value Node does have a singleton value of true. How do I change it? When I create a new Value Node, I can't change the singleton value to false either.

Thanks,

Andrew

Former Member
0 Kudos

Hi,

I noticed that if I create a second value node underneath my root node, I can change the singleton value. Why is this? Do I have to recreate this structure and change all my code? bogus!

Thanks,

Andrew

Former Member
0 Kudos

No, there are no need to do so.

Please provide more details here first

1. Write your context tree starting from root and covering all involved nodes.

2. Describe what of them are singletons and how they are populated (via relation, via supply function, ad-hoc way)

VS

Former Member
0 Kudos

Hi Valery,

Thanks for looking at this. You seem to be the one that answers most of the problems I've been searching for! Being new to this but with an OO background, your understanding of the Dynpro tool has been invaluable to me so far.

<b>

Context  (TimeEntryView)
-TimesheetTable (Model node)
-InputTimesheetTable (Value node 0..n, singleton=true
  -employeenumber
  -activity
  - ..
  -MondayHours
  -TuesdayHours
  - etc.

</b>

====================

InputTimesheetTable is a root node that is populated by an adhoc method. Secondly, this node was created in a view and not the controller.

So, in the init of the controller, I get the persons PersonnelNumber and execute the bapi to retrieve their records. I trigger an event, to which the TimeEntry view has subscribed, and the Event Handler method in TimeEntry view in turn calls executePopulateTable method which populates nodeInputTimesheetTable by iterating through nodeTimesheetTable.

When reading further, and in retrospect, I think it might be best to keep all this functionality in the controller instead of the view. Also, for future enhancements, it may be best to create a Controller Value node that could be used for all employees for a specified manager and underneath these nodes have the InputTimesheetTable node for that particular employee.

<b>

Context (Controller)
->EmployeeTimesheet  (Value node - 0..n singleton=true)
    -EmployeeNumber  (Value attribute)
    -InputTimesheetTable (Value node - 1..1, singleton=false)
       - Activity
       - ...
       - MondayHours
       - TuesdayHours
       - Etc.

</b>

I could then use the supply function for the InputTimesheetTable passing the employeeNumber from it's parent node.

Do you think this is the best approach? I'm open to suggestions. If it makes sense to rewrite this portion, I only want to do it once!

Thanks,

Andrew

Former Member
0 Kudos

Actually, I think the controller context should be:

Context (Controller)
- Employees (Value node, 0..n, s=true)
  - EmployeeNumber (value attribute)
  - EmployeeName
  - TimesheetRecords (value node, 0..n, s=false)
    - Activity
    - Rec_ord
    - MondayHours
    - TuesdayHours
    - etc.

Former Member
0 Kudos

Ok, let me re-interpret your words with some guidelines:

1. Me & my co-workers establish a practice where context-population code is place in custom controller(s). So below I assume that we create everything in custom controller and use context mapping for view.

2. From our experience, the more you left to handle by WD the better. So, in this concrete case rather then keep in sync 2 independent hierarchies, it is better to manage only one hierarchy and place all transformed data under model node.

So, we receive the following structure (SF stays for supply function):


<b>Context</b> (CustomController, 1..1, singleton)
+- <b>TimesheetTable</b> (Model node, 0..n, singleton)
   +- <b>Employee</b> (Value node, 0..1, non-singleton, SF)
      - EmployeeNumber (Attribute)
      +- <b>TimeEntries</b> (Value node, 0..n, non-singleton, SF)
         - Activity
         - MonHours
         - TueHours
         - ...
         - FriHours

Supply function for employee calls back-end with EmployeeNumber from parentElement (corresponding attribute not shown for TimesheetTable).

Supply function for TimeEntries populate time entries by parentElement (Employee) and grand-parent (TimeSheet table).

The drawback of this solution is that you have to invoke separate call to back-end for every employee. If back-end supports batch loading, then I can elaborate further.

VS

Former Member
0 Kudos

The bapi I'm calling for the timesheet_GetList will return all the timesheet records for the time period specified. But, for what I'm trying to do in a very short timeframe, is to be able to pull back MY timesheet records and eventually add a new one.

So, I populate the Sel_Employee input table for the bapi so it only returns the current logged in persons timesheet records. So, the Model Node for TimesheetTable is specific to a particular employee already and is what is used to populate the Value node.

The reason for this is the necessity to change the row data into column data. The Model Node will have one element for each day and the Value node will be one element for the entire week being populated with up to 7 rows of the Model node.

Now, I would like to create a structure that will handle multiple employees for future enhancements, but I have to have a working application that can insert a Timesheet record for a single employee completed by tomorrow at 4pm! This will be using the BAPI to insert a record.

My controller context looks like the following after I applied the ServiceController template to my ComponentController to create the binding to the model.

<b>Context</b>
+- <b>Timesheet_GetList</b> (Model node, 0..1, s=true)
   - Fromdate
   - Todate
   +- <b>SelectEmployee</b>
      - High
      - Low
      - Sign
      - Option
   +- <b>Timesheet_Output</b> (Model node, 0..1, s=true)
      +- <b>TimesheetTable</b> (Model node, 0..n, s=true)
         - Employeenumber
         - Keycolumns
         - Workdate
         - Catshours
         - etc.

So, in my ViewController, I simply did the ContextMapping to bring over the TimesheetTable model node into my context. I then used this Model node to populate the InputTimesheetTable that I described in an earlier post.

Questions:

1. Why do you use a custom controller instead of the component controller?

2. Based on this layout of my Model nodes and what I need to accomplish, how would you create your Value nodes? In the component controller or in the View controller?

Thanks!

Andrew

Former Member
0 Kudos

Andrew,

1. Component controller is always instantiated, custom controllers instantiated on demand. If they are always "demanded" then there is no real difference. But if you component has several areas of functionality, and it is possibility that user does not enter certain navigation paths, then it is preferred to use "lazy" custom controller(s).

2. If you need both display / modify functionality the consider the following approach:

a) Get initial snapshot via BAPI call (plain table of entries)

b) Transform snapshot to working set of custom JavaBeans:

Employee (id, name) -1..n-> TimeEntries (activity, monHours, tueHours, ..., friHours). So you get a collection of Employee objects with corresponding TimeEntries. Better yet, create a map Employee.id -> Employee. See reasons latter.

c) Create context structure that adhere to your working set:


<b>Context</b>
+- <b>Employees</b> (0..n, singleton, SF)
   - id 
   - name
   +- <b>TimeEntries</b> (0..n, singleton!!!, SF)
      - activity
      - monHours

d) Use working set to update via BAPI call. Optionally you can use snapshot (a) to create delta-update.

Every supply function will get data from corresponding object in working set. For employees it is just traversing values() of Map, for TimeEntries it is getting first Employee from Map by parentElement.getId(), then use it TimeEntries Collection property.

Operations on TimeEntries:

1. Adding data: add both to JavaBeans collection and node, or only to JavaBeans collection and invalidate node

2. Deleting data: remove from both JavaBeans collection and node, or only to JavaBeans collection and invalidate node.

3. Updating data: before navigating from Employee element in node, copy back values from TimeEntries node to corresponding JavaBeans classes.

VS

Former Member
0 Kudos

Do you want a job? I have a perfect contract for you if your interested!

Well, this goes well beyond the scope of my knowledge and I'm not sure I will be able to grasp all of this and implement what I have to implement by tomorrow. I'm rolling off this project and back onto a project where I will the portal architect and not a developer. It's been several years since I did any serious development work but I'm having fun doing this.

So, with that said, what's the general process of transforming Model Node data into a set of custom JavaBeans? How do I create a JavaBean and how do I map it to a node?

"Every supply function will get data from corresponding object in working set. For employees it is just traversing values() of Map, for TimeEntries it is getting first Employee from Map by parentElement.getId(), then use it TimeEntries Collection property."

Could you elaborate on this? What do I have to do in order to create a supply function for the TimeEntries node? In the function, do I just call nodeEmployee.GetLeadSelection().getEmployeeNumber() and process accordingly?

Operations on Time Entries:

I have three supporting BAPI's for maintaining the data on the backend. Timesheet_Change, Timesheet_Insert and Timesheet_Update. My plan was to iterate through every cell when the user hits "Save" to determine if it was an insert, update or delete.

Each of these BAPI's has their own table as input that needs to be populated before the BAPI is called. So, for each delete, the delete input table gets an entry. For each inserts, the insert input table gets and entry and the same for updates.

Also, I need to display the error messages that are returned from each BAPI.

Thanks,

Andrew

Former Member
0 Kudos

Would it make sense to create a Value node like:

<b>Context</b>
+- <b>Employees</b> (Value Node, 0..n, s=true)
    - PersonnelNumber
   +- <b>TimesheetRecords</b> (Value node, 0..n, s=false)
      +- <b>Workday</b> (Recursive Node with TimesheetRecords as repeated node)
       - Key columns (about 8 attributes)
       - Catshours
       - Workdate

Then, for each element I would have 1..7 elements in the recursive node for each day of the week. If I do this, can I still map it to the table correctly? I don't think I can but it would be nice if I could instead of having MonDate, MonHours, TueDate, TueHours, etc.

Thanks,

Andrew

Former Member
0 Kudos

Here is a better explanation of what I've done:

I've imported the Bapi_Catimesheetmgr_GetList which populates a model node in my controller context. This bapi retrieves multiple rows for the given time period.

To display the data as it is in the CAT2 transaction, I have to turn the row data into column data. I've created a Value Node (0..n) and created an attribute for the key columns I need plus a MondayHours, TuesdayHours, etc. in order to display the timesheet.

So, if I had hours for each day of the week in the CAT2 transaction all with the same key columns, this would return 5 records into the Model Node. In my Value Node, I populate 1 row with the 5 values.

Steps I've done:

1. I've retrieved the records from the database into my Model Node.

2. I've created a Value Node with attributes of the correct type to match the Model Node

3. I've looped through the ModelNode to correctly populate my Value Node

4. I've set the dataSource of my table to be my Value Node

5. I've selected "Create Binding" and selected the columns I want to display from my Value Node

6. I've changed each of the types of the columns to be "InputField" with a binding of "value"

Now, when I change a value in the table it resets to the original value when I click into another cell. If I just use the tab or arrow keys, the values remain.

Any ideas?

Former Member
0 Kudos

Your description sounds a little vague. Is your value node properly bound?

Do you have the proper context structure?

|- Table Node (0..n)

|- Value element

Is the value property set to read-only? It shouldn't be.

Is your table's dataSource mapped to the Table Node?

If you have created the above context structure, what I suggest is simply to go to your Outline view, select 'Apply Template' and do a table.

Make sure you are creating new context elements, as well, it might be that you are mapping to the same element in your java code.

Former Member
0 Kudos

Hi Thomas,

Thanks for the quick reply.

I am re-writing the CAT2 functionality and I have a Model Node with a bunch of BAPCAT2 records. I created a Value node with (0..n) with multiple Value attributes that have the same types as my Model Node.

I populate the Value node which is bound to my Table. I create a new InputTimesheetTableElement() and set all the values accordingly.

In the binding of the table, I changed the columns to be InputField and the binding is set to "value."

I tried what you said by Applying the table template and it exhibits the same behavior.

Any more thoughts? Should I be doing something in the wdDoModifyView method?

Thanks!

Andrew

Former Member
0 Kudos

There shouldn't be anything you that you would need to add to your code in the wdDoModify.

Is your table bound to the node you think they are, or is it bound to the model node? Are your columns?

Former Member
0 Kudos

Are you using calculated attributes to map your value nodes to your model nodes? If you are, you might need to do something else to deep copy your nodes. ( Since they get calculated every time that you access the variable )

Former Member
0 Kudos

Yes, it is bound to the value node and I did a "create binding" to get my columns from the Value node.

Another thing is that it only resets if I click another cell. If I tab out or use my arrow keys, the values stay.

Thanks,

Andrew