First, declare a variable for the html string of your form:
<script type="text/javascript">
var formHtml = "";
function canRender() {
return _canRender;
}
$(function () {
_canRender = false;
});
</script>
We use canRender so we can defer the execution of javascript of the form's html string
<div id="editor" style="visibility: hidden">
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "theForm" }))
{
<fieldset>
<legend>Person</legend>
@Html.HiddenFor(x => x.PersonId)
@Html.HiddenFor(x => x.RowVersion)
<div class="editor-label">
@Html.LabelFor(x => x.Username)
</div>
<div class="editor-field">
@Html.EditorFor(x => x.Username)
@Html.ValidationMessageFor(x => x.Username)
</div>
<div class="editor-label">
@Html.LabelFor(x => x.Firstname)
</div>
<div class="editor-field">
@Html.EditorFor(x => x.Firstname)
@Html.ValidationMessageFor(x => x.Firstname)
</div>
<div class="editor-label">
@Html.LabelFor(x => x.Lastname)
</div>
<div class="editor-field">
@Html.EditorFor(x => x.Lastname)
@Html.ValidationMessageFor(x => x.Lastname)
</div>
<div class="editor-label">
@Html.LabelFor(x => x.Country.CountryId)
</div>
<div class="editor-field">
<table style="border-style: none">
<tr>
<td style="border-style: none">
@Html.AjaxComboBoxFor(x => x.Country.CountryId, "/Countries/Management/Lookup/", "/Countries/Management/Caption/",
new { }, new { sub_info = true, can_render_callback = "canRender", textbox_width = 200 })
</td>
<td style="border-style: none">
@Html.ValidationMessageFor(x => x.Country.CountryId)
</td>
</tr>
</table>
</div>
<div class="editor-label">
@Html.LabelFor(x => x.FavoriteNumber)
</div>
<div class="editor-field">
@Html.EditorFor(x => x.FavoriteNumber)
@Html.ValidationMessageFor(x => x.FavoriteNumber)
</div>
<p>
<input type="submit" value="Save" />
<input type="button" id="Closer" value="Close" />
</p>
</fieldset>
<div style="max-width: 500px; width: 500px;">
@Html.JsAccessibleValidationSummary(excludePropertyErrors: true)
</div>
}
<script type="text/javascript">
$(function () {
if (!canRender()) return;
var scope = $('#theForm');
parseDynamicContent(scope);
$('#Closer', scope).click(function (e) {
closeForm($(scope));
});
$('input[type=submit]', scope).click(function (e) {
try {
e.preventDefault();
if (!scope.valid()) {
// alert('has invalid');
return;
}
save(scope);
// closeForm(scope);
} catch (e) {
alert("Error " + e);
}
});
$(scope).attr('id', guid());
});
function save(scope) {
$.ajax({
url: '/People/Management/SaveViaAjax',
type: 'POST',
data: $(scope).serialize(),
success: function (result) {
var isOk = $(scope).modelValidation(result);
if (isOk) {
var isNew = $('#PersonId', scope).val() == '';
if (isNew) {
$('#PersonId', scope).val(result.PersonId);
}
$('#RowVersion', scope).val(result.RowVersion);
if (isNew) {
$(scope).closest('table').flexReload();
}
else {
setFgEditText(scope, 'Username', $('#Username', scope).val());
setFgEditText(scope, 'Firstname', $('#Firstname', scope).val());
setFgEditText(scope, 'Lastname', $('#Lastname', scope).val());
setFgEditText(scope, 'FavoriteNumber', $('#FavoriteNumber', scope).val());
setFgEditText(scope, 'Country', $('#Country_CountryId', scope).ajc().getText());
closeForm(scope);
}
}
// $('#firstTable').flexReload();
},
error: function (a, b, c) {
alert(a.statusText);
alert(b);
alert(c);
}
}); //ajax
}//save
</script>
</div>
Here's the flexigrid setup and getting the form's html string:
<script type="text/javascript">
$(function () {
// main..
setupForm();
setupFirstTable();
// ..main
});
function setupForm() {
formHtml = $('#editor').html();
$('#editor').remove();
}
function setupFirstTable() {
$('#firstTable').flexigrid({
url: '/People/Management/List',
dataType: 'json',
colModel: [
{ display: 'User', name: 'Username', width: 150, sortable: true, align: 'left' },
{ display: 'Firstname', name: 'Firstname', width: 150, sortable: true, align: 'left' },
{ display: 'Lastname', name: 'Lastname', width: 150, sortable: true, align: 'left' },
{ display: 'Favorite#', name: 'FavoriteNumber', width: 150, sortable: true, align: 'left' },
{ display: 'Country', name: 'Country', width: 150, sortable: true, align: 'left' },
{ display: 'RowVersion', name: 'RowVersion', width: 150, sortable: true, align: 'left', hide: true }
],
buttons: [
{ name: 'Add', bclass: 'add', onpress: add },
{ separator: true },
{ name: 'Edit', bclass: 'edit', onpress: edit },
{ separator: true },
{ name: 'Delete', bclass: 'delete', onpress: del }
],
singleSelect: true,
sortname: 'Lastname',
sortorder: 'asc',
usepager: true,
title: 'Persons',
useRp: true,
rp: 5,
rpOptions: [5, 10, 15, 20, 25, 40],
showTableToggleBtn: true,
width: 900,
height: 'auto',
preProcess: function (data) {
var rp = getFgRowsPerPage($('#firstTable'));
for (i = data.rows.length; i < rp; ++i) {
data.rows.push({ 'id': '', 'cell': ['', '', '', '', '', ''] });
}
return data;
}
}); // flexigrid
setupGrid($('#firstTable'));
} //setupFirstTable
function add(com, grid) {
try {
closeFormByGrid(grid);
showAddFormByGrid(grid, formHtml);
} catch (e) {
alert('error ' + e);
}
}
function edit(com, grid) {
closeFormByGrid(grid);
var items = $('.trSelected', grid);
var item = items[0];
var pk = item.id.substr(3);
if (pk.length == 0) return;
$.ajax({
url: '/People/Management/GetUpdated/' + pk,
type: 'POST',
success: function (data) {
showEditForm(item, formHtml, function () {
var form = $('form', grid);
$('#PersonId', form).val(data.Record.PersonId);
$('#Username', form).val(data.Record.Username);
$('#Firstname', form).val(data.Record.Firstname);
$('#Lastname', form).val(data.Record.Lastname);
$('input[id=Country_CountryId]', form).val(data.Record.CountryId);
$('#FavoriteNumber', form).val(data.Record.FavoriteNumber);
$('#RowVersion', form).val(data.Record.RowVersion);
$('#Country_CountryId', form).ajc().showCaption();
setFgEditText(grid, 'Username', data.Record.Username);
setFgEditText(grid, 'Firstname', data.Record.Firstname);
setFgEditText(grid, 'Lastname', data.Record.Lastname);
setFgEditText(grid, 'FavoriteNumber', data.Record.FavoriteNumber);
}); //showEditForm
} //success
}); //ajax
}//edit
function del(com, grid) {
var deleteIt = confirm('Do you want to delete the selected record?');
if (!deleteIt) return;
var pk = getCurrentRowPk(grid);
var version = getFgGridColumnText(grid, 'RowVersion');
// alert(pk + " " + version + " " + encodeURIComponent(version));
$.ajax({
url: '/People/Management/Delete',
type: 'POST',
data: 'pk=' + pk + '&version=' + encodeURIComponent(version),
success: function (result) {
if (result.IsOk) {
$('#firstTable').flexReload();
}
}
});
}
</script>
Lastly we put this at the end of the html:
<script>
$(function () {
_canRender = true;
});
</script>
Here's the Flexigrid form-inliner helper functions:
function showEditForm(selectedTr, html, assignerFunc) {
$(selectedTr).after('<tr class="fgEdit" editId=' + selectedTr.id + '><td width="1" colspan="20" style="border-width: thin; border-top: thick; border-color: #EEE; white-space: normal;"><span></span></td></tr>');
var content = $('td > span', $(selectedTr).next());
// var form = $(content).hide().html(html);
var form = $(content).html(html);
assignerFunc();
$(content).show();
}
function showAddFormByGrid(grid, formHtml) {
var tbl = $('.bDiv table', grid);
showAddForm(tbl, formHtml);
}
function showAddForm(tbl, formHtml) {
var tbody = $('tbody', tbl);
if (tbody.length == 0) {
$(tbl).append($('<tbody/>'));
tbody = $('tbody', tbl);
}
$(tbody).prepend('<tr class="fgEdit"><td width="1" colspan="20" style="border-width: thin; border-top: thick; border-color: #EEE; white-space: normal"><span></span></td></tr>');
var content = $('tr td span', tbody);
$(content).html(formHtml);
}
Flexigrid CRUD(inline form) example with ASP.NET MVC, complete with model validation:
http://code.google.com/p/flexigrid-crud-example/downloads/list
Known issues:
1. Not with flexigrid per se; but when inside of flexigrid, the jQuery Ajax ComboBox's result area is far from its textbox when using Firefox or IE, have made a work-around in Chrome though. If you could lend a help in correcting that problem of jQuery Ajax ComboBox, I'll be more than glad to accept a patch.
2. If the flexigrid has no rows, the inline form is not in full width. Accepting patch for flexigrid code or helper code.
![]() |
| Sample output |
![]() |
| jQuery Ajax ComboBox's detached result screenshot(IE and Firefox problem) |

