Welcome, Guest
Username Password: Remember me

object level validation?
(1 viewing) (1) Guest
  • Page:
  • 1
  • 2

TOPIC: object level validation?

object level validation? 1 year, 4 months ago #1

What is the right place to do object level validation? What I mean is this:

Say I have an object with two boolean properties and a detail view with two cells with a switch to edit those. I want the Done button to remain disabled until *at least one of the two* is set to true. I don't think this can be done using the normal validation framework which looks at a single cell and I do not see any delegate method returning a boolean that allows me to inspect the entire bound object and determine whether it's valid. How do I do this?

Thanks,

Frank
  • fsauer
  • OFFLINE
  • Fresh Boarder
  • Posts: 14
  • Karma: 1

Re: object level validation? 1 year, 4 months ago #2

here is what I do now. It works but doesn't "feel" right for some reason:

 
- (BOOL)tableViewModel:(SCTableViewModel *) tableViewModel valueIsValidForRowAtIndexPath:(NSIndexPath *) indexPath {
DLog(@"Is value valid for cell at %@", indexPath);
SCTableViewSection *section = [tableViewModel sectionAtIndex:indexPath.section];
SCSwitchCell *sw1 = (SCSwitchCell *)[section cellAtIndex:indexPath.row];
SCSwitchCell *sw2 = (SCSwitchCell *)[section cellAtIndex: 7 - indexPath.row]; // 3->4, 4->3
return sw1.switchControl.on || sw2.switchControl.on;
}
 



This could get really hairy when the validation code becomes more complicated and involves more data of the bound object.
I would suggest one additional delegate method that is called after all the cell validation is all done and successful and that method would take the bound object as the parameter and return a boolean, something like -(BOOL)isBoundObjectValid: (id)boundObject

Thanks,

Frank
  • fsauer
  • OFFLINE
  • Fresh Boarder
  • Posts: 14
  • Karma: 1

Re: object level validation? 1 year, 4 months ago #3

Hi Frank,

Your solution is great. If you want, you can access the bound object like this:

 
- (BOOL)tableViewModel:(SCTableViewModel *)tableViewModel
valueIsValidForRowAtIndexPath:(NSIndexPath *)indexPath
{
SCTableViewSection *section = [tableViewModel sectionAtIndex:indexPath.section];
NSObject *boundObject = section.boundObject;
 
// validation code here
...
}
 
  • tarekskr
  • OFFLINE
  • Administrator
  • Posts: 2404
  • Karma: 72

Re: object level validation? 1 year, 4 months ago #4

Well, it works but I don't like it for the following reason:

This gets called for every cell that has autovalidate set to FALSE and it gets called before the cell's value is set in the bound object. This makes writing the validation code hard because it has to either use all the values from all the other cells with values involved in the validation logic (as I am doing here), or it must contain a switch to figure out what the cell is that actually is being validated in this invocation (the value to be tested is not in the bound object yet) and get the other values from the bound object. I think it would be much easier to write a method that gets called once and receives the entire bound object with all cell values set in it (unless a cell level validation failed, then this method never even gets invoked). That way the entire validation logic can be written in terms of the bound object. If we had such a method, I would in this case not even turn autovalidate off and not implement the cell level validation method at all. I would use cell level validation only for those validation rules that can be evaluated based on the cell value alone, such as matching a regular expression or being between 0 and 10, and simple things like that.

Hope this makes some sense,

Frank
  • fsauer
  • OFFLINE
  • Fresh Boarder
  • Posts: 14
  • Karma: 1

Re: object level validation? 1 year, 4 months ago #5

It actually does make a lot of sense, Frank.

There is only one issue that we need to take into consideration: the cell values are not committed to the bound object until the user taps the "Done" button. Thus, currently validation is used preemptively, that is, the done button is disabled until the cell values are valid.

Any approach that will use the bound object for validation will require that changes be committed to it first, then your custom code would decide on what to do with the object. This means that if at this stage the object is not valid, you'll probably need to display a message to the user that explains why their data is not being accepted. Is this what you're looking for, or is it the current preemptive validation style?
  • tarekskr
  • OFFLINE
  • Administrator
  • Posts: 2404
  • Karma: 72

Re: object level validation? 1 year, 4 months ago #6

I am looking for the preemptive style but without having to deal with cell values I guess. Are the cells bound to a temporary copy of the actual bound object perhaps? If so, then this temporary copy could be used for object level validation perhaps.

 
2011-01-05 12:52:42.739 PlatypusUniversal[34862:207] -[SubscriptionTVC tableViewModel:valueIsValidForRowAtIndexPath:] [Line 221] Is value valid for cell at <NSIndexPath 0x707a580> 2 indexes [0, 3]
2011-01-05 12:52:42.740 PlatypusUniversal[34862:207] -[SubscriptionTVC tableViewModel:valueIsValidForRowAtIndexPath:] [Line 221] Is value valid for cell at <NSIndexPath 0x707f7e0> 2 indexes [0, 4]
2011-01-05 12:52:42.740 PlatypusUniversal[34862:207] -[SubscriptionTVC tableViewModel:valueChangedForRowAtIndexPath:] [Line 164] value at <NSIndexPath 0x707f7e0> 2 indexes [0, 4] changed
 


The above is the logging output from a single click on one switch in a form that has two switches. Both SCSwitchCells have their autovalidation set to FALSE and the validation method is invoked for both cells every time I click one switch. And then the valueChangedForRowAtIndexPath method is called. I was assuming by this time the value is set in the bound object but perhaps I am wrong in this assumption. The valueChangedForRowAtIndexPath callback is invoked well before I click the done button.

What I was hoping for is a callback that gets invoked once every time I change a cell value, with the bound object or a copy as the parameter, so I can perform validation logic that involves multiple properties of that object. Extending this idea even further, I can envision ArrayOfObjectSection level validation where the validity of one object depends on the existence of other objects in that section, for example if each row needs to have a unique name.

Maybe all this is simply not possible, not sure, just some food for thought

Regards,


Frank
  • fsauer
  • OFFLINE
  • Fresh Boarder
  • Posts: 14
  • Karma: 1
  • Page:
  • 1
  • 2
Time to create page: 1.91 seconds