掲示板

Populate DDLFormScreenlet fields programmatically

thumbnail
7年前 に Arne Leeman によって更新されました。

Populate DDLFormScreenlet fields programmatically

Junior Member 投稿: 29 参加年月日: 11/02/24 最新の投稿
Hi there,

Is there a way to set default field values in a DDLFormScreenlet besides default values defined in the structure?

My usecase is replying to an entry (news message) from a DDLlistScreenlet.
I pass the default reply data as extra's in the intent used to start the reply activity
The reply activity contains a DDLFormScreenlet with no recordId specified.

I tried to update the current record in the DDLFormScreenlet object (_screenlet) in both onDDLFormLoaded(Record record) and onDDLFormRecordLoaded(Record record) to no avail like this:

Map<String, Object> data = new HashMap<String, Object>();
data.put("toUserId", Long.toString(_recUserId));
data.put("subject", _recSubject);
data.put("_threadId", Long.toString(_recThreadId));

record.setValues(data);
_screenlet.setRecord(record);

I attach the concerning activity java file for reference.
Is there a way to do this properly?

Cheers,
Arne

ps Android Studio doesn't show any liferay errors debugging the app on my mobile
thumbnail
7年前 に Javier Gamarra によって更新されました。

RE: Populate DDLFormScreenlet fields programmatically

Expert 投稿: 348 参加年月日: 15/02/12 最新の投稿
We are inheriting part of the structure of the data in the portal, so you should write something like this:


@Override
	public void onDDLFormLoaded(Record record) {
		loaded = true;

		Map<string, object> data = new HashMap&lt;&gt;();
		Map<string, object> modelValues = new HashMap&lt;&gt;();
		data.put("modelValues", modelValues);
		modelValues.put("TextBoxeuwq", "1");
		screenlet.onDDLFormRecordLoaded(record, data);

		info("Form loaded!");
	}
</string,></string,>


The data for the record is stored in the "modelValues" key.

If you don't mind coupling with the UI (you should) you could also fill the values retrieving the fields directly with findViewById / Children.
thumbnail
7年前 に Arne Leeman によって更新されました。

RE: Populate DDLFormScreenlet fields programmatically

Junior Member 投稿: 29 参加年月日: 11/02/24 最新の投稿
Hi Javier,

Thanks for your swift reply, this is usefull.

I wouldn't mind going with the UI option, as it would allow me to not show specific fields in the form - control values for the server - as well.
Could you maybe point me to snippets for this? I couldn't find any..

Best, Arne
thumbnail
7年前 に Javier Gamarra によって更新されました。

RE: Populate DDLFormScreenlet fields programmatically

Expert 投稿: 348 参加年月日: 15/02/12 最新の投稿
Uhm... this is way brittler:

((DDLFieldTextView) ((LinearLayout) findViewById(R.id.ddlfields_container)).getChildAt(0))

That way you can access the rendered views and either change the underline value or the edittext itself.
thumbnail
7年前 に Arne Leeman によって更新されました。

RE: Populate DDLFormScreenlet fields programmatically

Junior Member 投稿: 29 参加年月日: 11/02/24 最新の投稿
Right, I'll have a go at it.

Thanks again,
Arne
thumbnail
7年前 に Arne Leeman によって更新されました。

RE: Populate DDLFormScreenlet fields programmatically

Junior Member 投稿: 29 参加年月日: 11/02/24 最新の投稿
Hi Javier,

I'm sorry to say that your first solution doesn't work: onDDLFormRecordLoaded only takes 1 argument of type Record..
(haven't tried the second yet)

This is what I did:


	@Override
	public void onDDLFormLoaded(Record record) {
		_loaded = true;

		Map<string, object> modelValues = new HashMap&lt;&gt;();
			modelValues.put("toUserId", Long.toString(_recUserId));
			modelValues.put("subject", _recSubject);
			modelValues.put("_threadId", Long.toString(_recThreadId));

		Map<string, object> data = new HashMap&lt;&gt;();
			data.put("modelValues", modelValues);

		_screenlet.onDDLFormRecordLoaded(record, data);

/*
		if ((record != null) &amp;&amp; !_recSetDef) {
			_recSetDef = true;

			// set default reply data

			Map<string, object> data = new HashMap<string, object>();
				data.put("toUserId", Long.toString(_recUserId));
				data.put("subject", _recSubject);
				data.put("_threadId", Long.toString(_recThreadId));

			record.setValues(data);

			_screenlet.setRecord(record);
		}
*/
	}
</string,></string,></string,></string,>


Could you please be more specific about the necessary coding?


*** quoting ***

Javier Gamarra:
We are inheriting part of the structure of the data in the portal, so you should write something like this:


@Override
	public void onDDLFormLoaded(Record record) {
		loaded = true;

		Map<string, object> data = new HashMap&lt;&gt;();
		Map<string, object> modelValues = new HashMap&lt;&gt;();
		data.put("modelValues", modelValues);
		modelValues.put("TextBoxeuwq", "1");
		screenlet.onDDLFormRecordLoaded(record, data);

		info("Form loaded!");
	}
</string,></string,>


The data for the record is stored in the "modelValues" key.

If you don't mind coupling with the UI (you should) you could also fill the values retrieving the fields directly with findViewById / Children.
thumbnail
7年前 に Javier Gamarra によって更新されました。

RE: Populate DDLFormScreenlet fields programmatically

Expert 投稿: 348 参加年月日: 15/02/12 最新の投稿
Sorry, I forgot you are on 1.4 or master... it should be something like this:


Map<string, object> values = new HashMap&lt;&gt;();
		values.put("Title", "TESTING");
		record.setValues(values);
		_screenlet.onDDLFormRecordLoaded(record);
</string,>
thumbnail
7年前 に Arne Leeman によって更新されました。

RE: Populate DDLFormScreenlet fields programmatically

Junior Member 投稿: 29 参加年月日: 11/02/24 最新の投稿
Hi Javier,

Had to devote my time to other matters but picked up yesterday where I left off.

Your code (below) does have the effect that the form is (pre)set with the desired values.
However, submitting the form generates the following exception:


10-15 11:29:24.773 30157-30157/com.liferay.mobile.screens.testapp E/MessagesReplyActivity: onDDLFormRecordAddFailed
com.liferay.mobile.android.exception.ServerException: Expected a ',' or '}' at character 50
       at com.liferay.mobile.android.http.Response.checkPortalException(Response.java:98)
       at com.liferay.mobile.android.http.Response.getBody(Response.java:49)
       at com.liferay.mobile.android.callback.BaseCallback.inBackground(BaseCallback.java:56)
       at com.liferay.mobile.android.http.client.OkHttpClientImpl$1.onResponse(OkHttpClientImpl.java:192)
       at com.squareup.okhttp.Call$AsyncCall.execute(Call.java:170)
       at com.squareup.okhttp.internal.NamedRunnable.run(NamedRunnable.java:33)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
       at java.lang.Thread.run(Thread.java:856)


This is my code:


	@Override
	public void onDDLFormLoaded(Record record)  {
		_loaded = true;

		if (record != null)  {

			// set default reply values

			Map<string, object> values = new HashMap<string, object>();
				values.put("toUserId", Long.toString(_recUserId));
				values.put("subject", _recSubject);
				values.put("_threadId", Long.toString(_recThreadId));

			record.setValues(values);

			_screenlet.onDDLFormRecordLoaded(record);
		}
	}

	@Override
	public void onDDLFormRecordLoaded(Record record)  {
		// do nothing
	}
</string,></string,>


I tried to follow the trace to pinpoint the cause but got lost..

Any suggestions how to fix this?

Best,
Arne


Javier Gamarra:
Sorry, I forgot you are on 1.4 or master... it should be something like this:


Map<string, object> values = new HashMap&lt;&gt;();
		values.put("Title", "TESTING");
		record.setValues(values);
		_screenlet.onDDLFormRecordLoaded(record);
</string,>
thumbnail
7年前 に Arne Leeman によって更新されました。

RE: Populate DDLFormScreenlet fields programmatically

Junior Member 投稿: 29 参加年月日: 11/02/24 最新の投稿
Well, I tried the second suggested method of accessing EditText views directly as well:


		ViewGroup container = (ViewGroup) findViewById(R.id.ddlfields_container);

		DDLFieldTextView subject = (DDLFieldTextView) container.getChildAt(1);
		EditText ev = (EditText) subject.getChildAt(1);
		ev.setText(_recSubject);


Again, the value appears correctly in the form but on submit I get the same exception mentioned earlier about stuff missing in the json object sent to the server. If I enter the (same) value manually in the form, everything runs allright!

So, presetting field values in a form this way apparently is a nono, at least to my knowledge..

Anyone else has a suggestion how to solve this?

Would it be feasible to somehow alter a predefined field value in the used ddm structure when the form is loaded?
thumbnail
7年前 に Javier Gamarra によって更新されました。

RE: Populate DDLFormScreenlet fields programmatically

Expert 投稿: 348 参加年月日: 15/02/12 最新の投稿
Uhm... I've tried my code against Liferay 6.2 with a 1.3.0 plugin and using the latest released version of screens (1.4.1) and it works when submitting the field...

What are the fields you are setting? are you trying to change an internal field of the record or just to preset some fields?

Can you check or pass me the json sent to the server? You can add a debug breakpoint in the line:


_command.put("/ddlrecord/add-record", _params);


of the class DDLRecordService (for 6.2) ?
thumbnail
7年前 に Arne Leeman によって更新されました。

RE: Populate DDLFormScreenlet fields programmatically

Junior Member 投稿: 29 参加年月日: 11/02/24 最新の投稿
Hi Javier,

I use the same setup, that is: Liferay 6.2 (GA2), 1.3.0 plugin and 1.4.1 version of screens.

I just want to preset some fields, no internal record fields like recordId and such.
I'm trying to run the debug test but haven't managed to do it yet.

For reference I enclose the android project.
If anyone can use it, or parts of it, please enjoy..

Arne.

添付ファイル:

thumbnail
7年前 に Arne Leeman によって更新されました。

RE: Populate DDLFormScreenlet fields programmatically

Junior Member 投稿: 29 参加年月日: 11/02/24 最新の投稿
Hi Javier,

I'm sorry to say that I can't get it done, intercepting the Json object sent to the server.

The obvious thing to do for me would be to log the json object in DDLRecordConnector62.java.
I just don't know how to do this. Can you give me some more pointers?

Thanks,
Arne
thumbnail
7年前 に Arne Leeman によって更新されました。

RE: Populate DDLFormScreenlet fields programmatically (回答)

Junior Member 投稿: 29 参加年月日: 11/02/24 最新の投稿
Utimately solved it by:

1. Setting the app fixed to en_US
2. taking care that values for preset fields do not contain ANY special characters (even : =/ etc.) as these somehow break the json.

For those interested I enclose the app code to enjoy..

Cheers,
Arne

添付ファイル:

thumbnail
7年前 に Javier Gamarra によって更新されました。

RE: Populate DDLFormScreenlet fields programmatically

Expert 投稿: 348 参加年月日: 15/02/12 最新の投稿
Thank you for your persistence!

We will take into account that problem for the next versions emoticon