IT TIP

상황에 맞는 메뉴로 Bootstrap 3 드롭 다운 메뉴 사용

itqueen 2020. 11. 2. 20:10
반응형

상황에 맞는 메뉴로 Bootstrap 3 드롭 다운 메뉴 사용


Bootstrap 3을 사용하여 드롭 다운 메뉴를 커서에 놓고 코드에서 열 수 있습니까?

행에 대한 컨텍스트 메뉴로 테이블에서 사용해야합니다.


것이 가능하다. 좋은 시작을 위해 작동하는 데모를 만들었습니다.

작동 데모 (테이블 행을 마우스 오른쪽 버튼으로 클릭하여 작동 하는지 확인)

먼저, 드롭 다운 메뉴를 만들고 그것을 숨기고 그 변경 position에를 absolute:

#contextMenu {
  position: absolute;
  display:none;
}

그런 다음 contextmenu이벤트를 테이블 행에 바인딩하여 드롭 다운 / 컨텍스트 메뉴를 표시하고 커서에 배치합니다.

var $contextMenu = $("#contextMenu");

$("body").on("contextmenu", "table tr", function(e) {
   $contextMenu.css({
      display: "block",
      left: e.pageX,
      top: e.pageY
   });
   return false;
});

그런 다음 사용자가 드롭 다운 / 컨텍스트 메뉴 숨기기 옵션을 선택하면 :

$contextMenu.on("click", "a", function() {
   $contextMenu.hide();
});

몇 가지 더 많은 제안을 통해 letiagoalves 훌륭한 답변 을 개선하고 싶었습니다 .
다음은 html 요소에 상황에 맞는 메뉴를 추가하는 방법에 대한 안내입니다.

jsFiddle에서 작동하는 데모로 시작하겠습니다.

마크 업 :

먼저 부트 스트랩 드롭 다운 컨트롤 에서 메뉴를 추가해 보겠습니다 . 가능하면 본문의 루트 수준에서 HTML에 추가하십시오. .dropdown-menu클래스를 설정합니다 display:none그것은 처음에 눈에 보이지 않는, 그래서.
다음과 같이 표시되어야합니다.

<ul id="contextMenu" class="dropdown-menu" role="menu">
    <li><a tabindex="-1" href="#">Action</a></li>
    <li><a tabindex="-1" href="#">Another action</a></li>
    <li><a tabindex="-1" href="#">Something else here</a></li>
    <li class="divider"></li>
    <li><a tabindex="-1" href="#">Separated link</a></li>
</ul>

확장 설정 :

디자인 모듈화를 유지하기 위해 JavaScript 코드를 contextMenu.

를 호출 할 때 $.contextMenu두 가지 속성이있는 설정 개체를 전달합니다.

  1. menuSelector HTML에서 앞서 만든 메뉴의 jQuery 선택기를 사용합니다.
  2. menuSelected 상황에 맞는 메뉴 동작을 클릭하면 호출됩니다.
$("#myTable").contextMenu({
    menuSelector: "#contextMenu",
    menuSelected: function (invokedOn, selectedMenu) {
        // context menu clicked
    });
});

플러그인 템플릿 :

jQuery 상용구 플러그인 템플릿을 기반 으로 즉시 호출 된 함수 표현식 을 사용하여 전역 네임 스페이스를 혼동하지 않습니다. jQuery에 대한 종속성이 있고 창에 대한 액세스가 필요하기 때문에 축소에서 살아남을 수 있도록 변수로 전달합니다. 다음과 같이 표시됩니다.

(function($, window){

    $.fn.contextMenu = function(settings) {  
        return this.each(function() {  
            // Code Goes Here
        }  
    };

})(jQuery, window);

좋아요, 더 이상 배관하지 마세요. 기능의 핵심은 다음과 같습니다.

오른쪽 클릭 이벤트 처리 :

contextmenu확장을 호출 한 객체 에서 마우스 이벤트를 처리합니다 . 이벤트가 시작되면 처음에 추가 한 드롭 다운 메뉴를 가져옵니다. 함수를 초기화 할 때 설정에 의해 전달 된 선택자 문자열을 사용하여 위치를 찾습니다. 다음을 수행하여 메뉴를 수정합니다.

  • 우리는 잡아 것이다 e.target속성을하고라는 데이터 속성으로 저장 invokedOn나중에 상황에 맞는 메뉴를 제기 요소를 식별 할 수 있도록.
  • 메뉴 표시를 다음을 사용하여 표시하도록 전환합니다. .show()
  • 을 사용하여 요소의 위치를 ​​지정합니다 .css().
    • position로 설정되어 있는지 확인해야합니다 absolute.
    • 그런 다음 이벤트 pageXpageY속성을 사용하여 왼쪽 및 위쪽 위치를 설정합니다 .
  • 마지막으로 오른쪽 클릭 동작이 자체 메뉴를 열지 return false않도록하려면 자바 스크립트가 다른 작업을 처리하지 못하도록합니다.

다음과 같이 표시됩니다.

$(this).on("contextmenu", function (e) {
    $(settings.menuSelector)
        .data("invokedOn", $(e.target))
        .show()
        .css({
            position: "absolute",
            left: e.pageX,
            top: e.pageY
        });

    return false;
});

메뉴 가장자리 케이스 수정 :

그러면 메뉴를 연 커서의 오른쪽 하단에 메뉴가 열립니다. 그러나 커서가 화면 맨 오른쪽에 있으면 메뉴가 왼쪽으로 열립니다. 마찬가지로 커서가 하단에 있으면 메뉴가 상단으로 열립니다. 물리적 프레임을 포함하는의 하단과 전체 html DOM을 나타내며 창을 훨씬 지나서 스크롤 할 수 있는의 하단window 을 구별하는 것도 중요합니다 document.

이를 위해 다음 기능을 사용하여 위치를 설정합니다.

다음과 같이 부를 것입니다.

.css({
    left: getMenuPosition(e.clientX, 'width', 'scrollLeft'),
    top: getMenuPosition(e.clientY, 'height', 'scrollTop')
});

이 함수를 호출하여 적절한 위치를 반환합니다.

function getMenuPosition(mouse, direction, scrollDir) {
    var win = $(window)[direction](),
        scroll = $(window)[scrollDir](),
        menu = $(settings.menuSelector)[direction](),
        position = mouse + scroll;

    // opening menu would pass the side of the page
    if (mouse + menu > win && menu < mouse) 
        position -= menu;

    return position
}

메뉴 요소에서 클릭 이벤트 바인딩 :

컨텍스트 메뉴를 표시 한 후에는 클릭 이벤트를 수신 할 이벤트 핸들러를 추가해야합니다. 동일한 이벤트가 두 번 발생하지 않도록 이미 추가되었을 수있는 다른 바인딩을 제거합니다. 메뉴를 열 때마다 발생할 수 있지만 클릭으로 인해 아무것도 선택되지 않았습니다. 그런 click다음 다음 섹션에서 논리를 처리 할 이벤트 에 새 바인딩을 추가 할 수 있습니다 .

으로 valepu가 언급 한 , 우리는 우리가 설정 소위, 메뉴 항목 이외의 클릭을 등록하지 않으 위임 핸들러 로 선택을 전달하여 on"이벤트를 트리거 선택한 요소의 자손을 필터링 할"것입니다 기능을.

지금까지 함수는 다음과 같아야합니다.

$(settings.menuSelector)
    .off('click')
    .on( 'click', "a", function (e) {
        //CODE IN NEXT SECTION GOES HERE
});

메뉴 클릭 처리

메뉴에서 클릭이 발생했음을 알게되면 다음 작업을 수행합니다 .hide(). 를 사용하여 화면에서 메뉴를 숨 깁니다 . 다음으로, 메뉴가 원래 호출 된 요소와 현재 메뉴의 선택을 저장하려고합니다. 마지막으로 .call()속성 을 사용 하고 이벤트 대상을 인수로 전달 하여 확장에 전달 된 함수 옵션을 실행합니다 .

$menu.hide();

var $invokedOn = $menu.data("invokedOn");
var $selectedMenu = $(e.target);

settings.menuSelected.call($(this), $invokedOn, $selectedMenu);

클릭 할 때 숨기기 :

마지막으로, 대부분의 컨텍스트 메뉴와 마찬가지로 사용자가 메뉴를 클릭 할 때 메뉴를 닫고 싶습니다. 이를 위해 본문에서 클릭 이벤트를 수신하고 다음과 같이 열려있는 경우 컨텍스트 메뉴를 닫습니다.

$('body').click(function () {
    $(settings.menuSelector).hide();
});

참고 : Sadhir의 의견 덕분에 Firefox Linux document는 마우스 오른쪽 버튼을 클릭 하는 동안 클릭 이벤트를 트리거 하므로에서 리스너를 설정해야합니다 body.

예제 구문 :

확장은 컨텍스트 메뉴를 발생시킨 원래 개체와 클릭 한 메뉴 항목과 함께 반환됩니다. 이벤트 대상에서 의미있는 것을 찾기 위해 jQuery를 사용 하여 dom탐색 해야 할 수도 있지만 이것은 기본 기능의 좋은 계층을 제공해야합니다.

다음은 선택한 항목 및 작업에 대한 정보를 반환하는 예입니다.

$("#myTable").contextMenu({
    menuSelector: "#contextMenu",
    menuSelected: function (invokedOn, selectedMenu) {
        var msg = "You selected the menu item '" + 
                  selectedMenu.text() +
                  "' on the value '" + 
                  invokedOn.text() + "'";
        alert(msg);
    }
});

스크린 샷 :

컨텍스트 메뉴 스크린 샷

업데이트 참고 :

이 답변은 jQuery 확장 메서드로 래핑하여 크게 업데이트되었습니다. 내 원본을보고 싶다면 게시물 기록을 볼 수 있지만이 최종 버전은 훨씬 더 나은 코딩 관행을 활용한다고 생각합니다.

Bonus Feature:

If you want to add some nice functionality for powerusers or yourself in developing features, you can bypass the context menu based on any key combinations being held when your right click. For example, if you wanted to allow the original browser context menu to display when holding Ctrl, you could add this as the first line of the contextMenu handler:

// return native menu if pressing control
if (e.ctrlKey) return;

Added some modifications to KyleMit's code:

  • moved "on document click" handler from "foreach"
  • removed "foreach", just add event to selector
  • hide menu on "document context menu"
  • passing events

    $("#myTable tbody td").contextMenu({
    menuSelector: "#contextMenu",
    menuSelected: function (invokedOn, selectedMenu) {
        var msg = "You selected the menu item '" + selectedMenu.text() +
            "' on the value '" + invokedOn.text() + "'";
        alert(msg);
    },
    onMenuShow: function(invokedOn) {
        var tr = invokedOn.closest("tr");
        $(tr).addClass("warning");
    },
    onMenuHide: function(invokedOn) {
        var tr = invokedOn.closest("tr");
        $(tr).removeClass("warning");
    } });
    

http://jsfiddle.net/dmitry_far/cgqft4k3/


이 간단하고 작동하는 상황에 맞는 메뉴를 찾았습니다. 이 라이브러리 http://swisnl.github.io/jQuery-contextMenu/index.html을 사용하고 있습니다 . 도움이되기를 바랍니다.

표:

<table id="ppmpsupplies" class="table table-bordered table-hover" cellspacing="0" width="100%">
          <thead>
            <tr>
              <th>Code</th>
              <th>General Description</th>
              <th>Unit</th>
              <th>Quantity</th>
              <th>Estimated Budget</th>
              <th>Mode of Procurement</th>                 

            </tr>
          </thead>
          <tbody>
            <?php foreach($items as $item){?>
            <tr>
             <td><?php echo $item->id;?></td>
             <td><?php echo $item->description;?></td>
             <td><?php echo $item->unit;?></td>
             <td><?php echo $item->quantity;?></td>
             <td><?php echo $item->budget;?></td>
             <td><?php echo $item->mode;?></td>                     
          </tr>
          <?php }?>

        </tbody>
        <tfoot>
          <td colspan="3"></td>
          <td>Total</td>
          <td></td>
        </tfoot>
      </table>

컨텍스트 메뉴 :

    "edit": {
        name: "Edit",
        icon: "fa-pencil-square-o",
        callback: function(item, id) {

        return true;
        }
        },
"delete": {
        name: "Delete",
        icon: "fa-trash-o",
        callback: function(item, id) {

        return true;
        }
        },

참고 URL : https://stackoverflow.com/questions/18666601/use-bootstrap-3-dropdown-menu-as-context-menu

반응형