Cannot pass SelectedValue and Text to Controller for a KendoUIDropDownListFor widget - asp.net-mvc-4

This works fine if I don't use any KendoUI functionality and am able to pass it easily using a regular Html.DropDownListfor helper (seen as comments in the code). The Description and the StatusID both do not come through.
How can I pass these values to the controller after selecting them in the dropdown list and then clicking enter with the KendoUI extension?
If I uncomment the Value and Text properties, I get "Object not set to an instance of an Object".
#using (Html.BeginForm("AddSingleStatus", "Status", new AjaxOptions { HttpMethod = "POST", }))
{
#Html.ValidationSummary(true)
<table>
<tr>
<td>
<div class="display-label">
#Html.LabelFor(model => Model.Description);
</div>
<div class="display-label" style="display: none;">
#Html.HiddenFor(model => Model.Description)
</div>
<div class="editor-field">
#(Html.Kendo().DropDownListFor(model => Model.StatusID)
.Name("statusDropDownList")
.DataTextField("Description")
.DataValueField("StatusID")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("ReadDDL", "Status");
})
.ServerFiltering(false);
})
.OptionLabel("Select a status")
.SelectedIndex(0)
.Events(e => e
.Change("dropdownlist_change")
)
)
#* #Html.DropDownListFor(model => Model.StatusID, new SelectList((YeagerTechModel.Status[])ViewData["statuses"], "StatusID", "Description"));*#
#*#Html.ValidationMessageFor(model => Model.StatusID)*#
</div>
</td>
</tr>
<tr>
<td>
<input type="submit" id="ddlSubmit" value='#Resources.Add' />
</td>
</tr>
</table>
}
<script type="text/javascript">
function dropdownlist_change()
{
var dropdownlist = $("#statusDropDownList").data("kendoDropDownList");
dropdownlist.bind("change", function (e)
{
var value = dropdownlist.value();
});
}
</script>

Related

How do you open a kendo drop down popup on page load?

I have several uses for kendo drop-downs in my application (DDL, ComboBox, etc.).
I want them to open up on page load, but Kendo's documentation doesn't indicate that is possible.
I am using the MVC server variables.
This is my view coding:
<script id="itemTemplate" type="text/x-kendo-template">
# var index=FullName.indexOf(" *****");
if (index > 0)
{
#
<span style="font-weight:bold;">
#: FullName.substring(0, index)#
</span>
#
} else {
#
<span style="font-weight:normal;">
#: FullName#
</span>
#
}
#
</script>
<table class="form-horizontal table-condensed" style="width:100%;">
<tr style="height:400px;">
<td style="width:40%;vertical-align:top;">
<h4 style="width:100%;text-align:center;">Available Members</h4>
<h4 style="width:100%;text-align:center;font-size:smaller;">Current Cancer Center Members are highlighted in Bold.</h4>
#(Html.Kendo()
.MultiSelect()
.Name("AvailableWGMembers")
.DataTextField("FullName")
.DataValueField("id")
.ItemTemplateId("itemTemplate")
.TagTemplateId("itemTemplate")
.BindTo((System.Collections.IEnumerable)ViewBag.AvailableWGMembers)
.AutoBind(true)
.Placeholder("Click here to select one or more members to add, ...")
.AutoClose(false)
.HtmlAttributes(new { style = "width:100%;", #class = "Roles" })
.Events(events => { events.Change("doRoles");})
.Value(new int[0])
.Height(650)
)
</td>
<td style="width:20%;text-align:center;vertical-align:top;">
<input id="btnAdd" type="submit" value="Select" class="btn btn-default" disabled="disabled" />
</td>
<td style="width:40%;vertical-align:top;">
<h4 style="width:100%;text-align:center;">#Model.WGTitle</h4>
<h4 style="width:100%;text-align:center;font-size:smaller;">Current Cancer Center Members are highlighted in Bold.</h4>
#(Html.Kendo()
.MultiSelect()
.Name("ExistingWGMembers")
.AutoBind(false)
.DataTextField("FullName")
.DataValueField("id")
.ItemTemplateId("itemTemplate")
.TagTemplateId("itemTemplate")
.BindTo((System.Collections.IEnumerable)ViewBag.ExistingWGMembers)
.Placeholder("Click here to select one or more members to remove, ...")
.AutoClose(true)
.HtmlAttributes(new { style = "width:100%;", #class = "UnusedRoles" })
.Events(events => { events.Change("doRoles"); })
.Value(new int[0])
.Height(650)
)
</td>
</tr>
</table>
I want the lists to both be open when the page loads, and I want to be able to use unobstrusive jQuery or javascript to control it if I have to.
Does anyone have any suggestions?
It took a little digging, but I finally figured out the answer. It was actually pretty simple.
The following should be added to the unobstrusive javascript code file:
function openPopup(e)
{
if (e.sender.list[0].childNodes['1'].childNodes['0'].childElementCount > 0) {
e.sender.popup.open();
}
}
You add the following code to your event listing:
.Events(events => { ...; events.DataBound("openPopup"); })
This can be done with any of the lists that have popups like Kendo DropDownList or ComboBox or MultiSelect.
I would check for the list length to make sure the list has members so you don't get an ugly empty list shown, but otherwise the result is actually pretty simple.
This answer is dependent upon the code example at: http://demos.telerik.com/aspnet-mvc/window/index
I took that example from the Index.cshtml version of their example and simply replaced the Content value of the # with your table template from the original question:
#(Html.Kendo().Window()
.Name("window")
.Title("Your modal popup with dropdown menus")
.Content(#<text>
<table class="form-horizontal table-condensed" style="width:100%;">
<tr style="height:400px;">
<td style="width:40%;vertical-align:top;">
<h4 style="width:100%;text-align:center;">Available Members</h4>
<h4 style="width:100%;text-align:center;font-size:smaller;">Current Cancer Center Members are highlighted in Bold.</h4>
#(Html.Kendo()
.MultiSelect()
.Name("AvailableWGMembers")
.DataTextField("FullName")
.DataValueField("id")
.ItemTemplateId("itemTemplate")
.TagTemplateId("itemTemplate")
.BindTo((System.Collections.IEnumerable)ViewBag.AvailableWGMembers)
.AutoBind(true)
.Placeholder("Click here to select one or more members to add, ...")
.AutoClose(false)
.HtmlAttributes(new { style = "width:100%;", #class = "Roles" })
.Events(events => { events.Change("doRoles");})
.Value(new int[0])
.Height(650)
)
</td>
<td style="width:20%;text-align:center;vertical-align:top;">
<input id="btnAdd" type="submit" value="Select" class="btn btn-default" disabled="disabled" />
</td>
<td style="width:40%;vertical-align:top;">
<h4 style="width:100%;text-align:center;">#Model.WGTitle</h4>
<h4 style="width:100%;text-align:center;font-size:smaller;">Current Cancer Center Members are highlighted in Bold.</h4>
#(Html.Kendo()
.MultiSelect()
.Name("ExistingWGMembers")
.AutoBind(false)
.DataTextField("FullName")
.DataValueField("id")
.ItemTemplateId("itemTemplate")
.TagTemplateId("itemTemplate")
.BindTo((System.Collections.IEnumerable)ViewBag.ExistingWGMembers)
.Placeholder("Click here to select one or more members to remove, ...")
.AutoClose(true)
.HtmlAttributes(new { style = "width:100%;", #class = "UnusedRoles" })
.Events(events => { events.Change("doRoles"); })
.Value(new int[0])
.Height(650)
)
</td>
</tr>
</table>
</text>)
.Draggable()
.Resizable()
.Width(600)
.Actions(actions => actions.Pin().Minimize().Maximize().Close())
.Events(ev => ev.Close("onClose"))
)
I hope this helps!

why call to saveChanges() throws error "Object reference not set to an instance of an object."

i have the following code for view:
#model test1.Models.CustomerVM
#{
ViewBag.Title = "Create";
}
<link href="~/Content/themes/base/jquery.ui.all.css" rel="stylesheet" />
<h2>Create</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Customer</legend>
#Html.HiddenFor(model=>model.UserId)
#Html.HiddenFor(model=>model.Id)
<div class="editor-label">
#Html.LabelFor(model => model.User)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.User)
#Html.ValidationMessageFor(model => model.User)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Password)
</div>
<div class="editor-field">
#Html.PasswordFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ConfirmPassword)
</div>
<div class="editor-field">
#Html.PasswordFor(model => model.ConfirmPassword)
#Html.ValidationMessageFor(model => model.ConfirmPassword)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.NameTitle)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.NameTitle, Model.NameTitleColl)
#Html.ValidationMessageFor(model => model.NameTitle)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.FName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.FName)
#Html.ValidationMessageFor(model => model.FName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.LName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.LName)
#Html.ValidationMessageFor(model => model.LName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Gender)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.Gender, Model.GenderColl)
#Html.ValidationMessageFor(model => model.Gender)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.DOB)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.DOB)
#Html.ValidationMessageFor(model => model.DOB)
</div>
#* contacts *#
<div class="editor-label">
#Html.LabelFor(model => model.AddressL1)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.AddressL1)
#Html.ValidationMessageFor(model => model.AddressL1)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.AddressL2)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.AddressL2)
#Html.ValidationMessageFor(model => model.AddressL2)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Suburb)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Suburb)
#Html.ValidationMessageFor(model => model.Suburb)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Country)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Country)
#Html.ValidationMessageFor(model => model.Country)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Phone)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Phone)
#Html.ValidationMessageFor(model => model.Phone)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
<script src="~/Scripts/jquery-2.1.4.min.js"></script>
<script src="~/Scripts/jquery-ui-1.11.4.min.js"></script>
#Scripts.Render("~/bundles/jqueryval")
<script>
$(document).ready(function () {
$('#DOB').datepicker({
appendText: 'mm/dd/yyyy',
showOn: 'both',
buttonText: 'click me',
dateFormat: 'mm/dd/yy',
changeMonth: 'true',
changeYear: 'true',
yearRange: '1900:2016'
});
});
</script>
}
the view works fine displays data as it should be. but when i click Create to save record the following error throws : Object reference not set to an instance of an object This is thrown when it executes the line db.SaveChanges();
Here is the action that does the save. Note: though the view has more field but im not saving all only the ones i have stated in Create() will be saved a.k.a only data in mst_users will be saved
[HttpPost]
public ActionResult Create(CustomerVM custObject)
{
if (ModelState.IsValid)
{
mst_users user = new mst_users
{
uName=custObject.User,
password=custObject.Password,
dtCreated=DateTime.UtcNow,
isLocked=false
};
db.mst_users.Add(user);
db.SaveChanges();
}
}
when i check the receiving data to the method it has all the required data to do the save but funny thing is when it throws the exception the debugger takes the control to the the view and points to the NameTitle field.
Line 44: </div>
Line 45: <div class="editor-field">
Line 46: #Html.DropDownListFor(model => model.NameTitle, Model.NameTitleColl)
Line 47: #Html.ValidationMessageFor(model => model.NameTitle)
Line 48: </div>
here is the table that maps to Entity class mst_users
[uName] varchar
[password] varchar
[dtCreated] datetime
[dtUpdated] datetime
[isLocked] bit
here is the entity class:
here is the video
Here is a null reference error video
As you stated that:
but funny thing is when it throws the exception the debugger takes the control to the the view and points to the NameTitle field.
The problem is not exactly at SaveChanges(), but the exception actually occurs when your action is successfully executed and your same Create view is rendered again. This time, your Model or Model.NameTitleColl is null.
When you make get call to your Create action, you must be populating your CustomerVM method and returning it to view. But after making POST call call to your Create method, if you want to render the same view again, you must populate your CustomerVM again, at the end, and pass it to the view. something like:
[HttpPost]
public ActionResult Create(CustomerVM custObject)
{
if (ModelState.IsValid)
{
mst_users user = new mst_users
{
uName=custObject.User,
password=custObject.Password,
dtCreated=DateTime.UtcNow,
isLocked=false
};
db.mst_users.Add(user);
db.SaveChanges();
}
return View(custObject);
//or return View(new CustomerVM()) just to make you understand
}
UPDATE: (based on video you attached)
You are only populating User, Password and ConfirmPassword field of your CustomerVM model. And you have decorated your Address, Fname and several other properties with *[Required]* attribute. Which means, it MUST not be null when posted, (in order to make model valid). Otherwise, your model state would be invalid. You can clearly see in video, custObject contains null for required values. so exactly as expected, you ModelState.IsValid will give you false in return.
UPDATE: (based on second video you attached)
You are right, your exception occurs at db.SaveChanges() line. The reason for why your debugger takes you to view is following piece of code in your action:
try
{
....
db.SaveChanges();
}
catch()
{
return View(); // <- this line
}
so technically, exception occurs, and the control of your program is moved to your catch block. and you execute return View() in order to handle your exception and when view is rendered, Model.NameTitleColl is null. This throws another exception, which you actually see. whereas, you have skipped the orignal exception.
Reason and Solution:
From your code, I can see, you do not initialize your db object in your action, which throws the orignal exception. Please initialize the db object before you perform any action on it. You can do something like:
db = new YourDbContextNameHere(); //initialize your db object with your Dbcontext class constructor
and then do:
db.mst_users.Add(user);
db.SaveChanges();
it will work fine this way.
This NullPointerException is thrown for db or db.mst_users? In my opinion any one of them is not properly Instantiated.
Based on #Zeeshan answer, I presume your mst_users is being saved to the database the very first time you click the Create button. The problem is likely to be that you are returning same view without passing in the appropriate model that contains the Model.NameTitleColl which is used to populate the dropdown. Hence, the NullExpception.
Update 1
Your model will be invalid because most of your required fields in CustomerVM are null.
For example
the following required field
LName, FName etc are all null. in your video, this values are not provided in the view.

Razor Engine Issue in MVC4

When I declare a text box in view page the below error will appear
The type arguments for method 'System.Web.Mvc.Html.InputExtensions.TextBoxFor<TModel,TProperty>(System.Web.Mvc.HtmlHelper<TModel>,
System.Linq.Expressions.Expression<System.Func<TModel,TProperty>>)'
cannot be inferred from the usage. Try specifying the type arguments
explicitly
even I included
<compilation debug="true" targetFramework="4.0">
<!-- ... -->
</compilation>
this in webconfig file
but the same error shows .
............
my code
#Html.TextBoxFor(x => x.Entity, new { #id = "Entityname" })
//..........
model
public string Entity { set; get; }
//.........
//..............
.cshtml page
#model BOSSNew.Models.NewQuantifierM
#{Layout = "../Shared/_Layout.cshtml";}
<div class="breadCrumbHolder">
#{Html.RenderAction("BreadCrumb", "Base", new { menulist = new string[] { "Quantifier", "New Quantifier" }, CurrentURL = new string[] { "#", "#" } });}
</div>
<div class="divContentPane">
<div class="contentPaneHead">
<span class="contentPaneTitle">Users Details </span>
</div>
<table class="ClsTable ClsPad0">
<tr class="even">
<th>#LabelHelper.GetLabel("THLentity", 3)
</th>
<td>
#Html.TextBoxFor(x => x.Entity, new { #id = "Entityname" })
<img title="" id="selectentit" style="margin: 5px" onclick="getentity('txtentity','optentity')"
alt="" src="../../../Name.Controls/Themes/Name-Theme/images/entity.png">
</td>
</tr>
</table>
</div>
//.............
Any idea ?
Any help will be appreciated
You haven't defined model for a view, so you can't use
x => x.Field
expression.
It should look more or less like that:
SomeView.cshtml
#model SomeModel
#{Layout = "../Shared/_Layout.cshtml";}
<div class="breadCrumbHolder">
#{Html.RenderAction("BreadCrumb", "Base", new { menulist = new string[] { "Quantifier", "New Quantifier" }, CurrentURL = new string[] { "#", "#" } });}
</div>
<div class="divContentPane">
<div class="contentPaneHead">
<span class="contentPaneTitle">Users Details </span>
</div>
<table class="ClsTable ClsPad0">
<tr class="even">
<th>#LabelHelper.GetLabel("THLentity", 3)
</th>
<td>
#Html.TextBoxFor(x => x.Entity, new { #id = "Entityname" })
<img title="" id="selectentit" style="margin: 5px" onclick="getentity('txtentity','optentity')"
alt="" src="../../../Name.Controls/Themes/Name-Theme/images/entity.png">
</td>
</tr>
</table>
</div>
SomeModel.cs
public class SomeModel
{
public string Entity { set; get; }
}
And finally in your action method...
public ActionResult SomeMethod()
{
var model = new SomeModel();
//here fill the entity field
return View(model);
}

Retaining Form Values After Post (not part of model)

I have a MVC4 page that has a form with a collection of checkboxes, radio buttons and textboxes used as the search fields. Upon post the selections are parsed and the lower results grid is updated with new results. Right now all the form values are wiped out upon return and the new results are displayed in the grid - only the grid is part of the model.
I want all the form selections to retain their values after post so the user can see (and change) the selections for next post/search. The form is popuplated with viewbags.
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "searchform" }))
{
#Html.ValidationSummary("Please correct the following errors")
<div style="float:left;">
<div style="float:left;">
<label>Name:</label>
#Html.TextBox("name")
</div>
<div style="float:left; margin-left:15px">
<label>Company:</label>
#Html.TextBox("company")
</div>
<div style="float:left; margin-left:65px">
<label>Date Range:</label>
#Html.TextBox("dateStart", "", new { #class = "datefield", type = "date" })
to
#Html.TextBox("dateEnd", "", new { #class = "datefield", type = "date" })
</div>
</div>
<div style="clear: both;">
Match Any Categories? <input type="radio" name="categoryMatchAll" value="false" checked="checked" />
Match All Categories? <input type="radio" name="categoryMatchAll" value="true" />
</div>
<div style="float:left;">
<div id="searchform-categories" style="float:left;">
<div class="scroll_checkboxes">
<label>Categories</label>
<ul>
#foreach (var x in ViewBag.Categories)
{
<li>
<input type="checkbox" name="categories" value="#x.Id"/>
#x.Name
</li>
}
</ul>
</div>
</div>
<div id="searchform-diversity" style="float:left; margin-left:30px">
<div class="search-selection" style="float:left;">
<label>Minority Owned</label>
<ul>
#foreach (var x in ViewBag.Minorities)
{
<li>
#Html.RadioButton("minorities", (String)x.Id.ToString())
#x.Name
</li>
}
</ul>
</div>
<div class="search-selection" style="float:left;">
<label>Diversity Class</label>
<ul>
#foreach (var x in ViewBag.Classifications)
{
<li>
#Html.RadioButton("classifications", (String)x.Id.ToString())
#x.Name
</li>
}
</ul>
</div>
</div>
</div>
<div style="clear: both;">
<input type="submit" value="Search Profiles" />
<input type="submit" value="Reset" />
</div>
}
the data grid is bound to the model as
#model IEnumerable<VendorProfileIntranet.Models.VendorProfile>
<table id="VendorTable" width="100%" class="gradeA">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.CompanyName)
</th>
<th>
#Html.DisplayNameFor(model => model.City)
</th>
<th>
#Html.DisplayNameFor(model => model.State)
</th>
<th>
#Html.DisplayNameFor(model => model.DateCreated)
</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td class="list-field">
#Html.DisplayFor(modelItem => item.Name)
</td>
<td class="list-field">
#Html.DisplayFor(modelItem => item.CompanyName)
</td>
<td class="list-field">
#Html.DisplayFor(modelItem => item.City)
</td>
<td>
#Html.DisplayFor(modelItem => item.State)
</td>
<td class="list-field">
#Html.DisplayFor(modelItem => item.DateCreated)
</td>
<td class="list-field">
#Html.ActionLink("Edit", "Edit", new { id = item.ProfileID }) |
#Html.ActionLink("View", "View", new { id = item.ProfileID }) |
#Html.ActionLink("Delete", "Delete", new { id = item.ProfileID }, new { onclick = " return DeleteConfirm()" })
</td>
</tr>
}
</tbody>
<tfoot>
<tr>
<td> </td>
</tr>
</tfoot>
if you are using html in mvc then check solution 2 from here, value="#Request["txtNumber1"]" worked fine for me,
<input type="text" id="txtNumber1" name="txtNumber1" value="#Request["txtNumber1"]"/>
hope helps someone.
So here is how I typically solve this problem. My notes are purely my opinion (religous?) about naming classes in an MVC project to keep clear their purpose.
Couple of interfaces to keep it extensible:
// be specific about what type of results, both in the name of the
// interface and the property needed, you don't want to have overlapping
// properies on your classes, I like suffixing interfaces that are specific
// to a View or Partial View with View
public interface IPersonSearchResultsView
{
IEnumerable<EFPerson> PersonSearchResults { get; }
}
public interface IPersonSearchCriteriaView
{
PersonSearchCriteriaModel PersonSearchModel { get; }
}
Couple of classes
// I like suffixing classes that I only use for MVC with Model
public PersonSearchCriteriaModel
{
public string Name {get; set;}
public string Company {get; set;}
public string DateStart {get; set;}
public string DateEnd {get; set;}
}
// I like suffixing classes that I used passed to a View/Partial View
// with ViewModel
public class PersonSearchViewModel : IPersonSearchResultsView,
IPersonSearchCriteriaView
{
public IEnumerable<EFPerson> PersonSearchResults { get; set; }
public PersonSearchCriteriaModel PersonSearchModel { get; set; }
}
Now for your controllers, I'll set them up in a way that would also allow you to do Ajax in the future.
public PersonController : Controller
{
public ActionResult Search()
{
var model = new PersonSearchViewModel();
// make sure we don't get a null reference exceptions
model.PersonSearchModel = new PersonSearchCriteriaModel ();
model.PersonSearchResults = new List<EFPerson>();
return this.View(model);
}
[HttpPost]
public ActionResult Search(PersonSearchViewModel model)
{
model.PersonSearchResults = this.GetPersonResults(model.PersonSearchModel);
return this.View(model)
}
// You could use this for Ajax
public ActionResult Results(PersonSearchViewModel model)
{
model.PersonSearchResults = this.GetPersonResults(model.PersonSearchModel);
return this.Partial("Partial-SearchResults", model)
}
private GetPersonResults(PersonSearchCriteriaModel criteria)
{
return DbContext.GetPersonResults(criteria)
}
}
Create a couple of partial-views your Views.
/Views/Person/Partial-SearchCriteria.cshtml
#model IPersonSearchCriteriaView
// the new part is for htmlAttributes, used by Ajax later
#using (Html.BeginForm(..., new { id="searchCriteria" }))
{
// Here is were the magic is, if you use the #Html.*For(m=>)
// Methods, they will create names that match the model
// and you can back back to the same model on Get/Post
<label>Name:</label>
#Html.TextBoxFor(m => Model.PersonSearchModel.Name)
// or let mvc create a working label automagically
#Html.EditorFor(m => Model.PersonSearchModel.Name)
// or let mvc create the entire form..
#Html.EditorFor(m => Model.PersonSearchModel)
}
/Views/Person/Partial-SearchResults.cshtml
#model IPersonSearchResultsView
#foreach (var person in Model.PersonSearchResults )
{
<tr>
<td class="list-field">
#Html.DisplayFor(modelItem => person.Name)
</td>
// etc
</tr>
}
And Finally the view:
/Views/Person/Search.cshtml
#model PersonSearchViewModel
#Html.Partial("Partial-SearchCriteria", Model)
// easily change the order of these
<div id="searchResults">
#Html.Partial("Partial-SearchResults", Model);
</div>
Now enabling Ajax is pretty crazy easy (simplified and my not be exactly right):
$.Ajax({
url: '/Person/Results',
data: $('#searchCriteria').serialize(),
success: function(jsonResult)
{
$('#searchResults').innerHtml(jsonResult);
});
What I typically do is pass the posted Model back into the view. This way the values are not cleared out.
Your code would look something like this:
<div style="float:left;">
<div style="float:left;">
<label>Name:</label>
#Html.TextBox("name", Model.Name)
</div>
<div style="float:left; margin-left:15px">
<label>Company:</label>
#Html.TextBox("company", Model.Company)
</div>
<div style="float:left; margin-left:65px">
<label>Date Range:</label>
#Html.TextBox("dateStart", Model.DateStart, new { #class = "datefield", type = "date" })
to
#Html.TextBox("dateEnd", Model.DateEnd, new { #class = "datefield", type = "date" })
</div>
When initially getting the form, you'll have to create a new Model, otherwise the Model will be null and throw an exception when properties are called on it.
Sample Model
public class SearchModel
{
public SearchModel()
{
Results = new List<Result>();
}
public string Name {get; set;}
public string Company {get; set;}
public string DateStart {get; set;}
public string DateEnd {get; set;}
public List<Result> Results {get; set;}
}
#foreach (var item in Model.Results)
{
<tr>
<td class="list-field">
#Html.DisplayFor(modelItem => item.Name)
</td>
<td class="list-field">
#Html.DisplayFor(modelItem => item.CompanyName)
</td>
<td class="list-field">
#Html.DisplayFor(modelItem => item.City)
</td>
<td>
#Html.DisplayFor(modelItem => item.State)
</td>
<td class="list-field">
#Html.DisplayFor(modelItem => item.DateCreated)
</td>
<td class="list-field">
#Html.ActionLink("Edit", "Edit", new { id = item.ProfileID }) |
#Html.ActionLink("View", "View", new { id = item.ProfileID }) |
#Html.ActionLink("Delete", "Delete", new { id = item.ProfileID }, new { onclick = " return DeleteConfirm()" })
</td>
</tr>
}
Here is a link on creating models for a view in MVC.

Adding a column which contains a hyperlink for every row in KendoUI grid control in ASP.NET MVC

Here is my View that contains the KendoUI Grid Control:
I want to add a new column that contains a hyperlink before the Date of creation column .
#using Kendo.Mvc.UI
#model IEnumerable<ExamplekendoDropdown.Models.FacilityGroup>
#{
ViewBag.Title = "Grid";
}
<table width="700">
<tr>
<td align="center">
<table width="1000">
<tr>
<td align="left">
#using (Html.BeginForm("Grid", "Grid", FormMethod.Get))
{
<table>
<tr>
<td>
<span>Facility Group Name</span>
</td>
<td>
#(Html.Kendo().AutoComplete()
.Name("FacilityGroupName")
.Value("")
.Enable(true)
)
#Html.Hidden("FacilityGroupName")
</td>
</tr>
<tr>
<td>
<input id="Submit1" type="submit" value="Search" />
</td>
</tr>
</table>
}
</td>
</tr>
<tr>
<td align="center" >
#(Html.Kendo().Grid(Model)
.Name("Grid")
.Columns(columns =>
{
columns.Bound(p => p.FacilityGroupId);
//columns.Bound(#Html.ActionLink("Create Facility", "Facility"));
columns.Bound(p =>p.FaclityGroupName);
columns.Bound(p => p.status).Width(80);
columns.Bound(p => p.CreationDate);
columns.Command(command => { command.Edit(); });
})
//.ToolBar(toolbar =>toolbar.Create())
//.Editable(editable => editable.Mode(GridEditMode.PopUp))
.Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateName("EditUserPopupTemplate")
.Window(w => w.Title("Facility").Name("editWindow").Width(300).Height(300)))
.Pageable()
.Sortable()
.Scrollable()
.DataSource(datasource => datasource
.Server()
.Model(model => model.Id(p => p.FacilityGroupId ))
.Read("Grid", "Grid")
.Update("Update", "Grid")
//.Create("Create","Grid")
//.Destroy("Destroy","Grid")
)
)
<script type="text/javascript">
$(document).ready(function () {
$("form.k-edit-form").kendoValidator();
});
</script>
</td>
</tr>
</table>
</td>
</tr>
</table>
Now i need to add another column before the "Date Of Creation" Column that contains a hyperlink.
Please share your inputs
Thanks
But why not this if you are using ajax
Ajax().ClientTemplate("#=FileName#");
if server()
columns.Bound(p => p.ProductID).Template(#<text>
#Html.ActionLink("Show Product Details", "ProductDetails", new { id = #item.ProductID } )>
</text>);
This example
columns.Template(#<text></text>).ClientTemplate(
#Html.ActionLink("Send Reset Email", "Login", new { loginButton = "reset",activate=true,fromAdmin=true,rowField="#=rowField#" }).ToHtmlString()
);
This worked for me.
You can use Template and ClientTemplate, to get a column with a hyperlink.
columns.Bound(p => p.CreationDate)
.Template(#<text>#item.CreationDate</text>)
.ClientTemplate("<a href=''>#CreationDate<a/>").Title("Link");
columns.Bound(p => p.CreationDate);
You only need to use the Template method for Server Binding. (ClientTemplate is for Ajax binding). You do not need to bind it to specific property unless you want to associate the column header to filter/sort/group by that property.
columns.Template(#<text>#Html.ActionLink("Create Facility", "Facility")</text>)
columns.Template(#<text></text>)
.ClientTemplate("<a href='" + Url.Action("Index", "Home") + "'>Create Facility</a>")
.HtmlAttributes(new { style = "text-align: left;" })
.Width(60);
This worked for me
If your grid has Server Binding use this:
columns.Bound(x => x.ProjectCode)
.Template(items => Html.ActionLink(items.ProjectCode, "Manage", "Project", new {projectId = items.ProjectId}, null));