Skocz do zawartości

Zdjęcie
* * * * * 2 głosy

[poradnik] Jak stworzyć formularz AJAXowy z filtrem anty-bot

javascript html php jQuery ajax

15 odpowiedzi w tym temacie
  • Zaloguj się, aby dodać odpowiedź
unbreak

    WT Elite

  • 1936 postów
    • Czas spędzony online: 27d 8h 38m 23s
506
Znakomita!
  • Location/home/unbreak

Napisano 26 styczeń 2014 - 13:49

#1

W tym poradniku pokażę jak stworzyć prosty formularz kontaktowy, obsługiwany ajaxem, czyli bez konieczności przeładowywania strony.
 
Zaczniemy od htmla, przedstawiam najprostszy formularz chyba z możliwych:
HTML (index.html)

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"> 
	
	<title>AJAX FORM</title>
	<script src="//code.jquery.com/jquery-1.10.2.min.js"></script>
	<script src="js.js"></script>
	<style>
		.error{color:#f00;border:1px solid #f00;}
	</style>
</head>
<body>
	<form id="actionForm" action="send.php" method="post">
	Imię: <input type="text" name="name" id="name" placeholder="Podaj swoje imię" /><br />
	Temat: <input type="text" name="subject" id="subject" placeholder="Podaj temat kontaktu" /><br />
	Wiadomość: <textarea name="message" placeholder="Wpisz wiadomość"></textarea><br />
        Czy lew jest psem czy kotem? <input type="text" name="question" placeholder="Odpowiedz na pytanie" /><br />
	<button type="submit">Wyślij</button>
	</form>
</body>
</html>

 
Teraz w php odbierzemy informacje przesłane z formularza:
PHP (send.php)

<?php 
//zapisujemy otrzymane wartości do zmiennych
$name = isset($_POST['name']) ? $_POST['name'] : '';
$subject = isset($_POST['subject']) ? $_POST['subject'] : '';
$message = isset($_POST['message']) ? $_POST['message'] : '';
$question= isset($_POST['question']) ? $_POST['question'] : '';

//na wstepie sprawdzamy czy formularz nie zostal wypelniony przez bota:
if( !in_array(strtolower($question),array('kot','kotem') ) ){
	echo json_encode(array('status'=>false,'errors'=>array('question'),'msg'=>"Ty bocie ty!"));
    exit;
}

//przygotowujemy sobie zmienne do zwrocenia
$status = true;
$error = array();
$msg = 'Dziękujemy zapraszamy ponownie';

//tutaj robimy walidację jaką chcemy, ja upewniam się że pole 'name' składa się z przynajmniej 3 znaków i składa się jedynie z liter, liczb, spacji oraz '-'
if( !preg_match("/^([a-zA-z0-9 -]{3,})$/",$name) ){
	//w przypadku niepoprawnego pola ustawiamy status na false i do tablicy $error dodajemy name pola z bledem
	$status = false;
	$error[] = 'name';
}

//tutaj upewniam się ze tytul nie jest pusty
if( !preg_match("/^(.+)$/",$subject) ){
	//w przypadku niepoprawnego pola ustawiamy status na false i do tablicy $error dodajemy name pola z bledem
	$status = false;
	$error[] = 'subject';
}

//tutaj upewniam się ze wiadomosc ma przynajmniej 10 znaków
if( !preg_match("/^((.*){10,})$/",$message) ){
	//w przypadku niepoprawnego pola ustawiamy status na false i do tablicy $error dodajemy name pola z bledem
	$status = false;
	$error[] = 'message';
}

//jeżeli wystąpił jakiś błąd zmieniamy komunikat
if( !$status ){

	$msg = "Proszę wypełnić formularz poprawnie";

}else{
	
	//tutaj robimy co chcemy robić w przypadku poprawnych danych, np zapisujemy do bazy, wysyłamy maila, etc.
	//możemy tu też sprawdzać czy docelowa akcja się powiedzie i jeżeli nie to zmieniamy status na false i msg na konkretną informacę

}

//wyświetlamy wynik całej operacji jako json
echo json_encode(array('status'=>$status,'errors'=>$error,'msg'=>$msg));
exit;

 
Jeżeli teraz wysłalibyśmy taki formularz to strona by się przeładowała do pliku send.php i otrzymalibyśmy goły json z wynikami operacji. Żeby to zmienić potrzebny nam jest odpowiedni skrypt JavaScript (musimy mieć załączoną bibliotekę jquery).
JAVASCRIPT (js.js)

$(document).ready(function(){
	$("form#actionForm").submit(function(e){
		e.preventDefault(); //
		var form = $(this);
		$.post(
			form.attr('action'),
			form.serialize(),
			function(r){
				if( r.status ){
					form.html(r.msg);
				}else{
					alert(r.msg);
					form.find('.error').removeClass('error');
					for( var i=0;i<r.errors.length;i++ ){
						var name = r.errors[i];
						form.find('input[name="'+name+'"],textarea[name="'+name+'"]').addClass('error');
					}
				}
				
				return;
			},
			'json'
		);
	});
});

Przeanalizujmy źródło js:
3: e.preventDefault() - dzięki tej linijce formularz się nie wyśle standardową akcją
5: $.post -  wysyłamy formularz za pomocą AJAXA, requestem POST (można użyć $.get)
6: form.attr('action') - ustawiamy cel wysłania formularza na taki jaki jest w htmlu ustawiony action
7: form.serialize() - przetwarzamy wartosci wszystkich pol formularza na stringa i przekazujemy je do skryptu php
8: function® - jako parametr callback-u (funkcji wywołanej po otrzymaniu odpowiedzi od serwera) podajemy odpowiedź serwera
9: if( r.status ) - sprawdzamy czy w ospowiedzi jest ustawiona wartość status na true
10: form.html(r.msg) -  jeżeli powyższe tak to wyświetlamy w miejsce formularza podziękowanie
jeżeli powyższe nie to:
12: alert(r.msg) - wyświetlamy błąd
13: form.find('.error').removeClass('error') - usuwamy wszystkim elementom formularza klasę 'error'
14-17: for(...){ ... } - przelatujemy przez wszystkie błedy i błędnym polom ustawiamy klasę error - za mocą css wyrózniamy te pola
22: 'json' - jako ostatni parametr funkcji post podajemy typ danych jakie otrzmyamy od serwera
 
DEMO: http://web-talk.pl/demo/933-formularz/

DOWNLOAD: Załączony plik  formularz.zip   4,45 KB   0 Ilość pobrań
Jeżeli masz jakieś propozycje zmian lub rozbudowy, czekam na informację.
 

Poradnik jest własnością autora zgodnie z ustawą z dnia 4 lutego 1994 roku o prawie autorskim i prawach pokrewnych. Publikowanie ich na innych forach i serwisach internetowych bez wiedzy i zgody autorów jest surowo zabronione.


  • 6

webDeveloper


ernest
6
Neutralna

Napisano 26 styczeń 2014 - 14:13

#2

Chyba mam swój wkład w tym poradniku :D:D

Jeszcze nie przeanalizowałem, ale już Ci bardzo dziękuję za pomoc ;)


  • 0

zonic

    WT Elite

  • 2911 postów
    • Czas spędzony online: 134d 2h 27m 36s
472
Znakomita!
  • LocationToruń

Napisano 26 styczeń 2014 - 14:31

#3

Wrzucę na dniach na serwer :) Chyba warto będzie przygotować jakąś podstronę dla skryptów. Bo przeglądając tematy, znalazłoby się jeszcze kilka, prymitywnych, ale bardzo potrzebnych skryptów.


+++

To okaż swoją dobroć i dorzuć jeszcze pytanie antyspamowe, o którym ostatnio była dyskusja ;)


  • 0

unbreak

    WT Elite

  • 1936 postów
    • Czas spędzony online: 27d 8h 38m 23s
506
Znakomita!
  • Location/home/unbreak

Napisano 26 styczeń 2014 - 15:03

#4

Dodałem ;]

Co do wrzucenia plików to stwórz katalog demo i w nim katalog '933-formularz' (id tematu i skrót tematu) i wrzuć pliki, mogę Ci podesłać na pw.


Użytkownik unbreak edytował ten post 26 styczeń 2014 - 15:04

  • 0

webDeveloper


zonic

    WT Elite

  • 2911 postów
    • Czas spędzony online: 134d 2h 27m 36s
472
Znakomita!
  • LocationToruń

Napisano 26 styczeń 2014 - 15:40

#5

To podeślij pliki :)

PS na pewno dobrze sprawdzasz odpowiedź na pytanie antyspamowe?


  • 0

unbreak

    WT Elite

  • 1936 postów
    • Czas spędzony online: 27d 8h 38m 23s
506
Znakomita!
  • Location/home/unbreak

Napisano 27 styczeń 2014 - 09:12

#6

Tym ifem:

in_array(strtolower($question),array('kot','kotem') )

sprawdzam czy $question (czyli odpowiedź - tak dla zmyłki, cholera wie co jeszcze boty będą umiały) pomniejszony do małych liter (jakby ktoś wpisał z dużej, lub samymi dużymi) znajduje się w array-u czyli ma wartość albo kot, albo kotem (bo to nie przewidzisz w jakiej formie ludzie odpowiedzą).

Chyba że gdzieś jest literówka której nie widzę?


  • 0

webDeveloper


zonic

    WT Elite

  • 2911 postów
    • Czas spędzony online: 134d 2h 27m 36s
472
Znakomita!
  • LocationToruń

Napisano 27 styczeń 2014 - 10:44

#7

Tym ifem:

in_array(strtolower($question),array('kot','kotem') )

sprawdzam czy $question (czyli odpowiedź - tak dla zmyłki, cholera wie co jeszcze boty będą umiały) pomniejszony do małych liter (jakby ktoś wpisał z dużej, lub samymi dużymi) znajduje się w array-u czyli ma wartość albo kot, albo kotem (bo to nie przewidzisz w jakiej formie ludzie odpowiedzą).

Chyba że gdzieś jest literówka której nie widzę?

Pytam, bo coś mi nie działało jak testowałem. Sprawdzę później dokładnie.


+++

chyba jeśli ktoś poprawnie odpowie na pytanie to mu error wypluwasz :P


  • 0

unbreak

    WT Elite

  • 1936 postów
    • Czas spędzony online: 27d 8h 38m 23s
506
Znakomita!
  • Location/home/unbreak

Napisano 27 styczeń 2014 - 11:19

#8

Zgadza się, jest błąd :D Brakuje ! już poprawiłem :) możesz w demo zaktualizować w send.php linia 9?


  • 0

webDeveloper


Rodzyn

    Nowy użytkownik

  • 36 postów
    • :
0
Neutralna

Napisano 27 styczeń 2014 - 17:03

#9

Hm, co do regex_email to porażka :) Popraw to na to co tu mój znajomy napisał: http://benio.me/#!valid_mail

 

PS. Sry, nie przeczytałem komentarza w kodzie ale i tak sądzę że lepiej użyć ten regex który podałem :)


  • 0

unbreak

    WT Elite

  • 1936 postów
    • Czas spędzony online: 27d 8h 38m 23s
506
Znakomita!
  • Location/home/unbreak

Napisano 27 styczeń 2014 - 19:17

#10

Hm, co do regex_email to porażka :) Popraw to na to co tu mój znajomy napisał: http://benio.me/#!valid_mail
 
PS. Sry, nie przeczytałem komentarza w kodzie ale i tak sądzę że lepiej użyć ten regex który podałem :)


Sorry, ale w którym miejscu ja sprawdzam email?


  • 0

webDeveloper


Rodzyn

    Nowy użytkownik

  • 36 postów
    • :
0
Neutralna

Napisano 27 styczeń 2014 - 19:58

#11

Aha, fakt :) popatrzyłem na fazę preg_match i pomyślałem że to forma sprawdzenia e-mail :) Ale tak czy siak mógłbyś dodać ten regex :) Zawsze bezpieczniej nie? :D


  • 0

unbreak

    WT Elite

  • 1936 postów
    • Czas spędzony online: 27d 8h 38m 23s
506
Znakomita!
  • Location/home/unbreak

Napisano 29 styczeń 2014 - 10:08

#12

Hm, co do regex_email to porażka :) Popraw to na to co tu mój znajomy napisał: http://benio.me/#!valid_mail

 

PS. Sry, nie przeczytałem komentarza w kodzie ale i tak sądzę że lepiej użyć ten regex który podałem :)

Swoją drogą:

1. Z tego co widzę to nie Twój znajomy napisał, ale Paul Warren (no chyba że go znasz?), Twój znajomy sklepał do kupy czyjeś wyrażenie regularne

2. Właśnie jestem w trakcie testów tej funkcji i coś mi działa / nie działa ;]

3. Poza tym od kiedy adres "[email protected]" jest poprawny? xD


Użytkownik unbreak edytował ten post 29 styczeń 2014 - 14:15

  • 1

webDeveloper


zonic

    WT Elite

  • 2911 postów
    • Czas spędzony online: 134d 2h 27m 36s
472
Znakomita!
  • LocationToruń

Napisano 29 styczeń 2014 - 11:57

#13

Demo podmieniłem.
Błąd jest chyba, wyrażeniu weryfikującym wiadomość.
 


  • 0

unbreak

    WT Elite

  • 1936 postów
    • Czas spędzony online: 27d 8h 38m 23s
506
Znakomita!
  • Location/home/unbreak

Napisano 29 styczeń 2014 - 14:13

#14

IPB coś zpsuł, faktycznie pojawiły się w ifie spacje których nie powinno być.


  • 1

webDeveloper


zonic

    WT Elite

  • 2911 postów
    • Czas spędzony online: 134d 2h 27m 36s
472
Znakomita!
  • LocationToruń

Napisano 29 styczeń 2014 - 15:17

#15

IPB coś zpsuł, faktycznie pojawiły się w ifie spacje których nie powinno być.

A mógłbyś dołączyć do tematu załączniki z pojedynczymi plikami skryptu? 


  • 0

JJay

    Stary wyjadacz

  • 199 postów
    • Czas spędzony online: 5d 9h 38m 21s
19
Dobra
  • LocationCieszyn > Łódź

Napisano 08 luty 2015 - 05:17

#16

Demo nie działa :P


  • 0





Podone tematy Collapse


Również z jednym lub większą ilością słów kluczowych: javascript, html, php, jQuery, ajax

Użytkownicy przeglądający ten temat: 0

0 użytkowników, 0 gości, 0 anonimowych