Показать сообщение отдельно
  #45 (permalink)  
Старый 28.06.2017, 23:00
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от ФедорН
Добавил функцию для учета атрибутов инпутов min и max, в jsfiddle она отлично работает, а у меня в php -нет
Что именно на РНР не работает, значения min и max? Ну они и не передаются на сервер.

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

Грамотно, это так:

1) Опции списка color в значениях должны содержать не величины, которые для расчета, а идентификаторы этих величин.

2) Значения min и мах для полей типа number должен задавать север.

На основании 1 и 2 следует, что параметры всех величин сервер знает, а значит получая идентификатор списка он может проверить истинность выбранного. Выбранные величины ширины/высоты на корректность сервер может проверить, зная величины min и мах.

Вы так не поступаете, что там у вас за проблемы не знаю. Но если вы доверяете все клиенту, то и <output></output> не годится, так как его значение на сервер не передается, даже если задать тегу имя. Тогда уж обычное поле ввода с запретом на ввод.

Говоря о неизбежных багах в коде я имел ввиду min и мах в том числе, но в ином ракурсе.

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

<div id="form" >
    <div class="roword">
        <div class="col-md-3 col-sm-6 col-xs-12 form-col-1">
            <select  form="send" name="color[]">
                <option value="">Выберите цвет</option>
                <option value="1.2">Зеленый</option>
                <option value="1.6">Синий</option>
                <option value="1.8">Красный</option>
            </select>
        </div>
        <div class="col-md-3 col-sm-6 col-xs-12 form-col-2">
            <input form="send" class="minmax" min="40" max="200" type="number" name="width[]">
        </div>
        <div class="col-md-3 col-sm-6 col-xs-12 form-col-3">
            <input form="send" class="minmax" min="40" max="300" type="number" name="height[]">
        </div>
        <div class="col-md-3 col-sm-6 col-xs-12 form-col-4">
            <output></output> <a style="display:none">Удалить</a>
        </div>
    </div>
</div>
<div class="clearfix"></div>
<button>Добавить</button>


Код обслуживающий добавление/удаление полей:

$(function() {
    $('button').click(function() {
        $('div.roword').first() //получаем первый набор полей
                       .clone() //клонируем его
                       .appendTo($('#form')) //добавляем набор в форму
                       .find('select, output').val('') //сбрасываем значения полей 
                       .end() //в начало набора
                       .find('input') //ищем поле ввода
                       .val(function() {
                            return this.min //устанавливаем значение равное минимальному   
                       })
                       .end() //в начало набора
                       .find('a').click(function() { //получаем кнопку удаления полей из формы
                            $(this).closest('.roword').remove() //удаляем добавленное из формы
                       })
                       .show() //делаем видимой кнопку удаления
    });
});


Проблемы неизбежные заложены в полях типа number. В поле можно вводить значение не только кнопками, но и ручным вводом (утомительно набирать максимальное значение с шагом 1). А то, что это поле типа number совсем не означает, что я не могу ввести в нем "абвгд". Вторая проблема, это "что определяет момент расчета"? Если бы это действие запускалось по кнопке "Рассчитать", тогда проблем с проверкой на min бы не было даже при ручном вводе. Но если расчет запускается при каждом изменении ввода и ввод не кнопками, а ручной, то возникает проблема с определением min. Можно конечно навесить таймер, определяя "вроде бы ввод закончен", но это палка о двух концах. С определением max проблем нет.

//обработка ввода, выбора кнопками и выбора в списке
    $('#form').on('change input', 'select, input', function() {
        if(this.type == 'number') { //если поле ввода
            this.value = this.value.replace(/^0|\D/, ''); //вырезаем не цифровые символы и 0 вначале 
            if(this.value.length >= this.max.length && this.max < this.value) this.value = this.max //если значение превышает максимальное             
        }
        //расчет
        //.........
    })


Обработчик определяет - если источник поле number, то удаляет не цифры из набора, сравнивает длину значения и значение с параметрами max. Подобное с min сделать нельзя, так как ввод в поле к примеру 2, еще не означает, что это будет меньше 40, это может быть в итоге 250.

Решить эту проблему можно используя поле не number, а range, тогда необходимость в проверке min/max отпадает (но только для клиента). В этом случае поля описываются так

<input form="send" type="range" min="40" max="300" name="width[]" value="40"> <output>40</output>
и
<input form="send" type="range" min="40" max="200" name="height[]" value="40"> <output>40</output>


В обработчик такой:

$(function() {
    $('button').click(function() {
        $('div.roword').first() //получаем первый набор полей
                       .clone() //клонируем его
                       .appendTo($('#form')) //добавляем набор в форму
                       .find('select').val('') //сбрасываем значение списка
                       .end() //в начало набора
                       .find('input, output') //слайдеры и выводы
                       .val(function(i) {
                            return i == 4 ? '' //очищаем output результата расчета
                                          : this.type == 'range' ? this.min //минимальное значение слайдеру
                                                                 : $(this).prev().attr('min') //отобразить значение слайдера по умолчанию   
                       })
                       .end() //в начало набора
                       .find('a').click(function() { //получаем кнопку удаления полей из формы
                            $(this).closest('.roword').remove() //удаляем добавленное из формы
                       })
                       .show() //делаем видимой кнопку удаления
    })
    //обработка изменения слайдера и выбора в списке
    //событие input в данном случае для отображения значения слайдера непосредственно при перемещении ползунка
    $('#form').on('change input', 'select, input', function() {
        if(this.type == 'range') $(this).next().val(this.value)  //отобразить значение слайдера
        //расчет
        //.........
    })
});
Ответить с цитированием