Search code examples
swifteureka-forms

Adding a rule to a custom rule in Eureka


So I've created a custom row which is just a row with a simply UITextView now I want to create a rule such that if the UITextView has under 100 characters the variable row.isValid will evaluate to false.

<<< TextViewRow("About Me") {
    let cell = $0.baseCell as! TextViewCell
    cell.textView.text = currentUser.aboutMe
    $0.disabled = Condition.function([]) {
        form in
        print("in disabled")
        let section = form.sectionBy(tag: "About Me")
        let view = section!.header?.viewForSection(section!, type: .header) as! TitleHeaderView
        if view.isLocked {
            return true
        } else {
            return false
        }
    }
    $0.cellUpdate({ (cell, row) in
        if row.isDisabled {
            cell.textView.isUserInteractionEnabled = false
            cell.textView.textColor = UIColor.gray
        } else {
            cell.textView.isUserInteractionEnabled = true
            cell.textView.textColor = UIColor.black
        }
    })
    let ruleRequiredViaClosure = RuleClosure<String> { rowValue in
        guard let rowValue = rowValue else {
            return(ValidationError(msg : "Please write more!"))
        }
        let numberOfCharacters = rowValue.characters.count
        return (numberOfCharacters < 250 ? ValidationError(msg: "Please write more!") : nil)
    }
    $0.add(rule: ruleRequiredViaClosure)
    $0.validationOptions = .validatesOnDemand
}

With a normal TextRow this would compile and XCode won't throw any error, although since TextViewRow is a custom row I believe this is why it is throwing an error.

The error it gives me is that I need to use:

$0.add(ruleSet: ...)

but I can't find any documentation on it.

Also I'm not sure whether I am able to define my rule as I have since the rowValue in the closure probably isn't referencing anything. How would I fix this problem?


Solution

  • Welcome to the world of Eureka, %&*@ all documentation on anything. I recently took a liking to Eureka and began to convert my project to it, along the way I hit many obstacles that could easily have been avoided if the documentation was decent. Fortunately for you, custom validation rules was one such obstacle; my implementation is as follows:

    struct RulePassword<T: Equatable>:RuleType {
    
        public init() {}
    
        public var id: String?
        public var validationError: ValidationError = ValidationError(msg: "Invalid password.")
    
        public func isValid(value: T?) -> ValidationError? {
            if let str = value as? String {
                let errorMsg = RGOValidationHelper.passwordValidation(str)
                return errorMsg != nil ? ValidationError(msg: errorMsg!) : nil
            }
            return validationError
        }
    }
    

    Note the call to RGOValidationHelper simply returns an error string in the event that the validation fails, nil otherwise.

    Before you go and create a custom rule however, it must be noted that Eureka actually includes a facility to set a minimum length on a field. RuleMinLength is the name of the rule and it can be initialised by passing in a value for min length, in your case 100. Here is Eureka's implementation for the rule:

    public struct RuleMinLength: RuleType {
    
        let min: UInt
    
        public var id: String?
        public var validationError: ValidationError
    
        public init(minLength: UInt, msg: String? = nil){
            let ruleMsg = msg ?? "Field value must have at least \(minLength) characters"
            min = minLength
            validationError = ValidationError(msg: ruleMsg)
        }
    
        public func isValid(value: String?) -> ValidationError? {
            guard let value = value else { return nil }
            return value.characters.count < Int(min) ? validationError : nil
        }
    }
    

    I hope this helps somewhat, if you have any further problems with Eureka chances are I've come across and solved them before, so feel free to send me a message.