Praktyczne wprowadzenie do JavaScript #11

Pozostawiliśmy po sobie z poprzedniego odcinka skromny formularz, który może pochwalić się walidacją danych (równie skromną) oraz licznikiem wpisanych znaków w polu Treść. Dzisiaj poeksperymentujemy trochę właśnie z tym ostatnim, dodając funkcjonalność podobną na przykład do serwisu sms Orange – http://sms.orange.pl.

Screencast z tego odcinka znajdziecie tutaj.

Chodzi głównie o zabezpieczenie przed wpisaniem nadmiernej ilości znaków. Ustawimy więc na początek limit znaków, po każdym wpisaniu czegoś w formularz policzymy ich liczbę i odejmiemy ją od limitu. Jeśli różnica będzie ujemna, czyli wpiszemy za wiele, wyświetli nam się ostrzeżenie, a wartość formularza wróci do stanu przed przekroczeniem naszego limitu.

Na początek przypomnijmy sobie, jakim dokumentem HTML dysponujemy w tej chwili:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="pl-PL">
<head>
<title>Strona z formularzem</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />

<style type="text/css">

label
{
	display: block;
	margin: 2px;
}

</style>

<!-- Nasz kod Javascript: -->

<script type="text/javascript">
window.onload = Laduj;

function Laduj()
{
	document.forms['dodawanie_posta'].onsubmit = Verify;
	document.forms['dodawanie_posta'].content.onkeyup = Licz; 
}

function Licz()
{
	var odnosnik = document.getElementById('licznik_znakow');
	var liczba_znakow = document.forms['dodawanie_posta'].content.value.length;

	odnosnik.innerHTML = "Liczba wpisanych znaków:"+liczba_znakow;

}

function Verify()
{
	var nick = document.forms['dodawanie_posta'].nick.value;
	var content = document.forms['dodawanie_posta'].content.value;
	var error = false;

	if (nick == "")
	{
		document.forms['dodawanie_posta'].nick.style.border = "2px solid #FF0000";
		alert('Nie wypełniłeś pola z nickiem!');
		error = true;

	}
	else
	{
		document.forms['dodawanie_posta'].nick.style.border = "1px solid #000000"; 
	}
		
		
	if (content == "")
	{
		document.forms['dodawanie_posta'].content.style.border = "2px solid #FF0000";
		alert('Nie wypełniłeś pola z treścią!');
		error = true;
	}
	else
	{
		document.forms['dodawanie_posta'].content.style.border = "1px solid #000000";
	}
		

	if (error)
	{
		return false;
	}

}
</script>
</head>
<body>
	<form method="post" action="" name="dodawanie_posta">
			<label>Nick: <input type="text" name="nick" value="" /></label>
			<label>Tresc <textarea name="content" rows="5" cols="20"></textarea>
			<div id="licznik_znakow"></div> <!-- o tutaj -->
			</label>
			<input type="submit" value="dodaj" />
	</form>
</body>
</html>

Z tego, co widzimy powyżej, wiemy już, że po wpisaniu jakiegokolwiek znaku z klawiatury w polu Treść, wykona się funkcja Licz. Ta z kolei odpowiedzialna jest za policzenie wszystkich znaków z wspomnianego elementu formularza. Ich liczbę pokazuje w <div id=”licznik_znakow”></div>.

Funkcja musi wiedzieć, jaki jest limit znaków. Przedstawmy go w postaci zmiennej o nazwie, dajmy na to, limit. Musimy teraz postanowić, jaką wartość mieć będzie ta zmienna, czyli ile znaków będzie można wpisać w pole Treść. Powiedzmy, że będzie to 500 znaków. Czas teraz na uzupełnienie funkcji Licz rzeczoną zmienną:


function Licz()
{
	var limit = 500;
	// pozostala część funkcji

W ten sposób, funkcja Licz ma dostęp do wartości zmiennej o nazwie limit. Gdybyśmy jednak chcieli, aby wszystkie funkcje w skrypcie mogły z niej korzystać, należy tą zmienną zdefiniować poza kodem funkcji, czyli tam, gdzie mamy np. window.onload = Laduj;. Wyglądałoby to tak:


<script type="text/javascript">
window.onload = Laduj;
var limit = 500;

Warto zobaczyć działanie tej właściwości na przykładzie oderwanym od kontekstu:


	var liczba = 2;

	function PokazLiczbe()
	{
		alert(liczba);
	}

	function PokazLiczbe2()
	{
		alert(liczba);
	}

	PokazLiczbe();
	PokazLiczbe2();

W powyższym kodzie mamy dwie funkcje: PokazLiczbe i PokazLiczbe2, które wyświetlają w okienku alert(); zawartość zmiennej liczba. Warto zauważyć, że zdefiniowaliśmy ją poza ciałem obu funkcji. Mimo wszystko, będą one mieć do niej dostęp i wyświetli się w obu przypadkach wartość 2. To dlatego, że zdefiniowaliśmy tę zmienną poza ciałem funkcji.

W tym przypadku będzie już jednak inaczej:


	function PokazLiczbe()
	{
		var liczba = 2;
		alert(liczba);
	}

	function PokazLiczbe2()
	{
		alert(liczba);
	}

	PokazLiczbe();
	PokazLiczbe2();

Tutaj zdefiniowaliśmy zmienną liczba (var liczba = 2;) w ciele funkcji PokazLiczbe. Efekt jest taki, że za pierwszym razem ujrzymy okienko z liczbą dwa (właśnie po wywołaniu funkcji PokazLiczbe). W drugim przypadku, kiedy wywołamy funkcję PokazLiczbe2, która także chce wyświetlić wartość zmiennej liczba, ujrzymy błąd. Funkcja ta bowiem nie ma dostępu do tej zmiennej, która zdefiniowana jest tylko dla funkcji PokazLiczbe.

Wracając do naszego przykładu. Kiedy wpiszemy cokolwiek w pole Treść, wywołuje się funkcja Licz. Jako że chcemy uzyskać liczbę znaków, jaka pozostała do wyczerpania limitu, logika nakazuje odjąć od limitu liczbę znaków, które już wpisaliśmy. Liczbę tą mamy zapisaną dzięki tej konstrukcji: var liczba_znakow = document.forms[‚dodawanie_posta’].content.value.length;. Mamy także limit znaków (pod zmienną limit), więc pora wykonać odejmowanie. Wartość tego działania zapiszemy do nowej zmiennej – niech to będzie zmienna o nazwie reszta.


function Licz()
{
	var limit = 500;
	var odnosnik = document.getElementById('licznik_znakow');
	var liczba_znakow = document.forms['dodawanie_posta'].content.value.length;
	
	var reszta = limit - liczba_znakow;

Wspomniane działanie zapisaliśmy w tym miejscu:


	var reszta = limit - liczba_znakow;

Takim oto sposobem, otrzymaliśmy ilość znaków, jaka została do wykorzystania w naszym polu formularza. Teraz pozostaje nam sprawdzenie jej wartości. Musimy bowiem zablokować wpisywanie do formularza, kiedy reszta będzie ujemna i przywrócić wartość pola Treść przed wpisaniem 501. znaku. Jeśli jednak reszta będzie dodatnia, czyli możliwe będzie wpisanie czegokolwiek, musimy wyświetlić, ile znaków pozostało nam jeszcze do wykorzystania. Użyjemy tutaj stary, dobry warunek if, by sprawdzić naszą wartość reszty:


function Licz()
{
	var limit = 500;
	var odnosnik = document.getElementById('licznik_znakow');
	var liczba_znakow = document.forms['dodawanie_posta'].content.value.length;
	
	var reszta = limit - liczba_znakow;

	if (reszta < 0)
	{
		
	}
	else
	{
		
	}

}

Konkretnie dodaliśmy to:


	if (reszta < 0)
	{
		
	}
	else
	{
		
	}

To, co zrobimy teraz z tym fragmentem, przetłumaczyć można następująco:

Jeśli zmienna reszta będzie mniejsza od zera (czyli zostanie przekroczony limit), wyświetl ostrzeżenie o przekroczeniu limitu znaków oraz usuń z formularza znaki, poprzez wpisanie których został przekroczony limit.

W przeciwnym razie, kiedy zmienna reszta nie będzie nieujemna, pokaż, ile znaków zostało do wykorzystania, czyli wyświetl wartość zmiennej reszta.

Pora więc dodać określone właściwości po kolei. Najpierw ostrzeżenie o przekroczeniu limitu:


	if (reszta < 0)
	{
		alert('Wpisałeś za dużo znaków!');
zmienna.substring(x, y);

Funkcja .substring pozwala nam wyciąć fragment z wartości zmienna, poczynając od znaku x aż do y, licząc kolejne znaki od zera. zmienna musi być ciągiem znaków np. "Moherowy beret 1337" lub "234421" i tak dalej. Inaczej funkcja zwróci błąd.

Jeśli przekroczyliśmy limit wpisanych znaków, to naturalnie, w naszym textarea znajduje się ich więcej, aniżeli wynosi limit. Na przykład 501. Jako że w tym polu formularza nie może być więcej znaków, niż wynosi limit, trzeba odjąć tyle znaków, o ile został przekroczony limit. Jednym słowem, należy pozostawić tylko 500 znaków. Pomoże nam w tym funkcja substring, która potrafi wyciąć liczbę znaków z konkretnego ich ciągu. Dzięki niej można np. wyciąć fragment wyrazu od 3 do 6 znaku, licząc od zera oczywiście, o czym już wspominałem. Zobaczmy, jak substring operuje na prostym przykładzie: wytnijmy bowiem z wyrazu Barbara pierwsze trzy litery, czyli znaki od pierwszego do trzeciego, czyli wyraz Bar.


	var slowo = "Barbara";

	alert(slowo.substring(0, 3));

W ten sposób ujrzymy w okienku słówko Bar.

Stosując substring w naszym przykładzie, otrzymamy następujący kod:


	if (reszta < 0)
	{
		alert('Wpisałeś za dużo znaków!');
		document.forms['dodawanie_posta'].content.value = document.forms['dodawanie_posta'].content.value.substring(0, 500);
	}

Dodaliśmy ten fragment:


		document.forms['dodawanie_posta'].content.value = document.forms['dodawanie_posta'].content.value.substring(0, 500);

W ten oto sposób, ustawiamy wartość pola textarea o name="content" na 500 pierwszych znaków, które wpisaliśmy do tej pory w te właśnie pole. Jako że zmienna limit ma wartość 500, możemy podstawić ją do substring. Otrzymamy coś takiego:


		document.forms['dodawanie_posta'].content.value = document.forms['dodawanie_posta'].content.value.substring(0, limit);

Wyjdzie na to samo.

Pora teraz zająć się sytuacją, kiedy limit nie zostanie przekroczony. Uzupełnijmy więc konstrukcję else o kod, wyświetlający ile znaków zostało do wyczerpania limitu. Ilość tychże znaków mamy już, dzięki różnicy, której wynik zapisaliśmy do zmiennej reszta.

function Licz()
{
	var limit = 500;
	var odnosnik = document.getElementById('licznik_znakow');
	var liczba_znakow = document.forms['dodawanie_posta'].content.value.length;
	
	var reszta = limit - liczba_znakow;

	if (reszta < 0)
	{
		alert('Wpisałeś za dużo znaków!');
		document.forms['dodawanie_posta'].content.value = document.forms['dodawanie_posta'].content.value.substring(0, limit);
	}
	else
	{
		odnosnik.innerHTML = "Pozostało " +reszta+ " znaków";
	}

}

Dodaliśmy to:


odnosnik.innerHTML = "Pozostało " +reszta+ " znaków";

Dzięki temu, wartość diva, którego odnośnik pobraliśmy do zmiennej odnosnik, ma wartość Pozostało x znaków, gdzie x to zawartość naszej zmiennej o nazwie reszta. Aby ją wyświetlić, otoczyliśmy ją dwoma plusami i cudzysłowami. Tak wplata się zmienne pomiędzy ciągi znaków, np.:


	var slowo = "Barbara";

	var zdanie = "Imię" +slowo+ " jest brzydkie";
	alert(zdanie);

wyświetli nam Imię Barbara jest brzydkie.

I tak, doszliśmy do szczęśliwego finału. Nasz dokument wygląda tak:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="pl-PL">
<head>
<title>Strona z formularzem</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />

<style type="text/css">

label
{
	display: block;
	margin: 2px;
}

</style>

<!-- Nasz kod Javascript: -->

<script type="text/javascript">
window.onload = Laduj;

function Laduj()
{
	document.forms['dodawanie_posta'].onsubmit = Verify;
	document.forms['dodawanie_posta'].content.onkeyup = Licz; 
}

function Licz()
{
	var limit = 500;
	var odnosnik = document.getElementById('licznik_znakow');
	var liczba_znakow = document.forms['dodawanie_posta'].content.value.length;
	
	var reszta = limit - liczba_znakow;

	if (reszta < 0)
	{
		alert('Wpisałeś za dużo znaków!');
		document.forms['dodawanie_posta'].content.value = document.forms['dodawanie_posta'].content.value.substring(0, limit);
	}
	else
	{
		odnosnik.innerHTML = "Pozostało " +reszta+ " znaków";
	}

}

function Verify()
{
	var nick = document.forms['dodawanie_posta'].nick.value;
	var content = document.forms['dodawanie_posta'].content.value;
	var error = false;

	if (nick == "")
	{
		document.forms['dodawanie_posta'].nick.style.border = "2px solid #FF0000";
		alert('Nie wypełniłeś pola z nickiem!');
		error = true;

	}
	else
	{
		document.forms['dodawanie_posta'].nick.style.border = "1px solid #000000"; 
	}
		
		
	if (content == "")
	{
		document.forms['dodawanie_posta'].content.style.border = "2px solid #FF0000";
		alert('Nie wypełniłeś pola z treścią!');
		error = true;
	}
	else
	{
		document.forms['dodawanie_posta'].content.style.border = "1px solid #000000";
	}
		

	if (error)
	{
		return false;
	}

}
</script>
</head>
<body>
	<form method="post" action="" name="dodawanie_posta">
			<label>Nick: <input type="text" name="nick" value="" /></label>
			<label>Tresc <textarea name="content" rows="5" cols="20"></textarea>
			<div id="licznik_znakow"></div> <!-- o tutaj -->
			</label>
			<input type="submit" value="dodaj" />
	</form>
</body>
</html>

Tym sposobem mamy działający formularz z limitem znaków na polu textarea.

Komentarze

1

[…] że dostępny jest już screencast do jedenastego odcinka Praktycznego wprowadzenia do JavaScript. Post informacyjny, zostanie usunięty za parę dni… […]

2

Witam, i dzieki za dobrą robotę, jednakże wydaje mi się, że w przypadku omawianym powyżej do textarea będzie wpisywane 501 znaków:
[‚dodawanie_posta’].content.value.substring(0, limit);
przy var limit = 500;
Pozdrowienia
jzk

jzk
3

Nie, bedzie ich 500…

4

Za to ja znalazlem inny problem…
W przypadku gdy wkleimy jakis ciag znakow i przekroczy on limit, to wyswietli nam sie komunikat, tekst zostanie obciety, ale wyswietlany limit bedzie niepoprawny (rozny od 0).
Poza tym, bardzo fajny kurs. Przeczytalem dzisiaj juz nascie odcinkow i mam nadzieje, ze jeszcze dzisiaj dobrne do konca.
Pozdrawiam

jozek000
5

Oczywiście najprostszym rozwiązaniem limit określić bezpośrednio w textarea np.

Jeśli nawet chcemy zmienić ten limit to możemy korzystać z dostaniem się do tej właściwości przez JavaScript, ale takie rozwiązanie raczej nie ma sensu ;]

Oczywiście zdaję sobie sprawę, że zabieg ten został tu wprowadzony po to, aby pokazać elementy JS :)

Pozdrawiam,
ktos

P.S. Bardzo fajny kursik z fajnymi przykładami :)

ktos
6

witam!

Bardzo przydatna funkcja – mam tylko jedno pytanie z nia zwiazane:

Co zrobic aby limit znakow do wpisania wyswietlas sie od razu po otwarciu skryptu a nie po wpisaniu pierwszego znaku?

Czy dodanie funkcji Reszta do window.onload rozwiaze sprawe?

P.S bardzo fajny kursik.

Piotr
7

Helllo! to znów ja, „wynalazłem” sposób na rozwikłanie mojego problemu, mianowicie:

Dodanie funkcji licz do window.onload nie rozwiązało by sprawy a nawet popsuło działanie skryptu- ponieważ funkcja Licz została by wykonana tylko raz.( przynajmniej tak mi się wydaje!:p )

Rozwiązałem mój problem bardziej łopatologiczne ale nie jestem do końca pewien czy poprawnie.

Wprowadziłem zmianę w kodzie HTML:

Pozostało 500 znaków

Wartość (a właściwie zdanie) ta wyświetlana jest przy otwarciu strony a później przy pomocy funkcji Licz zamieniana jest na wartość właściwa.

Skrypt funkcjonuje, ale nie jestem przekonany do końca o poprawności tego zastosowanie.

Moze jakaś podpowiedz jak to zrobić wykorzystaj możliwości komputera?;>

Piotr
8

nie wiem jak dokładnie zrealizowałeś ten drugi sposób ale według mnie ta pierwsza opcja byłaby najbardziej odpowiednia i chyba najprostsza :) chodzi mi tu o umieszczenie Licz () w funkcji Laduj :)

function Laduj(){
document.forms['dodawanie_posta'].onsubmit = Verify;
document.forms['dodawanie_posta'].content.onkeyup = Licz;
Licz ();
}

funkcja Licz () zostanie wykonana kiedy załaduje się cały dokument (zostanie dodane zdanie: Pozostało 500 znaków ) a reszta kodu bez zmian.

Raphy
9

Jako ciekawostkę dla ambitnych proponowałbym użyć funkcji onkeydown, zamiast onkeyup :) Efekt jest jeszcze bardziej interesujący ;)

Karlitto
10

Niestety nasz walidacja ma dwie wady, w polach nick i treść można wpisać same spacje i taki komentarz zostanie zatwierdzony. Limit znaków też łatwo obejść, wystarczy zamiast wpisywania tekstu zrobi „kopiuj/wklej” za pomocą myszy. Przy okazji chciałbym dodać, że jest to najlepszy kurs JS jaki spotkałem, trochę zbyt łopatologiczny, ale mimo wszystko wielkie brawa dla Autora

Logan
11

W kwestii formalnej ;-).

W poniższym zdaniu wydaje mi się, że jest błąd logiczny.

„W przeciwnym razie, kiedy zmienna reszta nie będzie nieujemna, pokaż, ile znaków zostało do wykorzystania, czyli wyświetl wartość zmiennej reszta.”

powinno być: „(…)zmienna reszta nie będzie ujemna(…)”,
lub „(…)zmienna reszta będzie nieujemna(…)”.

Inaczej wpadamy w warunek pierwszy czyli zmienna < 0.
Pozdrawiam

fantoom
12

Usually I really don’t read through publish about blogs, even so would like to claim that this kind of write-up quite pushed my family you need to do it! Your own crafting flavour have been amazed everyone. Many thanks, very good report.

Dodaj komentarz

Dozwolone tagi: <blockquote>, <code>, <strong>