I have a ASP.NET MVC page with multiple forms on it, where each form edits a different instance of the same class. Each form also includes a Telerik DateTimePicker control. What I want is to have the element IDs change, but not the element name. So I have something like this:
string idString = string.Format("MyObject{0}", Model.ID)
#Html.Telerik().DatePickerFor(m => m.SomeDate).HtmlAttributes(new { id = idString + "-SomeDate" })
Now this works mostly fine, except that at the bottom of the page, the auto-generated Javascript that Telerik puts in looks like:
jQuery('#SomeDate').tDateTimePicker({
format:'M/d/yyyy h:mm tt',
minValue:new Date(1899,11,31,0,0,0,0),
maxValue:new Date(2100,0,1,0,0,0,0),
startTimeValue:new Date(2013,3,22,0,0,0,0),
endTimeValue:new Date(2013,3,22,0,0,0,0),
interval:30,
selectedValue:new Date(2013,3,22,11,9,1,180)
});
Note that my idString value didn't get put in. I can try:
#Html.Telerik().DatePickerFor(m => m.SomeDate).Name(idString + "SomeDate")
And this makes the auto-generated Javascript correct (jQuery('#MyObject123-SomeDate')) but now the element name is wrong, so TryUpdateModel fails.
How can I get this to work? Thanks.
EDIT: I hacked this using the following Javascript, but this is a kludgy way to fix this.
$(function () {
window.setTimeout(function () {
for (var i = 0; i < document.getElementsByTagName("input").length; i++) {
var obj = document.getElementsByTagName("input")[i];
if (obj.id.indexOf("SomeDate") == -1)
continue;
obj.name = "SomeDate";
}
}, 150)
});
The solution was to use the Telerik object's .InputHtmlAttributes method.
#Html.Telerik().DatePickerFor(m => m.SomeDate).InputHtmlAttributes(new { id = idString + "-SomeDate" })
Related
I am new to MVC. I am trying for Cascading Dropdownlist in ASP.NET MVC 4. My problem is I want to access the selected countryid in #foreach loop
#Html.DropDownList("ddlCountry", new SelectList(#Model.Countries, "CountryId", "CountryName"))
$("#ddlCountry").change(function () {
#foreach (var item in #Model.States.Select(x=>x.countryId = ?))
{
}
});
How can I substitute countryId with the question mark above, so that I can filter the states
Thanks in Advance
Thanks
SRRIN
you can get the value in jquery by this
$("#ddlCountry option:selected").text();
As #Stephen said you cannot get the value of selected option using razor. Because the razor code is executed before page load.
A work around would be
$("#ddlCountry").change(function () {
var selectedVal= $("#ddlCountry option:selected").text();
var list = #Model.States.Tojson();
});
then use inArray for doing further operations
Thanks to all.
As Stephen and Nikitesh stated, javascript variable are not accessible inside razor scripts. So I succeeded with following approach.
var selectedCountryId = $("#ddlCountry").val();
var states = #Html.Raw(Json.Encode(Model.States));
for (var i = 0; i < states .length; i++) {
if (states [i].countryid == selectedCountryId ) {
... populate states here
}
}
Thanks
SRRIN
you can use dropdown selected value and pass in your query as:
#Html.DropDownList("ddlCountry", new SelectList(#Model.Countries,"CountryId", "CountryName"))
$("#ddlCountry").change(function () {
var countryId=parseInt($(this).val());
#foreach (var item in #Model.States.Select(x=>x.countryId = countryId))
{
}
});
Normally when you ModelBind a list of objects with MVC, the action looks like so:
public ActionResult Hello(List<DocumentViewModel> viewModels)
{
And the Post data looks something like:
[0].Id 1
[0].Name Bob
[1].Id 2
[1].Name Jane
But, how could I get the following post data to work?
0[Id] 1
0[Name] Bob
1[Id] 2
1[Name] Jane
The Post data is being provided by Kendo UI, so I don't imagine I have much flexibility to change it.
Update Thanks Petur for the answer. To expand on his answer, this function:
common.MvcSerializeArray = function (array, prefix) {
var result = {};
if (!prefix) {
prefix = '';
}
if (array) {
for (var i = 0; i < array.length; i++) {
if ($.isPlainObject(array[i])) {
for (var property in array[i]) {
result[prefix + "[" + i + "]." + property] = array[i][property];
}
} else {
result[prefix + "[" + i + "]"] = array[i];
}
}
}
return result;
};
should wrap arrays before being returned to Kendo's Data method:
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read
.Action("PickerDocuments", "DocumentRepository")
.Data(#<text>function(e) { return MyApp.Common.MvcSerializeArray(#Html.Raw(Json.Encode(Model))); }</text>)))
And voila, I get post data MVC ModelBinds with ease:
[0].Id 1
[0].Name Bob
[1].Id 2
[1].Name Jane
You cannot change it but you can add the desired format by sending addiotional parameters like explained here for the Ajax Grid. Same approach is used in this code library (you can get the magic function inside of the code, it is used to send the multi-select values)
I have this Html.ActionLink in my code:
#Html.ActionLink("Up",
"GetCategory",
"Category",
new { C_ID = CID, D_ID = DID, E_ID = EID, F_ID = FID },
new { id = "item-" + ItemID + "-getcategories-" + ItemLevel,
#class = "getCategory" })
I want to append a Javascript variable's value to the route dictionary. For this, I used the solution specified in this SO question ASP.NET MVC 2 Html.ActionLink with JavaScript variable
I attempted to customise the answer and this is what I have:
$(function ()
{
$('a.getCategory').click(function ()
{
.
.
.
var CatID = 0; //Calculate from this.ID
this.href = this.href + '?Cat_ID=' + CatID;
});
});
Thing is, the value of this.href is not the value generated by Html.ActionLink. Rather, it is the current URL of the page.
My understanding was this.href should refer to the ActionLink's href (since this refers to the anchor element generated by the ActionLink). What am I doing wrong?
EDIT
What is even more confusing: The Html.ActionLink is for one of the tabs (I'm using Jquery UI Tabs). So if I use .attr('href') to read the value in the JS function, I get a completely different value:
var AnchorHref = $(this).attr('href');
The value of AnchorHref is #ui-tabs-XX (where XX is a number) - this is a div auto-generated by Jquery UI tabs.
I want to show a poll result for a specific poll question.
When question list clicked i want to bind my chart with a query according to selected questionId.
So my plan was;
1. get questionId from selected question row. it's ok.
defining ClientEvents.OndataBinding event on my chart. So i would be able to
pass questionId with;
function onChartDataBinding(e) {
e.data = $.extend(e.data, { questionId: questionId });
}
using $('#ChartPollResults').data('tChart').rebind(); on question list grid row selected event.
This scenario works when i have second grid binding according to first grids selected row.
But it seems there is no ClientEvents.OnDataBinding event on chart control.
And "rebind()" method isn't supported on Chart control.
The chart conrol i use is below.
#(Html.Telerik().Chart<QuestionResult>()
.Theme("WebBlue")
.Name("ChartPollResults")
.Title("Poll Question Choice Number vs. Choice Count")
.Legend(legend => legend.Position(ChartLegendPosition.Bottom))
.Series(series =>
{
series.Bar("ChoseCount").Name("Choice Count").Gap(5);
})
.CategoryAxis(axis => axis.Categories(o => o.ChoiceNumber))
.DataBinding(dataBinding => dataBinding.Ajax().Select("_PollResultChartBinding", "Poll", new { questionId = 0 }))
.HtmlAttributes(new { style = "width: %100px; height: 270px" })
)
My Controller binding method;
public ActionResult _PollResultChartBinding(int questionId = 0)
{
//questionId = 3;
if (!ModelState.IsValid || questionId == 0)
return Json(new List<QuestionResult>());
PollQuestionDefinition pollQuestion = service.Get(questionId);
List<PollAnswer> pollAnswers = service.GetPollAnswersByQuestion(questionId);
PollQuestionResultUI result = new PollQuestionResultUI(pollQuestion, pollAnswers);
return Json(result.Results);
}
When i comment out //questionId = 3; line i can see the results for the question wiht Id= 3 in chart with no problem.
But i can't pass questionId to chart.
Thanks in advance.
This is my Opinion for your source code should be like this:
//controller binding method
public ActionResult _PollResultChartBinding(string questionId)
{
//questionId = 3;
int _questionId = String.IsNullOrEmpty(questionId) ? 0 : Convert.ToInt32(questionId);
if (_questionId == 0)
return Json(new List<QuestionResult>());
PollQuestionDefinition pollQuestion = service.Get(_questionId);
List<PollAnswer> pollAnswers = service.GetPollAnswersByQuestion(_questionId );
PollQuestionResultUI result = new PollQuestionResultUI(pollQuestion, pollAnswers);
return Json(result.Results);
}
**in your view, there is no problem with the code**.
but, for rebind that chart, this is the code :
example : (running from developer console for IE or firebug for firefox browser)
var chartPollResult = $('#ChartPollResults').data('tChart');
chartPollResult.rebind({ questionId: "0"});
but if you want make it into function, code should be like this:
function rebindChartPollResult(e, param) {
e.data('tChart').rebind({ questionId: param});
}
calling method :
rebindChartPollResult($('#ChartPollResults'), "0");
reference for telerik chart ajax binding (not included how to rebind chart) :
http://demos.telerik.com/aspnet-mvc/chart/ajaxbinding
First of all, one thing I immediately noticed is that you set questionId equal to 0 in your ActionResult parameters. I actually just modified a Chart I had up and running to pass in
new { questionID = 0}
as an additional parameter to my Ajax select statement and it passed in fine.
As for passing the parameter you could consider using a POST to the server on Grid selection and pass the parameter that way. I know it might not be ideal here, but you could theoretically either populate the Chart in that post, or just set a ViewData entry to contain the particular questionID that you are looking for.
I also noticed that you submitted this to the Telerik forums and from the response there it would seem that the above approach might actually work pretty well, or you could use the approach mentioned there (partial view with ajax calls).
(target framework is 4.0)
I am implementing a feature to delete multiple records in a simple table. In order to do this, I am using simple HTML checkboxes with a Javascript function to loop through each one to find which are selected. The Javascript is returning an array of int values representing the record IDs to delete.
I am using an ActionLink to call all of this, and to ultimately return to the Delete function (with an int array as a parm) in my controller file to actually submit the deletions to the database.
My problem is, I don't know how to take the array I get back from the Javascript to place into the ActionLink, to pass it into the controller.
Here is the code with which I am working:
<p>
#Html.ActionLink("Add New", "Add") | #Html.ActionLink("Delete Selected", "Delete", new { id = "???" }, new { onclick = "return getProjectsToDelete()" })
</p>
<script type="text/javascript">
function getProjectsToDelete() {
var answer = confirm("Are you sure you wish to delete the selected projects?");
if (answer) {
var listToDelete = new Array();
var arrayCount = 0;
for (i = 0; i < document.projectList.deleteProject.length; i++) {
if (document.projectList.deleteProject[i].checked) {
listToDelete[arrayCount] = document.projectList.deleteProject[i].value;
arrayCount++;
}
}
return listToDelete;
}
}
</script>
If I understand you correctly, you want to know how to push back a collection of IDs to a controller?
In general, this would be done as a FORM and POST the form to the back end. I myself prefer to do this via AJAX but thats just me.
While you can do this using a GET and stuffing all of the IDs in the query string, its dirty!
It would look something like /controller/action?id=7&id=8&id=9
The Model Binder in .NET will convert that in to a List<int> or int[].
I would suggest using ".push" in Javascript to manage you array of IDs. You can also use the ".join" method on your array to create a clean querystring.