Ajax, JS og jQuery

Tetto

Medlem
Jeg bruker Ajax til å kjøre en php-fil. Php-filen skal gjøre et søk i en database og skrive ut resultat i en tabell. I tabellen skal man kunne klikke på resultatene for å komme til en ny side med mer info resultatet. Problemet er at jeg ikke kan bruke <a>-tager rundt en <tr>. Derfor må jeg bruke JS eller jQuery til å navigere til neste side når man trykker på et av resultatene i tabellen.

Men - så får jeg ikke dette til å virke. Php-koden fungerer, men JS og jQuery fungerer ikke i php-filen som kjøres av Ajax. Derimot fungerer koden bra dersom jeg ikke bruker Ajax. Noen forslag til hvordan jeg kan løse dette?

Koden ser slik ut:
Kode:
function searchFilter(str) {
var xmlhttp;
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else {// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
document.getElementById("searchResult").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET", "search.php?q="+str, true);
xmlhttp.send();
}

jQuery-funksjonen i search.php ser slik ut:
Kode:
$(function(){
$(".clickableRow").click(function() {
window.document.location = $(this).attr("href");
});
});
 

amaheath

Medlem
Problemet kan være at linjene blir lagt til etterpå, og da er ikke click knyttet til .clickableRow.

Se på jquery 'on' som virker på dynamisk innhold som er lagt til etter at jquery-koden er kjørt initielt.

Endre den ene linjen du tester på click til noe sånt (ikke sjekket!)

Kode:
$(document.body).on('click', '.clickableRow', function(){
 

Tetto

Medlem
Problemet kan være at linjene blir lagt til etterpå, og da er ikke click knyttet til .clickableRow.

Se på jquery 'on' som virker på dynamisk innhold som er lagt til etter at jquery-koden er kjørt initielt.

Endre den ene linjen du tester på click til noe sånt (ikke sjekket!)

Kode:
$(document.body).on('click', '.clickableRow', function(){

Nei, det virket ikke dessverre. Kan legge ved hele search.php:
Kode:
<?php include "../includes/checkSession.php"; ?>
<head>
<script>
$(function(){
$(document.body).on('click', '.clickableRow', function(){
window.document.location = $(this).attr("href");
});
});
</script>
</head>
<body>
<?php
$id = $_SESSION['email'];

$con = mysql_connect("localhost", "bruker", "passord);
mysql_select_db("navn", $con);

$q = mysql_real_escape_string($_REQUEST["q"]);
$sql = "SELECT * FROM customers WHERE id='$id' AND name LIKE '%$q%'";
$result = mysql_query($sql); 

echo "<table>";
echo "<tr>";
echo "<th style='width:100px;'>Kundenr</th>";
echo "<th style='width:400px;'>Kundenavn</th>";
echo "<th style='width:200px;'>Sum omsetning</th>";
echo "</tr>";
while($row = mysql_fetch_array($result)) {
echo "<tr class='clickableRow' href='endre-kunde/endre.php?number=" . $row[1] . "'>";
echo "<td>" . $row[1] . "</td>";
echo "<td>" . $row[2] . "</td>";
echo "<td>" . number_format((float)$row[10], 2, ',', '') . "</td>";
echo "</tr>";
} 
echo "</table>"
?>
</body>
</html>

Dette virker altså helt perfekt uten Ajax. Prøvde også å skrive det som til en onclick-event, men det fungerte heller ikke. Jeg klarte ikke engang å lage en onclick-event som alertet "Hei".
 

adeneo

Medlem
search.php er jo en komplett fil, med body, head osv.
Hva forventer du når du setter inn en komplett fil slik som search.php som HTML i elementet #searchResult ?

Nettleseren din forventer i hvert fall ikke at du har to head seksjoner, body osv. slik at det fjernes automatisk for å ikke rote til hele DOM'en med to <head></head> inne i hverandre.
Det betyr altså at javascriptet som er i search.php aldri blir inkludert på siden din, det fjernes på veien.

Nå kan du selvfølgelig legge event handleren i den filen hvor ajax funksjonen er, og så bare delegere til #searchResult for å ta høyde for dynamisk innhold, men jeg forstår ikke helt hvorfor du ikke kan bruke anchors.

Først og fremst, ettersom du bruker jQuery

PHP:
function searchFilter(str) {
    $.ajax({
        url  : 'search.php',
        data : {q : str}
    }).done(function(data) {
        $('#searchResult').html(data);
    });
}

Så er det slik at et table element inneholder TR elementer (row), som igjen inneholder TD elementer (col), og inne i TD elementene kan du jo ha anchors ?

PHP:
echo "<tr>";
echo   "<td><a href='endre-kunde/endre.php?number=" . $row[1] . "'>" . $row[1] . "</a></td>";
echo "</tr>";

Derimot er href en ugyldig attribut for et TR element, da bør du nok bruke data attributer

PHP:
echo "<tr class='clickableRow' data-href='/endre-kunde/endre.php?number=" . $row[1] . "'>";
echo "<td>" . $row[1] . "</td>";
echo "<td>" . $row[2] . "</td>";
echo "<td>" . number_format((float)$row[10], 2, ',', '') . "</td>";
echo "</tr>";

og så fjerner du resten av HTML i search.php, du må returnere (echo) kun den HTML du ønsker å sette inn, altså kun table elementet, ikke en helt ny komplett side, og da kan du legge event handleren sammen med ajax greiene

PHP:
function searchFilter(str) {
    $.ajax({
        url  : 'search.php',
        data : {q : str}
    }).done(function(data) {
        $('#searchResult').html(data);
    });
}

$(function() {
    $('#searchResult').on('click', '.clickableRow', function(e) {
        e.preventDefault();
        window.location.href = $(this).data('href');
    });
});
 
Sist redigert:

amaheath

Medlem
Du har inkludert selve jquery-biblioteket også i search.php, sant? i <head> en før selve scriptet?

<script src= og så videre..... altså selve jquery.js
 

Tetto

Medlem
search.php er jo en komplett fil, med body, head osv.
Hva forventer du når du setter inn en komplett fil slik som search.php som HTML i elementet #searchResult ?

Nettleseren din forventer i hvert fall ikke at du har to head seksjoner, body osv. slik at det fjernes automatisk for å ikke rote til hele DOM'en med to <head></head> inne i hverandre.
Det betyr altså at javascriptet som er i search.php aldri blir inkludert på siden din, det fjernes på veien.

Hm, dette er første gang jeg bruker Ajax så jeg var litt usikker på hvordan det fungerte. Brukeren under deg spør om jeg har inkludert jQuery-biblioteket i search.php - og det har jeg jo - men hvis jeg forstår deg rett er ikke det nødvendig hvis det er inkludert i hovedfilen?

Takk for svar, skal teste etterpå!
 

adeneo

Medlem
Nei, det er ikke nødvendig, hold javascript i hovedfilen din, og hent kun innhold, altså JSON, HTML eller whatever med ajax, og ikke hent hele sider, hent kun det du trenger.

Tenk på den måten at dette

PHP:
<!DOCTYPE html>
    <head>
         <title></title>
    </head>
    <body>

        <div id="searchResult">

            <head>
                <script>
                    $(function(){
                        $(document.body).on('click', '.clickableRow', function(){
                            window.document.location = $(this).attr("href");
                        });
                    });
                </script>
            </head>
            <body>
                   .....osv
            </body>

        </div>

    </body>
</html>

er fullstendig ugyldig, og du må fortsatt passe på at HTML'en din er gyldig og i tilfeller hvor du forsøker å sette inn hele nettsider i ett element, så blir det helt feil.

Du generer derfor kun den HTML du skal ha, sender den med ajax, og setter inn på rette plassen.

Javascript inkludert på sider du henter med ajax vil normalt ikke evalueres, og det bør derfor alltid unngås, sett inn javascript på hovedsiden, den siden som henter HTML med ajax.
 

Tetto

Medlem
Nei, det er ikke nødvendig, hold javascript i hovedfilen din, og hent kun innhold, altså JSON, HTML eller whatever med ajax, og ikke hent hele sider, hent kun det du trenger.

Tenk på den måten at dette

PHP:
<!DOCTYPE html>
    <head>
         <title></title>
    </head>
    <body>

        <div id="searchResult">

            <head>
                <script>
                    $(function(){
                        $(document.body).on('click', '.clickableRow', function(){
                            window.document.location = $(this).attr("href");
                        });
                    });
                </script>
            </head>
            <body>
                   .....osv
            </body>

        </div>

    </body>
</html>

er fullstendig ugyldig, og du må fortsatt passe på at HTML'en din er gyldig og i tilfeller hvor du forsøker å sette inn hele nettsider i ett element, så blir det helt feil.

Du generer derfor kun den HTML du skal ha, sender den med ajax, og setter inn på rette plassen.

Javascript inkludert på sider du henter med ajax vil normalt ikke evalueres, og det bør derfor alltid unngås, sett inn javascript på hovedsiden, den siden som henter HTML med ajax.

Ok, nå fungerer det. Takk for hjelpen! Men jeg måtte både koble til databasen på nytt og hente session-variablene på nytt.
 

adeneo

Medlem
Når du kjører PHP scriptet på serveren må du fortsatt koble til databasen, hente sessions osv. ettersom det ikke er noen kobling mellom hovedsiden og det PHP scriptet som kjøres med ajax.

Ajax henter bare en URL, og leverer innholdet på den URL'en til callback funksjonen, slik at PHP scriptet som generer innholdet på den URL'en er fortsatt helt frittstående, men du trenger altså ikke levere en hel nettside når du kun trenger et table element osv.

Merk også at når du delegerer event handlere så bør det alltid delegeres til nærmeste statiske element, slik at det bør være

PHP:
$('#searchResult').on('click', '.clickableRow', function(){ ...

altså #searchResult, som er det nærmeste statiske elementet, og ikke document eller document.body selv om de også er statiske.
 
Topp