Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Обработка неизвестного количества input (https://javascript.ru/forum/jquery/54453-obrabotka-neizvestnogo-kolichestva-input.html)

Daniel93 17.03.2015 22:03

Обработка неизвестного количества input
 
Доброго времени суток! Есть форма, которая создается с помощью php.
<?php
$smet = mysql_query("SELECT id_pc_price, name_pc_price, min_pc_price, max_pc_price
FROM pc_price") or die(mysql_error());
echo  '<table class="table">';
echo "
<thead>
<tr>
    <th>Наименование</th>
    <th>Рекомендуемая цена</th>
    <th>Фактическая цена цена</th>
</tr>
</thead>";
 
while ($smeta = mysql_fetch_assoc($smet)) {
        $id_s = $smeta["id_pc_price"];
        $name_s = $smeta["name_pc_price"];
        $min_price = $smeta["min_pc_price"];
        $max_price = $smeta["max_pc_price"];
        
echo "
<tr>
    <td>$name_s</td>
    <td>$min_price-$max_price</td>
    <td>
        <form name='price' action='price.php' method='POST' id='price'>
            <input type='text' size='8' name='id_price[]' class='id_s' id='id_price'>
        
    </td>
</tr>
";
 
     }
echo "
<input type='submit' name='in_price' value='Расчитать'>
</form>";   
 ?>


Мне нужно посчитать сумму, которую введет пользователь в поле "Фактическая цена". Кол-во полей заранее неизвестно.

<script>
$(function(){
$('#price').submit(function(){
	//var field = $('#id_price').val();
	//alert(field);
	//return false;
	var inputs = $('#id_price');
	var iii = inputs.length;
	alert(iii);
	for (var i = 0; i < iii; i++) {
		alert(inputs[i]);
		return false;
	}
}); // Конец submit
}); // Конец function
</script>


//var field = $('#id_price').val();
	//alert(field);
	//return false;

Этот код работает, но обрабатывает только одно поле.

var inputs = $('#id_price');
	var iii = inputs.length;
	alert(iii);
	for (var i = 0; i < iii; i++) {
		alert(inputs[i]);
		return false;
	}

Этот код работает, но когда вводишь число, то в переменную inputs[i] помещается object HtmlInputElement, а в переменную iii помещается число 1, хотя на странице 3 поля.

Извините, если коряво описал проблему.

laimas 18.03.2015 04:43

or die(mysql_error()); - так можно писать в каком-то отдельном примере, когда нужно выяснить что-то. На реальных страницах такого быть не должно - нельзя вываливать ошибки запросов к базе на клиенте, это богатая пища для размышлений тем, кому эти ошибки как манна небесная. Если таким образом контролировать запросы, то нужно выводить ошибки по условию - включен режим отладки, значит ошибка, иначе сообщение "мол извиняйте, но...".

Плевать кусками тоже нет ни смысла не выгоды:

echo  '<table class="table"><tr>
    <th>Наименование</th>
    <th>Рекомендуемая цена</th>
    <th>Фактическая цена цена</th>
</tr>
</thead>';

Самое интересное дальше - $id_s = $smeta["id_pc_price"];, объявление этих промежуточных переменных для чего, облегчить жизнь интерпретатору? Ну так тогда зачем вы вгоняете эти переменные в строку, заставляя интерпретатор парсить ее, когда в этом нет никакой надобности? Не нужны эти "посредники" в коде если они не используются кроме этого цикла нигде более. А вогнав переменные в строку, даже не контролируете что получится:

echo "<td>$min_price-$max_price</td>"; //что в итоге получится?


И формы у вас нет, у вас бардак, потому, что открывающий тег формы выводится в цикле, а закрывающий вне его.

В JS тоже полный швах, но сперва наведите порядок в серверной части.

Daniel93 18.03.2015 20:16

Решил переделать код, вот так получилось. Только все равно не пойму, как jquery обработать неизвестное кол-во инпутов

<?php
			define('DEBUG', 1);
	
	$order = mysql_query("SELECT * 
						FROM pc_price") or die(DEBUG ? __FILE__ . '/' . __LINE__ . '/' . mysql_error() : 'Извините, ошибка');
	while ($row = mysql_fetch_assoc($order)) {
		$html = "<div class='col-xs-6 col-md-4 proba2'>
			<p>Название услуги: $row[name_pc_price]</p>
			<p>Минимальная цена: $row[min_pc_price]</p>
			<p>Максимальная цена: $row[max_pc_price]</p>
			<form action='master_function.php' method='POST' name='in_work'>
				<label>Фактическая цена</label>
				<input type='text' name='fact_price' id='fact_price'>
				<input type='submit' name='in_w' value='Добавить в смету'>
			</form>
			</div>";
		echo $html;
	} // Конец while
			?>

laimas 18.03.2015 20:46

Не волнуйтесь за способности клиента, сможет он просчитать, вот только что?

Сначала у вас была ошибка в том, что серверный скрипт формировал некорректный html-код. Сейчас этой ошибки нет, но в контексте вашего вопроса "обработать N-количество полей формы", по идее возникает логическая ошибка.

У вас сейчас будет формироваться N-форм с одним полем ввода каждая, и если нажать в любой из форм кнопку submit, то эта форма и будет отправлена. А какой тогда смысл обрабатывать N-полей, и в вашем случае не одной, а нескольких форм?

Нет ли в этом у вас ошибки?

И зачем вы опять вгоняете переменные в строку? РНР строку заключенную в одинарные кавычки не разбирает, вот и выводите так, а переменные конкатенацией. И либо сразу вывод строки (к чему у вас отдельное echo $html;?), либо собирайте в одну строку $html .= 'string'; в итерации, а после цикла echo $html;

while ($row = mysql_fetch_assoc($order)) 
        $html  .= '<div class="col-xs-6 col-md-4 proba2">
            <p>Название услуги: ', $row['name_pc_price'], '</p>
            <p>Минимальная цена: ', $row['min_pc_price'], '</p>
            <p>Максимальная цена: ', $row['max_pc_price'], '</p>
            <form action="master_function.php" method="post" name="in_work">
                <label>Фактическая цена</label>
                <input type="text" name="fact_price" id="fact_price">
                <input type="submit" name="in_w" value="Добавить в смету">
            </form>
            </div>'; //фигурные скобки не обязательны, цикл содержит одно выражение 
        echo $html; //а это после цикла

Daniel93 18.03.2015 23:38

Я просто пытаюсь сделать что-то наподобие корзины. Из базы выводится название работы, диапазон цены (минимальная и максимальная) и фактическая цена. Пользователь сам вводит фактическую цену. В итоге в базу заносится название работы и цена, которую указал пользователь.

Пытаюсь сделать так, нашел в одном из видео(http://www.youtube.com/watch?v=QE6yhvqRlwg)

<?php
			define('DEBUG', 1);
	
	$order = mysql_query("SELECT * 
						FROM pc_price") or die(DEBUG ? __FILE__ . '/' . __LINE__ . '/' . mysql_error() : 'Извините, ошибка');
	while ($row = mysql_fetch_assoc($order)) {
		$html = "<div class='col-xs-6 col-md-4 proba2'>
			<p>Название услуги: $row[name_pc_price]</p>
			<p>Минимальная цена: $row[min_pc_price]</p>
			<p>Максимальная цена: $row[max_pc_price]</p>
			<form action='handler/pc_smeta.php' method='POST' name='in_work'>
				<label>Фактическая цена</label>
				<input type='text' name='fact_price' id='fact_price$row[id_pc_price]'>
				<input type='submit' name='in_w' value='Добавить в смету' id='$row[id_pc_price]'>
			</form>
			</div>";
		echo $html;
	} // Конец while
			?>


<script>
$(function(){
$('#<?php echo $row[id_pc_price]?>').click(function {
	var item = $('#fact_price<?php echo $row[id_pc_price]?>').val();
	alert(item);
	//$.cookie('item', item);
	return false;
}); // Конец submit
}); // Конец function
</script>


Но, во-первых, это какая-то порнография, понимаю, что это должно решаться по-другом, а во-вторых, в выборку ничего не заносится.

laimas 19.03.2015 00:04

Предупреждаю - мультиков смотреть я не буду, не хватало еще ради ответа смотреть сериалы. )

$('#<?php echo $row[id_pc_price]?>') - это конечно порнография, но вы не ответили на главный вопрос - что надо просчитать? Если у вас несколько форм но с одним полем в них, ну просчитали вы сумму этих полей, и что это дает? Отправляться серверу ведь может только одна форма, то есть пользователь может выбрать одно из ...

Может все таки одна форма, а в ней несколько полей fact_price сумму которых и надо вычислить?

Daniel93 19.03.2015 00:24

Вот, например, есть 3 таких блока.

Пользователь в первом блоке пишет - 450
Во втором - 260
В третье - 500

В базу должно заноситься так:
Услуга 1 - 450
Услуга 2 - 260
Услуга 3 - 500

Я думаю, что это все сначала должно заноситься или в сессию, или куки, а после этого заноситься в базу.

Или заноситься в отдельное поле input, в отдельную форму, а после этого заноситься в базу.


laimas 19.03.2015 01:33

Если:

Пользователь в первом блоке пишет - 450
Во втором - 260
В третье - 500

то это означает выбор нескольких из множества, и значит форма должна быть одна, а не несколько с одним полем в каждой. Разве можно в нескольких формах написать и отправить их одновременно?

То есть РНР сценарий совсем не ту html-структуру выдает. Таблица должна быть вложена в форму, ячейки таблицы должны содержать поля формы (а данном случае три), кнопка "Добавить в смету" должна быть одна.

Имя поля формы должно отражать принадлежность поля к массиву, то есть:

<input type="text" name="fact_price[id_pc_price]">


Атрибут id полям формы совсем не нужен, имя "in_w" у кнопки submit нужно только в том случае, если price.php кроме POST данных этой формы принимает и обрабатывает еще и другие POST данные и их селекция включает и проверку этого имени. Иначе имя совсем не нужно, и кнопку на сервер отправлять не надо.

Заносить в сессию или в куки, а только потом в базу... Не знаю, все зависит от задач, может и надо, а может и пустое занятие, мне трудно об этом судить не зная многого.

Как бы ни было, сервер получит массив вида:

Код:

fact_price (
    [25]  => 450
    [123] => 260
    [46]  => 500
)

То есть не 1, 2, 3, а идентификаторы услуг будут его ключами. Остается проверить и выбрать те услуги, которые заполнены:

if($fact = array_diff(array_map('intval', $_POST['fact_price']), array(0))) {
    //действия с данным, например сумма на сервере, если нужна:
    $sum = array_sum($fact);
    //требуется проверка и ключей полученного массива $fact, 
    //если только запись не подготовленными запросами PDO
} else {
    //ничего не выбрано
}


То есть на серверной стороне все просто и удобно, на клиентской тоже нет сложностей:

<html> 
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script> 
$(function() {
    var o = $('#price').find('input[name^="fact"]').keyup(function() {
        var m = 0; this.value = this.value.replace(/\D/, '');
        for(var i=0, k=o.length; i<k; i++) m += o[i].value * 1;
        $('#total').text(m)
    })
});
</script>     
</head> 
<body>
<form id="price">
    <input name="fact_price[25]" /> <input name="fact_price[123]" /> <input name="fact_price[46]" />
    <input type="submit" />
</form>
<span id="total"></span>
</body> 
</html>


Примечание: пример подразумевает, что форма присутствует на странице, иначе нужно не так назначать обработчик события полей.

Daniel93 19.03.2015 10:46

Спасибо большое! Пошел учить и разбираться! Огромное спасибо!

Daniel93 19.03.2015 15:00

Извините, что опять обращаюсь( Не ругайтесь, я только учусь)

В базу все заносится, все нормально, но javascript не срабатывает

<?php
			$smet = mysql_query("SELECT id_pc_price, name_pc_price, min_pc_price, max_pc_price
								FROM pc_price") or die(mysql_error());
			$table = "<table class='table'><form id='price' method='POST' action='handler/pc_smeta.php'>
			<thead>
				<tr>
					<th>Наименование</th>
					<th>Рекомендуемая цена</th>
					<th>Фактическая цена цена</th>
				</tr>
			</thead>
			";
			
			while ($smeta = mysql_fetch_array($smet)) {
				$table .= "<tr>
							
								<td>$smeta[name_pc_price]</td>
								<td>$smeta[min_pc_price]-$smeta[max_pc_price]</td>
								<td><input type='text' name='fact_price[$smeta[id_pc_price]]'></td>
							
						</tr>
				";
			}
			$table .="<input type='submit' name='pc_smeta' /></form><span id='total'></span></table>";
			echo $table;
			?>


<script> 
$(function() {
    var o = $('#price').find('input[name^="fact"]').keyup(function() {
        var m = 0; this.value = this.value.replace(/\D/, '');
        for(var i=0, k=o.length; i<k; i++) m += o[i].value * 1;
        $('#total').text(m)
    })
});
</script>

laimas 19.03.2015 15:37

А я разве ругаюсь?

Ну если заносится и нормально, а может и не нормально. Вы опять пишите костыли, которые либо выковыривать нужно будет, либо методично править во всех файлах. Я имею ввиду вывод ошибки запроса. Приучать надо себя к тому чтобы это писалось как автоматом.

Говорил и том, что заставлять интерпретатор парсить строки без необходимости тоже не есть гут. И что таблица должна быть вложена в форму .... Нельзя так своевольничать:

<table><form><thead>

не может быть такого, форму в таблицу можно поместить только в ячейку и целиком. Должно быть:

<form><table><thead> ... код таблицы с полями форм в ячейках ... </table><input type='submit' name='pc_smeta' /></form><span id='total'></span>

А не работает клиентский скрипт либо потому, что эта таблица подгружается на страницу динамически, либо есть этот скрипт, но не подключена jQuery. Поясняйте как именно у вас делается или какова структура вашей страницы, интересует подключение JS.

Daniel93 19.03.2015 18:20

Спасибо большое! Все заработало, после того как навел порядок в html коде и сделал все так:
<form><table><thead> ... код таблицы с полями форм в ячейках ... </table><input type='submit' name='pc_smeta' /></form><span id='total'></span>
Еще раз спасибо!

Daniel93 19.03.2015 20:11

Извините, опять обращаюсь(

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

Например, Общая сумма - 1200
Услуга 1 - 500
Услуга 2 - 350
Услуга 3 - 350

laimas 20.03.2015 08:24

Как понять расшифровка? Есть некая сущность в базе, назовем ее А, которая может иметь различные свойства описанные в таблице T1. Ей же может принадлежать некий множественный набор других свойств, либо ваши же услуги, количество которых переменно. В свою очередь эти свойства/услуги описывает другая таблица Т2.

Вопрос - каким образом сохранить в базе набор свойств из таблицы Т2 выбранных для сущности А? Вы же не станете для этого добавлять в таблицу Т1 новые поля при выборе услуг или удалять их при удалении услуг. Для того чтобы сохранить такой выбор, нужна третья таблица Т3, которая будут отражать такой набор, и которая будет связана с таблицами Т1 и Т2.

Таблица Т3 будет содержать уникальный идентификатор сущности А из таблицы Т1, по которому связываются таблицы Т1 и Т3, и уникальный идентификатор свойства/услуги из таблицы Т2, по которому связываются таблицы Т2 и Т3. В свою очередь эта пара полей таблицы Т3 создает уникальный индекс каждой записи таблицы Т3. Таблица Т3 являющаяся внешней таблицей связи между Т1 и Т2 как раз и содержит множественный набор свойств/услуг принадлежащих сущности А.

Этого и достаточно, если необходимо только описание набора. Но если свойство/услуга таблицы Т2 имеет какие либо количественные характеристики, как то цену за единицу, и такой услуги можно выбрать N-количество, то кроме идентификаторов таблица Т3 должна хранить и количество каждой выбранной услуги. Хранить общую же сумму за эти услуги и их общее количество нет необходимости, так как это всегда можно получить связанными запросами к таблицам Т1, Т2, Т3.

Смекаете, что для того чтобы ответить на ваш вопрос необходимо знать организацию ваших данных, то есть структуру базы - таблицы, связи? Рассказывая вам о том как должны именоваться поля формы и почему так, и предполагалось, что вы храните именно набор множества полученный из формы. Но если вы задаете этот вопрос, то получается что нет, значит организация вашей базы никуда не годится.

Именно продуманная структура данных отраженная в базе, это более чем половины успеха. Непродуманная тоже будет работать, но с костылями, не в меру нагружая базу лишними запросами, с тормозами на отклики, и сядет в лужу при большой нагрузке на сервер.

Daniel93 20.03.2015 12:25

Не, с базой, вроде бы, все нормально. У меня как раз и есть три таблицы.

Т1 - содержит идентификатор, наименование услуги, минимальная и максимальная цена
Т2 - содержит информацию о заказе и будет содержать идентификатор из таблицы Т3, в которой хранится составленная смета
Т3 - содержит информацию о составленной смете. Идентификатор сметы (который будет вставляться в Т2), расшифровка работ (про что я писал: услуга 1 - 500, услуга 2 - 350 и т.д. и т.п.) и общая сумма, с которой уже определились.

На данный момент я не могу понять, как мне из формы вытащить именно это расшифровку? Как на этой картинке

Услуга 1 - 350
Услуга 3 - 300
Услуга 4 - 670
Общая сумма - 1320

Вот с общей суммой все понятно, с остальным нет.
Может быть вытащить эту расшифровку в массив, а потом с помощью json_encode занести в базу? Тогда возникает вопрос, как мне узнать, что 350 указанно именно для Услуги 1, а не Услуги 4?

Извините, если коряво объяснил


laimas 20.03.2015 12:28

А из чего берутся эти именования "Услуга 1", "Услуга 2"... при выводе таблицы с формой на страницу?

Daniel93 20.03.2015 12:38

Да
<?php
			$smet = mysql_query("SELECT id_pc_price, name_pc_price, min_pc_price, max_pc_price
								FROM pc_price") or die(mysql_error());
			$table = "<form id='price' method='POST' action='handler/pc_smeta.php'><table class='table'>
			<thead>
				<tr>
					<th>Наименование</th>
					<th>Рекомендуемая цена</th>
					<th>Фактическая цена цена</th>
				</tr>
			</thead>
			";
			
			while ($smeta = mysql_fetch_array($smet)) {
				$table .= "<tr>
							
								<td>$smeta[name_pc_price]</td>
								<td>$smeta[min_pc_price]-$smeta[max_pc_price]</td>
								<td><input type='text' name='fact_price[$smeta[id_pc_price]]'></td>
							
						</tr>
				";
			}
			$table .="</table><input type='submit' name='pc_smeta' /></form><span id=''>Общая сумма:</span><span id='total'></span>";
			echo $table;
			?>


Может через чекбоксы? К каждому полю дать чекбокс и имя у чекбокса будет именеv из базы?

<input type="checkbox" name="item_name[$smeta[name_pc_price]]">

laimas 20.03.2015 12:42

fact_price[$smeta[id_pc_price]] - это что (выделенное) такое и зачем?

Как получаете и обрабатываете данные формы, что и как вы записываете в базу?

Daniel93 20.03.2015 12:47

Цитата:

Сообщение от laimas (Сообщение 362021)
Имя поля формы должно отражать принадлежность поля к массиву, то есть:

<input type="text" name="fact_price[id_pc_price]">

<?php
include("../../bd.php");
if (isset($_POST['pc_smeta'])) {
if($fact = array_diff(array_map('intval', $_POST['fact_price']), array(0))) {
    //действия с данным, например сумма на сервере, если нужна:
    $sum = array_sum($fact);
	$keys = array_keys($fact);
	//требуется проверка и ключей полученного массива $fact, 
    //если только запись не подготовленными запросами PDO
	echo $sum;
} else {
    //ничего не выбрано
}

} // Конец проверки кнопки
?>

laimas 20.03.2015 12:52

Фу ты господи, прости, это же имя набора $smeta у вас :)

Нет, покажите как и что вы записываете в базу из полученного.

Daniel93 20.03.2015 13:06

Пока заносится только общая сумма

define('DEBUG', 1);
$query = mysql_query ("INSERT INTO `item_smeta`
(`sub_item_smeta`, `score_item_smeta`) VALUES ('', '$sum')") or die(DEBUG ? __FILE__ . '/' . __LINE__ . '/' . mysql_error() : 'Извините, ошибка');


sub_item_smeta - Сюда должна заноситься расшифровка, как я думал с помощью json_encode

score_item_smeta - общая, конечная сумма.

laimas 20.03.2015 13:35

А говорите, что с базами все нормально. Если даже только посещает мысль "с помощью json_encode" что-то писать в базу, значит это уже не база, а свалка. )

Ну запишите вы это,и что это даст, как же вы будете делать выборку, если потребуется, что-то получить по заказу? А общую сумму как раз писать в базу нет нужды.

Еще раз - имена полей формы отражают массив, ключами которого являются уникальные идентификаторы услуг. Для его это и что это дает?

Вы не копируйте так "как есть", что я написал, то и вы себе вставляете. Я пишу лишь пример, "тезисы", а как оно должно быть на самом деле мне не известно, ибо я не знаю ни задач, ни условий.

Но кое что мне все-таки известно, и это кое что указывает на то, что вы поступаете не верно (это понятно из того, что вы сейчас представили).

1) Я добавил элемент SPAN для отображения общей суммы просто потому, что в примере ее нужно было во что-то вписать, но вам то он зачем? В вашем случае, например, у таблицы должна быть еще одна строка, последняя, такой структуры:

<tr>
    <th colspan="2">Общая сумма:</th>
    <th id="total"></th>
</tr>


ячейка id="total" которой и будет хранить сумму, а не span болтающийся под кнопкой отправки формы.

Форма у вас отправляется естественным способом, но у услуг есть условие (это ведь условие?) по цене - от минимума до максимума. Значит при наборе суммы в полях ввода, нужно проверять соответствует ли введенное этим условиям.

Эта проверка как сервис на клиенте, чтобы не гонять клиенту форму зря при ошибках ввода. А на севере такая проверка, это уже не сервис, а ваша обязанность как программиста. Что будет если пользователь ошибется, или что будет, если я вам пришлю форму с липовыми значениями, ключами которых будут не id услуг, а ABRACADABRA? Если таблица в базе грамотно составлена, будет ошибка о дубликатах ключей, а нет, так мусор и запишется. У вас у какой-то услуги цена от 200 до 500, а я ввиду 10 или 1000000, и что вы будете делать?

Проверка данных пришедших извне, соответствие их значений вашим же условиям, это первое что необходимо и только потом, если "таможня дала добро" следует их запись в базу. Правда писать надо совсем не то что вы в нее пишите. Решайте вопрос с проверкой, с учетом того, что по уму у вас должна быть не одна таблица описывающая заказ, а две - в первой это общие характеристики заказа, в другой выбранные услуги на указанную цену. Это есть детализация (расшифровка по вашему) заказа, детали же по услугам, как то их наименования можно получить из таблицы их описывающей по их идентификаторам, которые вы получите из формы, именно для этой цели они и помещаются в имена полей, именно они и пишутся в базу.

Думайте над проверкой сначала.


Часовой пояс GMT +3, время: 01:07.