Какой дизайн выбрать для кнопки на три состояния?
Добрый день,
хочу сделать блок маленьких кнопок, в каждой несколько букв (обычно это названия функциональных групп молекул, например, COOH, HN3, CH3) мне нужно три состояния такой кнопки: 1. функциональная группа присутствует, 2. функциональная группа точно отсутствует, 3. не важно. Всего таких кнопок планируется где-то 80, может в будущем будет больше, около 120. Один из вариантов, окрашивать background-color в 1. зеленый, 2. красный, 3 белый цвет, но как-то пестро получается. Возможно есть что-то красивее, например, галочку в правом левом углу ставить. Еще как вариант, играть шрифтом 1. жирный, 2. перечеркнутый, 3. обычный. Посоветуйте, пожалуйста, что было бы правильнее и логичнее, и как логичнее переключать эти состояния. Я планировал переключать все состояния одним щелчком по кругу 1-2-3-0, но может правильнее 1-3. переключается одинарным щелчком, 1-2. переключается двойным щелчком. Спасибо! |
Переключать лучше по кругу.
не важно - есть - нет - не важно. Визуально можно использовать checkbox с тремя состояниями.
<style>
input[type=checkbox]+span {
margin-left:10px;
}
input[type=checkbox][data-state="0"]+span::after {
content: "не важно";
}
input[type=checkbox][data-state="1"]+span::after {
content: "есть";
}
input[type=checkbox][data-state="2"]+span::after {
content: "нет";
}
</style>
<label>COOH <input id=ch1 name=ch1 type=checkbox data-state=0><span></span></label><br>
<label>HN3 <input id=ch2 name=ch2 type=checkbox data-state=0><span></span></label><br>
<label>CH3 <input id=ch3 name=ch3 type=checkbox data-state=0><span></span></label><br>
<script>
// state 0- не важно, 1 - есть, 2 - нет
const setState = (e, state) => {
if (state == 2) {
e.indeterminate = true;
} else {
e.indeterminate = false;
e.checked = state;
}
e.dataset.state = state
}
const getState = (e) => {
return +e.dataset.state
}
document.querySelectorAll('input[type=checkbox]')
.forEach(e => {
setState (e, +e.dataset.state);
e.addEventListener('click', (ev) => {
let st = +e.dataset.state
setState (e, st==2? 0 : st+1)
})
})
</script>
|
кнопка на три состояния
:) :write:
<!DOCTYPE html>
<html>
<head>
<title>Untitled</title>
<meta charset="utf-8">
<style>
input[type=checkbox]+span {
margin-left:10px;
}
input[type=checkbox]:indeterminate+span::after {
content: "нет";
}
input[type=checkbox]:checked+span::after {
content: "есть";
}
input[type=checkbox]+span::after {
content: "не важно";
}
</style>
</head>
<body>
<label>COOH <input id=ch1 name=ch1 type=checkbox ><span></span></label><br>
<label>HN3 <input id=ch1 name=ch1 type=checkbox ><span></span></label><br>
<label>CH3 <input id=ch1 name=ch1 type=checkbox ><span></span></label><br>
<script>
document.querySelectorAll('input[type=checkbox]')
.forEach(e => {
let t;
e.addEventListener('click', (ev) => {
if(!t && !e.checked) {
e.checked = false;
t = e.indeterminate = true;
}
else if(t){
e.checked = false;
t = false;
}
console.log(`st = ${e.indeterminate ? 2 : +e.checked}`);
});
})
</script>
</body>
</html>
|
:write:
ещё меньше кода на три состояния здесь в самом низу. |
Осталось придумать простой способ задавать начальное состояние в html
|
Я тут подумал, что если это должно быть в форме и отправляться на сервер, то такой чекбокс - не самое лучшее решение.
Проще сделать с обычными кнопками
<style>
.tristate {
border: 1px solid black;
background-color: inherit;
padding: 5px 1em;
margin: 0.5em 1em;
}
.tristate::before {
content: attr(name);
margin-right: 2em;
}
.tristate[value="0"]::after {
content: "не важно";
}
.tristate[value="1"]::after {
content: "есть";
}
.tristate[value="2"]::after {
content: "нет";
}
</style>
<button type="button" class="tristate" value="0" name="COOH"></button><br>
<button type="button" class="tristate" value="0" name="HN3"></button><br>
<button type="button" class="tristate" value="0" name="CH3"></button><br>
<script>
// state 0- не важно, 1 - есть, 2 - нет
const setState = (e, state) => {
e.value=state+'';
}
const getState = (e) => {
return +e.value
}
document.querySelectorAll('.tristate')
.forEach(e => {
e.addEventListener('click', (ev) => {
let st = getState(e)
setState(e, st==2? 0 : ++st)
})
})
</script>
|
voraa,
:write:
<style>
.tristate {
border: 1px solid black;
background-color: inherit;
padding: 5px 1em;
margin: 0.5em 1em;
}
.tristate::before {
content: attr(name);
margin-right: 2em;
}
.tristate[value="0"]::after {
content: "не важно";
}
.tristate[value="1"]::after {
content: "есть";
}
.tristate[value="2"]::after {
content: "нет";
}
</style>
<button type="button" class="tristate" value="0" name="COOH"></button><br>
<button type="button" class="tristate" value="0" name="HN3"></button><br>
<button type="button" class="tristate" value="0" name="CH3"></button><br>
<script>
document.querySelectorAll('.tristate')
.forEach(e => {
e.addEventListener('click', (ev) => {
e.value = (+e.value + 1) % 3;
})
})
</script>
|
Огромное спасибо за советы!!!
Попробовал оба варианта, и хотел бы выложить на обсуждение модифицированный вариант с кнопками, покритикуйте, пожалуйста, если там что-то совсем не красиво получается.
<!DOCTYPE html>
<html>
<head>
<title>Untitled</title>
<meta charset="utf-8">
<style>
.css_l { border-radius: 10px; border: 2px solid black; color: black; padding: 5px 5px; text-align: center; vertical-align: center; font-size: 16px; margin: 1px 1px; cursor: pointer; }
</style>
</head>
<body>
<div id="main"></div>
<script>
var Radicals = ["=C=O", "-HC=O", "-O-C(=O", "-C(=O", "-CH3", "-CH2-CH2-", "-CH=CH-", "-C#C-", "-CH2-CH3", "-NH2", "-NO2", "-NO", "-C#N", "#PO4", "=PO4", "C3", "c3", "C4", "c4", "C5", "c5", "C6", "c6", "C7", "c7", "C8", "c8", "C9", "c9", "C10", "c10", "C6-C4", "c6-c4", "C6-C3", "c6-c3", "C6-C4-C4", "c6-c4-c4", "-CH(OH)-", "-[CH(OH)]2-", "-[CH(OH)]3-", "-[CH(OH)]4-", "-[CH(OH)]5-"];
var RadicalsStatus = [];
var StatusName = [ " ", " ✅", " ⛔" ];
function Ini()
{ let html="";
for(let i=0; i<Radicals.length; i++)
{ RadicalsStatus[i]=0;
html+="<button class='css_l' id='ch" + i + "' onclick='ts(" + i + ")'>" + Radicals[i] + StatusName[0] + "</button>";
}
document.getElementById("main").innerHTML=html;
}
Ini();
function ts(i)
{ if((++RadicalsStatus[i])==3) RadicalsStatus[i]=0;
document.getElementById("ch" + i).innerHTML=Radicals[i] + StatusName[RadicalsStatus[i]];
}
</script>
</body>
</html>
Спасибо! С наступающим Вас Новым Годом!!! |
Was-Ja,
|
Спсибо большое, рони!!!
|
Was-Ja,
<style>
.css_l {
border-radius: 10px;
border: 2px solid black;
color: black;
padding: 3px 5px;
text-align: center;
vertical-align: center;
font-size: 16px;
margin: 1px 1px;
cursor: pointer;
}
.css_l:focus {
outline: none;
}
.css_l::before {
content: attr(name);
margin-right: .2em;
}
.css_l[value='0']::after {
content: '\2004\2004\2004\2004';
}
.css_l[value='1']::after {
content: ' ✅';
}
.css_l[value='2']::after {
content: ' ⛔';
}
</style>
<div id="main"></div>
<script>
const Radicals = ["=C=O", "-HC=O", "-O-C(=O", "-C(=O", "-CH3", "-CH2-CH2-", "-CH=CH-", "-C#C-", "-CH2-CH3", "-NH2", "-NO2", "-NO", "-C#N", "#PO4", "=PO4", "C3", "c3", "C4", "c4", "C5", "c5", "C6", "c6", "C7", "c7", "C8", "c8", "C9", "c9", "C10", "c10", "C6-C4", "c6-c4", "C6-C3", "c6-c3", "C6-C4-C4", "c6-c4-c4", "-CH(OH)-", "-[CH(OH)]2-", "-[CH(OH)]3-", "-[CH(OH)]4-", "-[CH(OH)]5-"];
const button = document.createElement("BUTTON");
button.className = "css_l";
button.value = "0";
const click = function() {
this.value = (+this.value + 1) % 3;
}
Radicals.forEach(title => {
let clone = button.cloneNode();
clone.setAttribute("name", title);
clone.addEventListener("click", click);
main.append(clone)
})
</script>
|
Спасибо огромное, рони !!! Как же здорово, что Вы подсказываете! Я многие вещи существенно сложнее сделал (не только в этом примере, но и в базе, что я недавно выкладывал), исправлюсь!!!
|
| Часовой пояс GMT +3, время: 17:48. |