JavaScript 미니 챌린지 - 솔루션

안녕하세요, 코더 여러분!

이틀 전에 구현해야 할 임무를 받았다고 게시했습니다.

사양은 충분히 간단합니다.

users should be able to select as many cities as they like from a drop down as long as they're not located in more than 2 countries.



RTFM



종종 그렇듯이 문서를 읽는 것은 큰 도움이 됩니다. 이번에도 예외는 아닙니다.
문서의 the events section으로 이동하면 기본 선택 값이 변경된 직후에 실행되는 changed.bs.select를 들을 수 있음을 알 수 있습니다.

$('#mySelect').on('changed.bs.select', function (e, clickedIndex, isSelected, previousValue) {
  // do something...
});


여기서 중요한 것은 변경되기 전에 드롭다운 값을 보유하고 있는 previousValue도 얻는다는 것입니다.
따라서 사용자가 제3국을 선택한 시기를 파악할 수 있으면 다음을 수행하여 값을 다시 previousValue로 설정할 수 있습니다.

$("#cities")
    .selectpicker()
    .on(
        "changed.bs.select",
        function (event, clickedIndex, isSelected, previousValue) {
            const $this = $(this);
            if (someCondition) {  // <== gotta work on this next
                $this.selectpicker('val', previousValue);
            }
        }
    );


얼마나 많은 국가가 선택되었는지 계산



우리는 선택한 도시의 수가 아니라 그들이 속한 국가의 수를 원합니다.
우리가 가지고 있는 유일한 정보는 optgroup 레이블이고 그것을 사용할 것입니다.

const selectedCountries = $this
    .find("option:selected")
    .get()
    .map((o) => $(o).parent().attr("label"))


기본적으로 선택한 각 옵션을 반복하고 optgroup 의 레이블을 가져옵니다.
문제는 둘 이상의 도시를 선택한 경우 국가 이름이 고유하지 않다는 것입니다.

여기 dev.to에서 JavaScript 관련 게시물을 읽고 있다면 someArray에서 고유한 값을 가져오는 다음과 같은 라이너를 보았을 것입니다.

const uniqueNames = [new Set(...someArray)];


정확히 우리가 원하는 것이므로 사용합시다.

const uniqueCategories = [
    ...new Set(
        $this
            .find("option:selected")
            .get()
            .map((o) => $(o).parent().attr("label"))
        )
    ];


이제 고유한 국가 목록이 있으므로 요소 수를 계산하고 2보다 크면 드롭다운 값을 previousValue로 설정하기만 하면 됩니다.

if (uniqueCategories.length > 2) {
    $this.selectpicker('val', previousValue);
}


함께 모아서




$(function () {
    const MAX_NUMBER_COUNTRIES = 2;
    $("#cities")
        .selectpicker()
        .on(
            "changed.bs.select",
            function (event, clickedIndex, isSelected, previousValue) {
                const $this = $(this);
                const uniqueCategories = [
                    ...new Set(
                        $this
                            .find("option:selected")
                            .get()
                            .map((o) => $(o).parent().attr("label"))
                    )
                ];

                if (uniqueCategories.length > MAX_NUMBER_COUNTRIES) {
                    $this.selectpicker('val', previousValue);
                }
            }
        );
});


CodePen에서 작동을 확인하십시오.

결론



이 "도전"은 어렵지 않았지만 문서를 읽는 것이 얼마나 중요한지 보여줍니다!
제가 학생이었을 때 Java 선생님이 일부 문자열을 조작하기 위해 가능한 한 가장 짧은 프로그램을 작성하라고 요구했습니다.
일부는 7줄 프로그램을 내놓았습니다. 다른 사람들은 4줄을 가졌습니다.

선생님은 한 줄이었습니다. ✨
정확히 요청한 것을 수행하는 기본 Java 함수에 대한 호출이었습니다. RTFM을 말하는 그의 방식이지만 정치적으로 올바른 방식입니다.

즐거운 코딩하세요! 💻

좋은 웹페이지 즐겨찾기