Mapping Umbraco Form Data Types to default Umbraco Data Types
Is it possible to map Umbraco Forms data types into default Umbraco Data Types?
What I mean is something like this
foreach (var set in form.AllFieldSets)
{
var safeAlias = set.Caption.ToSafeAlias(shortStringHelper, true);
if (type.PropertyGroups.SingleOrDefault(x => x.Alias == safeAlias) is null)
type.AddPropertyGroup(safeAlias, set.Caption);
foreach (var field in set.AllFields)
{
var dataType = dataTypeService.GetDataType(field.SOMETHING); // get the equivalent data type
type.AddPropertyType(dataType);
}
}
In other words,
Get the equivalent Umbraco Datatype from a Form Field (data type) in order to add to a document type or member type.
Any suggestions or help will be much appreciated!
EDIT
I got as far as getting the details for the field using code from Umbraco Forms
public static class FieldTypeExtensions
{
public static bool TryGetFieldTypeForFieldId(Form form, Guid fieldId, IFieldTypeStorage fieldTypeStorage, out FieldType? fieldType)
{
Field field = form.AllFields.SingleOrDefault((Field x) => x.Id == fieldId);
if (field is null)
{
fieldType = null;
return false;
}
fieldType = fieldTypeStorage.GetFieldTypeByField(field);
return fieldType is not null;
}
}
But I still haven't figured out how to map that field into a data type.
Although there are similarities of course - Forms has a text field, as does the CMS; Forms has a text area, as does the CMS - there's nothing really that links these up. They are separate implementations.
As such you won't find a common alias or ID of the "data types" used in CMS and Forms.
I think you'll have to maintain a mapping - perhaps in a dictionary - that relates the ID or alias of the Forms and CMS equivalents, and then use that to associate them in your code.
Details of the Form's field types can be found here.
But I'm still trying to figure out where the FieldType holds the DataType Id when it's a custom data type (like a checkbox list or dropdown). Or even the Form field itself.
Sorry Carlos, but I'm not following that step I'm afraid. Are you referring to the "prevalues" (the options that you have to pick from when you have a checkbox list or a dropdown? If so, you probably need to be looking on the Field object, rather than the FieldType.
Basically, I want to be able to map the prevalues to the member properties.
var type = memberTypeService.GetAll().FirstOrDefault(x => x.Alias == memberType.ToLower());
foreach (var set in form.AllFieldSets)
{
var safeSetAlias = string.IsNullOrEmpty(set.Caption) ? "Ungrouped" : set.Caption.ToSafeAlias(shortStringHelper, true);
var setName = string.IsNullOrEmpty(set.Caption) ? "Ungrouped" : set.Caption;
if (type!.PropertyGroups.SingleOrDefault(x => x.Alias == safeSetAlias) is null)
type.AddPropertyGroup(safeSetAlias, setName);
foreach (var field in set.AllFields)
{
var sourceId = field.PreValueSourceId;
FieldTypeExtensions.TryGetFieldTypeForFieldId(form, field.Id, fieldTypeStorage, out FieldType? fieldType);
if (fieldType is not null)
{
IDataType dataType = dataTypeService.GetEquivalent(fieldType);
//WHERE DO I SET THE PREVALUE SOURCE ID?
PropertyType? property = null;
if (dataType is not null)
{
property = new PropertyType(shortStringHelper, dataType)
{
Alias = field.Alias,
Name = field.Caption,
CreateDate = DateTime.Now,
DataTypeId = dataType.Id,
DataTypeKey = dataType.Key,
LabelOnTop = true,
Mandatory = false,
PropertyEditorAlias = dataType.EditorAlias,
ValueStorageType = ValueStorageType.Ntext
};
}
else
{
}
if (property is not null)
type.AddPropertyType(property, safeSetAlias);
}
}
}
memberTypeService.Save(type);
}
I want to be able to use each data type created for the pre-value source in the member properties
That was my assumption as well. I've used the context.Record.UniqueId, but after some investigation, I've realized the upload path does not include the UniqueId.
So, the actual question is:
Is it possible to assert the folder path to the uploaded file, or is it a random Guid every time?
The second GUID is random, generated when the record is created and the file is saved into the media system. It's not the same as the record unique ID.
Running the code, it's apparent that the record is actually saved to the database after all the workflows are returned completed. Then the database gets populated with that random Id for the UFRecordStringData, and I'm not understanding the Key relation to anything else.
Do know how to map that table to the records?
Once the form is persisted, the UFRecords table gets populated with the full form data in the RecordData column.
The workflow I've created copies all the form responses to the member that is also created when the form is submitted.
The workflow needs to grab the path to the uploaded files and just copy them over to the members as well, but I am not finding a way to do this.
You might try attaching your workflow to the "approved" state rather than the "submitted" one. The record is saved after the "submitted" workflows are completed, but before the "approved" ones.
public static string? ParseFieldValueType(this FieldType fieldType, Field field, WorkflowExecutionContext context)
{
switch (fieldType.Alias)
{
case "fileUpload":
if (field.Values.Count == 0) return "";
//Needs to be set after approved, in order to work
var path = JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JObject>(context.Record.RecordData).GetValue(field.Id.ToString()).ToString();
return path;
case "dataConsent":
if (field.Values.Count == 0) return "";
return field.Values[0].ToString() == "true" ? "1" : "0";
case "checkbox":
case "dropdown":
case "multipleChoice":
return JsonConvert.SerializeObject(field.Values);
default: return field.Values.Count > 0 ? field.Values[0].ToString() : null;
}
}
Mapping Umbraco Form Data Types to default Umbraco Data Types
Is it possible to map Umbraco Forms data types into default Umbraco Data Types?
What I mean is something like this
In other words,
Get the equivalent Umbraco Datatype from a Form Field (data type) in order to add to a document type or member type.
Any suggestions or help will be much appreciated!
EDIT
I got as far as getting the details for the field using code from Umbraco Forms
But I still haven't figured out how to map that field into a data type.
Hi Carlos
Although there are similarities of course - Forms has a text field, as does the CMS; Forms has a text area, as does the CMS - there's nothing really that links these up. They are separate implementations.
As such you won't find a common alias or ID of the "data types" used in CMS and Forms.
I think you'll have to maintain a mapping - perhaps in a dictionary - that relates the ID or alias of the Forms and CMS equivalents, and then use that to associate them in your code.
Details of the Form's field types can be found here.
Hope that helps.
Andy
Thank you Andy!
I got as far as mapping the default types now, thanks!
But I'm still trying to figure out where the FieldType holds the DataType Id when it's a custom data type (like a checkbox list or dropdown). Or even the Form field itself.
Do you have any suggestions on that?
Sorry Carlos, but I'm not following that step I'm afraid. Are you referring to the "prevalues" (the options that you have to pick from when you have a checkbox list or a dropdown? If so, you probably need to be looking on the
Field
object, rather than theFieldType
.Actually, that's it, you got the idea.
Basically, I want to be able to map the prevalues to the member properties.
I want to be able to use each data type created for the pre-value source in the member properties
It's not perfect yet, but I think I've figured it out. Here's the code:
I figured out how to deal with the data types, except for file upload, how can I get the upload path?
How can I get the path to the uploaded file, programmatically?
Does anyone know how to get the Record Unique ID?
It's not quite clear where this code is living, but you need a
Record
instance, and from there you can accessrecord.UniqueId
.If you are doing this in a workflow, the the
Record
is available on theWorkflowExecutionContext
- see an example here.Andy
Yes Andy,
That was my assumption as well. I've used the context.Record.UniqueId, but after some investigation, I've realized the upload path does not include the UniqueId.
So, the actual question is: Is it possible to assert the folder path to the uploaded file, or is it a random Guid every time?
Example:
/media/forms/upload/form_4b41bb46-7d76-4b46-8e48-3a1c890520cd/74e760bd-9b8b-4448-8fe9-c6e01555ab6f/Requirements.pdf
The second GUID is random, generated when the record is created and the file is saved into the media system. It's not the same as the record unique ID.
Andy
Is there a way to get it, to save it to the member?
I'm not quite sure where you are at the point your code is running, but the path to the media file for uploads is stored as the record field value.
You can see this is what is stored in the database, e.g. with:
select * from UFRecordDataString where Value like '/media%'
So if you get the record field, as opposed to the form field. you may be able to retrieve it from the value there.
Running the code, it's apparent that the record is actually saved to the database after all the workflows are returned completed. Then the database gets populated with that random Id for the UFRecordStringData, and I'm not understanding the Key relation to anything else.
Once the form is persisted, the UFRecords table gets populated with the full form data in the RecordData column.
The workflow I've created copies all the form responses to the member that is also created when the form is submitted.
The workflow needs to grab the path to the uploaded files and just copy them over to the members as well, but I am not finding a way to do this.
You might try attaching your workflow to the "approved" state rather than the "submitted" one. The record is saved after the "submitted" workflows are completed, but before the "approved" ones.
Yes!! that was the ticket! :D
Here's the final code
Thank you Andy!!!
is working on a reply...