Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Поле для ввода HEX с границами диапазона, динамически меняющимися от выбора <select> (https://javascript.ru/forum/dom-window/75688-pole-dlya-vvoda-hex-s-granicami-diapazona-dinamicheski-menyayushhimisya-ot-vybora-select.html)

brp80000 30.10.2018 00:38

Поле для ввода HEX с границами диапазона, динамически меняющимися от выбора <select>
 
<style>
.max1:invalid {
color: red }
.max1:valid {
color: black;} </style>

Есть вот такой select
<select name ="CanFrame_Type" id="CanFrame_Type">
<option value="Std">Std</option>
<option value="Ext">Ext</option>
</select>
Далее поле для ввода НЕХ
<input id="Can_ID" name="Can_ID" size="5" class="max1" pattern="[A-F\d]{1,5}" />

когда выбрано Std должен быть доступен диапазон 0x0-0x7FF
а когда Ext то 0x800-0xFFFFFFFF. Соответственно желательно ещё и менять количество доступных символов для ввода Std {1,3} а при Ext {3,8}

Paguo-86PK 30.10.2018 06:50

<style>
.max1:invalid {
    color: red }
.max1:valid {
    color: black;}</style>
<body>
<select name="CanFrame_Type" id="CanFrame_Type" onchange='document.getElementById("Can_ID").pattern=this.value'>
<option value="[0-7][A-F\d]{2}|[A-F\d]{1,2}">Std</option>
<option value="[8-9A-F][A-F\d]{2}|[A-F\D]{4,8}">Ext</option>
</select>
<input id="Can_ID" name="Can_ID" size="5" class="max1" pattern="[A-F\d]{1,5}" />
</body>

SuperZen 30.10.2018 08:37

javascript вариант,
<style>
  .invalid {
    color: red
  }
</style>

Есть вот такой select
<select name="CanFrame_Type" id="CanFrame_Type">
  <option value="Std" data-min-max="0-7FF">Std</option>
  <option value="Ext" data-min-max="800-FFFFFFFF">Ext</option>
</select>
Далее поле для ввода НЕХ
<input id="Can_ID" name="Can_ID" size="5" class="max1" />

<script>
  const select = document.getElementById('CanFrame_Type')
  const input = document.getElementById('Can_ID')
  const update = () => {
    var [min, max] = select.options[select.options.selectedIndex].dataset.minMax.split('-')
    var value = parseInt(input.value, 16)
    if (value.toString(16) === input.value.toLowerCase() && value >= parseInt(min, 16) && value <= parseInt(max, 16)) {
      input.classList.contains('invalid') && input.classList.remove('invalid')
    } else !isNaN(value) && !input.classList.contains('invalid') && input.classList.add('invalid')
  }
  select.addEventListener('change', update)
  input.addEventListener('input', update)
</script>

brp80000 30.10.2018 10:49

SuperZen,
Спасибо отлично работает. Огромное спасибо

brp80000 01.11.2018 06:23

SuperZen,
а можно как то до внедрить сюда ограничение по количеству вводимых символов для ввода Std {1,3} а при Ext {3,8}

SuperZen 01.11.2018 12:39

brp80000, не понятно, как должно вести себя при {3,8}, например, для 0004...

<style>
  .invalid {
    color: red
  }
</style>

Есть вот такой select
<select name="CanFrame_Type" id="CanFrame_Type">
  <option value="Std" data-min-max="0-7FF" data-len-min-max="1-3">Std</option>
  <option value="Ext" data-min-max="800-FFFFFFFF" data-len-min-max="3-8">Ext</option>
</select>
Далее поле для ввода НЕХ
<input id="Can_ID" name="Can_ID" class="max1" />

<script>
  const select = document.getElementById('CanFrame_Type')
  const hex = document.getElementById('Can_ID')
  const update = (e) => {
    var [min, max] = select.options[select.options.selectedIndex].dataset.minMax.split('-')
    var [lmin, lmax] = select.options[select.options.selectedIndex].dataset.lenMinMax.split('-')
    var lvalid = hex.value.toString(16).length >= lmin && hex.value.toString(16).length <= lmax
    if (!lvalid && !hex.value.toString(16).length <= lmax) {
      hex.value = hex.value.substr(0, lmax)
    }
    var value = parseInt(hex.value, 16)
    if (value.toString(16) === hex.value.toLowerCase() && value >= parseInt(min, 16) && value <= parseInt(max, 16)) {
      hex.classList.contains('invalid') && hex.classList.remove('invalid')
    } else !isNaN(value) && !hex.classList.contains('invalid') && hex.classList.add('invalid')
  }
  select.addEventListener('change', update)
  hex.addEventListener('input', update)
</script>

brp80000 01.11.2018 17:17

Std 1-3 символа 0-7FF
Ext 3-5 символа 800-7FFFF
Что то никак не работает ... где ошибка?

<style>
.max1:invalid {
    font-weight: Bold;
    margin-top: 5px;
	margin-bottom: 5px; 
    color: red }
.max1:valid {
    font-weight: Bold;
    margin-top: 5px;
	margin-bottom: 5px; 
    color: black;} 
</style>

<form>
<div>
	<select name ="CanFrame" id="CanFrame">
	<option value="Std" data-min-max="0-7FF" data-len-min-max="1-3">Std</option>
	<option value="Ext" data-min-max="800-7FFFF" data-len-min-max="3-5">Ext</option>
	</select>
	<div>
	<input id="CanID" name="CanID" class="max1" size="5" pattern="[A-F\d]"/>
	</div>
</div>
</form>

<script>
const select = document.getElementById('CanFrame')
const hex = document.getElementById('CanID')
const update = (e) => {
var [min, max] = select.options[select.options.selectedIndex].dataset.minMax.split('-')
var [lmin, lmax] = select.options[select.options.selectedIndex].dataset.lenMinMax.split('-')
var lvalid = hex.value.toString(16).length >= lmin && hex.value.toString(16).length <= lmax
if (!lvalid && !hex.value.toString(16).length <= lmax) {
hex.value = hex.value.substr(0, lmax)
}
var value = parseInt(hex.value, 16)
if (value.toString(16) === hex.value.toLowerCase() && value >= parseInt(min, 16) && value <= parseInt(max, 16)) {
hex.classList.contains('invalid') && hex.classList.remove('invalid')
} else !isNaN(value) && !hex.classList.contains('invalid') && hex.classList.add('invalid')
}
select.addEventListener('change', update)
hex.addEventListener('input', update)
CanID.value = 400;
</script>

SuperZen 01.11.2018 17:26

brp80000,
Ext 3-5 символа 800-7FFFF
Что то никак не работает ... где ошибка?

если для этого случая вводить 00044 то условие 800 не сработает, а так кто вводит что-то должен понимать )

brp80000 01.11.2018 17:39

Да вообще что то код не работает, то ли со стилями ошибка?

SuperZen 01.11.2018 18:24

у меня в коде не смотрю на паттерн и размер
<input id="CanID" name="CanID" class="max1" size="5" pattern="[A-F\d]"/>
и стили тоже не так назначаются, если инпут не в размере, то обрезается под выбранный размер с правой стороны на максимальную длину, и если строка не входит в пределы, то интупу назначается класс invalid, а в твоем примере значение назначается через псевдо класс :invalid, надо тогда сделать
<input id="CanID" name="CanID" class="max1"/>
и
<style>
  .max1.invalid {
    font-weight: Bold;
    margin-top: 5px;
    margin-bottom: 5px;
    color: red
  }

  .max1 {
    font-weight: Bold;
    margin-top: 5px;
    margin-bottom: 5px;
    color: black;
  }
</style>

brp80000 01.11.2018 19:31

Ага, вроде заработало

brp80000 01.11.2018 19:33

А как исключить ввод строчных английских символов?
да и исключить все символы кроме допустимых для HEX
почему то pattern="[A-F\d]" не отрабатывает?

SuperZen 02.11.2018 12:31

казалось бы простая задача на словах )...
<style>
  .invalid {
    color: red
  }
</style>

Есть вот такой select
<select name="CanFrame_Type" id="CanFrame_Type">
  <option value="Std" data-min-max="0-7FF" data-len-min-max="1-3">Std</option>
  <option value="Ext" data-min-max="800-FFFFFFFF" data-len-min-max="3-8">Ext</option>
</select>
Далее поле для ввода НЕХ
<input id="Can_ID" name="Can_ID" class="max1" />

<script>
  function HEX(s, h) {
    const select = document.getElementById(s)
    const hex = document.getElementById(h)
    function update() {
      !(parseInt(hex.value, 16).toString(16) === hex.value.toLowerCase()) && !!hex.value && (hex.value = hex.oldValue || '')
      var [min, max] = select.options[select.options.selectedIndex].dataset.minMax.split('-')
      var [lmin, lmax] = select.options[select.options.selectedIndex].dataset.lenMinMax.split('-')
      !(hex.value.toString(16).length <= lmax) && (hex.value = hex.oldValue || '')
      parseInt(hex.value, 16) >= parseInt(min, 16) && parseInt(hex.value, 16) <= parseInt(max, 16) ?
        hex.classList.contains('invalid') && hex.classList.remove('invalid')
        :
        !hex.classList.contains('invalid') && hex.classList.add('invalid')
      hex.oldValue = hex.value
    }
    select.addEventListener('change', update)
    hex.addEventListener('input', update)
    update()
  }
  const controller = new HEX('CanFrame_Type', 'Can_ID')
</script>

brp80000 03.11.2018 03:51

Маленькие латинские ABCDEF всё равно воспринимает, но подумав я понял что и так хорошо. СПАСИБО
Кстати тестил на старом айфоне, там скрипт не работает((

подскажите как указать атрибут download через JS

<a id="LastLog1"></a>
<script>
 var LastLog_r = "3";
LastLog1.href = "logs/lam"+(LastLog_r-2)+".log";
LastLog1.textContent = "lam"+(LastLog_r-2)+".log";
//LastLog1.setAttribute('download','download');
</script>


Чтобы по нажатию происходило скачивание

Malleys 03.11.2018 05:18

Цитата:

Сообщение от brp80000
подскажите как указать атрибут download через JS

там указывается имя файла для сохранения
<a id="lastLog">download</a><script>
lastLog.href = URL.createObjectURL(new Blob(["ваши данные для скачивания"], { type: "text/plain" }));
lastLog.download = "lam.log";
</script>


UPD
Вот ещё вариант поля для ввода HEX с границами диапазона, динамически меняющимися от выбора <select>
<style>
	html { font: 120% monospace }
	select, input { font: inherit }
	.invalid { color: red }
</style>
Есть вот такой select
<select name="CanFrame_Type" id="CanFrame_Type">
	<option value="0-7FF">Std</option>
	<option value="800-FFFFFFFF">Ext</option>
</select>
и поле для ввода НЕХ
<input id="Can_ID" name="Can_ID" class="max1">
<script>
function HEX(...ids) {
	const [select, hex] = ids.map(id => document.getElementById(id));
	function update() {
		const [valid, value] = select.value
			.split("-")
			.map(v => [parseInt(v, 16), v.length])
			.reduce(([min], [max, maxLength]) => {
				const value = hex.value.replace(/[^\da-f]/gi, "").slice(0, maxLength);
				const number = parseInt(value, 16);
				return [
					min <= number && number <= max,
					value
				]
			});
		hex.classList.toggle("invalid", !valid);
		hex.value = value;
	}
	addEventListener("input", ({ target }) => [select, hex].includes(target) && update());
	update();
}
new HEX("CanFrame_Type", "Can_ID");
</script>


UPD2
Цитата:

Сообщение от brp80000
Тут можно что угодно вводить !"№;sgфф?

они всё-равно красные, но теперь вводятся только 0-9a-fA-F

UPD3
Цитата:

Сообщение от brp80000
Кстати тестил на старом айфоне, там скрипт не работает((

Вам следует трансформировать код при помощи babeljs.io и подключить сервис полифилов
<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>

brp80000 03.11.2018 05:45

Как исключить все символы кроме допустимых для HEX. Тут можно что угодно вводить !"№;sgфф?

brp80000 03.11.2018 19:28

Цитата:

Сообщение от Malleys (Сообщение 497762)
Вам следует трансформировать код при помощи babeljs.io и подключить сервис полифилов
<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>

У меня локальная машина ... можно как то выкачать этот polyfill.min.js

brp80000 03.11.2018 19:33

Цитата:

Сообщение от brp80000 (Сообщение 497761)
подскажите как указать атрибут download через JS

<a id="LastLog1"></a>
<script>
 var LastLog_r = "3";
LastLog1.href = "logs/lam"+(LastLog_r-2)+".log";
LastLog1.textContent = "lam"+(LastLog_r-2)+".log";
//LastLog1.setAttribute('download','download');
</script>


Чтобы по нажатию происходило скачивание

А в моем варианте нет указателя на скачивание? У меня как бы значение LastLog_r = "3" передается другим скриптом и формируется ссылка типа "logs/lam"+(LastLog_r-2)+".log" = "logs\lam1.log"
файл открывается браузером, но не скачивается

Malleys 03.11.2018 22:05

Конкретно ваш вариант не устанавливает атрибут download(он был закомментирован)
<a id="LastLog1"></a>
<script>
 var LastLog_r = "3";
LastLog1.href = "logs/lam"+(LastLog_r-2)+".log";
LastLog1.textContent = "lam"+(LastLog_r-2)+".log";
LastLog1.setAttribute('download','download');
</script>

Malleys 03.11.2018 22:22

Цитата:

Сообщение от brp80000
У меня локальная машина ... можно как то выкачать этот polyfill.min.js

Оно возвращает только те полифилы, которые нужны вашему браузеру. Чтобы пример с HEX работал и в старых браузерах, достаточно использовать ту же самую ссылку. Однако, если предполагается отсутствие интернета или другая причина, то можно указать, какие именно новые методы должны быть доступны в старом браузере. Для того примера нужны Array.prototype.includes, Array.prototype.map, Array.prototype.reduce и Element.prototype.classList. Скрипт, который всегда, независимо от браузера, содержит определения этих функции https://cdn.polyfill.io/v2/polyfill.js?features=Array.prototype.map|always,Ar ray.prototype.reduce|always,Element.prototype.clas sList|always,Array.prototype.includes|always

brp80000 03.11.2018 22:53

Цитата:

Сообщение от Malleys (Сообщение 497788)
Конкретно ваш вариант не устанавливает атрибут download(он был закомментирован)
<a id="LastLog1"></a>
<script>
 var LastLog_r = "3";
LastLog1.href = "logs/lam"+(LastLog_r-2)+".log";
LastLog1.textContent = "lam"+(LastLog_r-2)+".log";
LastLog1.setAttribute('download','download');
</script>

Я пробывал, у меня почему то не срабатывает, всё равно открывает ... поэтому закоментировал. То есть по синтаксису всё правильно?

laimas 04.11.2018 06:08

А почему не по прямой ссылке из списка файлов каталога?

brp80000 05.11.2018 04:12

Я храню последние три лога, при записи четвертого первый стирается и т.д.
Последний номер передается, тут для простоты var LastLog_r = "3";
Скрипт генерирует путь к файлу и его имя (правда (LastLog_r-2) получается = 1 ... но чую как то коряво получается).
Файл просто открывается в браузере как текст, но не скачивается

laimas 05.11.2018 04:42

Вы же писали, что у вас сервер, а какой? Их в общем то используемых всего три - Apache, nginx, IIS. Сервер сам вполне может отдать список каталогов файлов, сформировав ссылки на них. Например Apache отдаст такую страницу:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
 <head>
  <title>Index of /doc</title>
 </head>
 <body>
<h1>Index of /doc</h1>
  <table>
   <tr><th valign="top"><img src="/apacheicons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a></th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th><th><a href="?C=D;O=A">Description</a></th></tr>
   <tr><th colspan="5"><hr></th></tr>
<tr><td valign="top"><img src="/apacheicons/back.gif" alt="[PARENTDIR]"></td><td><a href="/">Parent Directory</a></td><td>&nbsp;</td><td align="right">  - </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="/apacheicons/layout.gif" alt="[   ]"></td><td><a href="1.log">1.log</a></td><td align="right">2012-06-23 21:03  </td><td align="right">9.9K</td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="/apacheicons/layout.gif" alt="[   ]"></td><td><a href="2.log">2.log</a></td><td align="right">2012-06-23 21:03  </td><td align="right"> 26K</td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="/apacheicons/layout.gif" alt="[   ]"></td><td><a href="3.log">3.log</a></td><td align="right">2012-06-23 21:03  </td><td align="right"> 53K</td><td>&nbsp;</td></tr>
   <tr><th colspan="5"><hr></th></tr>
</table>
</body></html>


Такую страницу сервер отдает только в случае, если каталог не закрыт для внешнего доступа, в нем не запрещен листинг файлов посредством .htaccess или в нем нет индексного файла с пустым содержимым.


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