3lvis / Form

The most flexible and powerful way to build a form on iOS
http://hyper.no
Other
1.64k stars 145 forks source link

Modifying a 'FORMFields' within 'self.dataSource.allFields' doesn't update its respective 'self.dataSource.values' #563

Open sedwo opened 7 years ago

sedwo commented 7 years ago

My challenge is that when I update a value like this:

FORMFields *formField = [self.dataSource.allFields objectForKey:stringKey];
formField.value = newStringValue;

It doesn't reflect that updated new value within the self.dataSource.values container.

As I need to update fields within a form that haven't yet been scrolled into view. And if they never are, then the data that gets saved is missing the updated new value.

I've hacked it by

NSMutableDictionary *updatedValues = [[NSMutableDictionary alloc] 

FORMFields *formField = [self.dataSource.allFields objectForKey:stringKey];
formField.value = newStringValue;

updatedValues[formField.fieldID] = formField.value;
[self.dataSource updateValuesWithDictionary:updatedValues];

But I would expect this to be embedded within the control. It looks ugly to wrap each modification like this.

Any other clever techniques on how to accomplish this ?

3lvis commented 7 years ago

Hi @sedwo,

What about doing:

[self.dataSource updateValuesWithDictionary:@{stringKey: newStringValue}];

Or could you share a bit more of your JSON structure? I think I could share an example on how to do this if I get some more info.

sedwo commented 7 years ago

Are you suggesting then:

FORMFields *formField = [self.dataSource.allFields objectForKey:stringKey];
formField.value = newStringValue;    // update field
[self.dataSource updateValuesWithDictionary:@{stringKey: newStringValue}];    // update value

My thought (and hope) was that formField.value would update both. : )

Currently I'm experimenting with this snippet from other comments:

- (void)updateSelectField:(FORMFields *)formField withValue:(id)fieldValue
{
    __weak typeof(self)weakSelf = self;

    [self.dataSource fieldWithID:formField.fieldID
           includingHiddenFields:YES
                      completion:^(FORMFields *field, NSIndexPath *indexPath) {
         if (field)
         {
             field.value = fieldValue;
             [weakSelf.dataSource updateValuesWithDictionary:@{ field.fieldID : fieldValue }];
             [weakSelf.dataSource reloadFieldsAtIndexPaths:@[indexPath]];
         }
     }];
}

Does that method make sense?

3lvis commented 7 years ago

@sedwo what type of field is the one you're trying to update? https://github.com/hyperoslo/Form/blob/master/Source/Models/FORMField.h#L10-L24

sedwo commented 7 years ago

At the moment just TEXT and DATE/TIME strings.

sedwo commented 7 years ago

I added the method:

- (void)updateSelectField:(FORMFields *)formField withValue:(id)fieldValue
{
    __weak typeof(self)weakSelf = self;

    [self fieldWithID:formField.fieldID includingHiddenFields:YES completion:^(FORMFields *field, NSIndexPath *indexPath) {
        if (field)
        {
            field.value = fieldValue;
            [weakSelf updateValuesWithDictionary:@{ field.fieldID : fieldValue }];
            [weakSelf reloadFieldsAtIndexPaths:@[indexPath]];
        }
    }];
}

to the FORMDataSource class and it seems to do the job.

Thank you kindly for your feedback.

3lvis commented 7 years ago

Gonna add a recommendation to the readme.

sedwo commented 7 years ago

fyi After further usage and testing, I simplified the method to simply be:

- (void)updateSelectField:(FORMFields *)formField withValue:(id)fieldValue
{
    if (formField && fieldValue != nil)
    {
        formField.value = fieldValue;
        [self updateValuesWithDictionary:@{ formField.fieldID : fieldValue }];
    }
}