MVC3 WebGrid Row Select Checkbox - asp.net-mvc-3

I searched all over and can't seem to find the answer.
I have a MVC3 project with a WebGrid on it. The first column is a Select that is currently using the normal item.GetSelectLink to create a link to select that row.
I want this to be a checkbox instead of the test "Select". When the user hits the checkbox I want that row in the grid to be selected and the box to become "checked".
I would like the checked and unchecked states to be images that I provide.
How do I do this?

Unless you're doing something fancy with Ajax, the "select" link refreshes the page with "Selected=index" added to the query string. That would be an unusual experience, because people aren't used to checkboxes triggering a page reload.
You could do something like this, which completely mimics the "Select" link functionality. First add the checkbox to the row:
grid.Column(
format: (item) => #Html.Raw("<input class='select' type='checkbox'" + ((grid.SelectedRow == item) ? "checked" : "") + " />")
)
Then add some Javascript to handle the checkbox clicks:
var index = 1;
$("input.select").each(function () {
$(this).data('row', index);
$(this).click(function () { window.location = "?Selected=" + $(this).data('row'); });
index++;
});

Related

How to avoid multiple radio buttons selection when paginating a data table

I'm having a problem here:
When I select a radion button in a page 1 and another one in the same page it works fine, but when I select a radio button in the page number 2, and go back to the page number 1, that first radio button still selected and the one in the page number 2 is also selected, how can I solve this problem? I was looking for a solution here in the forum but couldn't find someone with the same problem.
*[code] $(document).ready(function () { var oTable = $('#example').dataTable({ "bJQueryUI": true, "sPaginationType": "full_numbers" }); }); [/code]*
There is no solution from DataTables itself. You'll have to do it on your own.
What you can do is save the selected value yourself on a click. Imagine you have a table called projectsTable. Then you can write:
var selection = -1;
$("#projectsTable input[type=radio]").on
(
"click",
function()
{
selection = $(this).val();
}
);
Then, you'll have to unselect all the wrong values every time the page changes. Add a callback in the construction of your table for page draw to do that:
//other settings go here, like the dom one
//you can choose your own, no need for this specific one
"dom": "lfBrtip",
"fnDrawCallback":
function(oSettings)
{
$("#projectsTable input[type=radio][value!="+selection+"]").prop('checked', false);
}
Every time the page is changed, this piece of code deselects everything you don't want to be selected any longer.

Is it possible (and if so how) to add an item to the column menu of a kendo UI grid?

So I have a grid and the columns have the good ol' column menu on them with the filtering/sorting/excluding of columns and it all works fine.
The fly in the ointment is that I would like to allow the user to rename a column heading and the obvious place in the UI to allow this is in said column menu.
Something like this:
(where the red bit is just another option that I click on and popup a little window to let me type in a new heading)
Is this possible and how would I do it?
I see that menus can be customized and the grid demo shows how to adjust the stuff in the filter popup but I am not sure how I would add this item (I can see how I would programmatically do the rename but just this getting an option onto the menu has me stumped).
You can use the columnMenuInit event. Two possibilities:
$("#grid").kendoGrid({
dataSource: dataSource,
columnMenu: true,
columnMenuInit: function (e) {
var menu = e.container.find(".k-menu").data("kendoMenu");
var field = e.field;
// Option 1: use the kendoMenu API ...
menu.append({
text: "Rename"
});
// Option 2: or create custom html and append manually ..
var itemHtml = '<li id="my-id" class="k-item k-state-default" role="menuitem">' +
'<span class="k-link"><b>Manual entry</b></span></li>';
$(e.container).find("ul").append(itemHtml);
// add an event handler
menu.bind("select", function (e) {
var menuText = $(e.item).text();
if (menuText == "Rename") {
console.log("Rename for", field);
} else if (menuText === "Manual entry") {
console.log("Manual entry for", field);
}
});
}
})
See fiddle with two alternatives:
http://jsfiddle.net/lhoeppner/jJnQF/
I guess that the point of a filter is to filter, not to make changes on the grid.
But anyways i found this Kendo Post that may help you to achieve what you need.
You can also take a look a this one too.

How to enable click in edit action button if new row is saved jqgrid

Edit formatter action button is placed to jqgrid column:
colModel: [{"fixed":true,"label":" change ","name":"_actions","width":($.browser.webkit == true? 37+15: 32+15)
,"align":"center","sortable":false,"formatter":"actions",
"formatoptions":{"keys":true,"delbutton":false,"onSuccess":function (jqXHR) {actionresponse = jqXHR;return true;}
,"afterSave":function (rowID) {
cancelEditing($('#grid'));afterRowSave(rowID,actionresponse);actionresponse=null; }
,"onEdit":function (rowID) {
if (typeof (lastSelectedRow) !== 'undefined' && rowID !== lastSelectedRow)
cancelEditing($('#grid'));
lastSelectedRow = rowID;
}
}}
New row is added to jqgrid in loadcomplete event
var newRowData = {};
var newRowId = '_empty' + $.jgrid.randId();
$('#grid').jqGrid('addRowData', newRowId, newRowData);
and its id is updated if save action button is clicked:
function aftersavefunc(rowID, response) {
restoreActionsIcons();
$('#grid').jqGrid('resetSelection');
var json = $.parseJSON(response.responseText);
$("#" + rowID).attr("id", json.Id);
lastSelectedRow = json.Id;
$("#grid").jqGrid('setSelection', lastSelectedRow);
}
After clicking save action button edit action button clicks are ignored. It is not possible to re-enter to edit mode after first editing.
How to fix this so that row can edited by edit button click again after saving ?
Update
I added $(this).focus() as suggested in Oleg answer and also wrapped id change into setTimeout as Oleg recommends in other great answer:
function aftersavefunc(rowID, response) {
restoreActionsIcons();
$(this).focus();
$('#grid').jqGrid('resetSelection');
var json = $.parseJSON(response.responseText);
setTimeout(function () {
$("#" + rowID).attr("id", json.Id);
lastSelectedRow = json.Id;
$("#grid").jqGrid('setSelection', lastSelectedRow);
}, 50);
}
Problem persists. The problem may related to row id change since:
It occurs only in last row (where id is changed after save). It does not occur for saved rows where responseText returns same id and row id is actually not changed.
It does not occur if cancel action button is pressed.
Maybe row id needs additional reset id addition to resetSelection or needs updated in somewhere other place also.
Update2
I added code form updated answer to errorfunc and used only english characters and numbers id ids. This allows to click multiple times but introduces additional issue:
extraparam is no more passed. If rowactions() calls are commented out, extraparam is passed with with rowactions calls extraparam is not passed.
I changed jqGrid source code and added alert to rowactions method:
alert( cm.formatoptions);
if (!$.fmatter.isUndefined(cm.formatoptions)) {
op = $.extend(op, cm.formatoptions);
}
In first clicks alert outputs 'Object'. In succeeding clicks to Save button it outputs undefined. So for unknown reason formatoptions is cleared.
Remarks to comment:
Absolute url in testcase is not used. Datasource is set to localarray.
I verified that testcase works in IE and FF without external url access.
For extraparam issue I can create new testcase.
Without image directory buttons are shown in cursor is moved over them.
Missing image directory still allows to reproduce the issue.
FormData function is defined in js file.
Since new issue occurs after adding rowactions() calls and does not occur if those calls are removed, this seems to be related to the code proposed in answer.
I suppose that the problem exist because one hide a button which has currently focus. Look at the code from the answer. If one remove the line $(this).focus(); // set focus somewhere one has the same problem as you describes. So I suggest that you just try to set somewhere, for example in restoreActionsIcons the focus to any the table element of the grid after hiding the button having currently the focus. I can't test this, but I hope it will help.
UPDATED: I examined your problem one more time and I hope I can suggest you a solution.
You problem can be divided on two sub-problems. The main your problem is the the changing of the id of the row. So it is not common problem which everybody has.
The problem is that "actions" formatter create onclick functions directly in the HTML code (see for example here):
ocl = "onclick=$.fn.fmatter.rowactions('"+rowid+"','"+opts.gid+"','edit',"+opts.pos+");..."
So the functions will contains the original rowid. To fix the problem you can modify the code fragment of your aftersavefunc inside of setTimeout from
$("#" + rowID).attr("id", json.Id);
lastSelectedRow = json.Id;
$("#grid").jqGrid('setSelection', lastSelectedRow);
to something like the following:
var $tr = $("#" + rowID),
$divEdit = $tr.find("div.ui-inline-edit"),
$divDel = $tr.find("div.ui-inline-del"),
$divSave = $tr.find("div.ui-inline-save"),
$divCancel = $tr.find("div.ui-inline-cancel");
$tr.attr("id", json.Id);
if ($divEdit.length > 0) {
$divEdit[0].onclick = function () {
$.fn.fmatter.rowactions(newId,'grid','edit',0);
};
}
if ($divDel.length > 0) {
$divDel[0].onclick = function () {
$.fn.fmatter.rowactions(newId,'grid','del',0);
};
}
if ($divSave.length > 0) {
$divSave[0].onclick = function () {
$.fn.fmatter.rowactions(newId,'grid','save',0);
};
}
if ($divCancel.length > 0) {
$divCancel[0].onclick = function () {
$.fn.fmatter.rowactions(newId,'grid','cancel',0);
};
}
lastSelectedRow = json.Id;
$("#grid").jqGrid('setSelection', lastSelectedRow);
The second problem is that you use special characters inside of ids. I found a bug in the $.fn.fmatter.rowactions which need be fixed to support special characters in ids. The problem is that in the line 407 of jquery.fmatter.js the original rowid parameter rid will be changed:
rid = $.jgrid.jqID( rid )
and later everywhere will be used modified id. For example in the id is my.id the encoded version will be my\\.id. It's correct for the most places of the $.fn.fmatter.rowactions code (see here), but it' s incorrect as the rowid parameter of the editRow, saveRow, restoreRow, delGridRow, setSelection and editGridRow (see the lines 433-453). So the code must be fixed to use the original not escaped (not encoded) rid value with which the $.fn.fmatter.rowactions was called.
I think I will post tomorrow the corresponding bug report with the suggestions in the trirand forum.
UPDATED 2: The code $.fn.fmatter.rowactions(newId,'grid','edit',0); which I wrote above is just an example. I took it from the test demo which you send me. You should of course modify the code for your purpose. How you can see for example from the line the second parameter of the $.fn.fmatter.rowactions in the id of the grid which you use: 'grid', 'list' of something like myGrid[0].id. The last parameter should be the index of the column having formatter:'actions' in the colModel. You can use getColumnIndexByName function from the answer on your old question to get the index by column name.

Using jQuery.validate, how do you validate only a portion of the form when doing an AJAX callback?

I have a web page that has a few text boxes, and a dual list control. All of these data elements are for a particular entity. The form is for creating a new instance of this entity and saving it to the database. The dual list shows available people to use, and the user can move options from the available list to the selected list. All of this works perfectly when posted. There is a button at the bottom of the page to post the form.
To make things easy, I also want to include a hidden "form" that lets the user add a new person to the dual list without leaving the page. They click an "Add New" link which shows a previously hidden div. In the div are two text boxes: "emailName" and "emailAddress", and a button to click called "Add".
When the user clicks the "Add" button I need to validate the emailName and emailAddress fields, and only those two fields. If they are valid then I will make my AJAX request and handle the return data by adding a new option to the dual list.
Here's the solution I am using.
First, I disable validation of my partial's form elements and never re-enable it. I do this by specifying a class selector in the validator options using a custom script that's referenced in the main page.
Then, on my parital's button click I call validator.element for each element. If they are all valid then I perform the AJAX request.
Calling .element will show the validation message for the field and return a boolean indicating if it's valid. You have to check these carefully to avoid boolean operator short-circuiting issues, to make sure all the error messages get shown. I used the bitwise & to accomplish this.
var validator = $("#EmailRecipient_Name").closest("form").validate();
//validator.settings.defaultIgnoreClass is defined in a custom script, and set to ".ignoreValidation"
$("#EmailRecipient_Name").addClass(validator.settings.defaultIgnoreClass);
$("#EmailRecipient_Email").addClass(validator.settings.defaultIgnoreClass);
$("#addNewRecipientLink").click(
function () {
$("#addNewRecipientBox").toggle()
return false;
}
);
$("#addNewRecipient").click(
function(){
var validator = $("#EmailRecipient_Name").closest("form").validate();
if ( validator.element( "#EmailRecipient_Name" ) & validator.element( "#EmailRecipient_Email" ) )
{
$.post(
"#Url.Action( "Create", "EmailRecipient" )",
{
Name: $("#EmailRecipient_Name").val(),
Email : $("#EmailRecipient_Email").val()
},
function( data ){
if ( data.ErrorMessage )
{
alert( data.ErrorMessage );
}
else
{
$("#SelectedEmailRecipients").append("<option value='" + data.EmailRecipientID + "'>" + data.Name + "</option>");
$("#EmailRecipient_Name").val("");
$("#EmailRecipient_Email").val("");
}
}
);
}
return false;
}
);

how to create first column value of jqgrid as iframe window?

In the jqgrid, when i click the first column value, i want to open as iFRAME window. if i use showlink or link formatter, its posted and redirect to the another page. how to create first column value as iframe window.
Thanks in avance..
One method is to use a link to the same page in your format options:
formatoptions: {baseLinkUrl: '#', showAction: '', addParam: ''}
Then after the grid is rendered - for example, in the loadComplete event - set up a click event handler for when a link is clicked:
jQuery('.ui-jqgrid-btable a', '#container').each(function()
{
jQuery(this).unbind('click');
jQuery(this).click(function(){
var link = jQuery(this).attr('href');
var equalPosition = link.indexOf('='); // Get the position of '='
var id = link.substring(equalPosition + 1); // Split the string and get the number.
// Your iframe code here...
return true;
});
This code simply parses out the link, gets the ID, and then lets to do whatever you want with that ID . So for example, you could load content into a new iFrame.
#container is optional, but you could use this as a div that contains the jqGrid div, if you have multiple grids on the same page and need to differentiate them.

Resources