Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make saveCurrentDocument and setFormFieldValue return a promise #308

Merged
merged 2 commits into from
Oct 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions android/src/main/java/com/pspdfkit/react/ReactPdfViewManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,15 @@ public void receiveCommand(final PdfView root, int commandId, @Nullable Readable
root.exitCurrentlyActiveMode();
break;
case COMMAND_SAVE_CURRENT_DOCUMENT:
root.saveCurrentDocument();
if (args != null) {
final int requestId = args.getInt(0);
try {
boolean result = root.saveCurrentDocument();
root.getEventDispatcher().dispatchEvent(new PdfViewDataReturnedEvent(root.getId(), requestId, result));
} catch (Exception e) {
root.getEventDispatcher().dispatchEvent(new PdfViewDataReturnedEvent(root.getId(), requestId, e));
}
}
break;
case COMMAND_GET_ANNOTATIONS:
if (args != null) {
Expand Down Expand Up @@ -241,8 +249,20 @@ public void accept(JSONObject jsonObject) {
}
break;
case COMMAND_SET_FORM_FIELD_VALUE:
if (args != null && args.size() == 2) {
annotationDisposables.add(root.setFormFieldValue(args.getString(0), args.getString(1)));
if (args != null && args.size() == 3) {
final int requestId = args.getInt(0);
Disposable annotationDisposable = root.setFormFieldValue(args.getString(1), args.getString(2))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(fieldSet -> {
root.getEventDispatcher().dispatchEvent(new PdfViewDataReturnedEvent(root.getId(), requestId, fieldSet));
}, throwable -> {
root.getEventDispatcher().dispatchEvent(new PdfViewDataReturnedEvent(root.getId(), requestId, throwable));
},() -> {
// Called when no form field was found.
root.getEventDispatcher().dispatchEvent(new PdfViewDataReturnedEvent(root.getId(), requestId, false));
});
annotationDisposables.add(annotationDisposable);
}
break;
}
Expand Down
77 changes: 41 additions & 36 deletions android/src/main/java/com/pspdfkit/views/PdfView.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
import java.util.concurrent.Callable;

import io.reactivex.Completable;
import io.reactivex.Maybe;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.Single;
Expand Down Expand Up @@ -446,17 +447,21 @@ public void accept(PdfFragment pdfFragment) {
}));
}

public void saveCurrentDocument() {
public boolean saveCurrentDocument() throws Exception {
if (fragment != null) {
try {
if (document.saveIfModified()) {
// Since the document listeners won't be called when manually saving we also dispatch this event here.
eventDispatcher.dispatchEvent(new PdfViewDocumentSavedEvent(getId()));
return true;
}
return false;
} catch (Exception e) {
eventDispatcher.dispatchEvent(new PdfViewDocumentSaveFailedEvent(getId(), e.getMessage()));
throw e;
}
}
return false;
}

public Single<List<Annotation>> getAnnotations(final int pageIndex, @Nullable final String type) {
Expand Down Expand Up @@ -658,49 +663,49 @@ public void run() {

}

public Disposable setFormFieldValue(@NonNull String formElementName, @NonNull final String value) {
public Maybe<Boolean> setFormFieldValue(@NonNull String formElementName, @NonNull final String value) {
return document.getFormProvider().getFormElementWithNameAsync(formElementName)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<FormElement>() {

@Override
public void accept(FormElement formElement) {
if (formElement instanceof TextFormElement) {
TextFormElement textFormElement = (TextFormElement) formElement;
textFormElement.setText(value);
} else if (formElement instanceof EditableButtonFormElement) {
EditableButtonFormElement editableButtonFormElement = (EditableButtonFormElement) formElement;
if (value.equalsIgnoreCase("selected")) {
editableButtonFormElement.select();
} else if (value.equalsIgnoreCase("deselected")) {
editableButtonFormElement.deselect();
}
} else if (formElement instanceof ChoiceFormElement) {
ChoiceFormElement choiceFormElement = (ChoiceFormElement) formElement;
.map(formElement -> {
if (formElement instanceof TextFormElement) {
TextFormElement textFormElement = (TextFormElement) formElement;
textFormElement.setText(value);
return true;
} else if (formElement instanceof EditableButtonFormElement) {
EditableButtonFormElement editableButtonFormElement = (EditableButtonFormElement) formElement;
if (value.equalsIgnoreCase("selected")) {
editableButtonFormElement.select();
} else if (value.equalsIgnoreCase("deselected")) {
editableButtonFormElement.deselect();
}
return true;
} else if (formElement instanceof ChoiceFormElement) {
ChoiceFormElement choiceFormElement = (ChoiceFormElement) formElement;
try {
int selectedIndex = Integer.parseInt(value);
List<Integer> selectedIndices = new ArrayList<>();
selectedIndices.add(selectedIndex);
choiceFormElement.setSelectedIndexes(selectedIndices);
return true;
} catch (NumberFormatException e) {
try {
int selectedIndex = Integer.parseInt(value);
// Maybe it's multiple indices.
JSONArray indices = new JSONArray(value);
List<Integer> selectedIndices = new ArrayList<>();
selectedIndices.add(selectedIndex);
for (int i = 0; i < indices.length(); i++) {
selectedIndices.add(indices.getInt(i));
}
choiceFormElement.setSelectedIndexes(selectedIndices);
} catch (NumberFormatException e) {
try {
// Maybe it's multiple indices.
JSONArray indices = new JSONArray(value);
List<Integer> selectedIndices = new ArrayList<>();
for (int i = 0; i < indices.length(); i++) {
selectedIndices.add(indices.getInt(i));
}
choiceFormElement.setSelectedIndexes(selectedIndices);
} catch (JSONException ex) {
// This isn't an index maybe we can set a custom value on a combobox.
if (formElement instanceof ComboBoxFormElement) {
((ComboBoxFormElement) formElement).setCustomText(value);
}
return true;
} catch (JSONException ex) {
// This isn't an index maybe we can set a custom value on a combobox.
if (formElement instanceof ComboBoxFormElement) {
((ComboBoxFormElement) formElement).setCustomText(value);
return true;
}
}
}
}
return false;
});
}
}
30 changes: 27 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,15 +131,27 @@ class PSPDFKitView extends React.Component {

/**
* Saves the currently opened document.
*
* Returns a promise resolving to true if the document was saved, and false otherwise.
*/
saveCurrentDocument = function() {
if (Platform.OS === "android") {
let requestId = this._nextRequestId++;
let requestMap = this._requestMap;

// We create a promise here that will be resolved once onDataReturned is called.
let promise = new Promise(function(resolve, reject) {
requestMap[requestId] = { resolve: resolve, reject: reject };
});

UIManager.dispatchViewManagerCommand(
findNodeHandle(this.refs.pdfView),
this._getViewManagerConfig("RCTPSPDFKitView").Commands
.saveCurrentDocument,
[]
[requestId]
);

return promise;
} else if (Platform.OS === "ios") {
return NativeModules.PSPDFKitViewManager.saveCurrentDocument(
findNodeHandle(this.refs.pdfView)
Expand Down Expand Up @@ -381,17 +393,29 @@ class PSPDFKitView extends React.Component {
*
* @param fullyQualifiedName The fully qualified name of the form element.
* @param value The string value form element. For button form elements pass 'selected' or 'deselected'. For choice form elements, pass the index of the choice to select, for example '1'.
*
* Returns a promise resolving to true if the value was set, and false otherwise.
*/
setFormFieldValue = function(fullyQualifiedName, value) {
if (Platform.OS === "android") {
let requestId = this._nextRequestId++;
let requestMap = this._requestMap;

// We create a promise here that will be resolved once onDataReturned is called.
let promise = new Promise(function(resolve, reject) {
requestMap[requestId] = { resolve: resolve, reject: reject };
});

UIManager.dispatchViewManagerCommand(
findNodeHandle(this.refs.pdfView),
this._getViewManagerConfig("RCTPSPDFKitView").Commands
.setFormFieldValue,
[fullyQualifiedName, value]
[requestId, fullyQualifiedName, value]
);

return promise;
} else if (Platform.OS === "ios") {
NativeModules.PSPDFKitViewManager.setFormFieldValue(
return NativeModules.PSPDFKitViewManager.setFormFieldValue(
value,
fullyQualifiedName,
findNodeHandle(this.refs.pdfView)
Expand Down
2 changes: 1 addition & 1 deletion ios/RCTPSPDFKit/RCTPSPDFKitView.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ NS_ASSUME_NONNULL_BEGIN

/// Forms
- (NSDictionary<NSString *, NSString *> *)getFormFieldValue:(NSString *)fullyQualifiedName;
- (void)setFormFieldValue:(NSString *)value fullyQualifiedName:(NSString *)fullyQualifiedName;
- (BOOL)setFormFieldValue:(NSString *)value fullyQualifiedName:(NSString *)fullyQualifiedName;

// Toolbar buttons customizations
- (void)setLeftBarButtonItems:(nullable NSArray <NSString *> *)items forViewMode:(nullable NSString *) viewMode animated:(BOOL)animated;
Expand Down
16 changes: 12 additions & 4 deletions ios/RCTPSPDFKit/RCTPSPDFKitView.m
Original file line number Diff line number Diff line change
Expand Up @@ -310,35 +310,43 @@ - (BOOL)addAnnotations:(id)jsonAnnotations error:(NSError *_Nullable *)error {
return @{@"error": @"Failed to get the form field value."};
}

- (void)setFormFieldValue:(NSString *)value fullyQualifiedName:(NSString *)fullyQualifiedName {
- (BOOL)setFormFieldValue:(NSString *)value fullyQualifiedName:(NSString *)fullyQualifiedName {
if (fullyQualifiedName.length == 0) {
NSLog(@"Invalid fully qualified name.");
return;
return NO;
}

PSPDFDocument *document = self.pdfController.document;
VALIDATE_DOCUMENT(document)

VALIDATE_DOCUMENT(document, NO)

BOOL success = NO;
for (PSPDFFormElement *formElement in document.formParser.forms) {
if ([formElement.fullyQualifiedFieldName isEqualToString:fullyQualifiedName]) {
if ([formElement isKindOfClass:PSPDFButtonFormElement.class]) {
if ([value isEqualToString:@"selected"]) {
[(PSPDFButtonFormElement *)formElement select];
success = YES;
} else if ([value isEqualToString:@"deselected"]) {
[(PSPDFButtonFormElement *)formElement deselect];
success = YES;
}
} else if ([formElement isKindOfClass:PSPDFChoiceFormElement.class]) {
((PSPDFChoiceFormElement *)formElement).selectedIndices = [NSIndexSet indexSetWithIndex:value.integerValue];
success = YES;
} else if ([formElement isKindOfClass:PSPDFTextFieldFormElement.class]) {
formElement.contents = value;
success = YES;
} else if ([formElement isKindOfClass:PSPDFSignatureFormElement.class]) {
NSLog(@"Signature form elements are not supported.");
success = NO;
} else {
NSLog(@"Unsupported form element.");
success = NO;
}
break;
}
}
return success;
}

#pragma mark - Notifications
Expand Down
9 changes: 7 additions & 2 deletions ios/RCTPSPDFKit/RCTPSPDFKitViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -233,10 +233,15 @@ @implementation RCTPSPDFKitViewManager
});
}

RCT_EXPORT_METHOD(setFormFieldValue:(nullable NSString *)value fullyQualifiedName:(NSString *)fullyQualifiedName reactTag:(nonnull NSNumber *)reactTag) {
RCT_EXPORT_METHOD(setFormFieldValue:(nullable NSString *)value fullyQualifiedName:(NSString *)fullyQualifiedName reactTag:(nonnull NSNumber *)reactTag resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
dispatch_async(dispatch_get_main_queue(), ^{
RCTPSPDFKitView *component = (RCTPSPDFKitView *)[self.bridge.uiManager viewForReactTag:reactTag];
[component setFormFieldValue:value fullyQualifiedName:fullyQualifiedName];
BOOL success = [component setFormFieldValue:value fullyQualifiedName:fullyQualifiedName];
if (success) {
resolve(@(success));
} else {
reject(@"error", @"Failed to set form field value.", nil);
}
});
}

Expand Down
42 changes: 24 additions & 18 deletions samples/Catalog/Catalog.android.js
Original file line number Diff line number Diff line change
Expand Up @@ -712,24 +712,30 @@ class PdfViewFormFillingScreen extends Component<{}> {
<Button
onPress={() => {
// Fill Text Form Fields.
this.refs.pdfView.setFormFieldValue("Name_Last", "Appleseed");
this.refs.pdfView.setFormFieldValue("Name_First", "John");
this.refs.pdfView.setFormFieldValue(
"Address_1",
"1 Infinite Loop"
);
this.refs.pdfView.setFormFieldValue("City", "Cupertino");
this.refs.pdfView.setFormFieldValue("STATE", "CA");
this.refs.pdfView.setFormFieldValue("SSN", "123456789");
this.refs.pdfView.setFormFieldValue(
"Telephone_Home",
"(123) 456-7890"
);
this.refs.pdfView.setFormFieldValue("Birthdate", "1/1/1983");

// Select a button form elements.
this.refs.pdfView.setFormFieldValue("Sex.0", "selected");
this.refs.pdfView.setFormFieldValue("PHD", "selected");
Promise.all(
this.refs.pdfView.setFormFieldValue("Name_Last", "Appleseed"),
this.refs.pdfView.setFormFieldValue("Name_First", "John"),
this.refs.pdfView.setFormFieldValue(
"Address_1",
"1 Infinite Loop"
),
this.refs.pdfView.setFormFieldValue("City", "Cupertino"),
this.refs.pdfView.setFormFieldValue("STATE", "CA"),
this.refs.pdfView.setFormFieldValue("SSN", "123456789"),
this.refs.pdfView.setFormFieldValue(
"Telephone_Home",
"(123) 456-7890"
),
this.refs.pdfView.setFormFieldValue("Birthdate", "1/1/1983"),

// Select a button form elements.
this.refs.pdfView.setFormFieldValue("Sex.0", "selected"),
this.refs.pdfView.setFormFieldValue("PHD", "selected")
).then(result => {
// Called when all form field values were set.
// If you want to fill forms then save the document this is the place to do it.
alert("All forms filled!");
});
}}
title="Fill Forms"
/>
Expand Down
Loading