FXForms
FXForms copied to clipboard
Hiding fields
I'm programming a form which only certain fields are required based on previous fields.
I'm having trouble hiding certain fields conditionally, I was wondering if this is native functionality?
I had the same issue, so maybe I can help.
You can handle this using some additions to your form model. I had certain sections that I wanted to appear or be hidden based on the value of some other field. What I did was used excludedFields to manage the entire form rather than the Fields array.
At a high level, I created methods that created the list(s) of fields I wanted to toggle and then some helper methods to manage the form by adjusting the array returned by [form excludedFields].
What I did was in the form model I created something like this:
-(NSArray *) characterAttributesFields {
return @[@"species",
@"sex",
@"age",
@"hair",
@"eyes",
@"build",
@"intelligence",
@"profession"
];
}
I did one of these for each clump of form field/properties I wanted to manage. (As an aside, I used a separate NSDictionary to control the individual stylings of each field. Just seemed a little easier to maintain). I created a property for an array of dynamicallyExcludedFields and I'd use methods to adjust the contents of this array.
Then I used these lists and some helper methods to adjust what gets returned by [excludedFields), like so:
- (NSArray *)excludedFields
{
NSMutableArray *excluded = [[NSMutableArray alloc] init];
[excluded addObjectsFromArray:[self alwaysExcludedFields]];
if ([_dynamicallyExcludedFields count]) {
for (id excludeMeToo in _dynamicallyExcludedFields) {
[excluded addObject:excludeMeToo];
}
}
return excluded;
}
So the above method just adjusts what is returned. It probably seems a little counter-intuitive that you manage the form contents by the contents of the excludedFields array rather than the Fields array, but that is the only way I could figure out how to do it.
Read a field value filled in by user Adjust dynamically excludedFieldsArray reload the form
wash, rinse, repeat
I'm sure there is a more clever way of getting the job done, but hey, what do I know?
Hope this helps.
//**********
Here are some of the helper methods that may save you a little hassle:
-(NSArray *) alwaysExcludedFields {
return @[@"dynamicallyExcludedFields",
@"isNewCharacter"
];
}
-(void) addToExcludedFields: (NSString *)fieldName {
bool alreadyThere = [_dynamicallyExcludedFields containsObject:fieldName];
if (!alreadyThere) {
[_dynamicallyExcludedFields addObject:fieldName];
}
}
-(void) dropFromExcludedFields: (NSString *)fieldName {
bool isThere = [_dynamicallyExcludedFields containsObject:fieldName];
if (isThere) {
[_dynamicallyExcludedFields removeObject:fieldName];
}
}
And finally a cover function or two that will fire based on the value of some other field:
-(void) addCharacterAttributesFieldsToForm {
for (id obj in [self characterAttributesFields]) {
[self dropFromExcludedFields:obj];
}
}
-(void) dropCharacterAttributesFieldsFromForm {
for (id obj in [self characterAttributesFields]) {
[self addToExcludedFields:obj];
}
NSLog(@"Excluded Fields: %@",self.excludedFields);
}
Thank you.
I wrote a Swift solution, which is quite different to your suggestion but I thought you might find interesting.
I added a FXFormFieldAction to the switch field, which calls a function containing
self.formController.form = self.formController.form
self.tableView.reloadData()
Then within the func fields() -> [AnyObject]! { function, I create an NSMutableArray to which I can conditionally add fields to before returning.
This solution works great, the only thing I am lacking is the ability to make the change in fields animated.