0

I am new to RxSwift and RxCocoa and I'm learning it.

I want to validate all textfield on button click and based on the validation I need to show alert message to user.

After validation is successful I need to insert record in table.

Refer the following code...

var result = txtFname.rx.text
    result.asObservable().subscribe(onNext: { text in
        if text!.isEmpty {
            self.showAlert(msg: "Plese enter first name.")
            self.txtFname.becomeFirstResponder()
        }
    }).disposed(by: disposeBag)

    result = txtLname.rx.text
    result.asObservable().subscribe(onNext: { text in
        if text!.isEmpty {
            self.showAlert(msg: "Please enter last name.")
            self.txtLname.becomeFirstResponder()
        }
    }).disposed(by: disposeBag)

    result = txtEmail.rx.text
    result.asObservable().subscribe(onNext: { text in

        if text!.isEmpty {
            self.showAlert(msg: "Please enter email id.")
            self.txtLname.becomeFirstResponder()
        }
    }).disposed(by: disposeBag)

   //need to check here if all fields are valid or not 
   //if all fields are valid then insert record....

When I press a button and it check all the validation at one and show alert...

But I want to do like if one validation is fail then it should not go further until previous validation is successful...

I don't know how to achieve this. Any help will be appreciated.

Mahendra
  • 8,448
  • 3
  • 33
  • 56
  • 1
    see this once may be it helps you https://stackoverflow.com/questions/42860384/rx-swift-complex-textfields-validation – Anbu.Karthik Mar 29 '18 at 10:06
  • Already seen this, this is not what I wanted to do...it actually disable a button based on result....and I don't want to do so....I want button will be enabled always and on button click I want to check validation. – Mahendra Mar 29 '18 at 10:08

3 Answers3

5

You could do something like this.

  self.button.rx.tap.asObservable()
     .filter({ (_) -> Bool in
        guard !(self.txtFname.text ?? "").isEmpty else {
           self.showAlert(msg: "Please enter first name.")
           self.txtFname.becomeFirstResponder()
           return false
        }

        guard !(self.txtLname.text ?? "").isEmpty else {
           self.showAlert(msg: "Please enter last name.")
           self.txtLname.becomeFirstResponder()
           return false
        }

        guard !(self.txtEmail.text ?? "").isEmpty else {
           self.showAlert(msg: "Please enter email id.")
           self.txtEmail.becomeFirstResponder()
           return false
        }

        return true
     })
     .subscribe { _ in
        // do something when all the fields are valid
        self.showAlert(msg: "All fields are valid")
     }
     .disposed(by: disposeBag)
1

It's not exactly the same answer but you can achieve something like this.

      class DataValidator {
            class func validName(name:String) -> Bool {
            if let regex =
            try? NSRegularExpression(pattern: "^\\w+( \\w+\\.?)*$", options:
            .CaseInsensitive) {
            return name.lengthOfBytesUsingEncoding(NSUTF8StringEncoding) > 2 &&
            regex!.matchesInString(name, options: NSMatchingOptions.ReportProgress, range: NSMakeRange(0,
            name.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))).count > 0 }
            return false }

            class func validEmail(email:String) -> Bool{ if let regex =
            try? NSRegularExpression(pattern: "^\\S+@\\S+\\.\\S+$", options: .CaseInsensitive){
            return regex!.matchesInString(email, options: NSMatchingOptions.ReportProgress, range: NSMakeRange(0,
            email.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))).count > 0 }
        return false }
 }

}// end of validator class

You can use something like below:

let nameSignal:RACSignal = nameTextField.rac_textSignal().map { (text) -> AnyObject! in
return DataValidator.validName(text as! String) }
let emailSignal = emailTextField.rac_textSignal().map { (text) -> AnyObject! in
return DataValidator.validEmail(text as! String) }

RACSignal.combineLatest([nameSignal, emailSignal]).subscribeNext { (valid) -> Void in
   self.button.enabled = valid as! Bool
}
Sanoj Kashyap
  • 5,020
  • 4
  • 49
  • 75
0
class Validator {

    class func validEmail(email:String) -> Bool {
        if let regex = try? NSRegularExpression(pattern: "^\\S+@\\S+\\.\\S+$", options: .caseInsensitive){
        return regex.matches(in: email, options: NSRegularExpression.MatchingOptions.reportProgress, range: NSMakeRange(0,                                                                                                                        email.lengthOfBytes(using: String.Encoding.utf8))).count > 0 }
        return false
    }
}

Then you can use it as follows:

var isValid : Observable<Bool>{
    return Observable.combineLatest(username.asObservable())
    { (username) in
        return Validator.validEmail(email: username)
    }
}
Aayushi
  • 787
  • 10
  • 14