如何提交本地jqgrid数据和表单输入元素

发布于 2024-11-25 19:05:02 字数 2783 浏览 1 评论 0原文

页面包含带有输入元素和 jqgrid 数据的单个表单。 使用 loadonce: true 选项以 json 形式检索 jqGrid 数据。 数据在本地编辑。

如果按下提交按钮,如何提交所有这些数据? jqGrid 有任何方法可以帮助提交所有行的所有数据。 jqGrid - 如何一次编辑和保存多行? 提到应该使用 jQuery ajax 表单插件,但我还没有找到任何示例。

jqGrid 可能在元素中保存检索到的 json 表。在这种情况下,表单插件无法读取此数据。

如何获取并提交使用 loadonce: true 检索并编辑的所有数据?

Update1

基于我尝试过的 Oleg 答案:

function SaveDocument()  {
  var gridData = $("#grid").jqGrid('getGridParam','data');
  var postData = JSON.stringify(gridData);    
  $('#_detail').val( postData );
  var res = $("#Form").serializeArray();
  $.ajax({ type: "POST",        
  url: 'Edit'
  data : res
  });
   }
}

aspx 页面:

<form id="Form" class='form-fields'>
.... other form fields
<input name='_detail' id='_detail' type='hidden' />
</form>
<div id="grid1container" style="width: 100%">
   <table id="grid">
   </table>
</div>

在 ASP.NET MVC2 控制器编辑方法中,我尝试使用

public JsonResult Edit(string _detail) {

var order = new Order();
UpdateModel(order, new HtmlDecodeValueProviderFromLocalizedData(ControllerContext));

var serializer = new JavaScriptSerializer();
var details = serializer.Deserialize<List<OrderDetails>>>(_detail);
}

Deserialize() 调用中发生的异常来解析结果。小数和日期属性以本地化格式传递,但看起来 Deserialize() 无法解析 本地化字符串,并且无法强制它使用像传递给 UpdateModel 的 HtmlDecodeValueProviderFromLocalizedData 这样的转换器。

如何修复? 是否合理/如何将 _detail 参数转换为 NameValue 集合,然后使用 UpdateModel 更新详细信息,使用其他反序列化或其他想法?

更新 2。

小数和日期 CurrentUICulture 值存在于表单和 jqGrid 数据中。提供的示例可以正常处理它们,但对于 jqGrid 数据则失败。 该控制器应该处理可以在运行时定义的不同实体类型、表单字段和 jqgrid 列。因此使用硬编码名称是不可能的。 根据 Oleg 回复,我尝试通过创建转换器来覆盖十进制转换

public class LocalizedTypeConverter : JavaScriptConverter
{
    public override IEnumerable<Type> SupportedTypes
    {
        get
        {
            return new ReadOnlyCollection<Type>(new Type[] { typeof(decimal) });
        }
    }

    public override object Deserialize(IDictionary<string, object> dictionary, Type type,
            JavaScriptSerializer serializer)
    {
        if (dictionary == null)
            throw new ArgumentNullException("dictionary");
        if (type == typeof(decimal))
            return decimal.Parse(dictionary["resources"].ToString(), CultureInfo.CurrentCulture);
        return null;

    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        throw new InvalidOperationException("We only Deserialize");
    }
}

,但转换仍然会导致异常

0,0000 不是有效的十进制值。看起来十进制转换器无法覆盖。如何修复?

Page contains single form with input elements and jqgrid data.
jqGrid data is retrieved in json using loadonce: true option.
Data is edited locally.

How to submit all this data if submit button is pressed?
Has jqGrid any method which can help to submit all data from all rows. jqGrid - How to edit and save multiple rows at once? mentions that jQuery ajax form plugin should be used but I havent found any sample.

jqGrid probably holds retrieved json table in element. In this case form plugin is not capable read this data.

How to get and submit all data retrieved using loadonce: true and edited?

Update1

Based on Oleg answer I tried:

function SaveDocument()  {
  var gridData = $("#grid").jqGrid('getGridParam','data');
  var postData = JSON.stringify(gridData);    
  $('#_detail').val( postData );
  var res = $("#Form").serializeArray();
  $.ajax({ type: "POST",        
  url: 'Edit'
  data : res
  });
   }
}

aspx page:

<form id="Form" class='form-fields'>
.... other form fields
<input name='_detail' id='_detail' type='hidden' />
</form>
<div id="grid1container" style="width: 100%">
   <table id="grid">
   </table>
</div>

In ASP.NET MVC2 Controller Edit method I tried to parse result using

public JsonResult Edit(string _detail) {

var order = new Order();
UpdateModel(order, new HtmlDecodeValueProviderFromLocalizedData(ControllerContext));

var serializer = new JavaScriptSerializer();
var details = serializer.Deserialize<List<OrderDetails>>>(_detail);
}

Exception occurs in Deserialize() call. Decimal and date properties are passed in localized format but it looks like Deserialize() does not parse
localized strings and there is no way to force it to use converter like HtmlDecodeValueProviderFromLocalizedData passed to UpdateModel.

How to fix ?
Is is reasonable/how to convert _detail parameter into NameValue collection and then use UpdateModel to update details, use some other deserialize or other idea ?

Update 2.

Decimal and Date CurrentUICulture values are present in form and in jqGrid data. Sample provided handles them in form OK but fails for jqGrid data.
This controller should handle different entity types, form fields and jqgrid columns can defined at runtime. So using hard-coded names is not possible.
Based on Oleg reply I tried to override decimal conversion by creating converter

public class LocalizedTypeConverter : JavaScriptConverter
{
    public override IEnumerable<Type> SupportedTypes
    {
        get
        {
            return new ReadOnlyCollection<Type>(new Type[] { typeof(decimal) });
        }
    }

    public override object Deserialize(IDictionary<string, object> dictionary, Type type,
            JavaScriptSerializer serializer)
    {
        if (dictionary == null)
            throw new ArgumentNullException("dictionary");
        if (type == typeof(decimal))
            return decimal.Parse(dictionary["resources"].ToString(), CultureInfo.CurrentCulture);
        return null;

    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        throw new InvalidOperationException("We only Deserialize");
    }
}

But conversion still causes exception

0,0000 is not valid value for decimal. It looks like decimal converter cannot overridden. How to fix ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

£烟消云散 2024-12-02 19:05:02

首先,您可以从 jqGrid 获取所有本地数据,

var localGridData = $("#list").jqGrid('getGridParam','data');

网格行的子集(例如仅选定的行),您可能需要获取 _index

var idsToDataIndex = $("#list").jqGrid('getGridParam','_index');

如果您只需要发送 将数据发送到服务器,您可以使用以下函数,例如

var sendData = function(data) {
    var dataToSend = JSON.stringify(data);
    alert("The following data are sending to the server:\n" + dataToSend);
    $.ajax({
        type: "POST",
        url: "yourServerUrl",
        dataType:"json",
        data: dataToSend,
        contentType: "application/json; charset=utf-8",
        success: function(response, textStatus, jqXHR) {
            // display an success message if needed
            alert("success");
        },
        error: function(jqXHR, textStatus, errorThrown) {
            // display an error message in any way
            alert("error");
        }
    });
};

演示中您会发现更复杂一点的例子有两个按钮:“发送所有网格包含”,“发送选定的行”。相应的代码如下

$("#sendAll").click(function(){
    var localGridData = grid.jqGrid('getGridParam','data');
    sendData(localGridData);
});
$("#sendSelected").click(function(){
    var localGridData = grid.jqGrid('getGridParam','data'),
        idsToDataIndex = grid.jqGrid('getGridParam','_index'),
        selRows = grid.jqGrid('getGridParam','selarrrow'),
        dataToSend = [], i, l=selRows.length;
    for (i=0; i<l; i++) {
        dataToSend.push(localGridData[idsToDataIndex[selRows[i]]]);
    }
    sendData(dataToSend);
});

var grid = $("#list"),
    decodeErrorMessage = function(jqXHR, textStatus, errorThrown) {
        var html, errorInfo, i, errorText = textStatus + '\n<br />' + errorThrown;
        if (jqXHR.responseText.charAt(0) === '[') {
            try {
                errorInfo = $.parseJSON(jqXHR.responseText);
                errorText = "";
                for (i=0; i<errorInfo.length; i++) {
                   if (errorText.length !== 0) {
                       errorText += "<hr/>";
                   }
                   errorText += errorInfo[i].Source + ": " + errorInfo[i].Message;
                }
            }
            catch (e) { }
        } else {
            html = /<body.*?>([\s\S]*)<\/body>/i.exec(jqXHR.responseText);
            if (html !== null && html.length > 1) {
                errorText = html[1];
            }
        }
        return errorText;
    },
    sendData = function(data) {
        var dataToSend = JSON.stringify(data);
        alert("The following data are sending to the server:\n"+dataToSend);
        $.ajax({
            type: "POST",
            url: "yourServerUrl",
            dataType:"json",
            data: dataToSend,
            contentType: "application/json; charset=utf-8",
            success: function(response, textStatus, jqXHR) {
                // remove error div if exist
                $('#' + grid[0].id + '_err').remove();
                alert("success");
            },
            error: function(jqXHR, textStatus, errorThrown) {
                // remove error div if exist
                $('#' + grid[0].id + '_err').remove();
                // insert div with the error description before the grid
                grid.closest('div.ui-jqgrid').before(
                    '<div id="' + grid[0].id + '_err" style="max-width:' + grid[0].style.width +
                    ';"><div class="ui-state-error ui-corner-all" style="padding:0.7em;float:left;"><span class="ui-icon ui-icon-alert" ' +
                    'style="float:left; margin-right: .3em;"></span><span style="clear:left">' +
                    decodeErrorMessage(jqXHR, textStatus, errorThrown) + '</span></div><div style="clear:left"/></div>');
            }
        });
    };

我认为,您将在服务器上遇到更困难和更复杂的问题。如果出现并发错误,但我之前写过有关问题的文章。正是由于这些问题,我个人永远不会在服务器上实现多行保存。

更新:要从表单中获取数据,您可以使用jQuery.serialize。您应该对要序列化的表单中的所有字段使用 name 属性。您需要发送的所有数据都是

var allData = {
    localGridData: grid.jqGrid('getGridParam','data'),
    formData: $("#formid").serialize()
};

您可以完全像我之前描述的那样发送数据:sendData(allData)

First of all you can get all local data from the jqGrid with respect of

var localGridData = $("#list").jqGrid('getGridParam','data');

If you will need to send only subset of rows of the grid, like the selected rows only, you can need to get _index:

var idsToDataIndex = $("#list").jqGrid('getGridParam','_index');

To send the data to the server you can use the following function for example

var sendData = function(data) {
    var dataToSend = JSON.stringify(data);
    alert("The following data are sending to the server:\n" + dataToSend);
    $.ajax({
        type: "POST",
        url: "yourServerUrl",
        dataType:"json",
        data: dataToSend,
        contentType: "application/json; charset=utf-8",
        success: function(response, textStatus, jqXHR) {
            // display an success message if needed
            alert("success");
        },
        error: function(jqXHR, textStatus, errorThrown) {
            // display an error message in any way
            alert("error");
        }
    });
};

In the demo you will find a little more sophisticated example having two buttons: "Send all grid contain", "Send selected rows". The corresponding code is below

$("#sendAll").click(function(){
    var localGridData = grid.jqGrid('getGridParam','data');
    sendData(localGridData);
});
$("#sendSelected").click(function(){
    var localGridData = grid.jqGrid('getGridParam','data'),
        idsToDataIndex = grid.jqGrid('getGridParam','_index'),
        selRows = grid.jqGrid('getGridParam','selarrrow'),
        dataToSend = [], i, l=selRows.length;
    for (i=0; i<l; i++) {
        dataToSend.push(localGridData[idsToDataIndex[selRows[i]]]);
    }
    sendData(dataToSend);
});

where

var grid = $("#list"),
    decodeErrorMessage = function(jqXHR, textStatus, errorThrown) {
        var html, errorInfo, i, errorText = textStatus + '\n<br />' + errorThrown;
        if (jqXHR.responseText.charAt(0) === '[') {
            try {
                errorInfo = $.parseJSON(jqXHR.responseText);
                errorText = "";
                for (i=0; i<errorInfo.length; i++) {
                   if (errorText.length !== 0) {
                       errorText += "<hr/>";
                   }
                   errorText += errorInfo[i].Source + ": " + errorInfo[i].Message;
                }
            }
            catch (e) { }
        } else {
            html = /<body.*?>([\s\S]*)<\/body>/i.exec(jqXHR.responseText);
            if (html !== null && html.length > 1) {
                errorText = html[1];
            }
        }
        return errorText;
    },
    sendData = function(data) {
        var dataToSend = JSON.stringify(data);
        alert("The following data are sending to the server:\n"+dataToSend);
        $.ajax({
            type: "POST",
            url: "yourServerUrl",
            dataType:"json",
            data: dataToSend,
            contentType: "application/json; charset=utf-8",
            success: function(response, textStatus, jqXHR) {
                // remove error div if exist
                $('#' + grid[0].id + '_err').remove();
                alert("success");
            },
            error: function(jqXHR, textStatus, errorThrown) {
                // remove error div if exist
                $('#' + grid[0].id + '_err').remove();
                // insert div with the error description before the grid
                grid.closest('div.ui-jqgrid').before(
                    '<div id="' + grid[0].id + '_err" style="max-width:' + grid[0].style.width +
                    ';"><div class="ui-state-error ui-corner-all" style="padding:0.7em;float:left;"><span class="ui-icon ui-icon-alert" ' +
                    'style="float:left; margin-right: .3em;"></span><span style="clear:left">' +
                    decodeErrorMessage(jqXHR, textStatus, errorThrown) + '</span></div><div style="clear:left"/></div>');
            }
        });
    };

I think, that more difficult and more complex problem you will become on the server. In case of concurrency errors, but I wrote you about the problems before. Exactly because of the problems I personally would never implement saving of multiple rows on the server.

UPDATED: To get data from the form you can use jQuery.serialize. You should use name attribute for all fields in the form which you want to serialize. All data which you need to send are

var allData = {
    localGridData: grid.jqGrid('getGridParam','data'),
    formData: $("#formid").serialize()
};

You can send the data exactly like I described before: sendData(allData).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文