Я работаю над базовой концепцией для выбора нескольких групп, где некоторые параметры ввода отключены, потому что они обычно недоступны в данный момент, а другие отключены, потому что они уже были выбраны в другом месте. Это может быть две или более форм или несколько элементов в одной форме, как в примере. Мне нужно связать числовой вывод выборок и отключить / включить опции между отдельными элементами.
Мы используем PHP для генерации списка опций в алфавитном порядке через php include на стороне сервера. Я оставил часть php за то, что у меня только статический html для тестирования.
В примере показаны два ввода формы множественного выбора. Члены команды идентифицируются по номеру на заднем плане и с человеческими именами в UX. Обычно скрытый числовой вывод теперь доступен для тестирования под каждой командой.
Я хотел просто предварительно проверить уже выбранные значения из скрытого числового вывода onBlur и onFocus при выборе следующей команды. Тем не менее, так как элементы формы перехвачены multi.js, больше нет событий Focus и Blur, срабатывающих.
CSS на основе multi.min.css Фабиана Линдфорса:
/* basic styling */
body { font-family: Avenir,sans-serif; }
.container { box-sizing: border-box; margin: 0 auto; max-width: 500px; padding: 0 20px; width: 100%; }
.developer { color:#999; font-size: small; margin-bottom:20px }
/* form and selection styling */
label{ margin-left:20px; color: #666; font-weight:bolder }
.multi-wrapper{ border: 1px solid #999; border-radius: 8px; width: 450px; margin:10px 0 10px 0 }
.multi-wrapper .non-selected-wrapper,.multi-wrapper .selected-wrapper{ box-sizing: border-box; display: inline-block; height: 150px; overflow-y: scroll; padding: 10px; vertical-align: top; width: 50% }
.multi-wrapper .non-selected-wrapper{ background: #fafafa; border-radius: 0 0 0 8px; border-right: 1px solid #ccc }
.multi-wrapper .selected-wrapper{ background: #FFF; border-radius: 0 0 8px 0 }
.multi-wrapper .header{ color: #4f4f4f; cursor: default; font-weight: 700; margin-bottom: 5px; padding: 5px 10px }
.multi-wrapper .item{ cursor: pointer; display: block; padding: 5px 10px }
.multi-wrapper .item: hover{ background: #ececec; border-radius: 2px }
.multi-wrapper .item-group{ padding: 5px 10px }
.multi-wrapper .item-group .group-label{ display: block; font-size: .875rem; opacity: .5; padding: 5px 0 }
.multi-wrapper .search-input{ border: 0; border-bottom: 1px solid #ccc; border-radius: 8px 8px 0 0; display: block; font-size: 1em; margin: 0; outline: 0; padding: 10px 20px; width: 100%; box-sizing: border-box }
.multi-wrapper .non-selected-wrapper .item.selected{ display: none; opacity: .5 }
.multi-wrapper .non-selected-wrapper .item.disabled,.multi-wrapper .selected-wrapper .item.disabled{ opacity: .5; text-decoration: line-through }
.multi-wrapper .non-selected-wrapper .item.disabled: hover,.multi-wrapper .selected-wrapper .item.disabled: hover{ background: inherit; cursor: inherit}
HTML-форма:
<div class="container">
<h1>team selection demo</h1>
<form>
<label for="team_1">Select members for day shift</label>
<select onChange="reportUpdatedValues(this,this.name);"
multiple="multiple"
name="team_1"
id="team_1_select">
<option value="13" disabled="disabled">Alex</option>
<option value="1">Bob</option>
<option value="8">Diana</option>
<option value="5">Frank</option>
<option value="9">Fred</option>
<option value="11">Helen</option>
<option value="10">Jeanne</option>
<option value="4">Linda</option>
<option value="3">Mary</option>
<option value="2" disabled="disabled">Max</option>
<option value="7">Mo</option>
<option value="6">Paul</option>
<option value="12">Sara</option>
</select>
<span class="developer" style="display:inherit; padding:10px 0 10px 20px">
normally hidden digital output:
<input id="output_team_1" type="text" style="float:right">
</span>
<label for="team_2">Select members for night shift</label>
<select onChange="reportUpdatedValues(this,this.name);"
multiple="multiple"
name="team_2"
id="team_2_select">
<option value="13" disabled="disabled">Alex</option>
<option value="1">Bob</option>
<option value="8">Diana</option>
<option value="5">Frank</option>
<option value="9">Fred</option>
<option value="11">Helen</option>
<option value="10">Jeanne</option>
<option value="4">Linda</option>
<option value="3">Mary</option>
<option value="2" disabled="disabled">Max</option>
<option value="7">Mo</option>
<option value="6">Paul</option>
<option value="12">Sara</option>
</select>
</form>
<span class="developer" style="display:inherit; padding:10px 0 10px 20px">
normally hidden digital output:
<input id="output_team_2" type="text" style="float:right">
</span>
</div>
JavaScript
// initialise multi, set headers for group 1
var select = document.getElementById("team_1_select");
multi(select, {
non_selected_header: "Candidates",
selected_header: "Team 1"
});
// initialise multi, set headers for group 2
var select = document.getElementById("team_2_select");
multi(select, {
non_selected_header: "Candidates",
selected_header: "Team 2"
});
function reportUpdatedValues(element,team){
// Return an array of the selected options in element
var result = [];
var options = element && element.options;
var opt;
for (var i=0, iLen=options.length; i<iLen; i++) {
opt = options[i];
if (opt.selected) {
result.push(opt.value || opt.text);
}
}
// for development purpose only we display the result in the team output
document.getElementById('output_'+team).value = result;
return result;
}
/*! multi.min.js version 03-12-2018 by Fabian Lindfors */
var multi=function(){var e=function(e,t,n){var a=e.options[t.target.getAttribute("multi-index")];if(!a.disabled){a.selected=!a.selected;var i,d,r,l=n.limit;if(l>-1){for(var s=0,o=0;o<e.options.length;o++)e.options[o].selected&&s++;if(s===l){this.disabled_limit=!0,"function"==typeof n.limit_reached&&n.limit_reached();for(o=0;o<e.options.length;o++){(c=e.options[o]).selected||c.setAttribute("disabled",!0)}}else if(this.disabled_limit){for(o=0;o<e.options.length;o++){var c;"false"===(c=e.options[o]).getAttribute("data-origin-disabled")&&c.removeAttribute("disabled")}this.disabled_limit=!1}}i="change",d=e,(r=document.createEvent("HTMLEvents")).initEvent(i,!1,!0),d.dispatchEvent(r)}},t=function(e,t){if(e.wrapper.selected.innerHTML="",e.wrapper.non_selected.innerHTML="",t.non_selected_header&&t.selected_header){var n=document.createElement("div"),a=document.createElement("div");n.className="header",a.className="header",n.innerText=t.non_selected_header,a.innerText=t.selected_header,e.wrapper.non_selected.appendChild(n),e.wrapper.selected.appendChild(a)}if(e.wrapper.search)var i=e.wrapper.search.value;for(var d=null,r=null,l=0;l<e.options.length;l++){var s=e.options[l],o=s.value,c=s.textContent||s.innerText,p=document.createElement("a");if(p.tabIndex=0,p.className="item",p.innerHTML=c,p.setAttribute("role","button"),p.setAttribute("data-value",o),p.setAttribute("multi-index",l),s.disabled&&(p.className+=" disabled"),s.selected){p.className+=" selected";var u=p.cloneNode(!0);e.wrapper.selected.appendChild(u)}if("OPTGROUP"==s.parentNode.nodeName&&s.parentNode!=r){if(r=s.parentNode,(d=document.createElement("div")).className="item-group",s.parentNode.label){var m=document.createElement("span");m.innerHTML=s.parentNode.label,m.className="group-label",d.appendChild(m)}e.wrapper.non_selected.appendChild(d)}s.parentNode==e&&(d=null,r=null),(!i||i&&c.toLowerCase().indexOf(i.toLowerCase())>-1)&&(null!=d?d.appendChild(p):e.wrapper.non_selected.appendChild(p))}};return function(n,a){if((a=void 0!==a?a:{}).enable_search=void 0===a.enable_search||a.enable_search,a.search_placeholder=void 0!==a.search_placeholder?a.search_placeholder:"Search...",a.non_selected_header=void 0!==a.non_selected_header?a.non_selected_header:null,a.selected_header=void 0!==a.selected_header?a.selected_header:null,a.limit=void 0!==a.limit?parseInt(a.limit):-1,isNaN(a.limit)&&(a.limit=-1),null==n.dataset.multijs&&"SELECT"==n.nodeName&&n.multiple){n.style.display="none",n.setAttribute("data-multijs",!0);var i=document.createElement("div");if(i.className="multi-wrapper",a.enable_search){var d=document.createElement("input");d.className="search-input",d.type="text",d.setAttribute("placeholder",a.search_placeholder),d.addEventListener("input",function(){t(n,a)}),i.appendChild(d),i.search=d}var r=document.createElement("div");r.className="non-selected-wrapper";var l=document.createElement("div");l.className="selected-wrapper",i.addEventListener("click",function(t){t.target.getAttribute("multi-index")&&e(n,t,a)}),i.addEventListener("keypress",function(t){var i=32===t.keyCode||13===t.keyCode;t.target.getAttribute("multi-index")&&i&&(t.preventDefault(),e(n,t,a))}),i.appendChild(r),i.appendChild(l),i.non_selected=r,i.selected=l,n.wrapper=i,n.parentNode.insertBefore(i,n.nextSibling);for(var s=0;s<n.options.length;s++){var o=n.options[s];o.setAttribute("data-origin-disabled",o.disabled)}t(n,a),n.addEventListener("change",function(){t(n,a)})}}}();"undefined"!=typeof jQuery&&function(e){e.fn.multi=function(t){return t=void 0!==t?t:{},this.each(function(){var n=e(this);multi(n.get(0),t)})}}(jQuery);
В этом примере имена Алекс и Макс находятся в отпуске, и поэтому PHP уже сделал их, как правило, недоступными для всех команд. Теперь, если Диана (числовой элемент 8) выбрана для Команды 1, опция Диана должна быть отключена или скрыта для Команды 2, Команды 3, Команды 4 и так далее. Общее количество команд может варьироваться в зависимости от случая.