This is standard register view which shows data collected so far for each beneficary. The register view is designed such that it replicates the paper registers field workers are comfortable with. This view is the one which opens up right after clicking on Register on Home.
To build a main datagrid for your register you need to
- Create an Activity extending SmartRegisterSecuredActivity that holds up the main view, forms, and details fragments for register like this.
- Create a BaseFragment extending SecuredNativeSmartRegisterFragment that renders the beneficairy records in listview and manages paging and data entry forms as here
- Create a DetailFragment extending DetailFragment that shows all details associated with beneficiary like this. This is explained in details here.
1- Create Register Activity
The first step to register building is creating an activity that manages fragments, forms, details, and navigation. As mentioned above implement SmartRegisterSecuredActivity .
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
public class MyRegisterActivity extends SmartRegisterSecuredActivity {
@Override
public SecuredNativeSmartRegisterFragment makeBaseFragment() {
// Return a fragment which generates the list view i.e. main grid fragment. Example is given below
return new MyMainRegisterFragment(new FormController(this));
}
@Override
public DetailFragment getDetailFragment() {
// Fragment handling details view for list records. Example would be in section Details view
// Or return null if no details view is applicable
return new MyDetailFragment();
}
@Override
protected String[] buildFormNameList() {
// Return a list of form names which would participate in data collection from this register.
// These froms are added to assets and generated via xlsforms
List<String> formNames = new ArrayList<String>();
formNames.add("my_form1");
formNames.add("my_form2");
formNames.add("my_form3");
return formNames.toArray(new String[formNames.size()]);
}
@Override
public String postFormSubmissionRecordFilterField() {
// The field which filters out data on successful form submission to highlight the new/updated record.
// The field should be a valid non-null field in your xlsform and should identify record uniquely, otherwise multiple records would be highlighted
// Return null if no data needs to be highlighted
return "my_beneficiary_id_in_form_submission";
}
@Override
protected void onResumption() {
// Any custom tasks on Resumption of activity
}
} |
2- Create Base Fragment
Once you have created register activity, next step is to create the fragment that is actually reponsible for showing list records i.e. main grid. The example is here.
As shown above there are different parts of Main grid which can be controlled by implementing SecuredNativeSmartRegisterFragment. TBD explain each in details
- Register Label
- Sort Option
- Filter Option
- Service Mode
- Client Action Handler
- Search Filter Option
- Search Type
- Default Options
- Navigation Options
- Custom Form Handler
- New Record Button
- Adapter
- Client Provider
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
public class MyRegisterFragment extends SecuredNativeSmartRegisterFragment {
private final ClientActionHandler clientActionHandler = new ClientActionHandler();
public MyRegisterFragment() {
super(null);
}
@SuppressLint("ValidFragment")
public MyRegisterFragment(FormController formController) {
super(formController);
}
// Default settings for Sort, Main Filter, Location, Service Mode, Search Filter and Search Type
@Override
protected SecuredNativeSmartRegisterActivity.DefaultOptionsProvider getDefaultOptionsProvider() {
return new SecuredNativeSmartRegisterActivity.DefaultOptionsProvider() {
@Override
public SearchFilterOption searchFilterOption() {
return new MySearchOption("");
}
@Override
public ServiceModeOption serviceMode() {
return new MyServiceModeOption(null, "My Service Mode Label",
new int[]{/* Resource ids for each header */ R.id.column1, R.id.column2, /*.....*/},
// Weight for each header. Should balance the weights of columns defined in client_record_layout.xml
new int[]{6,2,3,2,1});
}
@Override
public FilterOption villageFilter() {
return new CursorCommonObjectFilterOption("no village filter", "");
}
@Override
public SortOption sortOption() {
return new CursorCommonObjectSort(getResources().getString(R.string.alphabetical_sort_text), "sort_column DESC");
}
@Override
public String nameInShortFormForTitle() {
return Context.getInstance().getStringResource(R.string.my_register_title);
}
@Override
public SecuredNativeSmartRegisterActivity.SearchType searchType() {
return SecuredNativeSmartRegisterActivity.SearchType.PASSIVE;
}
};
}
@Override
protected SecuredNativeSmartRegisterActivity.NavBarOptionsProvider getNavBarOptionsProvider() {
return new SecuredNativeSmartRegisterActivity.NavBarOptionsProvider() {
@Override
public DialogOption[] filterOptions() {
return new DialogOption[]{};
}
@Override
public DialogOption[] serviceModeOptions() {
return new DialogOption[]{};
}
@Override
public DialogOption[] sortingOptions() {
return new DialogOption[]{
new CursorCommonObjectSort(getResources().getString(R.string.sort_type1), "my_column1 ASC"),
new CursorCommonObjectSort(getResources().getString(R.string.sort_type2), "my_column2 DESC"),
new CursorCommonObjectSort(getResources().getString(R.string.sort_dob_age), "my_dob_column DESC")
};
}
@Override
public String searchHint() {
return Context.getInstance().getStringResource(R.string.text_to_display_searchbox);
}
};
}
@Override
protected void onInitialization(){
// A handler where form submission would be routed for further processing after successful save
context.formSubmissionRouter().getHandlerMap().put("my_form1", new MyCustomForm1Handler(getActivity()));
}
@Override
protected void onCreation() {
// Custom tasks after fragment creation
}
// What app should do on click of New Record Button. It can launch QR Code activity or can also open a form directly
@Override
protected void startRegistration() {
// Any fields in form needs to be overriden.. A usecase could be load data from DB and send to form
Map<String, String> overrides = new HashMap<>();
overrides.put("my_form_field1", "abc");
startForm("my_form1", "", overrides);
}
@Override
protected SmartRegisterPaginatedAdapter adapter() {
// Setup the adapter to setup data. Here it is using CursorAdapter
return new SmartRegisterPaginatedCursorAdapter(getActivity(),
new SmartRegisterCursorBuilder("mybindType", null, "T", null,
(CursorSortOption) getDefaultOptionsProvider().sortOption(), "").limit(5), c
clientsProvider(), SmartRegisterCursorBuilder.DB.DRISHTI);
}
@Override
protected SmartRegisterClientsProvider clientsProvider() {
return new MySmartClientsProvider(getActivity(), clientActionHandler, context.alertService());
}
// Client interaction handler. A class that handles any clicks or taps on data row's different sections or layouts
private class ClientActionHandler implements View.OnClickListener {
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.column1_layout:
// open details fragment
((SmartRegisterSecuredActivity)getActivity()).showDetailFragment((CommonPersonObjectClient) view.getTag(), false);
break;
case R.id.column2_button_followup:
// do something else i.e. open another form or open a dialogue etc
break;
}
}
}
} |