ASP.NET mobile Formview

Eine Formular für des Editieren oder Anzeigen von Daten wird in jeder Website benötigt. Da es sich um ein relativ einmaliges UI handelt spricht wenig dagegen, den HTML Code am Server rendern zu lassen. Mit einem ASP.NET Webforms Control ist das ziemlich leicht möglich. Konkret werde ich gleich ein Formview Steuerelement einsetzen. Dieses beinhaltet Templates für die jeweiligen Modis, z.B. Edit, Insert, Item.

Da  der Benutzer vermutlich mit einem virtuellem Keyboard arbeiten muss, sollte man so wenig wie nötig Eingaben verlangen um die Frustration gering zu halten. Eine 1:1 Abbildung eines EF Models erscheint mir deswegen nicht sinnvoll. Darüber hinaus, soll die Eingabe geführt erfolgen und mit entsprechender Validierungslogik versehen sein.

Am einfachsten erscheint mir hier eine Datenklasse mit Annotationen zu verwenden.

   1:  Public Class person
   2:      <Required(ErrorMessage:="ID vergeben")>
   3:      Public Property id As Integer
   4:      Public Property Name As String
   5:      <Range(18, 99, ErrorMessage:="Value muss {0} muss zwischen {1} und {2} liegen")>
   6:      Public Property alter As Integer
   7:  End Class

Zunächst lässt sich mit dem Placeholder Attribut dem Benutzer ein Tipp geben was in das Feld eigentlich rein soll.

   1:   <asp:TextBox ID="TextBox1" runat="server" placeholder="Nummer" ></asp:TextBox>

Weiters gibt es seit HTML 5 ein Attribut TextMode, das die Eingabe spezifisch gestalten soll. Die Browser machen da lustige Dinge daraus oder ignorieren es ganz.

image

Witzig wirds wenn man min und max ergänzt und das ganze als Range deklariert, was laut Visual Studio kein Attribut einer ASP:Textbox ist.

   1:  <asp:TextBox ID="TextBox1" runat="server" placeholder="Nummer" 
TextMode="Range" min="1" max="10" ></asp:TextBox>

Das Ergebnis ist ein Slider sowohl im IE10 als auch Chrome. Wobei der IE wesentlich hübscher ist.

image

In meinem Fall hat aus irgendwelchen Gründen der IE im vorigen Screenshot den Kompatibilitätsmodus angeschalten und dann sieht man keine Slider. Am besten per Metatag erzwingen HTML5

   1:   <meta http-equiv="X-UA-Compatible" content="IE=edge">

Für einen Number Wert mit Range oder auch Color, Date, DateTime, DateTimeLocal, Email, Month, Number, Range, Search, Phone, Time, Url  Week wird dann eine passende Fehlermeldung angezeigt.

image

Damit kann man wesentliche Teile lösen die sonst mit einzelnen ASP.NET Validator Controls durchgeführt werden. Bemerkenswert: das funktioniert ohne eine Zeile gerenderten JavaScript Code im Browser. Das Problem ist nur funktioniert das überall? Davon kann man leider nicht ausgehen. Folgend die Anwendung per JQuery Mobile gepimpt auf einem IPad Simulator

   1:  <link href="Content/jquery.mobile-1.3.0.css" rel="stylesheet" />
   2:  <link href="Content/jquery.mobile.theme-1.3.0.css" rel="stylesheet" />
   3:  <script src="Scripts/jquery-1.8.2.min.js"></script>
   4:  <script src="Scripts/jquery.mobile-1.3.0.js"></script>
   5:      

image

Im Windows Phone 7.1 Emulator siehts nicht anders aus. Keine Validierung durch HTML 5 Attribute im INPUT Element.

image

Noch ein wenig schwieriger wird es wenn es um die Simulation der virtuellen Tastatur geht. Mein Versuch auf Windows 8 METRO IE 10 zeigt, das  man mit dem Attribut “pattern” in der Tat wechselnde Tastaturen erhält. Recherche im Web zeigt das die Unterstützung dafür wenig verbreitet ist

   1:  pattern="[0-9]*"

Obiges zeigt das nummerische onscreen Keyboard.

Die DynamicData Controls enthalten seit … ASP.NET 3.5? eine Template Engine die abhängig von dem Datentyp ein komplettes Template laden. Also wenn ein Wert Nummerisch ist und editiert wird, dann kommt das Template integer_edit.ascx automatisch zum Einsatz. Darin sind die fünf relevanten Validator Controls enthalten, so das man sich eine Menge deklaratives Coding spart.

Im Edit Template des Formview platziere ich so eine Dynamic Control. Das Feld wird über Datafield gebunden.

   1:      <EditItemTemplate>
   2:         <fieldset data-role="fieldcontain"> 
   3:              <label>Eindeutige ID</label>
   4:              <asp:DynamicControl runat="server" ID="ID" DataField="ID" Mode="Edit" />
   5:                      </fieldset>

Leider kann man hier keine zusätzlichen Attribute einfügen. Diese werden nicht gerendert. Dazu gleich mehr.

Spannend ist neue Databinding in ASP.NET 4.5. Man kann nun zum einen eine typisierte Bindung über Itemtype erzeugen. Im <%# wird dann statt Eval direkt per Item.Feld der Wert in den HTML Code injiziert. Alles natürlich mit Visual Studio Intellisense Unterstützung.  Ein weiteres neues Feature von Modell Binding ist, das man nun direkt an Methoden entsprechend der CRUD Operationen binden kann. Hier z.B. SelectMethod.

   1:   <asp:FormView ID="FormView1" runat="server"
   2:                  ItemType="WebApplication2.person" 
   3:                  DefaultMode="Edit"
   4:                  SelectMethod="getPerson"
   5:                  RenderOuterTable="false">

Mit ganz wenig VB.NET Code wird dann das Binding erledigt

   1:   Public Function getPerson() As person
   2:          Dim p As New person
   3:          p.alter = 23
   4:          p.id = 1
   5:   
   6:          Return p
   7:      End Function

Dank der Annotationen sogar bereits mit einer automatischen Eingabeprüfung.

image

Wenn man ein ValidatinSummary Control dazu hängt, dann sieht man auch die Error Messages.

image

Im späteren mobilen UI sollten die Fehler Texte direkt unter den Textboxen angezeigt werden. Dazu muss man aber in die Templates von Dynamic Data rein. Hier Integer_Edit.ascx und den Text auf leer Setzen. Das aber nur als Side note.

   1:  <asp:TextBox ID="TextBox1" runat="server" CssClass="DDTextBox" 
Text='<%# FieldValueEditString %>' Columns="10" TextMode="Number"></asp:TextBox>
   2:   
   3:   
   4:  <asp:RequiredFieldValidator runat="server" ID="RequiredFieldValidator1
CssClass="DDControl DDValidator" ControlToValidate="TextBox1"
   5:      Display="Static" Enabled="false" Text="" />
   6:  <asp:CompareValidator runat="server" ID="CompareValidator1" 
CssClass="DDControl DDValidator" ControlToValidate="TextBox1" Display="Static"
   7:      Operator="DataTypeCheck" Type="Integer"/>
   8:  <asp:RegularExpressionValidator runat="server" ID="RegularExpressionValidator1"
CssClass="DDControl DDValidator" ControlToValidate="TextBox1" Display="Static" Enabled="false" />
   9:  <asp:RangeValidator runat="server" ID="RangeValidator1" CssClass="DDControl DDValidator" 
ControlToValidate="TextBox1" Type="Integer"
  10:      Enabled="false" EnableClientScript="true" MinimumValue="0" MaximumValue="100" Display="Static" />
  11:  <asp:DynamicValidator runat="server" ID="DynamicValidator1" CssClass="DDControl DDValidator"
ControlToValidate="TextBox1" Display="Static" />

Um einen Update durchzuführen muss eine simple Methode erstellt werden, die auch Serverseitig gleich auf die Gültigkeit des Modells prüft ( never trust the user).

   1:     Public Sub FormView1_UpdateItem(ByVal p As person)
   2:          if ModelState.IsValid Then
   3:             
   4:   
   5:   
   6:          End If
   7:      End Sub

Es fehlen bisher noch Schaltflächen oder Links die per CommandName Attribut an die Funktion des Formviews gebunden werden. Soweit zur Logik. Nun noch ein wenig um die mobile Darstellung kümmern.

Jquery Mobile verwendet data- Attribute. Im wesentlichen Page, Content oder Header. Aus mehreren Themes wird mit data-theme und einem einfachen Buchstaben von a-e ausgewählt.

   1:  <body data-role="page" data-theme="b">  
   2:      <form id="form1" runat="server">
   3:      
   4:          <div data-role="content">
   5:                 <asp:FormView ID="FormView1" runat="server"
   6:                  ItemType="WebApplication2.person"
   7:                  DefaultMode="Edit"
   8:                  SelectMethod="getPerson"
   9:                  UpdateMethod="FormView1_UpdateItem"
  10:                  RenderOuterTable="false">
  11:                  <EditItemTemplate>
  12:                      <div data-role="header" data-position="fixed">
  13:                          <h1>mein Formular</h1>
  14:                      </div>
  15:                      <div data-role="fieldcontain">
  16:                          <label for="ID">Eindeutige ID</label>
  17:                          <asp:DynamicControl runat="server" ID="ID" DataField="ID" Mode="Edit" />
  18:                      </div>
  19:                      <div data-role="fieldcontain">
  20:                          <label for="Name">voller Name</label>
  21:                          <asp:DynamicControl runat="server" ID="Name" DataField="Name" Mode="Edit" />
  22:                      </div>
  23:                      <div data-role="fieldcontain">
  24:                          <label for="Alter">Alter</label>
  25:                          <asp:DynamicControl runat="server" ID="Alter" DataField="Alter" Mode="Edit" />
  26:                      </div>
  27:                      <fieldset data-role="fieldcontain">
  28:                      <div>  
<asp:Button ID="UpdateButton" Text="Update" CommandName="Update" runat="server" /></div>
  29:                        
  30:                       <div>   
<asp:Button ID="CancelUpdateButton" Text="Cancel" CommandName="Cancel" runat="server" /></div>
  31:   
  32:                      </fieldset>
  33:                  </EditItemTemplate>
  34:                  <ItemTemplate>
  35:                  </ItemTemplate>
  36:              </asp:FormView>

Letztendlich noch mittels Viewport Metatag die Auflösung an die Device Auflösung anpassen. Wenn man das nicht macht zoomt der Browser, wenn man in ein Input Feld toucht.

   1:      <meta name="viewport" content="width=device-width" />

image

Mit wenig Aufwand lässt sich so mit ASP.NET Webforms eine mobile Web Anwendung erstellen auch ohne auf MVC zu setzen.

Kommentare sind geschlossen