简体   繁体   English

附加和分离动态创建的输入

[英]Appending and detaching dynamically created inputs

I have two radio buttons:我有两个单选按钮:

  • fixed_price_option ( Selected by default.) fixed_price_option (默认选中。)
  • variable_price_option ( Disabled by default) variable_price_option (默认禁用

I also have two types of inputs:我也有两种类型的输入:

  • fixed_price_input ( Visable by default. Only one occurance.) fixed_price_input (默认可见。只出现一次。)
  • variable_price_input (Not present in code as it has to be added dynamically. One or more occurances.) variable_price_input (不存在于代码中,因为它必须动态添加。一次或多次出现。)

When fixed_price_option is selected an input called fixed_price_input should be visable and included when later running .serialize().fixed_price_option被选择的输入称为fixed_price_input应visable并且当以后运行.serialize包括()。

When fixed_price_option is selected no variable_price_input ´s should be visible or included when later running .serialize().fixed_price_option没有选择variable_price_input的应该是可见的或包括在以后运行.serialize()。

variable_price_option should only be selectable when the difference between two date inputs are more than 12 months. variable_price_option仅在两个日期输入之间的差异超过 12 个月时才可选择。 (this I have solved) (这个我已经解决了)

When variable_price_option is selected there should be one more variable_price_input ´s visable as there are whole years between the two date inputs (ie durationMonths + 1). When variable_price_option is selected there should be one more variable_price_input ´s visable as there are whole years between the two date inputs (ie durationMonths + 1). They also need to be included when later running .serialize() so they need to have names like price_year_1 , price_year_2 , price_year_3 and so on, depending on how many whole years there are between the two date inputs.稍后运行 .serialize() 时也需要包含它们,因此它们需要具有price_year_1price_year_2price_year_3等名称,具体取决于两个日期输入之间有多少整年。

When variable_price_option is selected fixed_price_input should not be visible or included when later running .serialize(). When variable_price_option is selected fixed_price_input should not be visible or included when later running .serialize().

I have supplied the code as far as I have come.我已经提供了代码。 The missing logic needs to be put in the event handler at the bottom of the js code.缺少的逻辑需要放在js代码底部的事件处理程序中。

Any suggestions on how to solve this?有关如何解决此问题的任何建议?

-- UPDATE -- - 更新 -

My question needed clarification:我的问题需要澄清:

What I'm struggling with is to toggle the existence of the two types of inputs ( fixed_price_input and variable_price_input ) depending on which radio button is checked.我正在努力的是根据选中的单选按钮来切换两种类型的输入( fixed_price_inputvariable_price_input )的存在。 Hiding/showing them isn't enough because I'm going to use .serialize() at a later point.隐藏/显示它们是不够的,因为稍后我将使用 .serialize()。 Should I use .detach() and .append() somehow?我应该以某种方式使用 .detach() 和 .append() 吗?

I'm also struggling with how to create one more variable_price_input 's than there are years between the start and end date.我也在努力创建一个比开始日期和结束日期之间的年份更多的variable_price_input Should I use <template> or .clone() somehow?我应该以某种方式使用<template>还是 .clone() ?

 $(document).ready(function() { $("#inputStartDate, #inputEndDate").change(function() { if ($('#inputStartDate').val() && $('#inputEndDate').val()) { var startDate = moment($('#inputStartDate').val()); var endDate = moment($('#inputEndDate').val()); var durationMonths = endDate.diff(startDate, 'months'); $('#durationMonths').text(durationMonths); var durationYears = endDate.diff(startDate, 'years'); $('#durationYears').text(durationYears); if (duration > 12) { $('#variablePriceOption').prop("disabled", false); } else { $('#variablePriceOption').prop("disabled", true); } } }); $('#variablePriceOption, #fixedPriceOption').change(function() { if (this.value == 'fixedPrice') { //Logic needed } else if (this.value == 'variablePrice') { //Logic needed } }); });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min.js"></script> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.0/css/bootstrap.min.css" rel="stylesheet" /> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.0/js/bootstrap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script> <div class="container"> <div class="row mt-3"> <div class="col"> <div class="form-group"> <label for="inputStartDate">Start date</label> <input type="date" class="form-control" id="inputStartDate" name="land_contract_start_date"> </div> </div> <div class="col"> <div class="form-group"> <label for="inputEndDate">End date</label> <input type="date" class="form-control" id="inputEndDate" name="land_contract_end_date"> </div> </div> </div> <div class="text-center">Months between selected dates = <span id="durationMonths"></span>. Years between selected dates = <span id="durationYears"></span>. </div> <div class="form-group"> <label for="inputPriceModel">Price model</label> <div id="inputPriceModel"> <div class="form-check"> <input class="form-check-input" type="radio" name="inputPriceModel" id="fixedPriceOption" value="fixedPrice" required checked="checked"> <label class="form-check-label" for="fixedPriceOption"> Fixed price </label> </div> <div class="form-check"> <input class="form-check-input" type="radio" name="inputPriceModel" id="variablePriceOption" value="variablePrice" disabled="disabled"> <label class="form-check-label" for="variablePriceOption"> Variable price </label> </div> </div> </div> <div class="form-group fixedPriceModelFormGroup"> <label for="fixed_price_input">Fixed price amount</label> <div class="input-group"> <input type="number" class="form-control" id="fixed_price_input" name="land_contract_fixed_annual_price"> <div class="input-group-append"> <span class="input-group-text">$</span> </div> </div> </div> </div>

This should help get you started as far as variable pricing inputs showing for each # of year difference of the calendar dates.就日历日期的每个年份差异显示的可变定价输入而言,这应该可以帮助您入门。 The code could be broken out into other functions for handling the display/hiding of elements, etc. You need to move your <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> code above your other JS references to get rid of the errors you're seeing for bootstrap .代码可以分解成其他函数来处理元素的显示/隐藏等。你需要移动你的<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>代码高于您的其他 JS 引用,以消除您在bootstrap看到的错误。

Also, your duration variable should be durationMonths for comparing > 12, as duration is undefined .此外,您的duration变量应该是durationMonths以比较 > 12,因为durationundefined durationYears should be moved outside the change function of the calendar dates so you can reference it in your other processing functions. durationYears应该移到日历日期的change功能之外,以便您可以在其他处理功能中引用它。 I added Math.abs() to the date calculations to ensure you're dealing with a positive integer for comparisons.我在日期计算中添加了Math.abs()以确保您正在处理一个正整数进行比较。

Using the disabled attribute on the inputs that are hidden will allow you to serialize the visible form data and ensure you won't get hidden inputs (variable pricing fields, etc) as part of the serialization data.在隐藏的inputs上使用disabled属性将允许您序列化可见的form数据并确保您不会将隐藏的输入(可变定价字段等)作为serialization数据的一部分。

As @Twisty mentioned in the comments on your post, you will want to use .detach() or some sort of way to store the variable pricing input values if you toggle back and forth between Fixed/Variable options ( localStorage , sessionStorage also options for storing data), if you want to maintain any values placed in the variable/fixed inputs .正如@Twisty 在您帖子的评论中提到的,如果您在固定/可变选项( localStoragesessionStorage也选项)之间来回切换,您将需要使用.detach()或某种方式来存储可变定价输入值存储数据),如果您想维护放置在变量/固定inputs中的任何值。 You will need to remove the .empty() usage on the input fields in my example as well, if you intend to store the data values of the inputs.如果您打算存储输入的数据值,您还需要在我的示例中删除输入字段上的.empty()用法。

The loop function handleVariablePricing for determining how many variable pricing inputs should show would need to hook into the stored data functionality to ensure you are creating the same amount of fields with previously entered values, and not adding additional new fields on top of the existing fields/values.用于确定应显示多少可变定价输入的循环函数handleVariablePricing需要挂钩到存储数据功能中,以确保您使用先前输入的值创建相同数量的字段,而不是在现有字段之上添加额外的新字段/值。

 $(document).ready(function() { var durationYears = 0; $("#inputStartDate, #inputEndDate").change(function() { if ($('#inputStartDate').val() && $('#inputEndDate').val()) { var startDate = moment($('#inputStartDate').val()); var endDate = moment($('#inputEndDate').val()); var durationMonths = Math.abs(endDate.diff(startDate, 'months')); $('#durationMonths').text(durationMonths); // maintain value outside of change function durationYears = Math.abs(endDate.diff(startDate, 'years')); $('#durationYears').text(durationYears); if (durationMonths > 12) { $('#variablePriceOption').prop("disabled", false); } else { $('#variablePriceOption').prop("disabled", true); } // If dates changed, update variable inputs shown if ($('#variablePriceOption').is(':checked')) { if (durationMonths > 12) { $('#variable_price_input_1').val(''); $('.duration-years-input').remove(); handleVariablePricing(); } else { $('#fixedPriceOption').click(); } } } }); $('#variablePriceOption, #fixedPriceOption').change(function() { if (this.value == 'fixedPrice') { $('.variablePriceModelFormGroup').removeClass('d-block').addClass('d-none'); $('.variablePriceModelFormGroup input').each(function() { $(this).val('').attr('disabled', true); }); $('.fixedPriceModelFormGroup input').prop('disabled', false); $('.fixedPriceModelFormGroup').removeClass('d-none').addClass('d-block'); $('.duration-years-input').remove(); } else if (this.value == 'variablePrice') { $('.fixedPriceModelFormGroup').removeClass('d-block').addClass('d-none'); $('.fixedPriceModelFormGroup input').val('').attr('disabled', true); $('#variable_price_input_1').prop('disabled', false); $('.variablePriceModelFormGroup').removeClass('d-none').addClass('d-block'); handleVariablePricing(); } }); /** * Creates inputs for variable pricing.. **/ var handleVariablePricing = function() { $rowClone = $('.row-main').clone(); for (var i = 2; i <= durationYears + 1; i++) { $rowClone.prop('class', 'duration-years-input'); $rowClone.find('label').text('Price Year ' + i); $rowClone.find('input').prop('id', 'variable_price_input_' + i); $rowClone.find('input').prop('name', 'land_contract_variable_annual_price_' + i); if ($('.duration-years-input').length === 0) { $('.row-main').after($rowClone); } else { $('.duration-years-input').last().after($rowClone); } $rowClone = $('.duration-years-input').last().clone(); } }; $('button').click(function() { console.log($('#test-form').serialize()); }); });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min.js"></script> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.0/css/bootstrap.min.css" rel="stylesheet" /> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.0/js/bootstrap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script> <div class="container"> <form id="test-form"> <div class="row mt-3"> <div class="col"> <div class="form-group"> <label for="inputStartDate">Start date</label> <input type="date" class="form-control" id="inputStartDate" name="land_contract_start_date"> </div> </div> <div class="col"> <div class="form-group"> <label for="inputEndDate">End date</label> <input type="date" class="form-control" id="inputEndDate" name="land_contract_end_date"> </div> </div> </div> <div class="text-center">Months between selected dates = <span id="durationMonths"></span>. Years between selected dates = <span id="durationYears"></span>. </div> <div class="form-group"> <label for="inputPriceModel">Price model</label> <div id="inputPriceModel"> <div class="form-check"> <input class="form-check-input" type="radio" name="inputPriceModel" id="fixedPriceOption" value="fixedPrice" required checked="checked"> <label class="form-check-label" for="fixedPriceOption"> Fixed price </label> </div> <div class="form-check"> <input class="form-check-input" type="radio" name="inputPriceModel" id="variablePriceOption" value="variablePrice" disabled="disabled"> <label class="form-check-label" for="variablePriceOption"> Variable price </label> </div> </div> </div> <div class="form-group fixedPriceModelFormGroup"> <label for="fixed_price_input">Fixed price amount</label> <div class="input-group"> <input type="number" class="form-control" id="fixed_price_input" name="land_contract_fixed_annual_price"> <div class="input-group-append"> <span class="input-group-text">$</span> </div> </div> </div> <div class="form-group variablePriceModelFormGroup d-none"> <div class="row-main"> <label for="variable_price_input">Price Year 1</label> <div class="input-group"> <input type="number" class="form-control" id="variable_price_input_1" name="land_contract_variable_annual_price_1" disabled="disabled"> <div class="input-group-append"> <span class="input-group-text">$</span> </div> </div> </div> </div> </form> <button>Serialize</button> </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM