1: <?php
2:
3: class BootstrapSideMenu extends \Sphp\tools\MenuGen{
4: public $brandicon = "";
5: public $navbarClasses = "nav flex-column flex-nowrap overflow-hidden nav-pills";
6: private $mkey = "";
7: private $mkeychar = "";
8: private $fixedPos = "";
9: private $rootMenu = "sidebar";
10: private $counter1 = 1;
11:
12: public function onrun() {
13: $this->init();
14: $this->genMenus();
15: }
16: public function setPosition($val="sticky-top") {
17: // fixed-bottom fixed-top sticky-top
18: $this->fixedPos = $val;
19: }
20: public function setRootMenu($val) {
21: $this->rootMenu = $val;
22: }
23: public function setNavBarCss($val) {
24: $this->navbarClasses = $val;
25: }
26: public function setBrandIcon($val) {
27: $this->brandicon = $val;
28: }
29: public function genMenus() {
30: $strmbar = $this->genMenuBar();
31: $mnuroot = $this->sphp_api->getMenuList("root");
32: // generate bootstrap 4 menu
33: $str1 = "";
34: foreach ($mnuroot as $mnuName => $lstMenu) {
35: $str1 .= $this->genMenu($lstMenu);
36: }
37: $this->htmlout = $strmbar[0] . $str1 . $strmbar[1];
38: }
39: private function genMenu($lstMenu,$submenu=0){
40: $mnuroot = $this->sphp_api->getMenuList($lstMenu[0]);
41: $stra = array();
42: $str = "";
43: $str1 = "";
44: if($mnuroot != null){
45: foreach ($mnuroot as $mnuName => $lstMenu2) {
46: $str .= $this->genMenu($lstMenu2,1);
47: }
48: $str1 = $this->genMenuLinks($this->sphp_api->getMenuLinkList($lstMenu[0]));
49: if($str1 != ""){
50: $stra = $this->getB4Menu($lstMenu[0],$lstMenu[1],$lstMenu[2],$lstMenu[3],$submenu);
51: }else{
52: $stra = $this->getB4Menu($lstMenu[0],$lstMenu[1],$lstMenu[2],$lstMenu[3],$submenu);
53: }
54: return $stra[0] . $str . $str1 . $stra[1];
55:
56: }else{
57: $str = $this->genMenuLinks($this->sphp_api->getMenuLinkList($lstMenu[0]));
58: if($str != ""){
59: $stra = $this->getB4Menu($lstMenu[0],$lstMenu[1],$lstMenu[2],$lstMenu[3],$submenu);
60: }else{
61: $stra = $this->getB4Menu($lstMenu[0],$lstMenu[1],$lstMenu[2],$lstMenu[3],2);
62: }
63: return $stra[0] . $str . $stra[1];
64: }
65:
66: }
67: private function genMenuLinks($mnuroot){
68: $str = "";
69: if($mnuroot != null){
70: foreach ($mnuroot as $mnuLinkName => $lstMenuLink) {
71: $str .= $this->getB4MenuLink($lstMenuLink[0],$lstMenuLink[1],$lstMenuLink[2],$lstMenuLink[3]);
72: }
73: }
74: return $str;
75: }
76: private function setAjax(){
77: $this->blnAjaxLink = true;
78: SphpBase::JSServer()->getAJAX();
79: addHeaderJSFunction('menu_ajax', "function menu_ajax(url){
80: ", " getURL(url); }");
81: }
82: private function getB4Menu($mnutext,$mnuhref="",$mnuicon,$blnAjaxLink2=false,$mnuSub=0){
83: $mnutitle = $mnutext;
84: if($mnuhref==''){
85: $mnuhref = "#";
86: }else if($blnAjaxLink2){
87: if(!$this->blnAjaxLink){
88: $this->setAjax();
89: }
90: $mnuhref = "javascript: menu_ajax('$mnuhref');";
91: }
92: $mnuhref2 = 'd'. $this->counter1;
93: $this->counter1 += 1;
94: $stro = array();
95: // if menu under root and dropdown
96: if($mnuSub==0){
97: $stro[0] = '<li class="nav-item nav-dli"><a class="nav-link nav-dlink text-truncate" data-toggle="collapse" data-target="#'. $mnuhref2 .'" href="#'.$mnuhref2.'" >' .
98: '<i class="'. $mnuicon .'"></i> <span class="d-none d-sm-inline">' . $mnutitle.'</span></a>'
99: . '<div id="'. $mnuhref2 .'" aria-expanded="true"><ul class="flex-column pl-2 nav">';
100: $stro[1] = '</ul></div></li>';
101: }else if($mnuSub==1){ // if sub menu and dropdown
102: $stro[0] = '<li class="nav-item nav-dli"><a class="nav-link nav-dlink collapsed text-truncate" data-toggle="collapse" data-target="#'. $mnuhref2 .'" href="#'.$mnuhref2.'" >' .
103: '<i class="'. $mnuicon .'"></i> <span class="d-none d-sm-inline">' . $mnutitle.'</span></a>'
104: . '<div class="collapse" id="'. $mnuhref2 .'" aria-expanded="false"><ul class="flex-column pl-2 nav">';
105: $stro[1] = '</ul></div></li>';
106: }else{ // if menu with no links and no sub menu without dropdown
107: $stro[0] = '<li class="nav-item"><a class="nav-link text-truncate" data-mkey="'. $this->mkey .'" href="'.$mnuhref.'"><i class="'. $mnuicon .'"></i> <span class="d-none d-sm-inline">'.$mnutitle.'</span></a>';
108: $stro[1] = '</li>';
109: }
110: return $stro;
111: }
112: private function getB4MenuLink($mnuitemtext,$mnuitemhref="",$mnuicon,$blnAjaxLink2=false){
113: $mnuitemtitle = $mnuitemtext;
114: $mnuitemtext = $mnuitemtext . $this->mkeychar;
115: $tfun = "menu_ajax";
116: if($mnuitemhref==''){
117: $mnuitemhref = "#";
118: }else if($blnAjaxLink2){
119: $mnuitemhref = "javascript: $tfun('$mnuitemhref');";
120: }
121: return '<li class="nav-item"><a class="nav-link nav-dli text-truncate" data-mkey="'. $this->mkey .'" href="'.$mnuitemhref.'"><i class="'. $mnuicon .'"></i> <span class="d-none d-sm-inline">'.$mnuitemtext.'</span></a></li>';
122: }
123: public function genMenuBar() {
124: if($this->brandicon != ""){
125: $this->brandicon = ' <!-- Brand -->
126: <div><a class="" href="#"><img class="img img-fluid img-circle" src="'. $this->brandicon .'" alt="Logo"></a></div>';
127: }
128: $bootstrapMenu = $this->brandicon . '<div class="snavbar"><ul class="'. $this->navbarClasses .'">';
129: return array($bootstrapMenu,'</ul></div>');
130: }
131: private function setKey($key,$controlkeys="") {
132: $fkeya = array();
133: $fkeya["F1"] = 112;
134: $fkeya["F2"] = 113;
135: $fkeya["F3"] = 114;
136: $fkeya["F4"] = 115;
137: $fkeya["F5"] = 116;
138: $fkeya["F6"] = 117;
139: $fkeya["F7"] = 118;
140: $fkeya["F8"] = 119;
141: $fkeya["F9"] = 120;
142: $fkeya["F10"] = 121;
143: $fkeya["F11"] = 122;
144: $fkeya["F12"] = 123;
145: $mkeychar = "";
146: $controlkeysp = "";
147: if(!is_numeric($key)){
148: $mkeychar = strtoupper($key);
149: if(strlen($key)>1){
150: $key = $fkeya[$mkeychar];
151: }else{
152: $key = ord($mkeychar);
153: }
154: }else{
155: $mkeychar = strtoupper(chr($key));
156: }
157: if($controlkeys != ""){
158: $controlkeysp = "+";
159: }
160: $this->mkeychar = " ". strtoupper($controlkeys). $controlkeysp . $mkeychar;
161: $this->mkey = $key;
162: $controlkeysa = explode('+',$controlkeys);
163: $strkey = "";
164: foreach ($controlkeysa as $key => $value) {
165: if($value == "alt"){
166: if($strkey != "") $strkey .= " && ";
167: $strkey .= "eventer.event.altKey";
168: }else if($value == "ctrl"){
169: if($strkey != "") $strkey .= " && ";
170: $strkey .= "eventer.event.ctrlKey";
171: }else if($value == "shift"){
172: if($strkey != "") $strkey .= " && ";
173: $strkey .= "eventer.event.shiftKey";
174: }
175: }
176: if($strkey != "") $strkey .= " && ";
177: // code depend on key listner javascript code of framework
178: addHeaderJSFunction("jq_menukeyevent", "function jq_menukeyevent(eventer){", "}",true);
179: addHeaderJSFunctionCode("jq_keyevent", "menukeyevent1", 'ret = jq_menukeyevent(eventer2);',true);
180: addHeaderJSFunctionCode("jq_menukeyevent", $this->name, ' if('. $strkey .'eventer.keycode=='. $this->mkey .'){
181: if(eventer.evt==\'keyup\'){
182: $(".dropdown-item[data-mkey='.$this->mkey.']")[0].click();
183: return false;
184: }
185: }
186: ',true);
187: //console.log(eventer.keycode);
188: //console.log(eventer.event.shiftKey);
189: //console.log(eventer.event.ctrlKey);
190: //console.log(eventer.event.altKey);
191: }
192:
193: private function init() {
194: addHeaderJSFunctionCode("ready", "snavbar1", '
195: var links = jql(\'.snavbar a\');
196: jql.each(links, function (key, va) {
197: if (va.href == document.URL) {
198: jql(this).addClass(\'active\');
199: var pa = jql(this).parents(\'li.nav-dli\');
200: jql.each(pa, function (key2, va2) {
201: jql(va2).children("a.nav-dlink:first").addClass(\'active\');
202: });
203: }
204: });
205: ',true);
206: addHeaderCSS("snavbar2", ' .nav-link[data-toggle].collapsed:before {
207: content: " ▾";
208: }
209: .nav-link[data-toggle]:not(.collapsed):before {
210: content: " ▴";
211: }
212:
213: ', true);
214:
215: }
216:
217: }
218: