So, I have this Property
class that is defined by ID
Name
and DataType
.
DataType
is already populated with static values, and is being used as a drop down list.
Now when a user picks certain value from the list, List
value to be precise, application opens additional textbox and button, for populating that list.
Models go like this.
Property model
public class Property
{
public int ID {get; set;}
public string Name {get; set;}
public int DTypeID {get; set;}
public virtual DType DTypes {get; set;}
}
List model
public class DList
{
public int ID {get; set;}
public int PropertyID {get; set;}
public string ListValue {get; set;}
}
And this is what I've done so far.
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<div class="labels tableRow">
<div class="editor-label tableCell">
<p>
Name
</p>
<p>
Data Type
</p>
</div>
<div class="editor-field tableCell">
<p>
@Html.TextBoxFor(model => model.Name, new { @class = "textEntry" })
@Html.ValidationMessageFor(model => model.Name)
</p>
<p>
@Html.DropDownList("DTypeID", (SelectList)ViewBag.DTypeID, new { @class = "dropdown", @onchange = "DropDownChange()"})
@Html.ValidationMessageFor(model => model.DTypeID)
</p>
</div>
</div>
<div id="StaticListUI" class="invis">
<div class="labels tableRow">
<div class="editor-label tableCell">
<p>
@*here goes list*@
</p>
</div>
<div class="editor-field tableCell">
<p>
@*here goes textbox*@
@Html.TextBox("textboxList")
</p>
<p>
@*here goes button*@
<button name="button" value="add">Add</button>
</p>
</div>
</div>
</div>
<p class="labels">
@*<input type="submit" value="Create" />*@
<button name="button" value="create">Create</button> |
<input type="button" value="Back" onClick='javascript:location.href = "@Url.Action("Index", "Property")";' />
</p>
</fieldset>
}
So in order to capture which button is clicked I did this for my controller.
[HttpPost]
public ActionResult Create(string button, string textboxList, Property property)
{
if (button == "add")
{
var lastProperty = db.Properties.OrderByDescending(p => p.PropertyID).FirstOrDefault();
int propID;
if (lastProperty == null)
{
propID = 1;
}
else
{
propID = 1 + lastProperty.PropertyID;
}
DList dList = new DList();
dList.PropertyID = propID;
dList.ListValue = textboxList;
db.DLists.Add(dList);
return View(property);
}
string projectID = System.Web.HttpContext.Current.Session["_SelectedProjectID"].ToString();
int projID = Convert.ToInt32(projectID);
property.ProjectID = projID;
property.DateCreated = DateTime.Now;
property.DateEdited = DateTime.Now;
if (ModelState.IsValid)
{
db.Properties.Add(property);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.DTypeID = new SelectList(db.DType, "ID", "Name", property.DTypeID);
return View(property);
}
And the problem is that when I click Add
button, it still sends a check for ModelState.IsValid
, which shouldn't. What have I done wrong, or have I done anything right :(
Note: Everything else basically works.
EDIT
So I've altered the controller to accept parameters from button clicked differently. But still something is missing...
[ActionName("Create")]
[AcceptVerbs(HttpVerbs.Post)]
[AcceptParameter(Name = "button", Value = "add")]
public ActionResult Create_Add(string textboxList)
{
var lastProperty = db.Properties.OrderByDescending(p => p.PropertyID).FirstOrDefault();
int propID;
if (lastProperty == null)
{
propID = 1;
}
else
{
propID = 1 + lastProperty.PropertyID;
}
DList dList = new DList();
dList.PropertyID = propID;
dList.ListValue = textboxList;
db.DLists.Add(dList);
db.SaveChanges();
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
[AcceptParameter(Name="button", Value="create")]
public ActionResult Create(Property property)
{
string projectID = System.Web.HttpContext.Current.Session["_SelectedProjectID"].ToString();
int projID = Convert.ToInt32(projectID);
property.ProjectID = projID;
property.DateCreated = DateTime.Now;
property.DateEdited = DateTime.Now;
if (ModelState.IsValid)
{
db.Properties.Add(property);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.DTypeID = new SelectList(db.DType, "ID", "Name", property.DTypeID);
return View(property);
}
public class AcceptParameterAttribute : ActionMethodSelectorAttribute
{
public string Name { get; set; }
public string Value { get; set; }
public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
{
var req = controllerContext.RequestContext.HttpContext.Request;
return req.Form[this.Name] == this.Value;
}
}
You have
db.DLists.Add(dList);
but do don't save it in the database, you just return the view. You could putdb.Configuration.ValidateOnSaveEnabled = false;
above thedb.DLists.Add(dList);
and see if that works, however I think it should look like this:You may want to turn the Validate On Save back on before the return.
Update Perhaps you could try this: