From e322f11defd133f4e85cd80ef5f2d9131d6877e0 Mon Sep 17 00:00:00 2001 From: Damyan Ivanov Date: Sun, 20 Jan 2019 17:16:45 +0000 Subject: [PATCH] profile details: validation on save --- .../ui/profiles/ProfileDetailFragment.java | 71 ++++++++++++++++++- app/src/main/res/layout/profile_detail.xml | 14 ++-- app/src/main/res/values/strings.xml | 4 ++ 3 files changed, 82 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/profiles/ProfileDetailFragment.java b/app/src/main/java/net/ktnx/mobileledger/ui/profiles/ProfileDetailFragment.java index d7b740e7..004763a7 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/profiles/ProfileDetailFragment.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/profiles/ProfileDetailFragment.java @@ -23,7 +23,10 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.design.widget.CollapsingToolbarLayout; import android.support.design.widget.FloatingActionButton; +import android.support.design.widget.TextInputLayout; import android.support.v4.app.Fragment; +import android.text.Editable; +import android.text.TextWatcher; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; @@ -58,12 +61,16 @@ public class ProfileDetailFragment extends Fragment { */ private MobileLedgerProfile mProfile; private TextView url; + private TextInputLayout urlLayout; private LinearLayout authParams; private Switch useAuthentication; private TextView userName; + private TextInputLayout userNameLayout; private TextView password; - private FloatingActionButton fab; + private TextInputLayout passwordLayout; private TextView profileName; + private TextInputLayout profileNameLayout; + private FloatingActionButton fab; /** * Mandatory empty constructor for the fragment manager to instantiate the @@ -114,6 +121,8 @@ public class ProfileDetailFragment extends Fragment { fab = context.findViewById(R.id.fab); fab.setOnClickListener(v -> { + if (!checkValidity()) return; + if (mProfile != null) { mProfile.setName(profileName.getText()); mProfile.setUrl(url.getText()); @@ -141,6 +150,8 @@ public class ProfileDetailFragment extends Fragment { Activity activity = getActivity(); if (activity != null) activity.finish(); }); + + profileName.requestFocus(); } @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, @@ -148,11 +159,15 @@ public class ProfileDetailFragment extends Fragment { View rootView = inflater.inflate(R.layout.profile_detail, container, false); profileName = rootView.findViewById(R.id.profile_name); + profileNameLayout = rootView.findViewById(R.id.profile_name_layout); url = rootView.findViewById(R.id.url); + urlLayout = rootView.findViewById(R.id.url_layout); authParams = rootView.findViewById(R.id.auth_params); useAuthentication = rootView.findViewById(R.id.enable_http_auth); userName = rootView.findViewById(R.id.auth_user_name); + userNameLayout = rootView.findViewById(R.id.auth_user_name_layout); password = rootView.findViewById(R.id.password); + passwordLayout = rootView.findViewById(R.id.password_layout); useAuthentication.setOnCheckedChangeListener((buttonView, isChecked) -> { Log.d("profiles", isChecked ? "auth enabled " : "auth disabled"); @@ -160,6 +175,11 @@ public class ProfileDetailFragment extends Fragment { if (isChecked) userName.requestFocus(); }); + hookClearErrorOnFocusListener(profileName, profileNameLayout); + hookClearErrorOnFocusListener(url, urlLayout); + hookClearErrorOnFocusListener(userName, userNameLayout); + hookClearErrorOnFocusListener(password, passwordLayout); + if (mProfile != null) { profileName.setText(mProfile.getName()); url.setText(mProfile.getUrl()); @@ -179,4 +199,53 @@ public class ProfileDetailFragment extends Fragment { return rootView; } + private void hookClearErrorOnFocusListener(TextView view, TextInputLayout layout) { + view.setOnFocusChangeListener((v, hasFocus) -> { + if (hasFocus) layout.setError(null); + }); + view.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + layout.setError(null); + } + @Override + public void afterTextChanged(Editable s) { + } + }); + } + boolean checkValidity() { + boolean valid = true; + + String val = String.valueOf(profileName.getText()); + if (val.trim().isEmpty()) { + valid = false; + profileNameLayout.setError(getResources().getText(R.string.err_profile_name_empty)); + } + + val = String.valueOf(url.getText()); + if (val.trim().isEmpty()) { + valid = false; + urlLayout.setError(getResources().getText(R.string.err_profile_url_empty)); + } + if (useAuthentication.isChecked()) { + val = String.valueOf(userName.getText()); + if (val.trim().isEmpty()) { + valid = false; + userNameLayout + .setError(getResources().getText(R.string.err_profile_user_name_empty)); + } + + val = String.valueOf(password.getText()); + if (val.trim().isEmpty()) { + valid = false; + passwordLayout + .setError(getResources().getText(R.string.err_profile_password_empty)); + } + } + + return valid; + } } diff --git a/app/src/main/res/layout/profile_detail.xml b/app/src/main/res/layout/profile_detail.xml index dfecf9d7..cab0eb66 100644 --- a/app/src/main/res/layout/profile_detail.xml +++ b/app/src/main/res/layout/profile_detail.xml @@ -27,6 +27,7 @@ tools:context=".ui.profiles.ProfileDetailFragment"> @@ -36,12 +37,11 @@ android:layout_height="wrap_content" android:ems="10" android:hint="@string/profile_name_label" - android:inputType="textPersonName" - android:text="Name" - tools:ignore="HardcodedText" /> + android:inputType="textPersonName" /> + android:paddingStart="8dp" + tools:ignore="RtlSymmetry"> + android:inputType="textPersonName" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 492bc605..d894ffae 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -113,6 +113,10 @@ Welcome A profile for connecting to the backend hledger-web instance needs to be created first Create profile + Profile name cannot be empty + Please enter backend URL, e.g. https://server/location + User name is required when authentication is switched on + Password is mandatory January February -- 2.39.2