skracanie formularzy + java script

Długie formularze, podzielone na kilka sekcji ciągnące się w dół strony, nie są zbyt czytelne. Formularz taki można zmodyfikować dzieląć go na klikalne etapy lub wizualne zakładki. Ale jeżeli mamy wiele takich formularzy napisanych na dodatek w samym HTML’u ?

widok normalny

Możemy to sobie uprościć za pomocą JavaScript. Odpowiednia funkcja wywołana po załadowaniu się strony [body onLoad="funkcja();"] może wyszukać sekcje naszego formularza i zwinąć je do ciekawszych wizualnie zakładek.

widok z zakładkami

Żeby funkcja wiedziała co jest sekcją, należy je odpowiednio oznaczyć np. poprzez odpowiednią klasę CSS ‘subpanel’

Druga ważna rzecz, skrypt musi wiedzieć jak nazwać zakładki. Do tego wykorzystałem atrybut title. Nasz kod wygląda teraz tak:

<div class="subpanel" title="zakładka 1">
    <h2>sekcja 1</h2>
</div>
<div class="subpanel" title="zakładka 2">
    <h2>sekcja 2</h2>
</div>

Teraz za pomocą JavaScript możemy odnaleźć wszystkie znaczniki DIV.

if (!document.getElementsByTagName
    || !document.createElement
    || !document.appendChild) return;

/* pobieramy wszystkie div'y */
var divs = document.getElementsByTagName("div");

Następnie przygotowywujemy dodatkowy element DIV, w którym umieścimy stworzone zakładki.

/*  nr. pierwszego div'a z klasą subpanel */
var firstDiv = -1;

/* tworzymy div na nasze menu */
var menu = document.createElement("div");
menu.className = "panels_menu";
menu.setAttribute("id","panels_menu");

Pozostaje nam przejść się pętlą po wszystkich znalezionych DIV‘ach i wybrać te, które posiadają klasę ‘subpanel’. Z każdego z nich pobieramy wartość atrybutu title i naszym ‘menu’ tworzymy odpowiedni odnośnik:

var source = divs[i].getAttribute("title");
if (!source) continue;
var link = document.createElement("a");
link.setAttribute("href","#"+source);
link.setAttribute("onclick","activMenu(this); ");
link.onclick = new Function('activMenu(this);'); // dla IE
link.setAttribute("id","menu_"+divs[i].id); // dla wywołań zewnętrznych
link.appendChild(document.createTextNode(source));

Aktywujemy pierwszą naszą zakładkę i dodajemy je do naszego nowego menu:

if(firstDiv == -1) firstDiv = i;
if(i == firstDiv) {
    divs[i].style.display='block';
    link.setAttribute('class','active');
}
/* dodajemy odnośnik do menu */
menu.appendChild(link);
link.className = "active"; // dla IE

A po zakończeniu całej pętli wklejamy nasze zakładki przed pierwszego DIV‘a z klasą ‘subpanel’:

/* wklejamy stworzone menu nad pierwszym div'em */
divs[firstDiv].parentNode.insertBefore(menu,divs[firstDiv]);

Tyle w temacie stworzenia zakładek. Pozostaje nam stworzyć funkcję activeMenu(this), którą wywołujemy po kliknięciu w odpowiednią zakładkę.

function activMenu(menu) {
  menubox = document.getElementById('panels_menu');
  links = menubox.childNodes;

  /* ustalamy clasę 'active' dla naszego
    odnośnika, a reszcie null */
  for(x=0;x<links.length; x++) {
    if(links[x].nodeName.indexOf('A') != -1) {
      links[x].className=null;
    }
  }
  menu.className='active';
  menu.blur();


  var divs = document.getElementsByTagName("div");
  /* chowamy wszystkie div'y prócz aktualnego */
  for (var i=0; i<divs.length; i++) {
    if(divs[i].className == 'subpanel') {
      if(divs[i].getAttribute("title") == menu.innerHTML) {
        divs[i].style.display = 'block';
      } else {
         divs[i].style.display = 'none';
      }
    }
  }
  return false;
}

Całość zwieńcza drobny CSS:

.panels_menu a {
        color: #eee;
        text-decoration: none;
        background: #666;
        padding: 0px 5px;
        margin: 0px 2px;
        border: solid 1px #333;
     }
    .panels_menu a:hover {
        background: #ccc;
        color: #f33;
        border-bottom: solid 1px #ccc;
    }
    .panels_menu a.active {
        background: #eee;
        color: #333;
        border-bottom: solid 1px #eee;
    }
    .subpanel {
                border: solid 1px #333;
        padding: 10px;
        margin: 0 0 10px;
    }

Wystarczy teraz do <body> dodać onLoad=”preparePanels()” i to już wszystko.

Poniżej jest pełen kod funkcji preparePanels():

function preparePanels() {
  if (!document.getElementsByTagName
    || !document.createElement
    || !document.appendChild) return;
  /* pobieramy wszystkie div'y */
  var divs = document.getElementsByTagName("div");

  /* nr. pierwsze div'a z klasą subpanel */
  var firstDiv = -1;

  /* tworzymy div na nasze menu */
  var menu = document.createElement("div");
  menu.className = "panels_menu";
  menu.setAttribute("id","panels_menu");

  for (var i=0; i<divs.length; i++) {
    /* jeśli klasa div'a to subpanel to: */
    if(divs[i].className == 'subpanel') {
      if(firstDiv == -1) firstDiv = i;

      /* sprawdzamy istnienie atrybutu 'title' */
      var source = divs[i].getAttribute("title");
      if (!source) continue;

      /* chowamy div'a */
      divs[i].style.display='none';

      /* tworzymi odnośnik do div'a w naszym menu */
      var link = document.createElement("a");
      link.setAttribute("href","#"+source);
      link.setAttribute("onclick","activMenu(this); ");
      link.appendChild(document.createTextNode(source));

      /* jeśli div jest pierwszym to go aktywujemy */
      if(i == firstDiv) {
        divs[i].style.display='block';
        link.setAttribute('class','active');
      }

      /* dodajemy odnośnik do menu */
      menu.appendChild(link);

    }
  }
  /* wklejamy stworzone menu nad pierwszym div'em */
  divs[firstDiv].parentNode.insertBefore(menu,divs[firstDiv]);
}

Działający przykład znajduje się tutaj. Odnośniki w lewym górnym rogu strony uruchamiają wersję kolejno z i bez preparePanels().

Jeżeli komuś się ta wiedza przyda, to miło mi będzie :)

Share and Enjoy:
  • del.icio.us
  • Twitter
  • Wykop
  • Digg
  • Facebook
  • LinkedIn
  • Google Bookmarks
  • email
  • StumbleUpon
  • MySpace

14 Comments to “skracanie formularzy + java script”

  1. Mariusz 20 lutego 2006 at 18:41 #

    Super, ale chyba nie działa pod IE.

  2. Marek 21 lutego 2006 at 08:01 #

    Znalazłem rozwiązanie dla IE.
    Ma on problem z link.setAttribute(‘onclick’, ‘funkcja’);

    Dla IE działa konkstrukcja:
    link.onclick = new Function(‘funkcja’);

  3. Mariusz 21 lutego 2006 at 20:03 #

    No to teraz rewelacja. Czekam na kolejne. Pozdr,

  4. Sad 30 marca 2006 at 10:53 #

    Bardzo fajny skrypt!
    Można jakoś wywołać daną zakładke akcją?
    Mam formularz na jeden z zakładek i chciałbym, zeby do niej wracał.

  5. Marek 30 marca 2006 at 11:18 #

    Przydatny ficzer.

    Zaktualizowałem skrypt aby takie wywołania było możliwe. W przykładzie jest wszystko podane, no i trzeba jeszcze raz pobrać skrypcik nowy.

    :) pozdrawiam.

  6. Sad 30 marca 2006 at 13:01 #

    Wielkie dzięki! :)
    Na prawde przydatny skrypcik.
    A gdzie paypal albo numer konta bankowego, co by w złocie podziękować?

  7. Sad 30 marca 2006 at 13:15 #

    Ja coś zle robie czy nie da się wywołać przez –

    activMenu(document.getElementById\’add_news’));”;
    ? :)

  8. Marek 30 marca 2006 at 13:19 #

    Musi być
    activMenu(document.getElementById(‘menu_add_news’));

    w dokumenie nie może być dwóch elementów o tym samym ID, więc ID dla menu rozpoczynają się od ‘menu_’, po którym następuje ID odpowiedniego DIV’a.

  9. Sad 30 marca 2006 at 13:22 #

    A da sie to tak wywołać po prostu wtrącajac nagłówek javascript? – bez akcji onClick

  10. Sad 31 marca 2006 at 07:09 #

    Znasz może odpowiedz na moje poprzednie pytanie (oczekujace na zatwierdzenie)?
    Ponaglam pytanie o konto bankowe, co byś moje zdrowie wypił :)

  11. Marek 31 marca 2006 at 07:52 #

    Zakładki tworzone są PO wczytaniu całej strony (<body onLoad=”preparePanels()”>). Więc kod wstawiony w treści strony nie może się do nich dostać, gdyż jeszcze nie istnieją.

    Najlepiej wrzucić to co ma się wykonać do swojego skryptu .js i wywołać po preparePanels() jako <body onLoad=”preparePanels();twojaFunkcja();”>

  12. Sad 31 marca 2006 at 11:23 #

    Mam pomysł na taki ficzer – możliwość umieszczenia zakładki [danej] na prawa strone. :)

  13. Marek 31 marca 2006 at 11:37 #

    Jak masz jabbera to JID:onjinx@chrome.pl lub ostatecznie gadu GG:4585264 . Będzie łatwiej nam pogadać :) dziś do 18-tej jestem on-line.

  14. [...] Skrypt skracający formularze stworzył onjin, tutaj znajduje się działający przykład. Funkcja preparePanels z pliku opanels.js odnajduje wszystkie elementy DIV przypisane do klasy CSS subpanel. Pobiera wartość ich atrybutu title jako nazwy zakładek. Następnie ukrywa wszystkie takie DIV’y oprócz pierwszego i wyświetla nad nim stworzone zakładki. [...]


Leave a Reply