Dynamiczne pola w jQuery

0

Witam,
dopiero zaczynam poznawać bibliotekę jQuery.Ogólnie chodzi o to, w czystym JS pisało się funkcję i jedną można było wywołać w drugiej.Właśnie nie wiem jak to zrobić w jQuery.Generuję dynamicznie elementy DIV, a po kliknięciu na [x] chciałbym, aby ten div znikał.Jak to zrobić w jQuery?

<input type="button" id="btn" />

<div id="upload_slots_container"></div>

w sekcji head:

<script type="text/javascript">
$(document).ready(

function()
{
var elid=0;
$("#btn").click(
function()
{ 
elid++;
$("#upload_slots_container").show();
$("#upload_slots_container").append('<div class="upfile_label" id="p'+elid+'"><span class="kontrahent">Kontrahent</span><span style="removeEl" onclick="deleteSlot(\'p'+elid+'\')">[x]</span></div>');
});

}

);
deleteSlot(ElId):function()
{
$(ElId).remove();
};
  </script>
<style type="text/css">
#upload_slots_container {
display: none;
border: 1px solid gray; }
  </style>

To (deleteSlot) niestety nie działa.Pomóżcie.

0

Z tego co widzę, w kodzie masz kilka błędów.

Po pierwsze, nie wiem o co chodzi z tą definicją deleteSlot() i z tym dwukropkiem. To jest błąd składni, w JavaScripcie tego typu funkcje deklaruje się np. tak:

function deleteSlot(ElId) {
}

Po drugie, funkcji $ z jQuery możesz podać m.in. selektor CSS, ale nie samo ID elementu. Czyli jak masz element, którego atrybut id ma wartość iii, to tak go nie złapiesz: $('iii'). Możesz jednak użyć selektora id z CSS, czyli tak: $('#iii') (zauważ proszę znak # z przodu). W niektórych frameworkach, np. w Adobe Spry, niektóre konstruktory wymagają samego ID i przez to znaku # czasem się zapomina. Spójrz do środka funkcji deleteSlot i zobacz, że zapomniałeś tam dodać # do samej wartości ID.

Po trzecie, nie wiem czy onclick w ogóle Ci zadziała na spanie. Nie mam pewności, bo sam nie używam tej przestarzałej metody dodawania zdarzeń (obecnie zaleca się używać metod W3C typu addEventListener). Wydaje mi się jednak, że żeby to zaczęło działać, musisz zmienić spany otaczające przycisk Usuń (x) na linki, czyli elementy a. Jako href ustaw im po prostu "#", ale pamiętaj, by po wywołaniu deleteSlot(...) w onclick napisać po średniku return false, żeby klikanie w te przyciski nie powodowało przeniesienia na górę dokumentu.

edit:
Zwykle dawanie gotowców odmóżdża, ale chciałbym Ci pokazać alternatywny sposób na osiągnięcie tego samego efektu, nieco lepiej -- jak mi się zdaje -- wykorzystujący jQuery.

Otóż nie potrzebujesz tworzyć w locie tymczasowych ID i nie potrzebujesz definiować globalnej funkcji, która usunie Ci element o danym ID.

jQuery umożliwia Ci łatwe zrobienie czegoś takiego:

  1. Dołącz do #upload_slots_container jednego kontrahenta, czyli kod HTML odpowiadający elementowi div.upfile_label. W tym kodzie znajduje się również kod przycisku Usuń (element span.removeEl), ale nie ma on żadnego onclick, ani niczego innego.
  2. Wciąż w elemencie #upload_slots_container, szukasz ostatnio dołączonego przycisku. Używasz selektora CSS. Wiesz, że ostatni przycisk to element o klasie removeEl znajdujący się w ostatnim elemencie o klasie .upfile_label (tym właśnie dołączonym). Przechodzisz do tego elementu, reprezentującego przycisk Usuń.
    2.1 Dajesz mu obsługę zdarzenia "click". W funkcji obsługi zdarzenia this oznacza element przycisku Usuń. Usuwasz więc jego rodzica, czyli element .upfile_label.

W kodzie wygląda to tak:

<script type="text/javascript">
$(document).ready(function() {
  $("#btn").click(function() {
    $("#upload_slots_container")
      .append('<div class="upfile_label"><span class="kontrahent">Kontrahent</span> <span class="removeEl">[x]</span></div>') // dolacz nowy wiersz
      .find('.upfile_label:last-child .removeEl')  // wybierz przycisk Usun w nowododanym wierszu
        .click(function(evt) {                     // dodaj do przycisku Usun zdarzenie click                                                                                               
          $(this).parent().remove();
        });
  });
});


</script>

To wszystko. Nie trzeba tworzyć funkcji deleteSlot, nie trzeba tworzyć w locie dynamicznych ID.

W powyższym kodzie przydałoby się pewnie złamać string w tym długim wierszu, ale nie chciałem Ci gmatwać.

0

Wszystko działa.Piękne dzięki kolego.
[soczek]
Kod wygląda tak:

  <script type="text/javascript">
$(document).ready(

function()
{

$("#btn").click(
function()
{ 
$("#upload_slots_container").show();
$("#upload_slots_container")
.append('<div class="upfile_label"><span class="kontrahent">Kontrahent</span><span class="removeEl">[x]</span></div>')
.find('.upfile_label:last-child .removeEl')
.click(function (evt) {
$(this).parent().remove();
});
});

}
);
  </script>

Sprawdzałem, faktycznie, może i lepiej dać zamiast .W Ff natomiast jak dam linkowi atrybut "#" to mnie przenosi na główną stronę (jak jestem na innej).Dlatego wolę dać linkowi atrybut href="javascript:void(0)".

Tak więc działa dodawanie i usuwanie elementów w locie.Muszę jeszcze zrobić coś takiego.Niech pierwszym kontrahentem będą klienci z miasta X.W kodzie będzie to 1 element <div class="upfile_label>Miasto X i przycisk [x].A musiałbym dorobić, żeby obok napisu Miasto X była rozwijana lista, gdzie np. za pomocą checkboxów użytkownik mógłby odhaczać, które firmy nie mają być ujęte w wykazie.Dlatego m.in. myślałem o nadaniu unikalnych identyfikatorów elementom, bo potem muszę przesłać do formularza listę ID firm które zatwierdził użytkownik.Myślę jednak, że odebranie ID mogę zrobić w ten sposób:

<input type="checkbox" nazwa="kontrahenci[]" checked="checked">

i tak w pętli dla każdej grupy klientów wypisywać checkboxy i od razu je zaznaczać.

A w formularzu przy odebraniu danych dać:

$klienci = $_POST['kontrahenci'];//odebrana tablica z ID kontrahentów
foreach($klienci as $klient)
{
//wyslanie oferty do klienta
}

Pozdrawiam

0

Dobrze, że sam kombinujesz i zdajesz się mieć jakieś pojęcie o programowaniu, bo czasem się zdarza, że za dość skomplikowane rzeczy biorą się ludzie całkiem zieloni i potrafią tylko przeklejać kod. Może i to dobrze świadczy o języku, jeśli takie rzeczy jakoś tam robią (czy raczej: wklejają w swoją stronę) nooby i na pewno bycie newbie to nic złego, ale odnoszę wrażenie, że większość z tych ludzi niczego się przy tym nie uczy, bo nawet nie próbują zrozumieć zasady działania.

Oczywiście, jeśli uznasz, że ID Ci się jednak przydadzą, to tak może być w istocie. Decyzja należy do Ciebie. Jak zapewne wiesz, można je równie dobrze dodać do kodu proponowanego przeze mnie.

Jeśli chodzi o Twoje problemy z a href="#", to chyba wiem, skąd one się biorą (o ile rozumiem, o co Ci chodzi). Na wszelki wypadek powiem Ci o tym, bo może o tym nie wiesz, a może Ci się to wielokrotnie bardzo przydać.

Otóż niektóre zdarzenia na pewnych elementach mają wyraźne domyślne zachowanie. Np. zdarzenie click na łączu powoduje, że przeglądarka podąża za tym łączem (przy czym jeśli href ma wartość #, to przeglądarka przewija się na początek strony). Zdarzenie click na przycisku Wyślij (type=submit) w formularzu powoduje z kolei wywołanie innego zdarzenia: submit. Zdarzenie submit domyślnie powoduje wysłanie formularza oraz przejście na docelową stronę.

Czasem -- dość często -- się zdarza, że skrypty chcą zapobiec wykonaniu domyślnej akcji jakiegoś zdarzenia. Przykładowo, możesz formularzowi dodać zdarzenie submit, w którym sprawdzasz poprawność wpisanych danych. Jeśli są niepoprawne, to chcesz zapobiec domyślnej akcji -- sprawić, by formularz nie został wysłany.

W modelu zdarzeń W3C takie coś można zrobić, wywołując na obiekcie zdarzenia funkcję preventDefault(). A skąd masz wziąć ten "obiekt zdarzenia"? Ano jest on przesyłany do funkcji obsługi zdarzenia. Zgodnie z konwencją nazywa się go "evt", jak event, ale oczywiście to tylko nazwa argumentu i możesz ją zmienić. Spójrz na ten pseudokod:

<script type="text/javascript">
// dodajemy do formularza obsluge zdarzenia submit
$('#walidowany_formularz').submit(function(evt) { // funkcja obslugi zdarzenia dostaje 1 argument -- obiekt zdarzenia
  if (wartości-pól-nie-są-poprawne()) {
    // formularz zawiera bledy!
    wyswietl-komunikat-o-bledzie();
    evt.preventDefault(); // zapobiegamy domyslnej akcji, czyli wyslaniu formularza
  }
});

</script>

Podobna sprawa jest z łączami. Funkcja obsługi zdarzenia click też dostaje jeden argument (evt). W tym przypadku chcesz bezwarunkowo użyć evt.preventDefault();, więc dodajesz tę instrukcję np. na końcu funkcji.

Dodam jeszcze, że normalnie Internet Explorer nie ma czegoś takiego jak preventDefault(). W nim trzeba ustawić evt.returnValue = false. Ale Ty nie musisz się o to martwić -- użyj samego preventDefault(), a jQuery automatycznie ustawi evt.returnValue = false Internet Explorerowi.

0

Dziękuję bardzo za rady.W tydzień udało mi się poznać jquery tak, że sam napisałem licznik wpisanych znaków, kod odblokowujący zablokowane pola input po kliknięciu radio i kilka innych :-)
Bardzo fajna biblioteka i zamierzam się jej nauczyć.
Wracając do tematu: osiągnąłem swój cel.Tu demo:
http://tinylink.pl/uczr
Proszę wpisać cokolwiek w dowolne pole, np. nazwa i wcisnąć Wyszukaj.Skrypt ten wypluwa mi id kontrahentów z bazy, które potem używam do wysyłania im ofert.

Tak wygląda kod html:

<li>52<input type="hidden" value="52" name="firmy[]"/><span class="podpunkt">[x]</span></li>
<li>744<input type="hidden" value="744" name="firmy[]"/><span class="podpunkt">[x]</span></li>
<li>586<input type="hidden" value="586" name="firmy[]"/><span class="podpunkt">[x]</span></li>

Jako, że w formularzu przesyłam już w polu ukrytym id kontrahenta (pole firmy[]) Chciałbym aby zamiast np.
<li>52
było
<li>Księgarnia pod Eskulapem

Próbowałem już ująć liczbę w span
<li><span id="nazwa">52</span><input type="hidden" value="52" name="firmy[]"/>

aby potem móc asynchronicznie pobierać nazwę z bazy za pomocą id firmy z bazy.Nie chcę jednocześnie wyciągać nazw i id firm z bazy, bo będą opóźnienia.Teraz już jak wyciągam same id, a jest ich około 100 to trwa to około 1,5 s.Tak więc po załadowaniu id firm do pól ukrytych chcę asynchronicznie zamieniać te pola na nazwy firm.I tu Was proszę o radę.Z użyciem jquery najprościej. :-P

Jeszcze informacja o strukturze bazy danych.
W bazie danych jest tabela firmy, która ma m.in. pola id oraz nazwa.Wartość pola id jest przekazywana do elementu <input type="hidden" value="&lt;b">idfirmy</b>" name="firmy[]"/>.

Żeby było, że nic nie zrobiłem.Widzę to tak:
1)Znajduje wszystkie elementy o nazwie firmy[] w dokumencie.

$(document).find("firmy[]")

2)Przetwarzam każdy osobno
.each(function(i)
{

});

3)Pobieram wartość tego elementu
var idfirmy = $(this).attr("value");

4)Szukam rodzica tego elementu
$(this:parent)
5)W tym elemencie szukam elementu potomnego o id nazwa
$(this).find("#nazwa")
6)Umieszczam w spanie nazwa wartość wyciągniętą z bazy
var url = ""id2name.php?id="+idfirmy
.load(url)

Powiem Wam, że za pomocą selektorów nie umiałem się dostać do elementu o nazwie firmy[], bo chyba się to myliło z atrybutami selektora.

Dzięki i Pozdrawiam

0

Ja bym jednak chyba pobierał naraz zarówno id, jak i nazwy firm. No bo pomyśl -- po jaką cholerę wyświetlać najpierw same ID firm? Czy użytkownikom na coś to się przyda? Czy będą znali na pamięć, jakie ID oznacza jaką firmę? Myślę, że istnieje bardzo niewiele przypadków, w których ludzie korzystający ze skryptu znaliby na pamięć ID choćby niektórych firm. To by miało miejsce tylko wówczas, gdyby skrypt używany był przez wyszkolonych pracowników, pracujących praktycznie codziennie z tymi danymi. Wtedy może po jakimś czasie ktoś by coś zapamiętał. Ale absolutnie bym na to nie liczył, chyba żebym miał 100% pewności, że już ludzie potrafią czasem używać ID. Znam tylko jeden taki przypadek u moich znajomych w księgowości, gdzie księgowe znają na pamięć kilka identyfikatorów najważniejszych kontrahentów, bo przecież po 8h dziennie mają z nimi do czynienia (ale nikt od nich nie wymagał wkucia ID na pamięć, samo wyszło po wielu miesiącach).

Oczywiście jeśli skrypt ma być używany przez normalnych ludzi, a nie wyszkolonych pracowników, to nie ma nawet co myśleć o tym, że ktoś kojarzyłby ID firmy -- utworzone sztucznie w Twojej bazie danych -- z jej nazwą. Nie ma takiej opcji. Zresztą sam pomyśl: nawet jako pracownik chciałbyś się uczyć na pamięć takich sztucznych ID? Nie wolałbyś po prostu poczekać 2 sekundy dłużej?

Dlatego to, co chcesz zrobić, nie ma IMO wielkiego sensu. Chyba że o czymś nie wiem. Jeśli zaś dobrze wszystko rozumiem, to wyświetlenie na początku paru ID po prostu nic nie daje użytkownikom skryptu. I tak nie będą w to klikali. Widzę tylko jeden przypadek użycia, wymyślony bardzo na siłę: jakby wpisywali w wyszukiwarkę fragment nazwy firmy (lub inną rzecz, która ją jednoznacznie identyfikuje) i jakby wyszukiwanie zwróciło tylko jeden wynik. Wtedy ktoś mógłby kliknąć w jakąś dziwną liczbę, pod którą powinna się kryć firma, o którą mu chodzi. Ale to strasznie naciągane.

Pisząc skrypty, trzeba pamiętać o ich użyteczności. Nie piszesz ich dla siebie, ani dla pochwalenia się przed innymi programistami. Piszesz skrypty dla użytkowników.

Twój pomysł nie jest głupi i może kiedyś z niego skorzystasz. Ale miałby sens wtedy, gdybyś chciał wyświetlić o każdej firmie stosunkowo dużo danych. Wtedy mógłbyś najpierw wyświetlać same nazwy firm, a dopiero potem (po paru sekundach, jakie zajęłoby przetwarzanie) ściągnąć i wyświetlić pozostałe informacje. Wtedy miałoby to sens, bo wielu osobom mogłaby wystarczyć sama nazwa firmy -- po jej zobaczeniu, od razu by w nią kliknęli (czy zrobili coś tam innego), żeby wykonać tam jakieś operacje. A tak, z samymi ID nie wiedzą nawet co im się wyświetliło.

BTW., czy testowałeś wydajność wyświetlania ID i nazw? Czy mówisz o optymalizacji na wyrost? Przedwczesna optymalizacja to źródło wszelkiego zła na świecie ;). Radziłbym Ci przede wszystkim sprawdzić, ile zajmie wygenerowanie listy ID wraz z nazwami. Może wyjdą 2 sekundy zamiast 1.5? To i tak niedużo. A jeśli czas wzrośnie znacznie, to dlaczego? Czy problemem jest działanie bazy? Czy może przetwarzanie po stronie klienta, w JavaScripcie?

Jeśli to baza tak muli przy 100 firmach, to jest bardzo możliwe, że z nią jest coś nie tak. I to tam powinieneś szukać możliwości optymalizacji. Może kwerenda wyszukiwarki jest nieoptymalna.

Mówisz też o wyciąganiu 100 firm. Czy wyświetlasz tyle na jednej stronie z wynikami? o_O? Czy to aby nie za dużo? Może powinieneś skoncentrować się na tym, by wyświetlać naraz np. po 10 firm i udostępnić użytkownikowi linki następne/poprzednie 10. Wtedy za każdym razem ściągałbyś tylko te 10.

Na Twoim miejscu solidnie przemyślałbym, co w ogóle zrobić i czy coś zrobić.

Aha, to Twoje find("firmy[]") jest niepoprawne. Rzeczywiście, takie coś: "[]" koliduje z selektorem atrybutu CSS. Polecam Ci po prostu nadać wszystkim elementom firmy[] klasę "firmy" (class="firmy"). Potem wystarczy zrobić: find(".firmy") i będzie działało. Rozwiązanie z dodatkową klasą wydaje mi się bardziej przejrzyste, ale jeśli chcesz koniecznie wybierać elementy na podstawie atrybutu name, to możesz zmodyfikować swój selektor tak:

find("*[name=firmy\\[\\]]")

^^Nie wiem nawet, czy forum poprawnie to wyświetli. Przed wewnętrznym [ i ] powinny stać po dwa ukośniki. Polecam jednak użyć klasy.

0

Dziękuję za odpowiedź.
Nie sprawdzałem jeszcze wydajności pobierania id nazwy firm, co teraz uczynię.
Kwerenda jest dość prosta.
SELECT id FROM firmy WHERE nazwa='$nazwa' OR miasto='$miasto' OR woj='$woj' OR powiat='$powiat' OR kodpoczt='$kodpoczt' OR keywords1 LIKE '%$slowo%' OR keyword2 LIKE '%$slowo%' ";
Dane pobierane ze skryptu są najpierw filtrowane.Nie wiadomo, ile kwerenda zwróci wyników.Kontrahent ma mieć możliwość wyszukania np. wszystkich firm z danego miasto.Dlatego nie dałem LIMIT.Jeśli wyjdzie za dużo wyników, to za pomocą [x] będzie sobie usuwał.
Sprawdzę metodę find na podanym atrybucie.Dlatego dałem nazwę pola ukrytego na firmy[], bo od razu w skrypcie php mogę to prosto odebrać:

$firmy = $_POST['firmy'];

Pozdrawiam

0

Właśnie testowałem skrypt wyciągający dodatkowo nazwy.
Przy zapytaniu zwracającym 80 rekordów trwa to może 0,3 s, skrypt wysyła 3 KB danych.
Przy zapytaniu dającym 300 rekordów (id i nazwa) trwa to niewiele dłużej, ok 0,6 s.Przeglądarka pobiera wtedy 10 KB danych.Wprawdzie mam szybkie łącze, ale przetestuje to jeszcze na innych komputerach.Wydaje się że działa dobrze.
Pozdrawiam

0

No to widzisz, różnica na poziomie pół sekundy w tym wypadku nie jest niczym strasznym. Jeśli chodzi o szybkość łącza, to to także nie powinno tu mieć znaczenia. Czemu? Bo wygląda na to, że nie ma dużej różnicy w szybkości pomiędzy wysyłaniem samych ID, a ID wraz z nazwami firm. Jeśli to drugie zajmie 10 sekund, to to pierwsze i tak zajmie niewiele mniej, np. 8 sekund. Więc myślę, że nie ma sensu się bawić w wyświetlanie samych ID. Tym bardziej, że takie coś to nie jedno, a dwa żądania. Czyli rozpatrując ten przykład (z liczbami wziętymi z powietrza :)), jeśli wyświetlisz od razu wszystko, to użytkownik zobaczy to po 10 sekundach. A możesz ewentualnie wyświetlić ID po 8 sekundach, a po dalszych 10 (!) wyświetlić również nazwy. Sumaryczny czas odpowiedzi -- tej użytecznej odpowiedzi -- jest więc dłuższy. Bardziej opłaca się nie "optymalizować".

Mam natomiast pewien pomysł na optymalizację i jedną ważną uwagę odnośnie skryptu PHP.

Jeśli wydajność byłaby jednak problemem, możesz spróbować w sprytny sposób generować bardziej optymalne zapytanie do bazy danych. Spójrz na to, jak wygląda ono teraz:

SELECT id FROM firmy WHERE nazwa='$nazwa' OR miasto='$miasto' OR woj='$woj' OR powiat='$powiat' OR kodpoczt='$kodpoczt' OR keywords1 LIKE '%$slowo%' OR keyword2 LIKE '%$slowo%' ";

Wyobraź sobie, że podano tylko miasto. Np. "warszawa" (btw. myślę, że pola typu string powinny być porównywane bez uwzględnienia wielkości liter, czyli żeby można było wpisać "warszawa", "Warszwa" itp.). W tym wypadku do bazy zostanie wysłane zapytanie (po podstawieniu zmiennych):

SELECT id FROM firmy WHERE nazwa='' OR miasto='warszawa' OR woj='' OR powiat='' OR kodpoczt='' OR keywords1 LIKE '%%' OR keyword2 LIKE '%%' ";

Widać od razu, że większość warunków jest niepotrzebnych. Mógłbyś sklejać zapytanie bardziej dynamicznie, warunkowo. Tzn. jeśli podano miasto, to dopiero wtedy doklejasz część o mieście. Nie podano kodu pocztowego, to nie doklejasz części warunku z kodem (OR kodpoczt='').

Troszkę tutaj będziesz miał problemów z tymi OR-ami, bo przed częścią warunku, która zostanie doklejona pierwsza, NIE powinieneś wstawić OR-a, tylko WHERE.

Możesz z tym sobie jednak w prosty sposób poradzić. Zrób sobie na przykład zmienną $cond (jak condition -- warunek) i ustaw ją na pusty string. Następnie, jeśli $miasto nie jest puste, doklej do niej "OR miasto='$miasto'". Podobnie zrób z pozostałymi zmiennymi. Teraz zmienna $cond albo będzie zupełnie pusta (jeśli nie podano żadnych danych), albo będzie miała postać "OR miasto='..' OR woj='....' [itd]", ewentualnie może być pusta gdy nie podano żadnych warunków. W drugim przypadku (jeśli nie jest pusta) widzisz, że zaczyna się od "OR", które jest niepotrzebne (przed pierwszym warunkiem powinno stać WHERE, a nie OR). Zrób więc -- uwaga, bo sposób typowo bamberski, że się tak wyrażę -- coś mniej więcej takiego:

$cond = '';

if ($miasto) {
  $cond .= "OR miasto='$miasto'";
}
// i tak dalej dla innych pol

if ($cond != '') { // jesli podano jakies warunki
 $cond = substr($code, 2); // wywal z $cond 2 pierwsze znaki, czyli OR
 $cond = 'WHERE' . $cond; // dorzuc na poczatek WHERE
}
// zbuduj zapytanie
$query = 'SELECT id, nazwa FROM firmy ' . $cond;

Sposób trochę na pałę, ale nie będę Ci teraz tłumaczył jak napisać porządniejszy, obiektowy skrypt. Tym bardziej, że sama obiektowość nie zawsze jest taka fajna. Nie radzę przeklejać tego kodu, tylko ewentualnie zrozumieć o co mi chodzi i samemu go napisać, bo ja tego nawet nie pisałem w edytorze, o testowaniu nie wspominając. Mogą więc być tam błędy, czy literówki.

Tak w ogóle to w Twoim kodzie ze stałym zapytaniem (że zawsze dodajesz warunki dla miasta, województwa itd.) widać taki błąd, że jeśli gdzieś np. pole województwo przy jakiejś firmie będzie puste, to firma zostanie zwrócona jako wynik dowolnego zapytania, które nie będzie zawierało województwa. Bo w zapytaniu pojawi się fragment OR woj='', a woj w tym wypadku rzeczywiście będzie puste.

I na koniec poważniejsza sprawa. Bezpieczeństwo. Kolego, mam nadzieję, że unieszkodliwiasz (ang. escape) te wszystkie zmienne używane w zapytaniu? Podany przez Ciebie kod:

$firmy = $_POST['firmy'];

niestety na to nie wskazuje. To ekstremalnie niebezpieczne, jeśli w podobny sposób traktujesz zmienne wstawiane potem na żywca do zapytania do bazy danych. Takie coś jest podatne na (nie)sławny atak SQL Injection. Nie sprawdzałem, czy masz przed tym zabezpieczenia, czy nie, ale jeśli nie, to można Ci np. usunąć wszystkie rekordy z bazy danych.

Jeśli używasz bazy danych MySQL, to powinieneś przynajmniej każdą zmienną wysyłaną z formularza potraktować funkcją mysqli_real_escape_string. Czasami funkcja ta może nie być dostępna (musi być zainstalowane mysqli, "i" jak "improved"), w takim wypadku użyj mysql_real_escape_string (zauważ brak "i"). Powinno to wyglądać np. tak:

$miasto = mysql_real_escape_string($_POST['miasto']);

Mam nadzieję, że tę część o SQL Injection napisałem niepotrzebnie i że się przed tym zabezpieczyłeś, bo jeśli nie, to możesz mieć w kodzie parę poważnych i niebezpiecznych błędów. Ja niestety nie jestem wielkim specjalistą od backendu i tutaj najlepiej jakby pomógł Ci ktoś bardziej znający się na SZBD i PHP.</php>

0

Nie opłaca się optymalizować.I przy tym zostaję.
Wszelkie parametry pobrane przy pomocy metod POST i GET filtruję tak:

$zmienna = filtruj($_POST['pola']);

function filtruj($zmienna)//wszystkie zmienne get i post
{
$zmienna = trim($zmienna);
return htmlspecialchars($zmienna);
}

Czytałem o SQL Injection, nie chcę, by ktoś rozwalił mi bazę danych.Zapytanie rzeczywiście buduję dynamicznie, nie wkleiłem go bo pokazałem jedynie jakie pola są brane pod uwagę.

$nazwa = filtruj($_GET['nazwa']);
$woj = filtruj($_GET['woj']); $woj=strtolower($woj);
$powiat = filtruj($_GET['powiat']);
$kodpoczt = filtruj($_GET['kodpoczt']);
$miasto = filtruj($_GET['miasto']);
$nip = filtruj($_GET['nip']);
$slowo = filtruj($_GET['slowo']);

$sql_where = array();

if(!empty($nazwa) && strlen($nazwa)>=3)
$sql_where[] = "nazwa LIKE '%$nazwa%' ";
if($woj != '-1' && !empty($woj) )
$sql_where[] = "woj='$woj' ";
if(!empty($powiat))
$sql_where[] = "powiat='$powiat' ";
if(!empty($kodpoczt))
$sql_where[] = "kodpoczt='$kodpoczt' ";
if(!empty($miasto))
$sql_where[] = "miasto='$miasto' ";
if(!empty($nip))
$sql_where[] = "nip='$nip' ";
if(!empty($slowo) && strlen($slowo)>=3)
$sql_where[] = "(keyword1 LIKE '%$slowo%' OR keyword2 LIKE '%$slowo%' OR keyword3 LIKE '%$slowo%' OR keyword4 LIKE '%$slowo%' OR keyword5 LIKE '%$slowo%') ";

$zapytanie = implode("AND ", $sql_where);

$sql = "SELECT id,nazwa FROM firmy WHERE $zapytanie";

Muszę jeszcze w formularzu w JS wprowadzić jakieś filtrowanie, żeby miasto było dłuższe od 3 liter, tak samo z nazwą firmy.
I w poprzednim poście podałem chyba ORy w zapytaniu.Sorry, pisałem z palca.Ogólnie jak user wpisze coś w konkretne pola, to musi obowiązywać między nimi koniunkcja.

Pozdrawiam

0

Uff, już się bałem, że ten skrypt masz napisany... niezbyt fajnie :). Czyli na szczęście niepotrzebnie napisałem poprzedniego posta. Na forum nigdy nie wiesz na kogo trafisz. Nieraz ktoś bardzo przypakowany np. z JavaScriptu czy (częściej) HTML/CSS nie ma bladego pojęcia o PHP. Albo ktoś rozpoczynający przygodę z JS (czy jQuery) jest doświadczonym programistą PHP...

0

Ja natomiast mam bardzo dobre pojęcie o php i smarty, dobre o js,sql i css.JQuery zgłębiam dopiero od kilku dni.

0

Na forum nigdy nie wiesz na kogo trafisz, ale część wyjadaczy powie tylko szukałeś?, to proste, wystarczy ruszyć głową i ....d@@@.Męcz się dalej sam.
Na szczęście Ty jesteś wyjątkowo pomocny, dzięki.

0

Mogę prosić o diagnozę, dlaczego nie działa mi skrypt Ajax po IE 6? Pod Operą i Ff wszystko gra.Tak tworzę objekt xmlhtmlrequest:

var xmlhttp;
if(window.XMLHttpRequest)
{
xmlhttp=new XMLHttpRequest();
}
else
{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if(xmlhttp.readyState==4)
{
//...
0

Możesz wrzucić update skryptu tam, gdzie poprzednio -- na http://tinylink.pl/uczr? Może błąd nie jest przy samym tworzeniu obiektu XHR (skrót od XMLHttpRequest), tylko gdzieś dalej. Samo tworzenie obiektu ActiveX wygląda OK.

Przy okazji, taka bardziej ciekawostka: niektórzy zalecają sprawdzanie, czy istnieje window.ActiveXObject i użycie go gdy tylko to możliwe. Bo w IE7 Microsoft zrobił już normalny obiekt window.XMLHttpRequest, a więc w Twoim (i podobnym) kodzie to on zostanie utworzony, gdy tymczasem zawiera on pewne drobne błędy. Obiekt stworzony za pomocą ActiveX już tych błędów miał nie będzie. Dlatego np. w bibliotece jQuery jest odwrotnie: jeśli jest window.ActiveXObject, to tworzy XHR za pomocą ActiveXObject. W przeciwnym wypadku używa window.XMLHttpRequest.

Piszę, że to ciekawostka dlatego, że te drobne błędy przeważnie nie mają żadnego wpływu na działanie aplikacji i jeśli wszystko Ci dobrze działa w IE7, to znaczy, że nie musisz niczego zmieniać.

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