im building some generic forms builder so im at the point where i can
public class Model
{
[Editor(typeof(CustomIntEditor), typeof(InputBase<>))]
public int? testInt{ get; set; }
}
so CustomIntEditor.razor
@using System.Diagnostics.CodeAnalysis
@using Microsoft.AspNetCore.Components.Forms
@inherits InputBase<int?>
<select @attributes="AdditionalAttributes"
type="number"
class="@CssClass"
value="@CurrentValueAsString"
@onchange="e => CurrentValueAsString = (string?)e.Value">
<option value =1>Choice 1</option>
<option value =2>Choice 2</option>
<option value =3 >Choice 3</option>
@code {
protected override string FormatValueAsString(int? value)
{
if (value != null) return value.ToString()!; else return string.Empty;
}
protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(false)] out int? result, [NotNullWhen(false)] out string? validationErrorMessage)
{
validationErrorMessage = null;
if (value != null) result = int.Parse(value!); else result = null;
return true;
}
}
so the question is how to this Editor pass some List<KeyValuePair<int,string>>
so i could build this options / values like
List<KeyValuePair<int,string>> L = new List<KeyValuePair<int,string>>(){
{1,"asd"},
{2,"bsd"}
}
.
.
.
[Editor(typeof(CustomIntEditor), typeof(InputBase<>),L)]
public int? testInt{ get; set; }
and loop on it to build the list like
<option value =@key>@value</option>
---------- update-----------
i have it now like this
private RenderFragment CreateOptionsListComponent() => builder =>
{
var optionsListAttribute = (OptionsListAttribute?)property.GetCustomAttributes(typeof(OptionsListAttribute), false).FirstOrDefault();
if (optionsListAttribute is not null)
{
var optionsList = (SortedDictionary<int, string>?)typeof(TModel).GetProperty(optionsListAttribute.List, typeof(SortedDictionary<int, string>))?.GetValue(model!);
}
builder.OpenComponent(0,typeof(InputOptionsListSelect<>).MakeGenericType(property!.PropertyType));
builder.AddAttribute(1, "Value", Value);
builder.AddAttribute(2, "ValueChanged", changeHandler);
builder.AddAttribute(3, "ValueExpression", lambdaExpression);
builder.AddAttribute(4, "id", FieldId());
builder.AddAttribute(5, "class", "form-control");
builder.CloseComponent();
}
but how pass this optionsList to this InputOptionsListSelect<> ? i canot instanciete this component myself ? it need parameterless ctor as far as i checked. any idea ?
i did try like this
builder.AddContent(6,ListOptions);
and
private RenderFragment ListOptions => (__builder) =>
{
foreach(var option in this.optionsList!)
{
__builder.OpenElement(7, "option");
__builder.AddAttribute(8, "value", option.Key);
__builder.AddContent(9, option.Value);
__builder.CloseElement();
}
};
but it did nothing at all. no idea where it is puting that ;P ----------------update2---------------- yes i see but still this noit solve my issue i havem o place for you are right but shis still does not solve it. i have nowhere place for <MySelect class="form-select" @bind-Value=modelData.Id />
please check
and
check how he uses InputEnumSelect - this is what i need to do but this is not an enum ;P
this is the concept that i took and base on this i do some modify / adding some features etc so no .razor in any of components - everything from the code
and initial component usage is
<DynamicFormComponent
TModel=DataX
Model=d
OnValidSubmitCallback="OnValidSubmit"
ShowValidationSummary=true
ShowValidationUnderField=true>
i found that i probably can do this via AdditionalAtributes cause it is string/object pair - not sure if it is best place for storing the list but it can be done this way i belive
thanks and regards !
I don't know how you're generating your form controls or doing your bindings but here's how to do the Attribute bit. I've wired it into a standard form so you can see the code in action.
Update
Based on the updated Question here's a custom component that shows how to get the model information and attribute value from the
ValueExpression
and build the option list.And a modified demo page:
Second Update
Here's the code from above implemented in a version of
InputEnumSelect