Custom pager in Telerik MVC Grid - asp.net-mvc-3

Can i customize appearance of a Grid's pager? I wanna select a page size from list (like Redmine, see 'Per page' block) not from dropdown.
It's standart Telerik's pager:
It's Redmine's pager:
Thanks.
PS for instance Devexpress' Grid has this ability

You could replace the DOM element that is responsible for page size. You need to do it when grid is loaded.
View
#Html.Telerik().Grid(Model)
.Name("Grid")
.ClientEvents(events => events.OnLoad("Grid_onLoad"))
JavaScript
function Grid_onLoad(e)
{
var html = { place your favorite template engine here }
$('#YourGridId').find('.t-page-size').html(html);
// bind 'click' event to your new control
}
Now the problem is that you need to bind own event to the change of the page size and tell new page size for the Telerik grid.
You can provide additional parameters to the controller action that provides data to your controller. There is an example in the documentation how to add additional data to your request.
<script type="text/javascript">
function Grid_onDataBinding(e) {
// pass additional values by setting the "data" field of the event argument
e.data = {
pageSize: // TODO: provide selected page size from your new control
};
}
</script>
In the server side controller action should automatically map your pageSize to an action parameter.
I hope this helps, let me know if you need more information.

Related

Kendo ui grid inline and popup mixed and template on popup

I just saw this link which is a great explanation by onabai, but i´m trying to also set a template for the temporary popup and i can´t make it work:
$(".k-grid-popup", grid.element).on("click", function () {
// Temporarily set editable to "popup"
grid.options.editable = "popup";
// Insert row
grid.addRow();
// Revert editable to inline
grid.options.editable = "inline";
});
How do you set the template of the popup?
Regards.
While you can access the grid options directly, any change to the options should be made using the setOptions method. This function will notify the grid of any options change and it will be able to make all the internal change the handle the event according the the new options.
$(".k-grid-popup", grid.element).on("click", function () {
grid.setOptions({editable: "popup"});
grid.addRow();
grid.setOptions({editable: "inline"});
});
I don't have any working example of your code so I can't tell if you need to change something else in your code.

jQuery - How to call/bind jquery events for elements added by ajax?

I'm working on an implementation of the jQuery plugin Tag-it! with a product entry form for assigning attributes to products of different type (laptops, tv's, gadgets etc).
The concept is the following:
When adding a new product, first, the user selects the product category from a dropdown for the product being added and a jQuery .change() event is triggered making an ajax call to get all the attributes that are related to that category. For example, if Im adding a TV i want my ajax call to populate 3 inputs for inches, panel type, hdmi whereas, if i'm adding a laptop I want those inputs to be cpu, ram, hdd, screen etc. Tag-it! works with a list of words (in my case, attributes) and an input field for choosing the set of words.
In my case, for each type of attributes I want to populate a separate input field and assign/bind it to/apply tagit plugin (sorry, I dont know how else to explain it).
Javascript:
<script src="../js/tag-it.js" type="text/javascript" charset="utf-8"></script>
<script>
$(function(){
// Sample1: var sampleTags1 = ["red", "green", "blue"];
// Sample2: var sampleTags2 = ["lcd", "plasma", "tft"];
var sampleTags1 = [<?=createTags('name', 'tags', 1)?>];
// createTags($name, $tags, $id) is a PHP function that returnss a list of tags for a given attribute
// Question 1: how do I place this here after a new input is added to the DOM?
$('#myTags').tagit();
//Question 2: for each input added to the DOM I need also to add this block in the javascript:
$('#allowSpacesTags1').tagit({itemName: 'item1', fieldName: 'tags1',
availableTags: sampleTags1, allowSpaces: true
});
$('#removeConfirmationTags').tagit({
availableTags: sampleTags,
removeConfirmation: true
});
});
$(document).ready(function() {
$('#cat_id').change(function(){
$.post('../includes/ajax.php', {
cat_id : $(this).find("option:selected").attr('value')}, function(data) {
$("#tagholder").html(data);
});
});
});
</script>
Ajax returns the following for each call:
<ul id="allowSpacesTags'.$row['ctid'].'"></ul> // $row['ctid'] is the ID for that attribute
which represents the input field for entering the tags/attributes.
Before there's any misunderstanding, I'm not asking how to do this in PHP.
My question is about the way I can dynamically add a var like sampleTags1 and also call the tagit() for each new input that is added to the DOM by ajax. I'll try to give any required information if my question isn't clear enough.
Please look at the questions in the code comments. Thanks!
http://api.jquery.com/live/
with .live( events, handler(eventObject) )
you don't need to attach or re-attach events when content is added dynamically
EDIT
i've just notticed that live is deprecated, instead you should use
.on()
http://api.jquery.com/on/

MVC3 Webgrid Paging is not working inside a Jquery dialog

I have a Jquery dialog and I load a view to it which contains a webgrid. It opens normally and display content in a webgrid. But when I click a paging link, then next page of webgrid is not open within the dialog but as a different page in the browser.
Can't I have a webgrid within a Jquery dialog?
If I can, do I have to set specific properties?
You need to define ajaxUpdateCallback function, in example:
var grid = new WebGrid(source: Model,
ajaxUpdateCallback: "GridUpdate",
ajaxUpdateContainerId: "grid"
rowsPerPage: 50);
ensure that your .GetHtml method has :
#grid.GetHtml(
htmlAttributes: new { id = "grid" },
//.. rest of the options here
)
and add the below to your main view
<script type="text/javascript">
function GridUpdate(data) {
$('#grid').html(data);
}
</script>
Take a 5 minutes to look at your WebGrid's code, it will help you a lot and save time in future. what it is, is a HTML table enhanced with jQuery code. Look at page links, and headers (for sorting) they are all just $.load() invocations with Url, and Callback parameter. So What is important is to figure out the right div id and a callback function :)

MVC 3 Razor - show modal based on an EF query

At work I have been tasked with adding additional functionality to an existing MVC 3/Razor project. I haven't used MVC before, but am quite versed with Web Forms.
However, I am not quite sure where to place everything I need.
When the app is first loaded, a login page appears. When the user logs in successfully, the user sees a dashboard type page.
The new functionality is to detect whether the user has FollowUpItems with a Due Date < Now. If Count > 0 then display a Modal popup with some text and a link to 'View Followup Items'.
There is already a controller and action made for viewing Followup items. I need to display the modal, and I would like to make the modal a reuseable type of object - I am assuming/thinking a PartialView where I can pass in the name of the Controller, Action, Params for a possible ActionLink that I would display in the modal popup, and the message text, etc.
I need a little guidance on how to open the modal since it isn't attached to a click, but rather to whether an expression evaluates true or false, and where the best place for the pieces are.
Thanks in advance for the guidance
I would detect if the user has FollowUpItems in the Action that loads the dashboard page, and store that information in the ViewBag. For example,
public ActionResult Dashboard()
{
ViewBag.HasFollowupItems = UserHasFollowupItems();
return View();
}
In this example, UserHasFollowupItems() returns a string, something like 'true' or false'.
In the dashboard view, add an empty div into which the modal data will be loaded
<div id="followup_items"></div>
then add a document.ready() in the same view which defines the modal and determines if the modal should be loaded:
$(document).ready(function ()
{
// define modal
$("#followup_items").dialog({
autoOpen: false,
height: 'auto',
width: 825,
title: 'Followup Items',
position: [75, 75],
modal: true,
draggable: true,
closeOnEscape: true,
buttons: {
'Close': function ()
{
$(this).dialog('close');
}
},
close: function ()
{
$('.ui-widget-content').removeClass('ui-state-error');
},
});
if(#ViewBag.HasFollowupItems == 'true')
{
$('#followup_items').load("/FollowupItems/Load", function (data, txtStatus, XMLHttpRequest)
{
$('#followup_items').dialog('open');
}
});
});
In this example /FollowupItems/Load is the URL to the proper controller/action that generates the data for the view. You are correct, the view for this would be a partial view, loaded into the empty followup_items div on the page.
So you can use the #ViewBag object anywhere in the view, in this case passing in your boolean indicating if the modal should be loaded/opened. I have not found a way to use ViewBag in an external javascript file, so I typically use embedded script tags in my views so I can use the ViewBag.
You could also add in the user id in the same way (/FollowupItems/Load/#ViewBag.Userid), or any other data the followup action needs.

Browser Memory Usage Comparison: inline onClick vs. using JQuery .bind()

I have ~400 elements on a page that have click events tied to them (4 different types of buttons with 100 instances of each, each type's click events performing the same function but with different parameters).
I need to minimize any impacts on performance that this may have. What kind of performance hit am I taking (memory etc) by binding click events to each of these individually (using JQuery's bind())? Would it be more efficient to have an inline onclick calling the function on each button instead?
Edit for clarification :):
I actually have a table (generated using JQGrid) and each row has data columns followed by 4 icon 'button' columns- delete & three other business functions that make AJAX calls back to the server:
|id|description|__more data_|_X__|_+__|____|____|
-------------------------------------------------
| 1|___data____|____data____|icon|icon|icon|icon|
| 2|___data____|____data____|icon|icon|icon|icon|
| 3|___data____|____data____|icon|icon|icon|icon|
| 4|___data____|____data____|icon|icon|icon|icon|
I am using JQGrid's custom formatter (http://www.trirand.com/jqgridwsiki/doku.php?id=wiki:custom_formatter) to build the icon 'buttons' in each row (I cannot retrieve button HTML from server).
It is here in my custom formatter function that I can easily just build the icon HTML and code in an inline onclick calling the appropriate functions with the appropriate parameters (data from other columns in that row). I use the data in the row columns as parameters for my functions.
function removeFormatter(cellvalue, options, rowObject) {
return "<img src='img/favoritesAdd.gif' onclick='remove(\"" + options.rowId + "\")' title='Remove' style='cursor:pointer' />";
}
So, I can think of two options:
1) inline onclick as I explained above
--or--
2) delegate() (as mentioned in below answers (thank you so much!))
Build the icon image (each icon type has its own class name) using the custom formatter.Set the icon's data() to its parameters in the afterInsertRow JQGrid event. Apply the delegate() handler to buttons of specific classes (as #KenRedler said below)
> $('#container').delegate('.your_buttons','click',function(e){
> e.preventDefault();
> var your_param = $(this).data('something'); // store your params in data, perhaps
> do_something_with( your_param );
> }); //(code snippet via #KenRedler)
I'm not sure how browser-intensive option #2 is I guess...but I do like keeping the Javascript away from my DOM elements :)
Because you need not only a general solution with some container objects, but the solution for jqGrid I can suggest you one more way.
The problem is that jqGrid make already some onClick bindings. So you will not spend more resources if you just use existing in jqGrid event handler. Two event handler can be useful for you: onCellSelect and beforeSelectRow. To have mostly close behavior to what you currently have I suggest you to use beforeSelectRow event. It's advantage is that if the user will click on one from your custom buttons the row selection can stay unchanged. With the onCellSelect the row will be first selected and then the onCellSelect event handler called.
You can define the columns with buttons like following
{ name: 'add', width: 18, sortable: false, search: false,
formatter:function(){
return "<span class='ui-icon ui-icon-plus'></span>"
}}
In the code above I do use custom formatter of jqGrid, but without any event binding. The code of
beforeSelectRow: function (rowid, e) {
var iCol = $.jgrid.getCellIndex(e.target);
if (iCol >= firstButtonColumnIndex) {
alert("rowid="+rowid+"\nButton name: "+buttonNames[iCol]);
}
// prevent row selection if one click on the button
return (iCol >= firstButtonColumnIndex)? false: true;
}
where firstButtonColumnIndex = 8 and buttonNames = {8:'Add',9:'Edit',10:'Remove',11:'Details'}. In your code you can replace the alert to the corresponding function call.
If you want select the row always on the button click you can simplify the code till the following
onCellSelect: function (rowid,iCol/*,cellcontent,e*/) {
if (iCol >= firstButtonColumnIndex) {
alert("rowid="+rowid+"\nButton name: "+buttonNames[iCol]);
}
}
In the way you use one existing click event handler bound to the whole table (see the source code) and just say jqGrid which handle you want to use.
I recommend you additionally always use gridview:true which speed up the building of jqGrid, but which can not be used if you use afterInsertRow function which you considered to use as an option.
You can see the demo here.
UPDATED: One more option which you have is to use formatter:'actions' see the demo prepared for the answer. If you look at the code of the 'actions' formatter is work mostly like your current code if you look at it from the event binding side.
UPDATED 2: The updated version of the code you can see here.
You should use the .delegate() method to bind a single click handler for all elements ,through jQuery, to a parent element of all buttons.
For the different parameters you could use data- attributes to each element, and retrieve them with the .data() method.
Have you considered using delegate()? You'd have one handler on a container element rather than hundreds. Something like this:
$('#container').delegate('.your_buttons','click',function(e){
e.preventDefault();
var your_param = $(this).data('something'); // store your params in data, perhaps
do_something_with( your_param );
});
Assuming a general layout like this:
<div id="container">
<!--- stuff here --->
<a class="your_buttons" href="#" data-something="foo">Alpha</a>
<a class="your_buttons" href="#" data-something="bar">Beta</a>
<a class="your_buttons" href="#" data-something="baz">Gamma</a>
<a class="something-else" href="#" data-something="baz">Omega</a>
<!--- hundreds more --->
</div>

Resources