How to create tabs for JQuery terminal

107 views Asked by At

Im trying to create a tab system for my JQuery terminal, but I cant see how I can add functionality to it. For example, I want the X button to close the current tab, and a + button to open a new tab. Im not really good a javascript obviously, but how can I get started in getting this to work? I have seen an example from github that could help me, but I cant access it right now since my school blocks sites, so if you are reading this, can you get the code from here: https://gist.github.com/lawrenceamer/3f2d48be524ee0eca95ada3910d4294d and put it in stack overflow for me? Or give me tips in completing this?

This is the code I have made so far:

<link href="https://db.onlinewebfonts.com/c/1db29588408eadbd4406aae9238555eb?family=Consolas" rel="stylesheet"> <link href="thetabs.css" rel='stylesheet'>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<style>
@import url('https://fonts.cdnfonts.com/css/menlo');
</style>

<style>
iframe {
  width: 100%;
  height: 100%;
}
a {
font-family: Menlo;
}
.ui-tabs .ui-state-active:after {
  content: "x";
  position: absolute;
  top: 5px;
  right: 5px;
  font-size: 12px;
  cursor: pointer;
}
.tab {
  outline: none;
}
  #terminal-tabs {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    overflow: hidden;
  }
  
  #terminal-tabs ul {
    position: sticky;
    top: 0;
    z-index: 1;
  }
  body {
  zoom: reset !important;
}
  #tab-1,
  #tab-2,
  #tab-3 {
    flex-grow: 1;
    display: flex;
    overflow: auto;
  }
  
  #tab-1 iframe,
  #tab-2 iframe,
  #tab-3 iframe {
    width: 100%;
    height: 100%;
    border: none;
  }
</style>

<div id="terminal-tabs">
  <ul>
    <li><a href="#tab-1">My-Terminal   (1)</a></li>
    <li><a href="#tab-2">My-Terminal   (2)</a></li>
    <li><a href="#tab-3">My-Terminal   (3)</a></li>
    <li><a href="#tab-4">My-Terminal   (4)</a></li>
  </ul>
  <div id="tab-1">

     <!-- terminal is hosted here from iframe  -->
  </div>
  <div id="tab-2">

       <!-- terminal is hosted here from iframe  -->
  </div>
  <div id="tab-3">

 <!-- terminal is hosted here from iframe  -->
  </div>
    <div id="tab-4">

    <!-- terminal is hosted here from iframe  -->
  </div>
</div>



<script>

$(function() {
  $("#terminal-tabs").tabs();
});

$("#terminal-tabs").on("click", ".ui-tabs-close", function() {
  var panelId = $(this).closest("li").remove().attr("aria-controls");
  $("#" + panelId).remove();
  $("#terminal-tabs").tabs("refresh");
});
$("#terminal-tabs .ui-tabs-nav").append('<li class="ui-state-default ui-corner-top ui-tabs-new"><a href="#">+</a></li>');

$("#terminal-tabs").on("click", ".ui-tabs-new", function() {
  var newTabIndex = $("#terminal-tabs .ui-tabs-nav li").length - 1;
  $("#terminal-tabs").tabs("add", "#tab-" + newTabIndex, "Tab " + newTabIndex);
});
</script>

(Note: I also understand that stackoverflow is not just a site where you could ask anything and expect an answer back, but I mostly do coding on a school pc since I dont have a working pc right now, and so I try to work with what I have. And yes, I have tried to do some research on this because google exists, but with my school's blocking system, there are alot of limitations.)

1

There are 1 answers

0
jcubic On BEST ANSWER

let count = 0;
terminal_tabs({
    echo(...args) {
       this.echo(args);
    }
}, {
    checkArity: false,
    greetings: 'This is really working'
});

function terminal_tabs(interpreter, option) {
    new_terminal(interpreter, option);
    $('.cloak').removeClass('cloak');

    $('.tabs').on('click', 'li.tab', function() {
        var li = $(this);
        tab_activate(this);
        return false;
    }).on('click', 'li.tab .close', function() {
        remove_tab(this);
        return false;
    }).on('click', 'li.new', () => new_terminal(interpreter, option));
    
}

function remove_tab(el) {
    el = $(el);
    const $li = el.closest('li');
    const $tabs = el.closest('.tabs');
    const index = $li.index();
    const $terminals = $tabs.find('.content > div');
    const $term = $terminals.eq(index).terminal();
    if ($terminals.length > 1 && $term.is('.active')) {
        const $other = $term.prev();
        if (!$other.length) {
            $other = $term.next();
        }
        const $new_li = $tabs.find('> ul li').eq($other.index());
        tab_activate($new_li);
    }
    $term.destroy().remove();
    $li.remove();
}

function tab_activate(li) {
    const $li = $(li);
    const index = $li.index();
    $li.addClass('active').siblings().removeClass('active');
    const $content = $li.closest('ul').next();
    const $tab = $content.children()
         .eq(index)
         .addClass('active');
    $tab.siblings()
        .removeClass('active');
}


function new_terminal(interpreter = $.noop, options = null, label = null) {
    const id = ++count;
    options = options ?? {
        greetings: `Welcome to jQuery Terminal, no: ${id}.\n`
    };
    const $term = $('<div/>').terminal(interpreter, options);
    label = options.label ?? `Terminal &lt;${id}&gt;`;
    const $li = $(`<li class="tab">
                   <a href="#">${label}</a>
                   <span class="close">&times</span>
                 </li>`);
    const $content = $('.tabs .content');
    if ($content.is(':empty')) {
        $li.add($term).addClass('active');
    }
    const $add = $('.tabs > ul li.new');
    $li.insertBefore($add);
    $content.append($term);
    tab_activate($li);
}
body {
    margin: 0;
    padding: 0;
    background: black;
}
:root {
    --size: 1.4;
    --color: #18B70A;
    --glow: 1;
}
.tabs.cloak {
    display: none;
}
body, html {
    height: 100%;
}
/* tabs */
.tabs {
    --gap: 10px;
    display: flex;
    flex-direction: column;
    --original-background: var(--backgroud, #000);
}
.tabs, .tabs .content > div {
    height: 100%;
}
.tabs > ul {
    list-style: none;
    margin: 0;
    padding: var(--gap, 10px) var(--gap, 10px) 0;
    font-family: var(--font, monospace);

}
.tabs > ul > li {
    border-color: var(--color, #aaa);
    border-radius: 3px 3px 0 0;
    border-style: solid;
    border-width: 1px 1px 0;
    cursor: pointer;
    display: inline-block;
    padding: 6px 14px;
    position: relative;
    text-align: center;
    font-size: calc(var(--size, 1) * 12px);
}
.tabs > ul > li > * {
    background: var(--background, #000);
    color: var(--color, #aaa);
    text-shadow: 0 0 calc(var(--glow) * 5px) var(--color, #ccc);
}
.tabs > ul > li .close, .tabs > ul > li.new a {
    display: inline-block;
    line-height: 0.9em;
    padding: 0 2px;
    border-radius: 50%;
}
.tabs > ul > li .close:hover, .tabs > ul > li.new a:hover {
    --background: var(--link-color, #3377FF);
    --color: var(--original-background, #000);
}
.tabs > ul > li + li {
    margin-left: var(--gap, 10px);
}
.tabs > ul > li a {
    text-decoration: none;
}
.tabs > ul > li.active::after {
    background-color: var(--background, #000);
    bottom: -1px;
    content: '';
    height: 1px;
    left: 0;
    position: absolute;
    width: 100%;
}
.tabs .content {
    border-top: solid 1px var(--color, #ccc);
    list-style: none;
    margin: 0;
    padding: 0;
    flex-grow: 1;
}
.tabs .content > :not(.active) {
    display: none;
}
<script src="https://cdn.jsdelivr.net/npm/jquery"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery.terminal/js/jquery.terminal.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/jquery.terminal/css/jquery.terminal.css" rel="stylesheet"/>
<div class="tabs cloak">
    <ul>
        <li class="new">
            <a href="#">+</a>
        </li>
    </ul>
    <div class="content"></div>
</div>