Сейчас мой код очень "жестко запрограммирован" и повторяется. Я хотел бы знать, есть ли более чистый способ сделать следующее. В идеале, я хочу перебирать поля своих форм с помощью цикла и вычислять результаты с одним утверждением, но я изо всех сил пытаюсь понять, как это сделать.
Резюме. У меня есть десять полей формы, каждое из которых имеет четкое десятичное значение, которое пользователь может или не может предоставить. Когда пользователь нажимает 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>
Что-то вроде этого должно работать. Предполагает ту же префиксную связь идентификаторов вывода/ввода
$(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);
})
});
}
С точки зрения пользовательского интерфейса это кажется очень противоречивым для изменения значений, которые пользователь вводит только.
Чтобы создать объект данных 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*/})
$('.form-expenses :input').val('');
немедленно скрыть значение, чтобы пользователь не увидел. Для пользователя это выглядит так, как будто они вводят значение, и оно добавляется в HTML. Однако, если у вас есть идея получше, дайте мне знать.
"если я разрешаю пользователю добавлять/удалять поля, тогда это может стать немного липким",
В этом случае дайте полям имя класса. Пока это существует в добавленных полях, все они будут вычислены.
<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);
});