cancel
Showing results for 
Search instead for 
Did you mean: 

Reusing the elements of wdDoModifyView()

Former Member
0 Kudos

I have want three input fields which are bound to view attributes.

users will enter the data into the fields and press the button. On clicking this button,

these values will be stored in node(cardinaltiy 0..n) and Table will be displayed at the bottom of the screen.

OnAction of Button executes

		
IPrivateDynTableView.IPersonElement element =
			wdContext.nodePerson().createPersonElement();
 
	element.setFirstName(wdContext.currentContextElement().getFirstName());
	element.setLastName(wdContext.currentContextElement().getLastName());
	element.setEMail(wdContext.currentContextElement().getEMail());

	wdContext.nodePerson().addElement(element);

It is working well to add one row. After that I am getting the error 500.

Error message reads "com.sap.tc.webdynpro.services.exceptions.WDCreationFailedException: Cannot create view element implementation com.sap.tc.webdynpro.clientserver.uielib.standard.impl.TextView"

Context

-Person(ValueNode; Cardinaltiy 0..n)

--EMail

--FirstName

--LastName

-EMail

-FirstName

-LastName


public static void wdDoModifyView(
	IPrivateDynTableView wdThis,
	IPrivateDynTableView.IContextNode wdContext,
	com.sap.tc.webdynpro.progmodel.api.IWDView view,
	boolean firstTime) {
	//@@begin wdDoModifyView

	if (!firstTime) {
	IWDTransparentContainer root =
					(IWDTransparentContainer) view.getRootElement();
	IWDTable table = (IWDTable) view.createElement(IWDTable.class, "table");
	table.bindDataSource(wdContext.nodePerson().getNodeInfo());

	IWDTableColumn colFirstName =(IWDTableColumn) view.createElement(IWDTableColumn.class,"firstName");
	IWDCaption capFirstName =(IWDCaption) view.createElement(IWDCaption.class,"firstNameCap");
	capFirstName.setText("First Name");

	IWDTextView textViewFirstName =	(IWDTextView) view.createElement(IWDTextView.class, "fname");
	textViewFirstName.setText(wdContext.nodePerson().currentPersonElement().getFirstName());

				colFirstName.setTableCellEditor(textViewFirstName);
	colFirstName.setHeader(capFirstName);

	table.addColumn(colFirstName);

	IWDTableColumn colLastName =(IWDTableColumn) view.createElement(IWDTableColumn.class,"lastName");
	IWDCaption capLastName =(IWDCaption) view.createElement(IWDCaption.class,"lastNameCap");
	capLastName.setText("Last Name");

	IWDTextView textViewLastName =	(IWDTextView) view.createElement(IWDTextView.class,"lname");
	textViewLastName.setText(wdContext.nodePerson().currentPersonElement().getLastName());

				colLastName.setTableCellEditor(textViewLastName);
	colLastName.setHeader(capLastName);

	table.addColumn(colLastName);

	IWDTableColumn colEMail =(IWDTableColumn) view.createElement(IWDTableColumn.class,"email");
	IWDCaption capEMail =(IWDCaption)view.createElement(IWDCaption.class,"eMailCap");
	capEMail.setText("Last Name");

	IWDTextView textViewEMail =(IWDTextView) view.createElement(IWDTextView.class,"email");
	textViewEMail.setText(wdContext.nodePerson().currentPersonElement().getEMail());
				colEMail.setTableCellEditor(textViewEMail);
	colEMail.setHeader(capEMail);
	table.addColumn(colEMail);
	root.addChild(table);
     }

			//@@end
}

Any ideas on re-using the table?

Thanks

~kranthi

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Hi Kranthi,

In your code, you are creating UI elements everytime except for the first time.

if (!firstTime) {

.

.

IWDTable table = (IWDTable) view.createElement(IWDTable.class, "table");

.

.

So the second time, wdDoModify() is encountered, this code will throw an exception as there already exists UI elemnts with the same name. So if you want to create UI elemnts each time the page is loaded, make sure you remove all the dynamically created UI elements by writing the following line of code:

if (!firstTime) {

<b>view.resetView();</b>

.

.

Another mistake is you haven't bound the UI elements to the corresponding attribute, but have explicitly set the values. This will show the same value in eachh row of the table. So instead of

textViewFirstName.setText(wdContext.nodePerson().currentPersonElement().getFirstName());

write

<b>textViewFirstName.bindText("Person.FirstName");</b>

Similarly for the rest of the columns too.

The rest of the code looks fine.

Hope this helps,

Best Regards,

Nibu.

Former Member
0 Kudos

Excellent, it worked perfectly.

Thaaaanks A lot!

~kranthi

Former Member
0 Kudos

Probably it worked, but in your use case, it is not necessary at all to recreate the view elements on every request.

Armin

Former Member
0 Kudos

Armin,

Can u pls suggest a better way without recreating the elements with each request to get the same functionality.

Thanks

~kranthi

Former Member
0 Kudos

Yes, you simply have to add new node elements into the context. No need to recreate the table UI element every time.

Data binding:

Context:

-Person(ValueNode; Cardinality 0..n)

--EMail

--FirstName

--LastName

Table.dataSource -> Person

TableColumn1:

--(TableCellEditor)TextView.text -> EMail

TableColumn2:

--(TableCellEditor)TextView.text -> FirstName

TableColumn3:

--(TableCellEditor)TextView.text -> LastName

Armin

Message was edited by: Armin Reichert

Former Member
0 Kudos

Armin,

Thanks for your reply.

I want to call wdDoModifyView() only with action. So I need to use <i>if(!firstTime)</i> condition.

By the time view changed with second action event, they are already defined. To overcome this, we are deleting the existing elements. Do u have any other ideas to overcome this?

Thanks

~kranthi

Former Member
0 Kudos

It's much simpler:

Create the table and the columns at design time and bind their properties as described to the view context.

In the action handler, simply add a new node element to the Person node. That's all.

Armin

Former Member
0 Kudos

During the initilization of the view I would see table with no rows. Still I see row header, footer etc. That is not my requirement.

Thanks

~kranthi

Former Member
0 Kudos

To avoid this, you could bind the Table.visible property to a context attribute of type "Visibility" and initialize it with Visibility.NONE. In the action handler, set the visibility to Visibility.VISIBLE.

Armin

Former Member
0 Kudos

Awesome, I like this idea!

Thanks

~kranthi

Former Member
0 Kudos

It's simply the general rule:

Create as much a possible at design time, only what is needed at runtime. Prefer data binding over view modification.

Armin

Answers (0)