javascript - 如何在特定条件下序列化表单

标签 javascript jquery forms

看看这个 fiddle here这是业务用户输入所提供服务的表单。我使用 ajax 并通过序列化表单发送了数据。

单击编辑并添加(加号)服务...在示例中添加了一个输入,其名称属性值为此 **form= form[5]...**与此表单进行对比其他输入中的名称属性值...只有新添加的服务具有这样的名称属性,其原因是仅序列化这些...而不是 DOM 中已存在/存储在数据库中的其他服务.

现在我的问题是: 想象一下,用户去编辑已经注册的服务(或者他去编辑它们添加一个新服务)...在这种情况下,已经注册的服务不会因为表单而被序列化name 属性值有...(其原因已在上面解释)。

在这种情况下我能做什么?有时我必须仅序列化表单的一部分,有时必须序列化整个表单。如果所有输入的 name 属性值为 form[1....] 则连同新添加的输入...已注册的服务将再次序列化。 感谢您的聆听。

代码如下(您也可以在 fiddle 中看到它)

    $('.editservices').click(function() {
    //console.log(('.wrapper_servp').length);
    originals_ser_input_lgth = $('.services').length;

    var originals = [];
    $('.show_price')
        // fetch only those sections that have a sub-element with the .value 
      class
        .filter((i, e) => $('.value', e).length === 1)
        // replace content in remaining elements
        .replaceWith(function(i) {
            var value = $('.value', this).data('value');
            var fieldsetCount = $('#serv').length;
            var index = fieldsetCount + i;
            return '<div class="show_price"><p id="show_p_msg">Price 
        visibility</p></div>' + '\
                                    <div class="show_p_inpts">' +
                '<input class="price_show"' + (value == 1 ? "checked" : "") + ' 
         type="radio" name="form[' + index + '][price_show]" value="1">yes' +
                '<input class="price_show"' + (value == 0 ? "checked" : "") + ' 
          type="radio" name="form[' + index + '][price_show]" value="0">no' +
                '</div>'; // HTML to replace the original content with
        });
    $('#buttons').removeClass('prfbuttons');
    $('#saveserv').addClass('hideb');
    $('.actionsserv').removeClass('actionsserv');
    priceavail = $(".price_show:input").serializeArray();

     });
     $('#addser').on('click', function() {

     $('#saveserv').css('border','2px solid none');

    var serviceCount = $('input.services').length + 1;
    var serv_inputs = '<div class="wrapper_servp"><div class="serv_contain">\n\
        <input placeholder="service" class="services text" name="form[' + serviceCount + '][service]" type="text" size="40"> \n\
        <input placeholder="price" class="price text" name="form[' + serviceCount + '][price]" type="text" size="3"></div>';
    var p_show = '<div class="show_p">' +
        '<p id="show_p_msg">Price visibility;</p>' +
        '<span id="err_show_p"></span><br>' +
        '</div>';
    var inputs = '<div class="show_p_inpts">' +
        '<input class="price_show" type="radio" name="form[' + serviceCount + '][price_show]" value="1">yes' +
        '<input class="price_show" type="radio" name="form[' + serviceCount + '][price_show]" value="0">no' +
        '</div></div>';
    $('.wrapper_servp').last().after(serv_inputs + p_show + inputs);
    $('#saveserv').removeClass('hideb');
    $('#remser').css('display', 'inline');

});

$('#cancelserv').click(function(e) {
    e.preventDefault();
    //var newinputs = $('.wrapper_servp').length;
    //var inp_remv = newinputs - originals_ser_input_lgth;
    //$('.wrapper_servp').slice(-inp_remv).remove()

    $('.show_p_inpts')
        .filter((i, e) => $('.price_show:checked', e).length === 1)
        .replaceWith(function(i) {
            var value = $('.price_show:checked').attr('value');
            return '<span data-value="' + value + '" class="value">' + (value == 1 ? "yes" : "no") + '</span>'
        });
});


var groupHasCheckedBox = function() {
        return $(this).find('input').filter(function() {
            return $(this).prop('checked');
        }).length === 0;
    },
    inputHasValue = function(index) {
        return $(this).val() === '';
    };

$('#saveserv').click(function(e) {

    e.preventDefault();
    //from here
    var $radioGroups = $('.show_p_inpts');

    $('.show_p_inpts').filter(groupHasCheckedBox).closest('div').addClass("error");

    $('.services, .price').filter(inputHasValue).addClass("error");
    //to here

    var $errorInputs = $('input.services').filter((i, e) => !e.value.trim());
    if ($errorInputs.length >= 1) {
        console.log($errorInputs);
        $('#err_message').html('you have to fill in the service'); return;

    }
    if ($('input.price').filter((i, e) => !e.value.trim()).length >= 1) {
        $('#err_message').html('you have to fill in the price'); return;

    }
});
   var IDs=new Array();
 $('body').on('click', '#remser', function(e){


  var inputval=$('.services:visible:last').val();

  if(inputval!=='')
  {r= confirm('Are you sure you want to delete this service?');}
  else
  {

       $('.wrapper_servp:visible:last').remove();

  }



  switch(r)
  {
   case true: 

   IDs.push($('.services:visible:last').data('service'));

   $('.wrapper_servp:visible:last').addClass('btypehide');
   if($('.serv_contain').length==1)$('#remser').css('display','none');
   $('#saveserv').removeClass('hideb').css('border','5px solid red');

              //originals.servrem=true;
   break;



    case false:var i;
    for(i=0;i<originals.ser_input_lgth;i++)
    { 
        $('input[name="service'+i+'"]').val(services[i].value);
         $('input[name="price'+i+'"]').val(prices[i].value);//εδω set value

     }


     $('.services').slice(originals.ser_input_lgth).remove();
     $('.price').slice(originals.ser_input_lgth).remove();

    $('.openservices').addClass('hide').find('.services,.price').prop('readonly', true);
     var text='<p class="show_price">Θες να φαίνεται η τιμή;<span data-value="'+ show_pr_val.value +'" class="value">' +(show_pr_val.value==1 ? 'yes':'no') + '</span></p>';

     $('.show_p_inpts').remove();
     $('.show_price').replaceWith(text);;
          break;

      }

});

最佳答案

我有一个想法给你。你可以做的是,当你在 html 中显示当前存在的值时,不要给出 name 属性,而只是给出 data-name 属性。即

改变这个

<input class="services text" data-service="21" size="40" value="hair" type="text" name="service0" readonly=""> 

至此

<input class="services text" data-service="21" size="40" value="hair" type="text" data-value="hair" data-name="service0" readonly="">

现在,当用户更新此值时,您可以在 jQuery 中绑定(bind)一个事件,如下所示。

    $(document).ready(function(){
    $(".services input").on("change paste keyup", function() {
      if($(this).val() === $(this).attr("data-value"))
      {
       $(this).removeAttr("name");
      }else{
       $(this).attr("name",$(this).attr("data-name"));
      } 
    });

});

通过这种方式,您可以仅将名称属性赋予那些值已更改的元素。现在每次你可以序列化整个表单,它只会获取更改元素的值。

不要忘记为已经存在的元素提供唯一的类,以便您可以绑定(bind)更改事件。希望您清楚。

关于javascript - 如何在特定条件下序列化表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49424045/

相关文章:

javascript - 有没有办法完全阻止popstate?

javascript - 使用ajax的表单不发送电子邮件

javascript - 初始化时光滑的 slider 宽度错误

javascript - 如何选择文本 block 每一行的第一个单词?

javascript - Uncaught ReferenceError : element is not defined

javascript - 以 Javascript/jQuery 表示的 PHP 表单 : One to many UI relationships,?

PHP输出单引号和双引号作为输入元素的值

ruby-on-rails-3 - 导轨 : method for 'standardizing' url input from users?

javascript - 使用 jquery 从 JSON 数据生成动态 html

javascript - 下拉菜单显示我的 JSON 文件中的第一个值而不是默认文本