Kendo MVC grid in edit mode - asp.net-mvc

I have a kendo mvc grid set for inline editing. I have a dropdown that I would like to populate when the user selects edit, and the list needs to be populated based upon a value in the row (which is in a hidden field)
c.Bound(a => a.MyId)
.Hidden(true);
I have the dropdown that I wish to populate in an editor template (which I need as this dropdown is shared by several grids).
#model int?
#(Html.Kendo().ComboBoxFor(m => m)
.AutoBind(true)
.Filter("contains")
.Placeholder("Select...")
.DataTextField("MyOtherName")
.DataValueField("MyOtherId")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("Data_Read", "MyController").Data("OnAdditionalData");
});
})
.Suggest(true)
.HtmlAttributes(new { data_value_primitive = "true" })
)
#Html.ValidationMessageFor(m => m)
With an additional data method in a script file ...
function OnAdditionalData()
{
var myId = $("#MyId").val();
return { myId : myId };
}
I would like for the dropdown to populate when the user clicks on the row edit button. With the autobind property set to true, it does just that. But the value in the additional datat function is always an empty string. This value does not populate correctly until after the additional data method (verified using the JS console.) If I set autobind to false, the user has to click on the drop down in the editable row, but then the value of myId is correct.
I see what is going on, with autobind true the values from the row object is not being populated until after the read method of the ComboBox is called.
Does anyone know of a work around for this?

Related

ASP.Net MVC Dynamic input bound to same controller property

I have 2 controller fields say Type and Data.
Depending on value selected for Type (Date or Text), I want to display Data field dynamically as either a text input or a custom timepicker input.
Since only one will be rendered at any time, I need to bind with the same property name (Data).
This is what I am trying:
#if (Model.Type == "Date")
{
// custom timepicker control goes here
<input asp-for="Data" class="form-control timepicker"/>
}
else
{
<input asp-for="Data" class="form-control text-input" type="text"/>
}
On page load only text input is rendered, and it shows/hides based on Type selected. The timepicker input is never displayed (the html is not generated at all).
Is there a way to achieve this in MVC?
You can not have two <input> elements with the same name. If a <form> containing multiple inputs with the same name is posted, the MVC model binder will only bind one value from the last input.
To achieve what you want, you have two options:
Either have only one input with name="Data" of type="text" in the View, and let the timepicker write the time as a string to this input. Then in the controller, parse this input value depending on the selected Type.
Or have two inputs with name="TextData" and name="TimeData", and disable and hide one of these inputs using JS depending on the selected Type. In the controller, read the value from the right input depending on the selected Type. This is arguably the cleaner solution.
In MVC5 the second solution would look like this (I am not familiar with MVC-Core):
#model MyViewModel
#using (Html.BeginForm("Submit", "MyController", FormMethod.Post)) {
#Html.EditorFor(m => m.Type)
#Html.EditorFor(m => m.TextData, new { #class = "text-input"})
#Html.EditorFor(m => m.TimeData, new { #class = "timepicker"})
}
<script type="text/javascript">
function toggleInput_() {
if ($('##Html.IdFor(m => m.Type)').val() === 'Text') {
$('##Html.IdFor(m => m.TextData)').prop('disabled', false).show();
$('##Html.IdFor(m => m.TimeData)').prop('disabled', true).hide();
}
else {
$('##Html.IdFor(m => m.TextData)').prop('disabled', true).hide();
$('##Html.IdFor(m => m.TimeData)').prop('disabled', false).show();
}
}
$(document).ready(function() {
$('##Html.IdFor(m => m.Type)').on('change', function() {
toggleInput_(); // toggle when drop down changes
});
toggleInput_(); // toggle initially on page load
});
</script>
Controller:
[HttPost]
public ActionResult Submit(MyViewModel postData) {
string textValue = null;
DateTime? timeValue = null;
if (postData.Type == "Text") {
textValue = postData.TextData;
}
else {
timeValue = postData.TimeData;
}
// ...
}
ASP MVC already has this functionality built in with Editor Templates. By following the convention, you can specify a template to be used for any type (including user-defined complex types) which will be rendered with #Html.EditorFor().
In a nutshell, just place two partial views in your ~/Views/Shared/EditorTemplatesfolder, one with model type DateTime and the other string. The correct partial view will be rendered when using #Html.EditorFor(m => m.Property) based on the type of Property.
Note: the default editor for a string property will already be an input with type="text", so you don't necessarily need to specify that template.
See this link for a tutorial on Editor templates (and Display templates):
https://exceptionnotfound.net/asp-net-mvc-demystified-display-and-editor-templates/

kendo radio button value

I've following code in razor view. How do I use Kendo Radio button to render the same? Mainly, I'm struggling to assign enum value to radio button value.
#if (Model == declaredEnum.​Val1)
{
#Html.RadioButtonFor(l => l, (int)declaredEnum.​Val1, new { #checked = "checked" });
}
else
{
#Html.RadioButtonFor(l => l, (int)declaredEnum.​Val1);
}
#Html.LabelFor(l => l, "Label")​
Edit
Definition of Enum
Public Enum declaredEnum
{
Val1,
Val2
}
There is another radio button with the same code, but it checks for val2. Current logic is working fine. I just need to convert to Kendo control instead of razor.
I realize that this post is very old, but I am working with Kendo UI for the first time and needed to figure this out for myself. The following code snippet creates a radio button group called "name-of-radio-group" from an enum with two values. It defaults the first radio button to checked:
<div class="form-group row">
#Html.Label(Enum.GetNames(typeof(declaredEnum)).ToList()[0], new { #class = "col-sm-2" })
#(Html.Kendo().RadioButtonFor(m => m.declaredEnum).Checked(true).Name(Enum.GetNames(typeof(declaredEnum)).ToList()[0])
.HtmlAttributes(new { #class = "col-sm-1", name = "name-of-radio-group"}))
#Html.Label(Enum.GetNames(typeof(declaredEnum)).ToList()[1], new { #class = "col-sm-2"})
#(Html.Kendo().RadioButtonFor(m => m.declaredEnum).Name(Enum.GetNames(typeof(declaredEnum)).ToList()[1])
.HtmlAttributes(new {#class = "col-sm-1", name = "name-of-radio-group"})
)
</div>
In my example I only had two enum values so I did not feel the need to use a loop, instead I just indexed the enums directly. In case it is not clear to someone the m.declaredEnum represents a property on a strongly typed model where the property name is the same as the name of the enum.

Kendo MVC ComboBox with million records - Initial Value

I have a Kendo ComboBox as an EditorTemplate for nullable IDs (people). I bind the model normally with a UIHint
#Html.Kendo().ComboBoxFor(x=>x.Person.MotherID)
The combo works great, I can type and it filters on the server.
The problem is that when the form first loads, the ID of the person appears as the visible text, not the name.
There are 1 million records, so I can't send them all to the combobox initially.
How do I get the combobox, when it first renders, to go get the name of the person via Ajax and not show the ID?
#(Html.Kendo()
.ComboBoxFor(m => m)
.DataTextField("Name")
.DataValueField("Value")
.AutoBind(true)
.ValuePrimitive(true)
.Filter(FilterType.Contains)
.Placeholder(Words.Type_Name)
.MinLength(2)
.DataSource(source =>
source.Read(read =>
read.Action("ReadComboBoxPerson", "Picker", new { area = "" }))
.ServerFiltering(true))
)
MVC:
public ActionResult ReadComboBoxPerson(string text)
{
return Json(_personManager.PersonGetter(text), JsonRequestBehavior.AllowGet);
}

How to get checkbox row value selected in Grid.MVC

Hi I have included Grid.MVC in asp .net mvc 4 i am able to display the
checkbox in grid but how do i get to know the particular checkbox is
selected in a row since i want to post it to the server and check it
at the controller end Below is the code any advice regarding are
welcome and is there any way i can place a checkbox for header
#Html.Grid(Model).Columns(columns =>
{
columns.Add().Encoded(false).Sanitized(false).SetWidth(10).RenderValueAs(o => Html.CheckBox("checked", false));
columns.Add().Encoded(false).Sanitized(false).Titled("Headline").SetWidth(220).RenderValueAs(news => #Html.ActionLink(news.HeadLine, "Details", new { Id = news.Id }));
columns.Add(news => news.Time).Titled("News Time").SetWidth(110).Sortable(true).Filterable(true);
}).WithPaging(20)
Sorry for the late reply, but today I found my self with the same question.
The following code will work as you want:
columns.Add()
.Encoded(false)
.Sanitized(false)
.SetWidth(10)
.RenderValueAs(o => Html.CheckBox("checked", o.YourModelBoolProperty));
Good luck.
Add value attribute to the checkboxes, set their value as news.Id (if news.Id is the primary key or unique else set some value by which you will be able to identify the checked rows in controller).
Add the name attribute to the checkboxes and give same name to all of them.
Html.CheckBox("checked", false, new {name = "assignChkBx"})
Use a action in controller with form colection object to get the checkbox values
public void Controls(FormCollection form)
You will get only those values in FormCollection which are checked.
var checkBox = form.GetValues("assignChkBx");
if (checkBox != null)
{
foreach (var id in checkBox)
{
}
}
columns.Add().Titled("").Encoded(false).Sanitized(false).RenderValueAs(o => Html.CheckBox(string.Format("ArrayProperty[{0}].Selected", Model.ArrayProperty.IndexOf(o)), o.Selected));
Works for me - and a little bit cleaner than the other answer. For some reason I can't get the other item posted to work

Retrieving Data of a combobox item -Telerik MVC

my application is asp.net MVC, I am using Telerik MVC Combobox, using ViewData, I send items as:
people.Add(new Person { Id = 1, Name = "John", viewed = true });
<% Html.Telerik().ComboBox()
.Name("ComboBox")
.BindTo(new SelectList((IEnumerable<Person>)ViewData["people"], "Id", "Name"))
.ClientEvents(events => events.OnChange("ComboBox_onChange")
.OnLoad("ComboBox_onLoad")
.OnOpen("ComboBox_OnOpen"))
.Render();
%>
I can get the text of a specific item using:
var item = combobox.dropDown.$items.eq(0);
alert(item.text());
Any idea how I can get the data of this item to check if the value of viewed if it is true of false.
I tried:
alert(item.Value.split('|'));
but got this error: Unable to get value of the property 'split': object is null or undefined
Thanks in advance.
Here is the Client API documentation
Basically you need to get a reference to the combobox plugin first:
var combo = $('#ComboBox').data('tComboBox');
Then you can call whatever method you need:
alert( combo.value() );
EDIT:
Your combobox is currently bound to a SelectList where the Value is Person.Id and Text is Person.Name. The "viewed" property is not stored anywhere. You could include it as part of the Value, retrieve the value as I described above, and then split() to get the "viewed" part:
Html.Telerik().ComboBox()
.Items(items =>
{
// pseudo-code
foreach (person)
items.Add().Text(person.Name).Value(person.Id + "_" + person.Viewed)
})
...

Resources