diff --git a/Android/doric/src/main/java/pub/doric/plugin/ModalPlugin.java b/Android/doric/src/main/java/pub/doric/plugin/ModalPlugin.java index 1dcb3d37..f18e86d7 100644 --- a/Android/doric/src/main/java/pub/doric/plugin/ModalPlugin.java +++ b/Android/doric/src/main/java/pub/doric/plugin/ModalPlugin.java @@ -19,6 +19,10 @@ import android.app.AlertDialog; import android.content.DialogInterface; import android.text.TextUtils; import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.EditText; +import android.widget.TextView; import android.widget.Toast; import pub.doric.DoricContext; @@ -119,7 +123,7 @@ public class ModalPlugin extends DoricJavaPlugin { JSValue okBtn = jsObject.getProperty("okLabel"); JSValue cancelBtn = jsObject.getProperty("cancelLabel"); - AlertDialog.Builder builder = new AlertDialog.Builder(getDoricContext().getContext(), R.style.Theme_Doric_Modal_Alert); + AlertDialog.Builder builder = new AlertDialog.Builder(getDoricContext().getContext(), R.style.Theme_Doric_Modal_Confirm); if (titleVal.isString()) { builder.setTitle(titleVal.asString().value()); } @@ -155,4 +159,69 @@ public class ModalPlugin extends DoricJavaPlugin { promise.reject(new JavaValue(e.getLocalizedMessage())); } } + + + @DoricMethod(name = "prompt", thread = ThreadMode.UI) + public void prompt(JSDecoder decoder, final DoricPromise promise) { + try { + JSObject jsObject = decoder.decode().asObject(); + JSValue titleVal = jsObject.getProperty("title"); + JSValue msgVal = jsObject.getProperty("msg"); + JSValue okBtn = jsObject.getProperty("okLabel"); + JSValue cancelBtn = jsObject.getProperty("cancelLabel"); + JSValue defaultVal = jsObject.getProperty("defaultText"); + JSValue text = jsObject.getProperty("text"); + + AlertDialog.Builder builder = new AlertDialog.Builder(getDoricContext().getContext(), R.style.Theme_Doric_Modal_Prompt); + if (titleVal.isString()) { + builder.setTitle(titleVal.asString().value()); + } + String okLabel = getDoricContext().getContext().getString(android.R.string.ok); + if (okBtn.isString()) { + okLabel = okBtn.asString().value(); + } + String cancelLabel = getDoricContext().getContext().getString(android.R.string.cancel); + if (cancelBtn.isString()) { + cancelLabel = cancelBtn.asString().value(); + } + + + View v = LayoutInflater.from(getDoricContext().getContext()).inflate(R.layout.doric_modal_prompt, null); + TextView tvMsg = v.findViewById(R.id.tv_msg); + tvMsg.setText(msgVal.asString().value()); + final EditText editText = v.findViewById(R.id.edit_input); + if (defaultVal.isString()) { + editText.setHint(defaultVal.asString().value()); + } + if (text.isString()) { + editText.setText(text.asString().value()); + editText.setSelection(text.asString().value().length()); + } + builder.setView(v); + builder + .setPositiveButton(okLabel, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + promise.resolve(new JavaValue(editText.getText().toString())); + } + }) + .setNegativeButton(cancelLabel, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + promise.reject(new JavaValue(editText.getText().toString())); + } + }); + builder.setCancelable(false); + try { + builder.show(); + } catch (Exception e) { + e.printStackTrace(); + } + } catch (ArchiveException e) { + e.printStackTrace(); + promise.reject(new JavaValue(e.getLocalizedMessage())); + } + + + } } diff --git a/Android/doric/src/main/res/layout/doric_modal_prompt.xml b/Android/doric/src/main/res/layout/doric_modal_prompt.xml new file mode 100644 index 00000000..1e0c88f0 --- /dev/null +++ b/Android/doric/src/main/res/layout/doric_modal_prompt.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/demo/src/ModalDemo.ts b/demo/src/ModalDemo.ts index f896c2cc..9fccd7e6 100644 --- a/demo/src/ModalDemo.ts +++ b/demo/src/ModalDemo.ts @@ -100,14 +100,45 @@ class ModalDemo extends Panel { okLabel: "OkLabel", cancelLabel: 'CancelLabel', }).then( - e => { + () => { modal(context).toast('Clicked OK.') }, - e => { + () => { modal(context).toast('Clicked Cancel.') }) } } as IText), + text({ + text: "Prompt", + layoutConfig: layoutConfig().w(LayoutSpec.AT_MOST), + textSize: 30, + textColor: Color.WHITE, + bgColor: colors[4], + textAlignment: Gravity.Center, + height: 50, + }), + label('Click me').apply({ + width: 200, + height: 50, + bgColor: colors[0], + textSize: 30, + textColor: Color.WHITE, + layoutConfig: layoutConfig().exactly(), + onClick: () => { + modal(context).prompt({ + msg: 'This is Prompt.', + title: 'Prompt title', + okLabel: "OkLabel", + cancelLabel: 'CancelLabel', + }).then( + e => { + modal(context).toast(`Clicked OK.Input:${e}`) + }, + e => { + modal(context).toast(`Clicked Cancel.Input:${e}`) + }) + } + } as IText), ]).apply({ layoutConfig: layoutConfig().atmost().h(LayoutSpec.WRAP_CONTENT), gravity: Gravity.Center, diff --git a/iOS/Pod/Classes/Plugin/DoricModalPlugin.m b/iOS/Pod/Classes/Plugin/DoricModalPlugin.m index 38b71192..e9925e34 100644 --- a/iOS/Pod/Classes/Plugin/DoricModalPlugin.m +++ b/iOS/Pod/Classes/Plugin/DoricModalPlugin.m @@ -74,4 +74,42 @@ - (void)confirm:(NSDictionary *)dic withPromise:(DoricPromise *)promise { [vc presentViewController:alert animated:YES completion:nil]; }); } + +- (void)prompt:(NSDictionary *)dic withPromise:(DoricPromise *)promise { + dispatch_async(dispatch_get_main_queue(), ^{ + UIAlertController *alert = [UIAlertController alertControllerWithTitle:dic[@"title"] + message:dic[@"msg"] + preferredStyle:UIAlertControllerStyleAlert]; + NSString *placeholder = dic[@"defaultText"]; + NSString *preText = dic[@"text"]; + [alert addTextFieldWithConfigurationHandler:^(UITextField *_Nonnull textField) { + if (placeholder.length > 0) { + textField.placeholder = placeholder; + } + if (preText.length > 0) { + textField.text = preText; + } + }]; + __weak typeof(alert) _alert = alert; + UIAlertAction *okAction = [UIAlertAction actionWithTitle:dic[@"okLabel"] ?: NSLocalizedString(@"Ok", nil) + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action) { + __strong typeof(_alert) alert = _alert; + [promise resolve:alert.textFields.lastObject.text]; + }]; + [alert addAction:okAction]; + + UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:dic[@"cancelLabel"] ?: NSLocalizedString(@"Cancel", nil) + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action) { + __strong typeof(_alert) alert = _alert; + [promise reject:alert.textFields.lastObject.text]; + }]; + [alert addAction:cancelAction]; + + + UIViewController *vc = [UIApplication sharedApplication].keyWindow.rootViewController; + [vc presentViewController:alert animated:YES completion:nil]; + }); +} @end diff --git a/js-framework/src/util/modal.ts b/js-framework/src/util/modal.ts index 5f740c89..ec27dfdd 100644 --- a/js-framework/src/util/modal.ts +++ b/js-framework/src/util/modal.ts @@ -47,5 +47,15 @@ export function modal(context: BridgeContext) { return context.modal.confirm(arg) } }, + prompt: (arg: { + title?: string, + msg?: string, + okLabel?: string, + cancelLabel?: string, + text?: string, + defaultText?: string, + }) => { + return context.modal.prompt(arg) + }, } } \ No newline at end of file