JS zaznaczanie wiersza w tabeli

0

Mam na stronie tabelę. W drugiej kolumnie ma pola typu radio. Dla wierszy mam ustawione podświetlanie wiersza pod kursorem oraz zaznaczanie radio buttona po kliknięciu na dany wiersz.

<tr onMouseOver="this.bgColor = \'#EEE\'" onMouseOut ="this.bgColor = \'#FFF\'" onClick ="document.list_form.radio_'.$wiersz['Id'].'.checked=true">

Jak zrobić by w momencie kliknięcia wiersz był zaznaczany (inny kolor tła) ale tak by całej tabeli mógł być zaznaczony tylko jeden wiersz? Po kliknięciu następnego, wcześniejszy by się odznaczał.

0

Może przed zaznaczeniem klikniętego wiersza przejechać się po wszystkich wierszach tabeli i poodznaczać każdy z nich?

0

To prosty skrypt, ale musisz znać podstawy JavaScriptu i DOM. Cały kod powinieneś napisać w zewnętrznym pliku .js, zamiast mieć JavaScript porozrzucany po atrybutach HTML-a.

Niech skrypty same się podepną do odpowiednich wierszy tabeli za pomocą metod DOM. Niech najechanie myszą na wiersz spowoduje dodanie do wiersza klasy (zjechanie myszą spowoduje usunięcie tej klasy). Potem w stylach CSS zdefiniujesz, że wiersze o tej klasie mają taki i taki kolor tła, a jeśli trzeba będzie zmienić wygląd zaznaczenia, to zmienisz tylko CSS.

Generalnie nie powinno się czyścić tego w ten sposób, że dodanie zaznaczenia dla jednego wiersza jest poprzedzane przeleceniem wszystkich wierszy po to, by usunąć z nich zaznaczenie. Ma to złożoność obliczeniową O(n), gdzie n jest liczbą wierszy w tabeli -- zupełnie niepotrzebnie.

Zamiast tego należy mieć zmienną, która pamiętałaby ostatnio zaznaczony wiersz. Zaznaczenie nowego wiersza wskazywanego przez zmienną aktualnieZaznaczanyWiersz wyglądałoby mniej więcej tak:
-Jeśli zmienna poprzednioZaznaczonyWiersz ma wartość prawdziwą, to usuń zaznaczenie z wiersza wskazywanego przez tą zmienną.
-Dodaj zaznaczenie do wiersza wskazywanego przez zmienną aktualnieZaznaczanyWiersz
-Ustaw poprzednioZaznaczonyWiersz na aktualnieZaznaczanyWiersz.
(można jeszcze dodać na początku warunek: jeśli aktualnieZaznaczanyWiersz == poprzednioZaznaczonyWiersz, to nie rób nic)
Ten algorytm ma złożoność O(1), tj. będzie działał tak samo szybko nawet jeśli liczba wierszy w tabeli wzrośnie dziesięciokrotnie.

0

Dzięki bswierczynski. Bardzo jasno nakreśliłeś mi sposób postępowania. Niestety na razie moja znajomość Javascript nie wystarcza napisania tak prostej rzeczy.

Odbiegając od tematu.. czy możecie mi polecić jakiś dobry kurs (lub książkę) do nauki Javascipt?

0

@AngelEyes:
Najlepsza książka, jaką znam, do nauki samego JĘZYKA JavaScript, to "JavaScript -- Mocne strony" (autor: Douglas Crockford). Ale tam nie ma za wiele praktycznych skryptów do wklejenia na stronę po ew. zmodyfikowaniu. Książka uczy wykorzystywać sprawnie JavaScript do napisania DOWOLNEGO algorytmu. Skupia się na jego funkcyjności i niespotykanym modelu obiektowym (dziedziczenie prototypowe, a nie klasyczne).

Książka do tego jest zwięzła, niedroga i dobrze napisana.

Musisz jednak chcieć faktycznie nauczyć się tego języka i musisz samemu umieć wymyślać algorytmy.

Do tego trzeba się koniecznie nauczyć DOM. DOM to (w tym kontekście) odwzorowanie dokumentu HTML widoczne z poziomu języka JavaScript. Dzięki DOM można wpływać na dokument z poziomu JavaScriptu, czyli np. dodawać elementy (takie jak wiersze tabeli, nagłówki, paragrafy...), usuwać je i modyfikować/odczytywać czy to ich zawartość, czy to atrybuty. DOM to dość kiepski i niezbyt wygodny w użyciu interfejs, ale to standard opisany przez konsorcjum W3C, zaimplementowany w wielu językach programowania. W przeglądarkowym JavaScripcie też.

W sumie ciężko mi jest odpowiedzieć na Twoje pytanie. Ja wiedzę z zakresu JavaScriptu z jednej strony zbierałem latami, a z drugiej strony ucząc się go tak naprawdę na poważnie znałem już wiele języków programowania (w tym również i coś funkcyjnego) i nawet miałem solidne podstawy z dziedziny definiowania języków formalnych (czyli: jak się tworzy języki programowania) i kompilatorów/interpreterów (czyli: w jaki sposób przeglądarka przetwarza JavaScript). Więc niemal od razu rozumiałem pewne w JavaScripcie na o wiele głębszym poziomie niż ktoś, kto jest początkującym programistą.

Jedno jest pewne: jest dużo źródeł, które są strasznie lipne. Nie tylko źródła w Internecie, ale również książki. Ja od jakiegoś czasu nie kupuję już raczej książek o JS, na pewno nie takich dla początkujących, bo nie są mi potrzebne.

Dobrą książką, którą przeczytałem o JS był "Kuloodporny Ajax" (Jeremy Keith). Cienka książka skupiająca się na Ajaxie, choć na początku jest małe wprowadzenie do języka JavaScript od samych podstaw. Ale jakość kodu w tej książce jest bardzo dobra, sam styl pisania i rozdzielenie warstw też jest bardzo fajnie przedstawione. Książka dość cienka.

Przyzwoita jest też "Ajax dla zaawansowanych. Architektura i najlepsze rozwiązania" (Shawn M. Lauriat). To już jest grubsza książka, niestety skupia się trochę na Ajaxie, choć wcale nie tylko. Zawiera sporo informacji o obsłudze zdarzeń, tzw. wzorcu Obserwator, choć nie jest to chyba napisane w książce explicite. Wzorzec ten jest w przypadku projektowania interfejsów bardzo ważny. Obsługi zdarzeń używasz nawet w pierwszym poście tego topicu, choć akurat atrybuty onclick są prymitywnym narzędziem (normalnie używa się raczej addEventListener).

To nie są idealne książki dla Ciebie. Po prostu je znam i wiem, że są przyzwoite.

Jeśli napiszesz jakieś źródła czy książki to -- o ile znajdę czas -- postaram się tam zajrzeć i sprawdzić, czy chociaż jakość kodu jest przyzwoita, bo nieraz znajduje się prawdziwe suchary uczące złych nawyków :/. Dlatego np. książka Keitha jest taka dobra: niby bardziej o Ajaxie, ale uczy również DOM i podzielenia kodu na warstwy: po jednej dla struktury dokumentu (HTML), jego sposobu prezentacji, czyli wyglądu (CSS) i jego dynamicznego zachowania (JavaScript). Np. chodzi o to, że w JavaScripcie generalnie nie powinieneś ustawiać bezpośrednio koloru wiersza, który ma być dynamicznie podświetlony. Lepiej nadać wierszowi klasę o nazwie np. "highlight", a potem w CSS napisać ".highlight td { background: #EDD; ".

Możesz poszukać też w necie wykładów Douglasa Crockforda. Są bardzo fajne, choć dotyczą również zaawansowanych (ale bardzo, bardzo, BARDZO przydatnych) części języka. Crockrord jest znany jako "dziad JavaScriptu"; jest zresztą współtwórcą specyfikacji języka. Nie szczędzi jednak JavaScriptowi oszczerstw i mówi wprost, że to i to jest błędem czy jest bez sensu i powinno być inaczej.

Jeśli chcesz pisać poważny kod, to musisz zdawać sobie sprawę, że JavaScript to nie są takie proste wstawki jak masz w pierwszym poście. Gdzie w bliżej nieokreślony sposób rzucasz słowem kluczowym this i łączysz je z innymi elementami na stronie za pomocą kropek, nie do końca wiedząc co tu się dzieje ;). JavaScript to normalny język programowania. Kod JS przechowujesz w osobnym pliku i wygląda to całkiem podobnie do kodu C, C++ czy PHP. Ja np. pisałem w JavaScripcie aplikacje na 5-10 tys. linii kodu, podzielonego na moduły i (pseudo)klasy.

0

Przepraszam że dopiero teraz odpowiadam (urlop).

Dzięki za polecenie książek. Dzisiaj próbowałem samodzielnie zrobić to zaznaczanie ale nie chce działać. Moja funkcja wygląda tak...

var previousMarkedRow = -1;

function selectRow(id) {
        document.getElementById("row" + id).className += " highlight";
        document.getElementById("row" + previousMarkedRow).className.replace(" highlight"," ");
        previousMarkedRow = id;
} 

Kolejne kliknięte wiersze się zaznaczają ale poprzednie nie chcą się odznaczać. Dlaczego?

0

@AngelEyes:
Wiesz co robi STR.replace(X, Y)? Zwraca nowy ciąg znaków, taki sam jak ciąg STR, ale z pierwszym wystąpieniem podciągu X zmienionym na Y (możesz użyć wyrażeń regularnych zamiast ciągu w przypadku X i dać im flagę g, dzięki czemu zamienione zostaną wszystkie wystąpienia pasujące do wyrażenia regularnego).

Funkcja replace NIE MA skutków ubocznych. W szczególności nie modyfikuje stringa STR -- ona tylko zwraca nowy, zmieniony string (a stary pozostawia bez zmian). Czyli tutaj nie zmieni łańcucha znaków będącego klasą danego elementu. Wywołanie className.replace zwróci Ci tylko ciąg znaków reprezentujący atrybut class elementu, ale bez klasy highlight. I to idzie w próżnię.

Jeśli chcesz zmienić jakiś string, to musisz zrobić coś w tym stylu:

str = str.replace('stare', 'nowe');
0

Nadal mi nie działa, próbowałem tak..

function selectRow(id) {
        document.getElementById("row" + id).className += " highlight";
        document.getElementById("row" + previousMarkedRow).className = document.getElementById("row" + previousMarkedRow).className.replace(" highlight"," ");
        previousMarkedRow = id;
} 

i tak..

function selectRow(id) {
        document.getElementById("row" + id).className += " highlight";
        document.getElementById("row" + previousMarkedRow).className = "unhighlight";
        previousMarkedRow = id;
} 

i nawet tak..

function selectRow(id) {
        document.getElementById("row" + id).className += " highlight";
        document.getElementById("row" + previousMarkedRow).className = "";
        previousMarkedRow = id;
} 
0

Naprawdę nikt nie zna rozwiązania mojego problemu?

0

Daj link do strony. Mógłbym podać w tym momencie kilka hipotez lub maksymalnie wgryzać się w te kilka linijek kodu, które tu zamieściłeś, ale mi się nie chce. Będzie efektywniej jak zerknę na (nie)działający kod ;).

0

Sprobuj tego:

<html>
<head>

<style type="text/css">
<!--
.highlight {
  background-color: #aaaaaa;
} 
-->
</style> 

<script type="text/javascript">

var selectedClass='highlight';
var selectedRow=null;
function selectRow(row){
         clearSelection();
         row.className += " "+selectedClass;
         selectedRow=row;
}
function clearSelection(){
        var reg = new RegExp('(\\s|^)'+selectedClass+'(\\s|$)');
        if(selectedRow!=null)  selectedRow.className=selectedRow.className.replace(reg,' ');
}


</script>

<title>Table</title>

</head>
<body>

 <table>
  <tr id="tr1" onClick="selectRow(this)"><td>1</td><td>2</td></tr>
  <tr id="tr2" onClick="selectRow(this)"><td>3</td><td>4</td></tr> 
  <tr id="tr3" onClick="selectRow(this)"><td>5</td><td>5</td></tr> 
  <tr id="tr4" onClick="selectRow(this)"><td>6</td><td>7</td></tr> 
</table>

</body>

</html> 

1 użytkowników online, w tym zalogowanych: 0, gości: 1