Is it possible to write something like this?
<input class="form-control" id="name" name="name"
placeholder='<asp:Label runat="server" ID="lblFormName"></asp:Label>' type="text" required autofocus />
Solution 1: let ASP.Net render extra attributes
You can use the native TextBox control :
<asp:TextBox runat="server"
ID="name"
required="required"
autofocus="autofocus"
CssClass="form-control"
placeholder="myplaceholder" />
Extra attributes (ones that are not properties of the TextBox class), will be rendered as is:
Html result:
<input name="ctl00$MainContent$name"
type="text"
id="MainContent_name"
class="form-control"
required="required"
autofocus="autofocus"
placeholder="myplaceholder" />
If the generated id must be explicit, you can add CliendIDMode="Static":
<asp:TextBox runat="server"
ID="name"
required="required"
autofocus="autofocus"
CssClass="form-control"
placeholder="myplaceholder"
ClientIDMode="Static" />
Result:
<input name="ctl00$MainContent$name"
type="text"
id="name"
class="form-control"
required="required"
autofocus="autofocus"
placeholder="myplaceholder" />
Solution 2: write your own control
An even better approach is to extend the textbox class:
using System.Web.UI.WebControls;
namespace WebApplication1.Controls
{
public class TextBoxEx : TextBox
{
protected override void AddAttributesToRender(System.Web.UI.HtmlTextWriter writer)
{
if (AutoFocus) writer.AddAttribute("autofocus", "autofocus");
if (Required) writer.AddAttribute("required", "required");
if (!string.IsNullOrEmpty(PlaceHolder)) writer.AddAttribute("placeholder", PlaceHolder);
base.AddAttributesToRender(writer);
}
public string PlaceHolder
{
get {
var obj = ViewState["PlaceHolder"];
return obj != null ? (string)obj : default(string);
}
set { ViewState["PlaceHolder"] = value; }
}
public bool AutoFocus
{
get {
var obj = ViewState["AutoFocus"];
return obj != null ? (bool)obj : default(bool);
}
set { ViewState["AutoFocus"] = value; }
}
public bool Required
{
get {
var obj = ViewState["Required"];
return obj != null ? (bool)obj : default(bool);
}
set { ViewState["Required"] = value; }
}
}
}
Then you can register and use the control:
<%# Register Assembly="WebApplication1" TagPrefix="local" Namespace="WebApplication1.Controls" %>
....
<local:TextBoxEx runat="server" required="true" autofocus="true" PlaceHolder="my placeholder" />
You want to assign some value to one of HTML element's properties?
<asp:HiddenField runat="server" ID="lblFormName" />
<input class="form-control" id="name" name="name" placeholder='<%# lblFormName.Value %>' ...
Then you pass lblFormName.Value from CodeBehind.
You cannot declare a single ASP.NET control in a pure HTML page. It must be a ASP.NET page (aspx) which is processed by the server.
Related
My click event is showing the error "the name login_password and login_username does not exist in the current context" when I am trying to access my text box from their ids. please help me identify the error as I am just a beginner.
click event:
protected void LogIn_Clicked(object sender, EventArgs e)
{
string usern = "abc";
string pass = "123";
if (login_username.Text == usern && login_password.Text == pass)
{
Response.Redirect("Default.aspx");
}
else
{
label1.Text = "LogIn";
}
}
}
login form:
<form id="login" runat="server">
<h1 style = "Background-color: deepskyblue;">
Log in to your account!</h1>
<p class="register">
<a style = "color: deepskyblue;" href="Login.aspx?logoff=true">Logoff</a>
</p>
<div>
<label for="login_username">
Username</label>
<input type="text" name="username" id="login_username" class="field required" title="Please provide your username" onclick="return login_username_onclick()" />
</div>
<div>
<label for="login_password">
Password</label>
<input type="password" name="password" id="login_password" class="field required"
title="Password is required" />
</div>
<div class="submit">
<asp:Button ID="Button1" Text="Log in" runat="server" OnClick="LogIn_Clicked"
BackColor="#00B2EE" ForeColor="White" />
Those aren't Asp.net Controls. Add the runat="server" attribute:
<input type="text" name="username" id="login_username" class="field required" title="Please provide your username" onclick="return login_username_onclick()" runat="server"/>
Or you can add Asp.net controls:
<asp:TextBox runat="server" ID="login_username" CssClass="field required" ToolTip="Please provide your username"></asp:TextBox>
your inputs for username and password are html only - they need a runat="server" tag to get them in the code behind. The usual way is to use an asp:Textbox though.
My form code is not generating correct HTML. Here's my code.
Here's the form code:
#using (Html.BeginForm("SendEmail", "PropertyDetails", FormMethod.Post))
{
<fieldset>
<div class="left">
<label for="Name">Your Name</label>
<input type="text" required name="Name" />
<label for="Phone">Your Phone Number</label>
<input type="text" required name="Phone" />
<label for="Email">Your Email</label>
<input type="email" class="text" required name="Email" />
</div>
<div class="right">
<label for="Message">Your Message</label>
<textarea name="Message">
</textarea>
<input type="submit" name="submit" value="send" />
<div class="clear"></div>
</div>
<div class="clear"></div>
</fieldset>
}
Here's my Controller. I have a breakpoint on the first line of the SendMail message which isn't being hit:
public class PropertyDetailsController : Controller
{
[HttpPost]
public ActionResult SendEmail(EmailData email)
{
if (ModelState.IsValid) // BREAKPOINT ON THIS LINE ISN'T BEING HIT
{
etc.
Here's the class that should get populated with the form data and passed into the method (I'm not doing this myself. I assume it's happening automatically under the covers).
public class EmailData
{
private string _name;
private string _email;
private string _phone;
private string _message;
[Required]
[StringLength(50, MinimumLength = 1)]
public string Name
{
get { return _name; }
set { _name = value == null ? string.Empty : value.Trim(); }
}
[Required]
[RegularExpression(RegEx.Email, ErrorMessage = "Invalid e-mail address.")]
public string Email
{
get { return _email; }
set { _email = value == null ? string.Empty : value.Trim(); }
}
public string Phone
{
get { return _phone; }
set { _phone = value == null ? string.Empty : HtmlHelper.StripIllegalXmlChars(value.Trim()); }
}
[StringLength(500, MinimumLength = 1)]
public string Message
{
get { return _message; }
set { _message = value == null ? string.Empty : HtmlHelper.StripIllegalXmlChars(value.Trim()); }
}
}
Here's the HTML that's being generated:
<form action="" method="post">
<fieldset>
<div class="left">
<label for="Name">Your Name</label>
<input type="text" required name="Name" />
<label for="Phone">Your Phone Number</label>
<input type="text" required name="Phone" />
<label for="Email">Your Email</label>
<input type="email" class="text" required name="Email" />
</div>
<div class="right">
<label for="Message">Your Message</label>
<textarea name="Message">
</textarea>
<input type="submit" name="submit" value="send" />
<div class="clear"></div>
</div>
<div class="clear"></div>
</fieldset>
</form>
Any ideas why the action is empty?
Change your <form> declaration to this:
<% using (Html.BeginForm("SendEmail", "[Controller]")) { %>
<!-- Form data -->
<% } %>
Where [Controller] is the name of your Controller minus "Controller". In other words, if the controller name is HomeController, you would use "Home".
Try changing the form declaration within your view to this (using Razor syntax):
#using (this.Html.BeginForm("SendEmail", "[your controller name]", FormMethod.Post))
{
[form HTML]
}
The using statement will ensure that your form is closed correctly.
Also the HtmlHelper.BeginForm extension method is flexible enough that it generates the URI for the action based on the routes defined in your application's RouteCollection, such that if your routes change the form does not need to be updated; the change in URI is handled gracefully and automatically.
You need to add an action to your form
<form action="/SendEmail/" method="post">
But really this should be done using the MVC3 BeginForm helper.
You need to have your HTML rendered by a controller. So put your HTML in a View called "SendEmail" and write a controller action with an [HttpGet] attribute.
Call the Action "SendEmail" and in it just do return View().
Like this
[HttpGet]
public ActionResult SendEmail()
{
return View();
}
That will cause the BeginForm to render the action="" properly.
Then once that's working you are going to have a problem when you do post the data back because the input fields aren't bound to you model. You need to add #model yournamespace.EmailData to the very top of your View and then you need to change your inputs to bind to the model properties.
I've no idea how good this link is but it's the first one I found that looks like it might guide you through a similar process http://geekswithblogs.net/WinAZ/archive/2010/10/30/an-mvc-3-contact-form.aspx
I am trying to bind a dynamic array of elements to a view model where there might be missing indexes in the html
e.g. with the view model
class FooViewModel
{
public List<BarViewModel> Bars { get; set; }
}
class BarViewModel
{
public string Something { get; set; }
}
and the html
<input type="text" name="Bars[1].Something" value="a" />
<input type="text" name="Bars[3].Something" value="b" />
<input type="text" name="Bars[6].Something" value="c" />
at the moment, bars will just be null. how could I get the model binder to ignore any missing elements? i.e. the above would bind to:
FooViewModel
{
Bars
{
BarViewModel { Something = "a" },
BarViewModel { Something = "b" },
BarViewModel { Something = "c" }
}
}
Add the .Index as your first hidden input to deal with out of sequence elements as explained in this Phil Haacked blog post:
<input type="text" name="Bars.Index" value="" />
<input type="text" name="Bars[1].Something" value="a" />
<input type="text" name="Bars[3].Something" value="b" />
<input type="text" name="Bars[6].Something" value="c" />
A possible workaround could be to instantiate the ViewModel and the collection to the correct size (assuming it's known), then update it with TryUpdateModel... something like:
[HttpPost]
public ActionResult SomePostBack(FormCollection form)
{
// you could either look in the formcollection to get this, or retrieve it from the users' settings etc.
int collectionSize = 6;
FooViewModel bars = new FooViewModel();
bars.Bars = new List<BarViewModel>(collectionSize);
TryUpdateModel(bars, form.ToValueProvider());
return View(bars);
}H
MVC is able to populate list itself.
public ActionResult Index(FooViewModel model)
{
...
So no matter if anything is missing mvc will create new List<BarViewModel> and
for each found index - [1],[3],[6] it will create new BarViewModel and add it to List. So you will get FooViewModel with populated Bars.
i didnt know even that worked!
bearing that in mind, id have done something like:
<input type="text" name="Bars.Something" value="a" />
<input type="hidden" name="Bars.Something" value="" />
<input type="text" name="Bars.Something" value="b" />
<input type="hidden" name="Bars.Something" value="" />
<input type="hidden" name="Bars.Something" value="" />
<input type="text" name="Bars.Something" value="c" />
which would hopefully post
a,,b,,,c
but I suspect that will bind in the same way as you describe
Youre probably going to have write a custom model binder that looks for the max index, makes a list of that size then puts the elements in the correct place.
Saying all that, wait for someone else to post a really simple attribute you can put on your property that makes it just work ;D
I want to retain data in the view controls like drop down list, radio button, checkbox, textbox while displaying same view again with validation fail message. Data is in the drop down list bind using the ViewData. Check box data bind using viewdata. User enter values in the textbox and for checkbox control.
When view is displayed with the validation messages controls are reset and for drop down list data needs to be passed in the viewData before displaying view. Please let me know any solution to this.
Thanks & Regards,
Tsara.
Find the required code below
Please find below View . There is some data in the drop down list and also in the check box. For the first time page render it is passed in the ViewData.
<div id="RegisterLogin">
<label id="Label1"> Project:</label>
<%= Html.Label( Convert.ToString(ViewData["SelectedProject"])) %>
<%= Html.DropDownList("ProjectCode", (SelectList)ViewData["ddlProject"], "--Select--", new { id = "ddlProject" , title = "Select Project" })%>
<br />
<br />
<label id="Label2">
Select User:</label>
<%= Html.DropDownList("ddlUsers", (SelectList)ViewData["ddlUsers"], "--Select User--", new { id = "ddlUsers", title = "Select User" })%>
<br />
<br />
<label id="spacing">
Username:</label>
<input type="text" name="txtUserName" title="Enter username" id="txtUserName" />
<%= Html.ValidationMessage("username") %>
<br />
<br />
<label id="leftalign">
Password :</label>
<input type="password" name="txtPassword" title="Enter your password" id="txtPassword" />
<%= Html.ValidationMessage("password") %>
<br />
<br />
Confirm Password :
<input type="password" name="txtConfirmPassword" title="Confirm your password" id="txtConfirmPassword" />
<%= Html.ValidationMessage("confirmPassword") %>
<br />
<br />
<label id="space" >Email :</label>
<input type="text" name="txtEmailId" title="Enter your email id" id="txtEmailId" />
<%= Html.ValidationMessage("email") %>
<br />
<br />
<label id="rolealign"> Assign Role : </label>
<div class="listPermissions">
<%= Html.ValidationMessage("role") %>
<% Dictionary<string, string> lstRoles = ViewData["ListRoles"] as Dictionary<string, string>; %>
<% if (lstRoles != null)
{
int iCounter = 1;
foreach (KeyValuePair<String,String> item in lstRoles)
{ %>
<%= Html.CheckBoxCustom(Convert.ToString(iCounter+1), "chkRole", item.Value,"") %>
<%= Html.Encode(item.Key) %><br />
<%}
}%>
</div>
<br />
<input type="image" src="../../Content/save.jpg" value="Save" alt="Save" style="padding-left:250px;"/>
<%--<img src="../../Content/save.jpg" alt="Save" id="imageGO" />--%>
<img src="../../Content/reset.jpg" onclick="document.forms[0].reset()" alt="Reset"/>
<%--<img src="../../Content/reset.jpg" alt="Reset" onclick="return btnCancel_onclick()" />--%>
</div>
In postback function call validation is done as follows
public ActionResult Register(string txtUserName, string txtPassword, string txtConfirmPassword, string txtEmailId, FormCollection frmCollection)
{
string strValue = frmCollection.Get("chkRole");
ViewData["PasswordLength"] = MembershipService.MinPasswordLength;
if (ValidateRegistration(txtUserName, txtEmailId, txtPassword, txtConfirmPassword, frmCollection))
{
if (strValue == "")
{
ModelState.AddModelError("role", "Please select the role");
}
else
{
// Attempt to register the user
MembershipCreateStatus createStatus = MembershipService.CreateUser(txtUserName, txtPassword, txtEmailId);
if (createStatus == MembershipCreateStatus.Success)
{
FormsAuth.SignIn(txtUserName, false /* createPersistentCookie */);
// Create an empty Profile for the newly created user
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("_FORM", ErrorCodeToString(createStatus));
}
}
}
//IDictionary<string, ValueProviderResult> valueProvider = frmCollection.ToValueProvider();
//Dictionary<string, string> valueProvider = frmCollection.AllKeys.ToDictionary(k => k, v => frmCollection[v]);
//foreach (string i in valueProvider.Keys)
//{
// ModelState.SetModelValue(i, valueProvider[i]);
//}
//Get list of projects
ProjectOperations objProjectOperations = new ProjectOperations();
List<Project> lstProjects = objProjectOperations.GetAll();
//Logging://Verbose:
logEntry = new LogEntry("List of project added into view data", "AzureTableLogs", 0, 0, System.Diagnostics.TraceEventType.Verbose, "", null);
Logger.Write(logEntry);
ViewData["ddlProject"] = new SelectList(lstProjects, "ProjectCode", "ProjectName");
MembershipUserCollection lstUser = Membership.GetAllUsers();
ViewData["ddlUsers"] = new SelectList(lstUser, "UserName", "UserName");
//MembershipUserCollection lstUser= Membership.GetAllUsers();
// If we got this far, something failed, redisplay form
return View();
}
Every time before displaying view need to have values in the view data.
For resolve this i tried solution i got like
IDictionary valueProvider = frmCollection.ToValueProvider();
but it is not supported in mvc 2.0.
If you need more details please let me know.
If I have an html input "<input id="score1" type="text" value=""/>" and want to initialize it on the c# page load, but I don't want to use asp controls.How do I do it?
Thanks
You can use server-side plain HTML controls, by just using runat="server".
For instance:
<input type="text" runat="server" id="myTextBox" />
// ...and then in the code-behind...
myTextBox.Value = "harbl";
<input id="score1" type="text" runat="server" value=""/>
Then in your page's load event:
score1.Value = "some value";
You could set a property on the page codebehind, the access the property on the page
public class MyPage
{
public string InputDefaultContent { get; set; }
private void Page_Load(object s, EventArgs e)
{
InputDefaultContent = "Blah";
}
}
then on the page
<input type="text" value="<%= InputDefaultContent %>" />
<input type='text' value='default value' />