jqgrid/mvc 3 - How to call grid in controller? - asp.net-mvc-3

I'm new to jqgrid. It's may be silly question, but please help me. I want to export data to excel file, and I watch demo on http://www.trirand.net/demoaspnetmvc.aspx , it's already support it.
However I defined grid in Views, not in Model like the demo:
$(document).ready(function () {
jQuery("#list").jqGrid({{
url: '/documents/List',{
datatype: 'json',{
mtype: 'GET',{
......
I wonder if there's a way to call this grid from controller, or how to name and use it like variable?
Thank in advance

You cannot call grid from your controller. Jqgrid extension just renders data on a client in a way you specify it, you have no access to it from server-side code.
If you take closer look on example which you provide, authors pass grid options in request and bind new grid object on server, then export data from this object. You need to do the same.

Related

Select2 with ajax option

I have been using selec2 version 4 with ajax option.
And I want to set a selected value, as recommended in the guideline, by adding new Option element.
A problem I have is that I do not know when to add the new option because the event select2-loaded does not seem to exist in the latest version of select 2.
Can you please let me know in what way I can know the moment when data has finished loading from the server and has finished setting up, so I can add a new option to it?
Thank you.
The Option element you mention is created by calling the Option() constructor which then constructs a HTMLOptionElement. So basically you are just adding to your DOM and don't need to do it in any select2 event. Instead just do it on document load.
Here's a very basic example of what it could look like:
$(function () {
$('#element-to-select').select2();
var option = new Option('text', 'value', true, true);
$('#element-to-select').append(option).trigger('change');
}
Note that we are calling .trigger('change') to report the change to select2 as documented here.

using ajax or not when displaying new records in asp.net mvc

I am a beginner in MVC. In my application, I list categories (as a button) on the left hand-side (inside a div). Just right to this div, there is another div which displays the items associated with the clicked category.
When a category button is clicked, I am planning to call the action of the controller that will retrieve the Items from the database and add these Items to the ViewModel (e.g., model.Items = db.Items...), and then call the View with the updated Model and display the Items.
However, I am curios if it is better to make an Ajax call here and use a partial view for displaying the Items of the clicked category.
If feel like between these two approaches in my scenario only difference will be the page-refresh, they should work the same in terms of speed since both of them require the same database call.
Can anyone share good practices in MVC for such scenarios?
Yes AJAX is faster and good way to update detail in same page without refresh.
For that you have to create JsonResult method in controller. It will give you result in Json.
Try JQuery Template plugin for repeated code.
<script id="trTemplate" type="text/x-jquery-tmpl">
<tr>
{{each $data}}
<td>${Col}</td>
{{/each}}
</tr>
</script>
<table id="containerTable">
</table>
AJAX Call
$.ajax({
url: 'Your JsonResult Method URL',
type: "GET",
data: data,
beforeSend: function () {
},
success: function (data) {
// It will pass data to template and template will bind parsing json
$('#trTemplate').tmpl(data).appendTo('#containerTable');
//Business logic
},
complete: function () {
// Your Code
}
});
Your JsonResult Method
[HttpPost]
public JsonResult GetData(ViewModel model)
{
// Your Code here
}
using ajax or not when displaying new records in asp.net mvc
Using jquery would be the best approach for this scenario. As you don't have to load the layout page which will have to render the scripts and stuff all over again. Stick on to Ajax calls in MVC as much as possible, The technologies are being improved and a lot of single page applications are out there, And if we still use a page load for every new request then there is no point.
Coming to comparison between passing back Partial View And Json Data. Which is better to use in the application design?
Both partial Views and Json data hold the same weight depending on the scenario.
When to use partial view: Lets say you have a Model and you have to build the view HTML by lot of if checks and loops and possibly some c# code ( in rare scenarios), etc, in such scenario using Partial view would be the better choice, Because if we try to build the same thing in Jquery using json data the complexity of the code required would be high compared to what can be done in Partial views, But still achieving it is possible but wont be that easy and we might make errors during development.
When to use Json Data: If the requirement is like updating a grid, generating dynamic drop down or dealing with some Jquery plugins in the page I think Json data would be better, as many plugins play with json data as the core requirement.
A Small Example Of Deciding Between Partial View And Json Data - interested folks and read through
Lets take a scenario where we have to display a grid of data. This is our initial requirement. So we can happily build our viewModel with data and pass it to our partial view and render the table using for loops. All set, Now the requirement changes and we are asked to build sorting, filtering and paging stuff in our table. So at present we look for a plugin that can be easily integrated with current code and yes the easy one to use at this scenario is Datatables. Ok, we wrote a small Jquery to apply the plugin to the table and all set we have the fancy stuff ready.
Now here is the tricky part, we are asked to add functionalities like add, edit, delete record from the table. Yes its possible but is little tricky to get it done in the best possible way with the current code which we have. What we tend to do is, when ever there is a change in the table we plan to recall the partial view. Which works fine but still asking to ourselves just to delete one record from the table is it good to reload the partial view again?? Definitely NOT,
What can we do? When ever there is any add, edit, delete operation we hit the controller to update the database and we can make the controller return a JSON data and just pass this Json data to the plugin API and refresh the table, This will be more neat and faster. So here you see JSON data would be the better choice. Also some might even want to make it more cleaner by just playing with that one record of data and writing up some jquery code to manipulate the table, which is absolutely fine, But it requires us to pass the Json data itself back from controller.
So having this done, we can go back and refactor our code to make partial view to use json data for the grid initially too or leave it as it is saying the initial load will be a partial view, but following operations would be a json result, which is fine but I feel let all the data related stuff come from one point.
So that explains how a simple module can change from being a partial view to then use Json data. There are scenarios where the story is the other way around, You have to pick the right one for the right work.

Assembling N-Nested Kendo UI Grid asp.NET MVC 4

I am looking for N level nested child behavior in Kendo UI grid.
so far i have been implementing upto 3-4 level but those grids have to be hard coded in the Code.
Please Guide if somebody has done it dynamic way or generating grid dynamically as child grid
if Possible any alternatives to achieve same.
I hope you guys can help out.
I have edited the Detail Template demo found here: http://demos.telerik.com/kendo-ui/grid/detailtemplate
The fiddle:
http://jsfiddle.net/j5b64/1/
detailRow.find(".orders").kendoGrid({
detailTemplate: kendo.template($("#template").html()),
detailInit: detailInit,
dataSource: {...
Detail rows are not initialized until they are expanded (They don't exist in the DOM). So the call to make the new grid can't happen until we expand the row that will contain it.
Luckily Kendo had provided a 'detailInit' Event that you can plug into and initialize your child grid.
Update for .net binding:
First on your page you will need to define a template. It is important to use a class and not an ID in your template. Your template will be used multiple times and you want to maintain the uniqueness of IDs.
<script type="text/x-kendo-template" id="template">
<div class="orders"></div>
</script>
You will then need to reference that template to be the detail row template for your grid. Here we just need to reference the id of our template above. (you can use .DetailTemplate() to define the template in line, but then it would be harder to use it for later child grids as you would have to parse it out of the server made JS)
#(Html.Kendo().Grid<mySite.ViewModels.GridViewModel>()
.Name("Grid")
.ClientDetailTemplateId("template")
.Columns(columns => .....
Now comes the JS. There is two things we need to do. One is create a reusable initiation function and the other is register this function to be ran on initiation.
In our function we should define a new grid. Again this is done in JS at this point. Theoretically you could define an example grid and look for the server built JQuery that would be its sibling and reuse that for your child grids, but at that point you might as well define your grid using JQuery.
function detailInit(e) {
var detailRow = e.detailRow;
detailRow.find(".orders").kendoGrid({
detailTemplate: kendo.template($("#template").html()),
detailInit: detailInit,
....
Now we need to link up our first grid to use our Initiation function
$(document).ready({
$("#Grid").data("kendoGrid").bind("detailInit", detailInit);
});
I hope this helps.

What is the right away to update a panel using AJAX?

In MVC4 applications, I would like to update a panel using AJAX but using jQuery methods instead using AjaxExtensions from MVC.
But my problem is the updatePanelId.
I've seen several people use this to update it when has success:
success: function (response) {
var $target = $("#target");
var $newHtml = response;
$target.replaceWith($newHtml);
}
But when I do this, it forces me to use in every partial view that includes the id="target" at the root level of my razor view, and I guess that's not a good practice; I said this because I've realized when I use AjaxExtensions it doesn't happens, replace the update and it does not remove the panelId. But using jQuery it does.
Any idea to port the AjaxExtensions feature to jQuery?
You can use just:
$("#target").html(response); // it will just update content of the $("#target") container
Use jQuery's .load function. This will load the contents of the URL you specify into the target element. You can optionally specify a selector after the URL in load to only grab part of the target page.
$(function() {
$("#target").load("/MyURL");
});
JavaScript same origin policy applies to this.

ASP.NET MVC 3 Dynamic Controls and Unobtrusive Validation

Good afternoon everyone. I was wondering if there is anyway to have the MVC framework automatically wire up the data-val* attributes on the controls or do we need to manually create and apply the attributes to dynamic content?
I have a view that initially calls a partial view passing in the main viewmodel. This partial view is bound to a complex property on my main viewmodel. The partial view simply contains a set of cascading dropdown lists. On initial load of the page I have a call to #Html.Partial("PartialName", Model), the two dropdown lists’ validation works perfectly if I try to submit without selecting proper values. I also have another button on the page that if clicked loads another instance of the partial view on the page. If I now try to submit the form these controls, although they are bound to the same model and although I have set the correct .ValidationMessageFor helpers, no validation appears for them since the dropdownlists do not appear to be generated with the data-val* attributes. Is there any way that I can get them to appear correctly? I also noticed that the associated <span /> tag associated to the .ValidationMessageFor is not generated either. Has anyone run into this problem as well, if so how did you resolved?
UPDATE
Here is the javascript function that I call to load the partial on the button's onClick event:
function AddNewVehicle() {
$.ajax({
type: 'GET',
url: '/ReservationWizard/AddVehicleToReservation',
data: $('#reservation-wizard-form').serialize(),
dataType: 'HTML',
async: true,
success: function (data) {
if (data != null) {
$('#vehicle-selection-container').append(data);
}
}
});
}
The problem is that if you are not inside a form context, the HTML helpers such as TextBoxFor do not output any client validation data-* attributes. The first time when the page loads you invoke your Html.RenderPartial inside an Html.BeginForm() but later when you use AJAX to append form elements there is no longer this form context and there won't be any data-* client validation attributes generated. One possible solution would be to put the form inside the partial and then update the entire form during the AJAX call and in the success callback re-parse the client validation rules using $.validator.unobtrusive.parse('#vehicle-selection-container').
But if you want to keep only a single element inside the partial you are pretty much on your own :-) Here's a blog post which covers your scenario that you might take a look at.
So what can I say: unobtrusive client validation is great on paper and Scott Gu's blog posts but at some stage of the development of real world applications people start to realize its limitations. That's one of the reasons why I directly use the jquery.validate plugin and no MS jquery.unobtrusive. And, yes I know that I repeat my server validation logic in the javascript and yes I don't care because I have total control. Oh, and on the server I use FluentValidation.NET instead of data annotations for pretty much the same reasons as the client side part :-)
So maybe some day in MVC 4 Microsoft will finally make validation right (imperative vs declarative) but until this day comes, we just need to be searching for workarounds.

Resources