JQuery / JavaScript: перебирайте поля формы, выполняйте вычисления, затем отправляйте

0

Сейчас мой код очень "жестко запрограммирован" и повторяется. Я хотел бы знать, есть ли более чистый способ сделать следующее. В идеале, я хочу перебирать поля своих форм с помощью цикла и вычислять результаты с одним утверждением, но я изо всех сил пытаюсь понять, как это сделать.

Резюме. У меня есть десять полей формы, каждое из которых имеет четкое десятичное значение, которое пользователь может или не может предоставить. Когда пользователь нажимает submit, он должен добавить значение в поле ввода со значением, отображаемым на текущей странице HTML, а затем вставить в БД.

Во-первых, я беру это значение из поля ввода формы и преобразую его в число с двумя знаками после запятой. Затем я хватаю текущую сумму из HTML и добавляю два числа вместе. После этого я ввожу эту сумму обратно в поле ввода формы, чтобы ее можно было сохранить в $_POST и вставить в базу данных.

Как я могу сделать свой код более СУХОЙ (т.е. Не повторяться)? Ниже приведены только два примера, но они абсолютно одинаковы, за исключением вызовов элементов:

var subtotal = Number($("#housing").val());
subtotal = (subtotal).toFixed(2);
var currentTotal = $('#output-housing').html().replace("$", "");
var total = Number(subtotal) + Number(currentTotal);
$('#housing').val(total);

var subtotal = Number($("#utilities").val());
subtotal = (subtotal).toFixed(2);
var currentTotal = $('#output-utilities').html().replace("$", "");
var total = Number(subtotal) + Number(currentTotal);
$('#utilities').val(total);

Я бы хотел, чтобы я повторял свои поля ввода так, но я пытаюсь понять, как я могу отобразить логику внутри:

var input = $('.form-expenses :input');
input.each(function() {
    // Insert switch statement here??  Some other construct??
});

HTML: (использует классы Bootstrap 3)

ФОРМА:

<form class="form-expenses form-horizontal" role="form" method="post" action="/profile/update">
    <div class="form-group">
        <label for="housing" class="control-label col-sm-3">Housing</label>
        <div class="input-group input-group-lg col-sm-9"> 
            <span class="input-group-addon">$</span> 
          <input type="text" class="form-control" name="housing" id="housing" />
        </div>
    </div>
    <div class="form-group">
        <label for="utilities" class="control-label col-sm-3">Utilities</label>
        <div class="input-group input-group-lg col-sm-9"> 
            <span class="input-group-addon">$</span>
          <input type="text" class="form-control" name="utilities" id="utilities" />
        </div>
    </div>
...
<button class="btn btn-lg btn-primary btn-block" id="update-expenses" type="submit"> Update</button>

</form>

ВЫВОД:

<tr>
  <td>Housing</td>
  <td id="output-housing">$<?php echo $total['housing']?></td>
</tr>

<tr>
  <td>Utilities</td>
  <td id="output-utilities">$<?php echo $total['utilities']?></td>
</tr>
  • 0
    С каким релевантным HTML мы работаем?
  • 0
    @DavidThomas Я добавлю это в.
Теги:
forms

2 ответа

1
Лучший ответ

Что-то вроде этого должно работать. Предполагает ту же префиксную связь идентификаторов вывода/ввода

$(function() {
  $('form.form-expenses').submit(function() {
    updateValues();
    return false/* prevent submit for demo only*/
  })
})

function updateValues(){
  $('.form-expenses :input').not('#update-expenses').each(function(){
    var $input=$(this), inputId=this.id;
    var curr=$('#output-'+inputId).text().replace("$", "");
    $input.val(function(i,val){
      return (1*(val ||0) + 1*curr).toFixed(2);
    })
  });
}

DEMO

С точки зрения пользовательского интерфейса это кажется очень противоречивым для изменения значений, которые пользователь вводит только.

Чтобы создать объект данных ajax вместо обновления отображаемых значений:

function getAjaxData(){
  var ajaxData={}
  $('.form-expenses :input').not('#update-expenses').each(function(){
    var $input=$(this), inputId=this.id;
    var curr=$('#output-'+inputId).text().replace("$", "");
    ajaxData[this.name] =(1*(val ||0) + 1*curr).toFixed(2);
  });
  return ajaxData
}

/* in submit handler*/

$.post('path/to/server', getAjaxData(), function(response){/*do something with reponse*/})
  • 0
    Связано с вашим последним комментарием. Я согласен, что при отправке я добавил $('.form-expenses :input').val(''); немедленно скрыть значение, чтобы пользователь не увидел. Для пользователя это выглядит так, как будто они вводят значение, и оно добавляется в HTML. Однако, если у вас есть идея получше, дайте мне знать.
  • 0
    при отправке через ajax я бы оставил форму в покое ... и просто отправил вычисленные данные. Не уверен, как работает ваш полный пользовательский интерфейс ... но нужно учитывать любые проблемы с почтой, которые могут возникнуть (например, потеря соединения)
Показать ещё 2 комментария
1

"если я разрешаю пользователю добавлять/удалять поля, тогда это может стать немного липким",

В этом случае дайте полям имя класса. Пока это существует в добавленных полях, все они будут вычислены.

<input type="text" class="form-control calculate-me" name="housing" id="housing" />

И повторите все, используя их идентификаторы в качестве ссылки

$(".calculate-me").each(function(){
    var ref=this.id;
    var subtotal = Number($("#" + ref).val());
    subtotal = (subtotal).toFixed(2);
    var currentTotal = $('#output-' + ref).html().replace("$", "");
    var total = Number(subtotal) + Number(currentTotal);
    $('#' + ref).val(total);
});
  • 0
    Мне нравится этот способ, потому что это действительно просто. Однако мне все еще нужно жестко закодировать массив refs. Честно говоря, мои поля не будут меняться так часто, так что это не слишком большая проблема, но если я позволю пользователю добавлять / удалять поля, это может стать немного неприятным ...
  • 0
    обновлено. посмотри

Ещё вопросы

Сообщество Overcoder
Наверх
Меню