I want to populate a form with fields that are both manually added and dynamically added.
public class ModelClass
{
[Prompt("URL?")]
public string URL { get; set; }
[Prompt("Name?")]
public string Title { get; set; }
}
Formbuilder:
public IForm<ModelClass> BuildApplyform()
{
var builder = new FormBuilder<ModelClass>();
// Parse string to json for usage in the foreach
dynamic json = JObject.Parse(jsonString);
builder.Message("Form builder");
builder.Field(nameof(ModelClass.Title), active: (state) => false);
builder.Field(nameof(ModelClass.URL), active: (state) => false);
foreach(string param in json.Parameters)
{
builder.Field(param);
}
return builder.Build();
}
The JSONstring is very dynamic and can be different every time. However, the string always contains the "d" and "parameter"childnodes. The string could look like:
"{
\n\t\"d\": {
\n\t\t\"parameters\": [
{
\n\t\t\t\"id\": \"url\",
\n\t\t\t\"name\": \"Site URL\",
\n\t\t\t\"required\": \"text\"
},
{
\n\t\t\t\"id\": \"title\",
\n\t\t\t\"URL\": \"Title\",
\n\t\t\t\"required\": true,
\n\t\t\t\"example\": \"www.stackoverflow.com\"\n\t\t
}
]\n\t
}\n
}"
How can I make sure that no matter what the JSON looks like, the parameters are dynamically added as field input's in the form builder? Thanks in advance.
Impossible
Alright, after some more research I found out it was practically impossible what I was trying to achieve. It's not possible to dynamically add fields, and add static fields at the same time with the Bot Framework. So formbuilder is not a realistic possibility in such a case.As Eric Dahlvang mentioned: it is a possibility when you use JSON only via a JSON schema with form builder.
How I solved this problem:
During my search of using Form Builder I stumbled upon a solution that loops through a promptdialog. It's possible to read JSON and convert it into C# objects so you can iterate them, so why not use that?
Globally define a list of strings, or as I used "Parameter object":
public class Parameter
{
public string Id { get; set; }
public string Title { get; set; }
public bool Required { get; set; }
public string Example { get; set; }
}
Then you'd have to get the JSON parameters and convert them to the C# object (Parameter). I used a global List to access the params later on. Then I prompted the first question (parameter) so the loop starts.The job contains the parsed JSON.
public void SomeFunction(IDialogContext context)
{
if (job["d"]["parameters"] != null)
{
var t = job["d"]["parameters"];
parameters = GetParametersFromJSON(t); // parameters is a globally defined list of <Parameter>
}
currentParameter = parameters[0];
PromptDialog.Text(context, ParamPrompt, "Please fill in: " + currentParameter.Title+ $", for example: {currentParameter.sampleValue}");
}
private async Task ParamPrompt(IDialogContext context, IAwaitable<string>
result)
{
var answer = await result;
index++;
if (index < parameters.Count)
{
currentParameter = parameters[index];
PromptDialog.Text(context, ParamPrompt, "Please fill in: " + currentParameter.Title + $", for example: {currentParameter.example}");
}
else
{
// handle logic, the loop is done.
}
}