I need to create a dynamic form using JSON. I have parsed the JSON but i don't have any idea how to create a form dynamically. i'm getting json data with some control like check box ,text fields ,and questions now i want to create From based on there Question . Similar to how we can create a from using Google Forms. Please Check below link https://docs.google.com/forms/d/1lPn1aSvJsiDbJchsJjwsC93tWizXhj1qWkFPygt3oU4/viewform Please suggest some code or tutorial.
2 Answers
My idea would be, in steps
1) create model class example
class UIControl
{
NSString *strControlName;
NSString *strControlType;
NSString *strControlValue;
Bool isSelected;
}
2) Parse json and create object of model class
3) add model class object into arrOfControls
4) either go for table view, or just use loop to traverse entire arrOfControls
5) in case, table view check at cellForRowAtIndexPath type of control.
6) create custom cell for every possible field which could be come with your JSON data.
7) Return custom cell in deleage function(cellForRowAtIndexPath) depending on type of control. ex:-
if([[arrOfControls objectAtIndexPath:indexPath.row] strType] isEqualToString:@"TextField"]])
{
//create object of customcell for textfield and return cell
}
else if([[arrOfControls objectAtIndexPath:indexPath.row] strType] isEqualToString:@"CheckBox"]])
{
//create object of customcell for checkbox and return cell
}
else
{
//control type if not match any of the above
}
this is rough idea not acutal code. few code from my project, for cellForRowAtIndexPath
if(indexPath.section==0)
{
FormField *currControl=[fieldArray objectAtIndex:indexPath.row];
if(([currControl.strFieldType caseInsensitiveCompare:@"TextLabel"]==NSOrderedSame )|| [currControl.strFieldType caseInsensitiveCompare:@"Text"]==NSOrderedSame)
{
TextFieldWithLabelTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellTextFieldWithLabel"];
cell.txtTextField.delegate=self;
[cell.txtTextField setTag:indexPath.row];
if([currControl strFieldValue]==nil)
{
cell.txtTextField.text = @"";
[cell.txtTextField setPlaceholder:[currControl strPlaceHolder]];
}
else
{
//if save value exists
cell.txtTextField.text=@"";
cell.txtTextField.text=[currControl strFieldValue];
}
cell.lblTextFieldIdenti.text=[[fieldArray objectAtIndex:indexPath.row] strFieldName];
if([currControl.strFieldType caseInsensitiveCompare:@"Text"]==NSOrderedSame)
{
cell.lblTextFieldIdenti.text=@"";
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
return cell;
}
else if(([currControl.strFieldType caseInsensitiveCompare:@"TextView"]==NSOrderedSame)||([currControl.strFieldType caseInsensitiveCompare:@"TextViewWithCam"]==NSOrderedSame))
{
TableViewTextAreaCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TableViewTextAreaCell"];
cell.txtView.delegate=self;
cell.txtView.text=@"";
if([currControl strFieldValue]!=nil)
{
//if save value exists
cell.txtView.text=@"";
cell.txtView.text=[currControl strFieldValue];
}
cell.fieldLabel.text=[[fieldArray objectAtIndex:indexPath.row] strFieldName];
NSMutableArray *barItems = [[NSMutableArray alloc] init];
UIToolbar* keyboardDoneButtonView = [[UIToolbar alloc] init];
keyboardDoneButtonView.barStyle = UIBarStyleDefault;
keyboardDoneButtonView.translucent = NO;
keyboardDoneButtonView.barTintColor=[UIColor colorWithHue:0.6 saturation:0.33 brightness:0.69 alpha:0];
[keyboardDoneButtonView sizeToFit];
UIBarButtonItem *leftFlexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
[barItems addObject:leftFlexSpace];
UIBarButtonItem *btnDone = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"BTN_DONE", nil) style:UIBarButtonItemStyleBordered target:self action:@selector(pickerDoneClicked:)];
[barItems addObject:btnDone];
[keyboardDoneButtonView setItems:barItems animated:YES];
[cell.txtView setInputAccessoryView:keyboardDoneButtonView];
[cell configureCell:currControl.strFieldName];
cell.fieldLabel.textColor=[UIColor darkTextColor];
cell.txtView.backgroundColor =[UIColor colorWithHexString:@"#f3f1f2"];
cell.fieldLabel.font=[UIFont systemFontOfSize:12];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[cell.imgViewCam setHidden:TRUE];
if([currControl.strFieldType caseInsensitiveCompare:@"TextViewWithCam"]==NSOrderedSame)
{
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(CameraClicked:)];
[singleTap setNumberOfTapsRequired:1];
[cell.imgViewCam addGestureRecognizer:singleTap];
[cell.imgViewCam setHidden:FALSE];
}
return cell;
}
else if([currControl.strFieldType caseInsensitiveCompare:@"DropDown"]==NSOrderedSame)
{
//if dropdwon box
DropDownTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellDropDown"];
cell.lblDropDownidentifier.text=[currControl strFieldName];
[cell.btnDropDown setTag:indexPath.row];
[cell.btnDropDown addTarget:self action:@selector(ShowOptions:) forControlEvents:UIControlEventTouchUpInside];
[cell.btnDropDown setTitle:@"" forState:UIControlStateNormal];
if([currControl strFieldValue]!=nil)
{
[cell.btnDropDown setTitle:[currControl strFieldValue] forState:UIControlStateNormal];
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
if([[currControl strFieldName] caseInsensitiveCompare:@"Time Of Delivery:"]==NSOrderedSame)
{
cell.imgDropDown.image=[UIImage imageNamed:@"stopwatch.png"];
}
else if([[currControl strFieldName] caseInsensitiveCompare:@"Date Of Delivery:"]==NSOrderedSame)
{
cell.imgDropDown.image=[UIImage imageNamed:@"calendar.png"];
}
else
{
cell.imgDropDown.image=[UIImage imageNamed:@"dropdown.jpeg"];
}
return cell;
}
-
yes i have, but it's huge code. and it's confidential for my company – Sheshnath Nov 26 '14 at 09:03
-
Ok How to Get Back the entered Value for Controls – naga rocks Nov 26 '14 at 09:05
-
i mean if user enter some value in Text field how to get that all value – naga rocks Nov 26 '14 at 09:06
-
In case of textfield, textFieldDidEndEditing:(UITextField *)textField. save textfield value into your model class member strValue and update array. – Sheshnath Nov 26 '14 at 09:08
-
but they can me more that one text filed not only text field i want the values of all controls – naga rocks Nov 26 '14 at 09:10
-
i have added, few lines of code from my project, answer modified. – Sheshnath Nov 26 '14 at 09:13
-
drop down is tableview(child) with different tag. when user selected option from tableview(child) at didrowSelected(delegate) we know selected value. update arrOfControls based on this value. – Sheshnath Nov 26 '14 at 09:22
-
Ok Thankq I will try .but if possible Send me those file u r using this – naga rocks Nov 26 '14 at 09:24
-
whenever you have problem, msg me, if you like my answer and help, please click up-arrow(above green tick mark) – Sheshnath Nov 26 '14 at 09:29
-
can i have u r Skype id – naga rocks Nov 26 '14 at 10:10
-
you could optimize this by using the strFieldType as cell identifier and simply using that identifier to get the cells from tableView. Add one Protocol and make all the custom cells (with one field type) implement that. – geekay Jun 16 '15 at 09:51
This is something that I found quite interesting and did a quick search. Depending on what your JSON has in it I can see 2 ways of achieving this.
1.) If your JSON is along these lines:
{ "Type":"TextField", "Properties" : { "Property1":"Value1", "Property2":"Value2"} }
etc.
You would have to have conditional code depending on the Type e.g;
UIControl *newControl
if([[parsedJson valueForKey:@"Type"] isEqualTo:"TextField"])
{
newControl = [UITextField alloc]init];
for(NSDictionary *dict in [parsedJson valueForKey:"Properties")
{
[newControl setValue:[dict value] forKey:[dict Key]];
}
}
On the other hand if your JSON uses UIKit names for Types e.g.:
{"Type":"UITextField","Properties":{"Property1":"Value1","Property2":2}}
etc.
There is a bit of Reflection you can do:
id *control = [[NSClassFromString([parsedJson valueForKey:"Type"]) alloc] init];
for(NSDictionary *dict in [parsedJson valueForKey:"Properties")
{
[newControl setValue:[dict value] forKey:[dict Key]];
}
But you need to have a lot of error handling/try{} catch{} in case the system fails to create a class or you set a value for a property that doesn't exist.
Also properties stated in the JSON need to reference the properties of the class.
Some references used for this answer:
how to instantiate an object of class from string in Objective-C? - StackOverflow Convert a string (“MyExampleClass”) into a class name (MyExampleClass) - StackOverflow

- 1
- 1

- 1,103
- 10
- 12
-
here in iOS we don't have check box control right how to handle that – naga rocks Nov 26 '14 at 09:38
-
I don't have a sample. This was all done from memory/references. A UITableView with the selection set to be a Checkmark is the best way to display multiple selection options. This follows the System UI as well – Naughty_Ottsel Nov 26 '14 at 09:40