11 Commits

Author SHA1 Message Date
Mathias Claassen e9de49db86 formValuesIncludingHidden returns all values of a form including the values of hidden rows 2017-05-18 11:56:26 -03:00
MiMo42 77db6b9492 nullability warning fixed (#952) 2017-04-26 10:21:35 -03:00
Mathias Claassen 74b26c1e64 make properties of XLFormOptionsObject writable (#955) 2017-04-25 11:55:54 -03:00
Mathias Claassen 085cf31e52 Updated Readme Eureka introduction (#954) 2017-04-25 10:48:47 -03:00
FatalDizz 313e5d5d40 Added method to set a title for form errors (#951) 2017-04-19 11:46:34 -03:00
Mathias Claassen f7777d9d27 Add Header and Footer section to Readme FAQ (#942) 2017-04-05 09:46:52 -03:00
Mathias Claassen 578dea99dd Use the correct locale in date row (not only date picker) (#935) 2017-04-05 09:23:41 -03:00
Santiago Castro 1da30107dc Fix README headings due to GitHub change (#937)
GitHub changed its Markdown processor to stop supporting heading without spaces https://gist.github.com/vmarkovtsev/59cd7349d41cf804b9a8775388e681f8
2017-03-21 09:18:22 -03:00
Mathias Claassen 4674c3abaf Make moveRowAtIndexPath:toIndexPath: public in XLFormSectionDescriptor to allow to reorder rows programmatically. (#929) 2017-02-22 12:58:47 -03:00
Felix Dumit 5ca54fd949 Fix use of formatter in Info Cells (#916)
Adds example with infocell and bytecount formatter
2017-01-16 18:15:42 -03:00
Mathias Claassen e64e5b4885 update Travis file to use Xcode 8.2 (#920) 2017-01-12 10:24:37 -03:00
15 changed files with 124 additions and 30 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
language: objective-c
osx_image: xcode7.2
osx_image: xcode8.2
before_install:
- gem install cocoapods --no-rdoc --no-ri --no-document --quiet
- gem install xcpretty --no-rdoc --no-ri --no-document --quiet
@@ -57,6 +57,7 @@ NSString *const kCountDownTimer = @"countDownTimer";
// Date
row = [XLFormRowDescriptor formRowDescriptorWithTag:kDateInline rowType:XLFormRowDescriptorTypeDateInline title:@"Date"];
row.value = [NSDate new];
[row.cellConfigAtConfigure setObject:[NSLocale localeWithLocaleIdentifier:@"FR_fr" ] forKey:@"locale"];
[section addFormRow:row];
// Time
@@ -105,6 +105,11 @@
[row.cellConfigAtConfigure setObject:@(NSTextAlignmentRight) forKey:@"textField.textAlignment"];
[section addFormRow:row];
row = [XLFormRowDescriptor formRowDescriptorWithTag:@"megabytes" rowType:XLFormRowDescriptorTypeInfo title:@"Megabytes"];
row.valueFormatter = [NSByteCountFormatter new];
row.value = @(1024);
[section addFormRow:row];
section = [XLFormSectionDescriptor formSection];
[formDescriptor addFormSection:section];
@@ -76,6 +76,7 @@ class DatesFormViewController: XLFormViewController {
// Date
row = XLFormRowDescriptor(tag: Tags.DateInline, rowType: XLFormRowDescriptorTypeDateInline, title:"Date")
row.value = Date()
row.cellConfigAtConfigure["locale"] = Locale(identifier: "FR_fr")
section.addFormRow(row)
// Time
+33 -14
View File
@@ -6,7 +6,7 @@ By [XMARTLABS](http://xmartlabs.com).
[![Build Status](https://travis-ci.org/xmartlabs/XLForm.svg?branch=master)](https://travis-ci.org/xmartlabs/XLForm)
<a href="https://cocoapods.org/pods/XLForm"><img src="https://img.shields.io/cocoapods/v/XLForm.svg" alt="CocoaPods compatible" /></a>
**If you are looking for Swift native implementation we have recently created [Eureka], a complete re-design of XLForm in Swift.** *Do not panic, We will continue maintaining and improving XLForm, obj-c rocks!!*
**If you are working in Swift then you should have a look at [Eureka], a complete re-design of XLForm in Swift.** *Do not panic, we will continue maintaining and improving XLForm, obj-c rocks!!*
Purpose
--------------
@@ -15,7 +15,7 @@ XLForm is the most flexible and powerful iOS library to create dynamic table-vie
XLForm provides a very powerful DSL (Domain Specific Language) used to create a form. It keeps track of this specification on runtime, updating the UI on the fly.
#####Let's see the iOS Calendar Event Form created using XLForm
##### Let's see the iOS Calendar Event Form created using XLForm
![Screenshot of native Calendar Event Example](Examples/Objective-C/Examples/RealExamples/XLForm.gif)
@@ -182,7 +182,7 @@ How to run XLForm examples
Rows
---------------------
####Input Rows
#### Input Rows
![Screenshot of Input Examples](Examples/Objective-C/Examples/Inputs/XLForm-Inputs.gif)
@@ -253,7 +253,7 @@ Will be represented by a `UITextView` with `UITextAutocorrectionTypeDefault`, `U
####Selector Rows
#### Selector Rows
Selector rows allow us to select a value or values from a list. XLForm supports 8 types of selectors out of the box:
@@ -320,7 +320,7 @@ This is the protocol declaration:
```
####Date & Time Rows
#### Date & Time Rows
XLForms supports 3 types of dates: `Date`, `DateTime` , `Time` and `Countdown Timer` and it's able to present the `UIDatePicker` control in 2 different ways, inline and non-inline.
@@ -427,7 +427,7 @@ section.addFormRow(row)
self.form = form;
```
####Boolean Rows
#### Boolean Rows
XLForms supports 2 types of boolean controls:
@@ -445,9 +445,9 @@ static NSString *const XLFormRowDescriptorTypeBooleanSwitch = @"booleanSwitch";
We can also simulate other types of Boolean rows using any of the Selector Row Types introduced in the [Selector Rows section](#selector-rows).
####Other Rows
#### Other Rows
#####Stepper
##### Stepper
XLForms supports counting using UIStepper control:
@@ -469,7 +469,7 @@ You can set the stepper paramaters easily:
[row.cellConfigAtConfigure setObject:@100 forKey:@"stepControl.maximumValue"];
```
#####Slider
##### Slider
XLForms supports counting using UISlider control:
@@ -490,11 +490,11 @@ You can adjust the slider for your own interests very easily:
Set `steps` to `@(0)` to disable the steps functionality.
#####Info
##### Info
Sometimes our apps needs to show data that are not editable. XLForm provides us with `XLFormRowDescriptorTypeInfo` row type to display not editable info. An example of usage would be showing the app version in the settings part of an app.
#####Button
##### Button
Apart from data entry rows, not editable rows and selectors, XLForm has a button row `XLFormRowDescriptorTypeButton` that allows us to do any action when selected. It can be configured using a block (clousure), a selector, a segue identifier, segue class or specifing a view controller to be presented. ViewController specification could be done by setting up the view controller class, the view controller storyboard Id or a nib name. Nib name must match view controller class name.
@@ -767,7 +767,7 @@ For instance if we want to show or hide a row depending on the value of another
Make a row or section invisible depending on other rows values
--------------------------------
###Summary
### Summary
XLForm allows you to define dependencies between rows so that if the value of one row is changed, the behaviour of another one changes automatically. For example, you might have a form where you question the user if he/she has pets. If the answer is 'yes' you might want to ask how their names are.
So you can make a row invisible and visible again based on the values of other rows. The same happens with sections.
@@ -777,7 +777,7 @@ Take a look at the following example:
Of course, you could also do this manually by observing the value of some rows and deleting and adding rows accordingly, but that would be a lot of work which is already done.
###How it works
### How it works
To make the appearance and disappearance of rows and sections automatic, there is a property in each descriptor:
@@ -897,6 +897,25 @@ section.addFormRow(row)
FAQ
-------
#### How to customize the header and/or footer of a section
For this you should use the UITableViewDelegate methods in your XLFormViewController.
This means you should implement one or both of these:
```objc
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
```
Also you might want to implement the following methods to specify the height for these views:
```objc
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
```
#### How to assign the first responder on form appearance
Assign the first responder when the form is shown is as simple as setting the property `assignFirstResponderOnShow` to `YES`. By default the value of the property is `NO`.
@@ -1008,7 +1027,7 @@ row.cellConfig.setObject(UIFont(name: "AppleSDGothicNeo-Regular", size: 17)!, fo
For further details, please take a look at [UICustomizationFormViewController.m](/Examples/Objective-C/Examples/UICustomization/UICustomizationFormViewController.m) example.
####How to set min/max for date cells?
#### How to set min/max for date cells?
Each XLFormDateCell has a `minimumDate` and a `maximumDate` property. To set a datetime row to be a value in the next three days you would do as follows:
+2 -2
View File
@@ -3,7 +3,7 @@ include FileUtils::Verbose
namespace :test do
desc "Run the XLForm Tests"
task :ios do
run_tests('XLForm Tests', 'iphonesimulator9.2')
run_tests('XLForm Tests', 'iphonesimulator10.2')
tests_failed unless $?.success?
end
end
@@ -17,7 +17,7 @@ task :default => 'test'
private
def run_tests(scheme, sdk)
sh("xcodebuild -workspace 'Tests/XLForm Tests.xcworkspace' -scheme '#{scheme}' -sdk '#{sdk}' -destination 'name=iPhone 6' -configuration Release clean test | xcpretty -c ; exit ${PIPESTATUS[0]}") rescue nil
sh("xcodebuild -workspace 'Tests/XLForm Tests.xcworkspace' -scheme '#{scheme}' -sdk '#{sdk}' -destination 'OS=10.1,name=iPhone 7' -configuration Release clean test | xcpretty -c ; exit ${PIPESTATUS[0]}") rescue nil
end
def tests_failed
+16 -3
View File
@@ -37,6 +37,7 @@
@implementation XLFormDateCell
{
UIColor * _beforeChangeColor;
NSDateFormatter *_dateFormatter;
}
@@ -109,6 +110,7 @@
{
[super configure];
self.formDatePickerMode = XLFormDateDatePickerModeGetFromRowDescriptor;
_dateFormatter = [[NSDateFormatter alloc] init];
}
-(void)update
@@ -173,10 +175,14 @@
}
}
if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeDate] || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeDateInline]){
return [NSDateFormatter localizedStringFromDate:date dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterNoStyle];
_dateFormatter.dateStyle = NSDateFormatterMediumStyle;
_dateFormatter.timeStyle = NSDateFormatterNoStyle;
return [_dateFormatter stringFromDate:date];
}
else if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeTime] || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeTimeInline]){
return [NSDateFormatter localizedStringFromDate:date dateStyle:NSDateFormatterNoStyle timeStyle:NSDateFormatterShortStyle];
_dateFormatter.dateStyle = NSDateFormatterNoStyle;
_dateFormatter.timeStyle = NSDateFormatterShortStyle;
return [_dateFormatter stringFromDate:date];
}
else if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeCountDownTimer] || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeCountDownTimerInline]){
NSCalendar *calendar = [NSCalendar currentCalendar];
@@ -184,7 +190,9 @@
NSDateComponents *time = [calendar components:NSCalendarUnitHour | NSCalendarUnitMinute fromDate:date];
return [NSString stringWithFormat:@"%ld%@ %ldmin", (long)[time hour], (long)[time hour] == 1 ? @"hour" : @"hours", (long)[time minute]];
}
return [NSDateFormatter localizedStringFromDate:date dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterShortStyle];
_dateFormatter.dateStyle = NSDateFormatterShortStyle;
_dateFormatter.timeStyle = NSDateFormatterShortStyle;
return [_dateFormatter stringFromDate:date];
}
-(void)setModeToDatePicker:(UIDatePicker *)datePicker
@@ -228,6 +236,11 @@
return _datePicker;
}
-(void)setLocale:(NSLocale *)locale
{
_locale = locale;
_dateFormatter.locale = locale;
}
#pragma mark - Target Action
+1 -1
View File
@@ -87,7 +87,7 @@
return tranformedValue;
}
}
return [self.rowDescriptor.value displayText];
return self.rowDescriptor.displayTextValue;
}
@@ -28,6 +28,9 @@
@interface XLFormOptionsObject : NSObject <XLFormOptionObject,NSCoding>
@property (nonatomic) NSString * formDisplaytext;
@property (nonatomic) id formValue;
+(XLFormOptionsObject *)formOptionsObjectWithValue:(id)value displayText:(NSString *)displayText;
+(XLFormOptionsObject *)formOptionsOptionForValue:(id)value fromOptions:(NSArray *)options;
+(XLFormOptionsObject *)formOptionsOptionForDisplayText:(NSString *)displayText fromOptions:(NSArray *)options;
+3 -4
View File
@@ -26,10 +26,6 @@
#import "XLFormOptionsObject.h"
@implementation XLFormOptionsObject
{
NSString * _formDisplaytext;
id _formValue;
}
+(XLFormOptionsObject *)formOptionsObjectWithValue:(id)value displayText:(NSString *)displayText
{
@@ -85,6 +81,7 @@
{
return _formValue;
}
#pragma mark - NSCoding
-(void)encodeWithCoder:(NSCoder *)encoder
{
@@ -94,6 +91,7 @@
[encoder encodeObject:self.formDisplayText
forKey:@"formDisplayText"];
}
-(instancetype)initWithCoder:(NSCoder *)decoder
{
if ((self=[super init])) {
@@ -108,4 +106,5 @@
return self;
}
@end
@@ -52,6 +52,7 @@ typedef NS_ENUM(NSUInteger, XLFormRowNavigationDirection) {
-(XLFormBaseCell *)updateFormRow:(XLFormRowDescriptor *)formRow;
-(NSDictionary *)formValues;
-(NSDictionary *)formValuesIncludingHidden;
-(NSDictionary *)httpParameters;
-(XLFormRowDescriptor *)formRowFormMultivaluedFormSection:(XLFormSectionDescriptor *)formSection;
@@ -60,6 +61,7 @@ typedef NS_ENUM(NSUInteger, XLFormRowNavigationDirection) {
-(NSArray *)formValidationErrors;
-(void)showFormValidationError:(NSError *)error;
-(void)showFormValidationError:(NSError *)error withTitle:(NSString*)title;
-(UITableViewRowAnimation)insertRowAnimationForRow:(XLFormRowDescriptor *)formRow;
-(UITableViewRowAnimation)deleteRowAnimationForRow:(XLFormRowDescriptor *)formRow;
@@ -346,6 +346,11 @@
return [self.form formValues];
}
-(NSDictionary *)formValuesIncludingHidden
{
return [self.form formValuesIncludingHidden];
}
-(NSDictionary *)httpParameters
{
return [self.form httpParameters:self];
@@ -492,6 +497,38 @@
#endif
}
-(void)showFormValidationError:(NSError *)error withTitle:(NSString*)title
{
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 80000
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(title, nil)
message:error.localizedDescription
delegate:self
cancelButtonTitle:NSLocalizedString(@"OK", nil)
otherButtonTitles:nil];
[alertView show];
#else
if ([UIAlertController class]){
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(title, nil)
message:error.localizedDescription
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:nil]];
[self presentViewController:alertController animated:YES completion:nil];
}
#ifndef XL_APP_EXTENSIONS
else{
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(title, nil)
message:error.localizedDescription
delegate:self
cancelButtonTitle:NSLocalizedString(@"OK", nil)
otherButtonTitles:nil];
[alertView show];
}
#endif
#endif
}
-(void)performFormSelector:(SEL)selector withObject:(id)sender
{
UIResponder * responder = [self targetForAction:selector withSender:sender];;
+1
View File
@@ -82,6 +82,7 @@ typedef NS_OPTIONS(NSUInteger, XLFormRowNavigationOptions) {
-(nullable NSIndexPath *)indexPathOfFormRow:(nonnull XLFormRowDescriptor *)formRow;
-(nonnull NSDictionary *)formValues;
-(nonnull NSDictionary *)formValuesIncludingHidden;
-(nonnull NSDictionary *)httpParameters:(nonnull XLFormViewController *)formViewController;
-(nonnull NSArray *)localValidationErrors:(nonnull XLFormViewController *)formViewController;
+17 -5
View File
@@ -284,13 +284,25 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
return nil;
}
-(NSDictionary *)formValuesIncludingHidden
{
return [self formValuesWithHidden:YES];
}
-(NSDictionary *)formValues
{
NSMutableDictionary * result = [NSMutableDictionary dictionary];
for (XLFormSectionDescriptor * section in self.formSections) {
return [self formValuesWithHidden:NO];
}
-(NSDictionary *)formValuesWithHidden:(BOOL)includeHidden
{
NSArray* sections = includeHidden ? self.allSections : self.formSections;
NSMutableDictionary* result = [NSMutableDictionary dictionary];
for (XLFormSectionDescriptor * section in sections) {
NSArray* rows = includeHidden ? section.allRows : section.formRows;
if (section.multivaluedTag.length > 0){
NSMutableArray * multiValuedValuesArray = [NSMutableArray new];
for (XLFormRowDescriptor * row in section.formRows) {
NSMutableArray* multiValuedValuesArray = [NSMutableArray new];
for (XLFormRowDescriptor * row in rows) {
if (row.value){
[multiValuedValuesArray addObject:row.value];
}
@@ -298,7 +310,7 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
[result setObject:multiValuedValuesArray forKey:section.multivaluedTag];
}
else{
for (XLFormRowDescriptor * row in section.formRows) {
for (XLFormRowDescriptor * row in rows) {
if (row.tag.length > 0){
[result setObject:(row.value ?: [NSNull null]) forKey:row.tag];
}
@@ -69,5 +69,6 @@ typedef NS_ENUM(NSUInteger, XLFormSectionInsertMode) {
-(void)addFormRow:(nonnull XLFormRowDescriptor *)formRow beforeRow:(nonnull XLFormRowDescriptor *)beforeRow;
-(void)removeFormRowAtIndex:(NSUInteger)index;
-(void)removeFormRow:(nonnull XLFormRowDescriptor *)formRow;
-(void)moveRowAtIndexPath:(nonnull NSIndexPath *)sourceIndex toIndexPath:(nonnull NSIndexPath *)destinationIndex;
@end