3

My customer wants a form which has to contain the following items:

  • name
  • email
  • address
  • state

On the admin panel of this application he wants to set the order of the form items on the admin panel. What is the best way to approach this? i want to keep correct validation for each field.

I was thinking of an array that contains the order of the form items but i have no idea how to display the form items in that order.

The sort order needs tobe set in the database.

I would appreciate help

tereško
  • 58,060
  • 25
  • 98
  • 150
Bernardmoes
  • 340
  • 1
  • 3
  • 13

2 Answers2

1

One option would be to order them on the client-side.

Steps to accomplish this:

  • In some way, you would have to associate each form field with the respective order number.
  • Form the HTML in a way that you could identify the order of each field.
  • Implement javascript logic to handle the HTML and display the fields in the proper order.

An example:

Let's say that each form field would be on a div with a common identifier and the order number:

<div id="official_div">
</div>
<div style="display:none">
    <div id="form_field_2">
       <--! Name Field here -->
    </div>
    <div id="form_field_1">
       <--! Email Field here -->
    </div>
    <div id="form_field_3">
      <--! Address Field here -->
    </div>
</div>

Now, knowing the number of fields, you could implement some javascript logic to get those fields together with the proper order and put them on the actual form field official div:

  var officialDiv = document.getElementById('official_div');
  for(var i =1; i <= numberOfFields; i++)
  {
       var element  = document.getElementById('form_field_' + i);
       //include element inside officialDiv 
  }
Mateus Schneiders
  • 4,853
  • 3
  • 20
  • 40
1

First you have to create a database table, TextBoxes to hold the settings (which will also be modified from the administration panel), with the following columns:

CREATE TABLE TextBoxes
(
    Id int NOT NULL PRIMARY KEY,
    Ordinal int NOT NULL,
    TextBoxName nvarchar(255) NOT NULL
);

Add a few records to it by using TextBoxName values like name, address, state etc - this will later be used to map the UI control - and the desired order in the Ordinal column. Add the table to your model.

Create the following class (I'll assume that the entity containing the properties in the question is named Contact):

public class MyDataAnnotationsModelMetadataProvider : 
    System.Web.Mvc.DataAnnotationsModelMetadataProvider
{
    protected override System.Web.Mvc.ModelMetadata 
        CreateMetadata(IEnumerable<Attribute> attributes, 
            Type containerType, 
            Func<object> modelAccessor, 
            Type modelType, 
            string propertyName)
    {
        if (containerType == typeof(Contact))
        {
            // get the repository instance  
            var db = new MyModelEntities();
            // find the current textbox by it's property name
            var textBox = db.TextBoxes
                .FirstOrDefault(t => t.TextBoxName == propertyName);
            if (!string.IsNullOrWhiteSpace(propertyName) && textBox != null)
                attributes = attributes.Union(new List<Attribute>() {
                    new DisplayAttribute() { Order = textBox.Ordinal } 
                });
        }
        return base.CreateMetadata(attributes, 
            containerType, 
            modelAccessor, 
            modelType, 
            propertyName);
    }
}

In the Global.asax.cs file, modify the Application_Start method:

protected void Application_Start()
{
    // set the current metadata provider to our custom class
    ModelMetadataProviders.Current = new MyDataAnnotationsModelMetadataProvider();
    // other method content
    AreaRegistration.RegisterAllAreas();
    // etc
}

Note: The example above will allow you to dynamically change the order of the text boxes for one model, but if you add another property in the TextBoxes model to hold the order for the properties for multiple models, you could extend the logic to your other models through some extra filtering.

Alex Filipovici
  • 31,789
  • 6
  • 54
  • 78