s:复选框fieldValue在提交前的验证中始终为true

时间:2016-01-28 13:09:50

标签: jquery angularjs forms checkbox struts2

我在表单处理中使用Struts 2 <s:checkbox />,以及AngularJS和jQuery。
在提交之前,我需要验证,直到现在我们在项目中执行此操作:

当我们按下提交按钮时,此功能被称为:

$scope.processForm('myForm', '<s:url value="/form/validate.action" />', 
                             '<s:url value="/form/save.action" />');

,其中processForm(formId, validateUrl, submitUrl)是我们定义的函数:

$scope.processForm = function(form, validateUrl, submitUrl) {
    window.scroll(0,0);
    ProccessFormService.processStandarForm(form, validateUrl, submitUrl);
};

此外,我们在全球服务中定义了processStandarForm()

angular.module('ourApp').controller('myFormCtrl', 
                                    function($scope, $modal, ProccessFormService) {
...
}

在服务中:

(function() {   
    angular.module('ourApp').factory('ProccessFormService', ['$http', function($http) {

    processStandarForm: function(form, validateUrl, submitUrl) {        
        this.processForm(form, validateUrl, submitUrl);
    },

    processForm: function(form, validateUrl, submitUrl, success) {

        if ((typeof form) == 'string') {
            form = document.getElementById(form);
        }

        var data = this.form2Object(form);
        var ctrl = this;

        if (data) {
            if (validateUrl) {
                $http({
                    method  : 'POST',
                    url     : validateUrl,
                    data    : $.param(data),  // pass in data as strings
                    headers : { 'Content-Type': 'application/x-www-form-urlencoded' }  
         // set the headers so angular passing info as form data (not request payload)
                }).success(function() {
                    if (!success) {
                        form.action = submitUrl;
                        form.submit();
                    } else {
                        ctrl.submitAjaxForm(submitUrl, data, success)
                    }
                });
            } else if (submitUrl) {
                if (!success) {
                    form.action = submitUrl;
                    form.submit();
                } else {
                    this.submitAjaxForm(submitUrl, data, success)
                }
            }
        }       
    },
}

基本上,我们提交两次表单,首先进行验证,然后提交。

我不明白的是,如果我在动作类中调试,在validate()的函数中,<s:checkbox />的布尔值总是为真,但在{{1函数,布尔值正确提交,根据它们被选中/未选中。复选框是这样的:

submit()

据我所知,<div class="col-sm-12 form-checkbox"> <s:checkbox name = "myForm.married" ng-model = "checkboxModel" value = "<s:property value='%{myForm.married}'/>" ng-change = "submitCheckbox();" ng-init = "checkboxModel= %{myForm.married}" theme = "simple" ng-disabled = "anotherFunction()" /> </div> 中提交的值为fieldValue="xxx",默认情况下为true。所以我这样做是为了在页面加载之前更改每个<s:checkbox />的{​​{1}}。虽然所有脚本都已执行,但没有任何改变。我在验证中仍然是真的。

fieldValue

那么,我怎样才能获得正确的checkbox值,不仅可以提交,还可以进行验证? Angular服务是否被错误地写了?我真的很怀疑,但我无法弄清楚这个问题。

3 个答案:

答案 0 :(得分:0)

你可能已经删除了(或搞砸了:uncheckedValue=true)拦截器堆栈中有用的东西,比如https://github.com/joelittlejohn/jsonschema2pojo

  

org.apache.struts2.interceptor.CheckboxInterceptor在   defaultStack。它检查提交给操作的每个表单参数   如果它找到前缀为_checkbox的那个,则为其插入一个值   一个参数,其名称从_checkbox的后缀派生而来   不存在。插入的默认值为false,但这可以是   通过在拦截器上设置uncheckedValue参数来更改。

     

这意味着复选框可以附带隐藏输入   相同的名称,但前缀为_checkbox,以便复选框不是。{   在表单上检查操作仍然会收到一个值而不是   未提供未选中值的默认HTML操作   复选框。

答案 1 :(得分:0)

怀疑与data一起使用的$http()未正确序列化。

如果要模仿jQuery中使用的$.param(),则应使用内置序列化程序$httpParamSerializerJQLike

 
  

替代$http params序列化程序,它遵循jQuery的param()   方法逻辑。序列化程序还将按字母顺序对params进行排序。

     

要将其用于序列化$http请求参数,请将其设置为   paramSerializer财产:

$http({
  url: myUrl,
  method: 'GET',
  params: myParams,
  paramSerializer: '$httpParamSerializerJQLike'
});
     

也可以将其设置为默认paramSerialize r   $httpProvider

     

此外,您可以注入序列化程序并明确使用它   序列化表单数据以提交的示例:

.controller(function($http, $httpParamSerializerJQLike) {
  //...

  $http({
    url: myUrl,
    method: 'POST',
    data: $httpParamSerializerJQLike(myData),
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    }
  });

});

您可以在Convert $.param in angularjs

中找到另一种从$.param转换为角度的方法

答案 2 :(得分:0)

我自己已经找到了问题。它在这里:

query:{"more_like_this":{"fields":[field1,field2],"like":"elastic kabana","boost_terms":3.0}}

注意var data = this.form2Object(form); 是另一个函数,我更多地挖掘了这个函数,发现这个函数正在序列化表单,手动将其转换为对象,而不是正确处理form2Object(form)

<input type="checkbox" />

所以我把它改成了这个:

form2Object: function(form) {

    var data = null;
    if ((typeof form) == 'string') {
        form = document.getElementById(form);
    }
    if (form) {
        data = new Object();
        for (var i = 0; i < form.elements.length; i++) {
            if ( (form.elements[i].tagName.toUpperCase() == 'INPUT') || form.elements[i].tagName.toUpperCase() == 'TEXTAREA') {
//here it considers `<input type="checkbox" />` as normal `<input />`, and will submit its `value=xxx` in validation, and it will always be `true` due to `<s:checkbox />`. 
//But it will be correct in real submission because before that, we don't go through here.
                data[form.elements[i].name] = form.elements[i].value;
            } else if (form.elements[i].tagName.toUpperCase() == 'SELECT') {
                data[form.elements[i].name] = form.elements[i].value;
            }
        }
    }
    return data;
}

但是,阅读@Roman C的回答,我意识到使用内置函数序列化表单可能会更好。所以我接受了他的回答。