• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

[ERLEDIGT] Ajax - FormularDaten generisch übermitteln

CGollhardt

Mitglied
Hallo Miteinander,

ich sitze gerade vor einem Problem. Ich setze mich derzeit mehr mit Javascript auseinander und den neuen Möglichkeiten mit Jquery und Ajax. Bisher war ich wohl noch zu sehr mit der "alten" Welt vertraut.

Ich würde gerne ein Formular per Ajax versenden, der Clue es sollte absolut generisch sein.

Um mein Anliegen genauer zu beschreiben, möchte ich euch zeigen, wie ich einen Link Ajaxifiziere:

HTML:
<a onclick="return UseAjax(this)" href="<?php echo $this->_['Url']; ?>" class="<?php echo $this->_['Class']; ?>"><?php echo $this->_['Text']; ?></a>

Mit der Methode UseAjax wird das ganze Ajaxifiziert

Code:
/**
 * Versucht den Link per Ajax zu laden
 * @return {boolean}
 */
function UseAjax(sender) {
    var url = $(sender).attr('href') + '?ajax=true';
    $.getJSON(url, function (data) {
        $('#AjaxContent').html(data.Content);
        document.title = data.Title;
    });
    return false;
    //$('div#content').load(sender + '?ajax=true');
}

/**
 * Lässt einen Ladebalken bei einem Ajax Request erscheinen
 */
$(document).ready(function () {
    $(this).ajaxStart(function () {
        $('body').append('<div id="AjaxLoader"></div>');
    });
    $(this).ajaxStop(function () {
        $('#AjaxLoader').remove();
    });
});

Soetwas hätte ich gerne für ein Formular. In etwa so:

HTML:
<form onsubmit="UseAjax(this)" method="post" action="foo.php" />
  <input type="text" name="answer" value="42" />
</form>

In der foo.php möchte ich gerne folgendes auswerten können
PHP:
echo $_POST['answer'];
//Ausgabe: 42

Also im Grunde soll es so etwas ähnliches wie UpdatePanel von ASP.NET werden, Nur halt für PHP.

Ist dies irgendwie möglich? Ich möchte nicht jedes einzelne Element ansprechen wollen, da dies Architektonisch in meiner PHP-Anwendung aufgrund loser Kopplung nicht machbar wäre.

Vielen Dank für eure Antworten.

//Edit:
Wichtig wäre für mich auch ein Fallback, wenn Ajax/JS nicht unterstützt werden würde.
 
Zuletzt bearbeitet:
Werbung:
onclick-Attribute direkt im HTML sind unsauber und zeugen im Gegensatz zu dem, was du glaubst, absolut nicht für generischen Code.
Was das Formular angeht: Wie willst du den Inhalt eines Formulars abschicken, wenn du nicht willst, dass man die einzelnen Textfelder überprüft?
 
Vielen Dank für deine Antwort.

Zu dem Onclick Attribut:

Ich erstelle Links per Code

PHP:
$link = new Cms\Core\HtmlControls\Basic\Link($urlFactory);
$link->UseAjax();
$link->AssignView($view)

Ich wüsste nicht wie ich sonst machen könnte. Ich muss ja irgendwie an
PHP:
<?php echo $this->_['Url']; ?>
ran kommen, wenn der Link aktiviert wurde.

Zum Thema mit der Validierung.

Dies wird vorerst Serverseitig überprüft. Wenn der User eine Fehleingabe macht, wird ihm die aktuelle Seite noch einmal angezeigt. Sicherlich verursacht das mehr Server Load, aber ich bin noch in einer frühen Phase beim erstellem meiner Anwendung. Ich denke eine Clientseitige Validierung wäre später sehr leicht umzusetzten, da bei mir jedes Control per Code erzeugt wird, einem Interface HtmlControl angehört und weiß, was es beinhaltet (password, shortname, longname, email, website).

Selbstverständlich wird beim Absenden des Formulars ein neuer Inhalt geladen. Aber das bekomme ich hin, die Frage ist halt nach einem generischen Ansatz alle Inputs/Textareas zu serialisieren oder sonste was, dass man diese Serverseitig aufrufen kann.
 
Werbung:
Ich rede gar nicht von Validierung. Aber einfach nur davon, dass du ein Formular abschicken willst, ohne die Formularelemente zu durchsuchen.
Ich glaube dein Framework ist nicht gut durchdacht, daher solltest du besser ein anderes verwenden und deine Applikation auf etwas Stabiles basieren lassen (wie Symfony).

Außerdem solltest du dich besser mit JavaScript beschäftigen bevor du eine komplexere JS/PHP-Interaktion machen willst. Denn wenn du nicht weißt, wie man inline-JavaScript vermeidet zeugt das von nicht genügend Kenntnissen, vor allem wenn man sogar jQuery benutzt, wo das Ganze noch einfacher ist.
 
Ich versteh gerade nicht, warum ich die Formularelemente durchsuchen sollte. Was meinst du denn damit? Nach was soll ich suchen? Die Frage ist ernstgemeint. Wie gesagt ich kenne mich nicht all zu sehr mit JS aus, aber das soll sich ja ändern.

Ein Framework möchte ich vermeiden.

Zu der Inline Thematik:
Wie kann ich es denn besser machen? Wie kann ich denn beim klicken eines Links eine Ajax interaktion auslösen, in dessen Event ich die href URL habe, ohne jeden einzelnen Link extra zuzuweisen. Ich habe es schon probiert, allen a elementen mit der Klasse AjaxLink einer anonymen funktion zuzuweisen, hat alles geklappt, aber ich kam nicht an das href attribut ran. Ein Beitrag auf Stackoverflow hat es auf diese Art und weise vorgeschlagen, und war mit mehr als 100 gevoted. Weiß nicht mehr den Link.
 
Wenn du ein Formular abschicken willst per Ajax muss doch auch irgendwas geschickt werden. Daher musst du alle Formularelemente abfragen, um den Request zu vervollständigen.

In jQuery gibt es die Methode:
PHP:
$("selector").click(function () {
    // Tu was
});
 
Werbung:
Hallo, vielen Dank für deine Mühe,

wie erhalte ich bei //Tu was das href Attriubte? Und ich möchte nicht mit "Selektor" jedes einzelne Link Attribute selektieren.

Was mich aber mehr interessiert ist, meine Eingangsfrage mit dem Formular. Gerne würde ich auch die Link Thematik verbessern, aber das ist jetzt eine sekundäre Geschichte.

//Edit:
Bei dem Link brauche ich doch irgendwie einen Sender, irgendwas, von dem aus ich das Atribut auslesen kann. Bei meiner aktuellen Funktion übergebe ich ja nur this und der hat das Attribute.
 
Zuletzt bearbeitet:
Vielleicht verstehe ich deine Frage ja nicht richtig, aber du musst doch lediglich zwei einfache jQuery-Funktionen zusammenbringen.

Erstens einen EventListener:
Code:
$(selector).on('submit', function(e) {
    e.prevent.Default();
    // tu was, z.B. Werte in Variablen Speichern
    // var bar = 'irgendEinWert';
   // und binde den Ajax-Request ein
})

und darin dann den Ajax-Call:
Code:
$.ajax({
    url: 'eineseite.php',
    type: 'POST',
    //$_POST['foo']
    data: {foo: bar}
    success: function(result) {
        $('#box').load(result);
    }
});
 
Hallo Tronjer, danke für deine Antwort. Genau in die richtung soll es gehen.

Das einzigste was ich erreichen will, ist dass ich nicht alle Daten "manuell" übergeben will (data: {foo:bar}) sondern dass dies automatisch ermittelt wird. Also wenn ich 15 inputs hätte, will ich nicht diese in den Data String übergeben müsssen, sondern diese automatisch finden.

Also noch einmal zur veranschaulichung, folgendes Html:

HTML:
<form>
  <input name="foo" type="text" value="bar">
  <input name="answer" type="text" value="42">
</form>

Dafür würde ich ja wahrscheinlich folgendes JS benötigen, wie du bereits geschrieben hast:

Code:
$.ajax({
    url: 'eineseite.php',
    type: 'POST',
    //$_POST['foo']
    data: {foo: bar, answer: 42}
    success: function(result) {
        $('#box').load(result);
    }
});

Gibt es jedoch eine Möglichkeit dieses Datenarray automatisch zu erzeugen lassen?

Ich hoffe ich konnte mein Vorhaben veranschaulichen.

Vielen Dank für deine Hilfe.
 
Werbung:
Gibt es jedoch eine Möglichkeit dieses Datenarray automatisch zu erzeugen lassen?

Ich hoffe ich konnte mein Vorhaben veranschaulichen.

Vielen Dank für deine Hilfe.

Entweder verstehe ich dich nicht, oder du denkst zu kompliziert. Wie Asterixus bereits erwähnte: kein Inline-JS :p

Also du hast ein Formular mit 15 <input> Feldern, deren Werte du beim submitten übertragen willst?

Schreibe eine Funktion, die über die <inputs> iteriert und ein Array mit den Werten zurückliefert. Den Funktionsaufruf speicherst du innerhalb des EventListeners in einer Variablen und diese wiederum übergibst du der Ajax-Methode data als Argument. Oder spare dir den Umweg mit der Variablen und übergib die Funktion direkt. Habe ich zwar noch nicht versucht, sollte aber gehen.
 
Schreibe eine Funktion, die über die <inputs> iteriert und ein Array mit den Werten zurückliefert.
Vielen Dank. Du verstehst mich richtig ;)

Hättest du da vielleicht einen Link für mich, wie man Elemente finden kann? Wie gesagt, mit JS hatte ich bisher noch nicht viel am Hut. Um ehrlich zu sein, weiß ich garnicht wie ich dass nennen soll, wenn ich es auf google finden möchte :(
 
Werbung:
Hallo Asterixus. Tut mir leid, dass ich mich nicht deutlich Ausgedrückt habe :oops:

In dem Link, den du gepostet hast ist folgender Code:

Code:
var inputs = document.getElementById("form1").elements;
var inputByIndex = inputs[2];
var inputByName = inputs["login"];

Hier muss ich jedoch wieder wissen, welche Id das Input hat. Das ist genau was ich vermeiden möchte.

Also Angenommen, ich bin im Sumbit Event, dann möchte ich gerne Vollautomatisch jedes Element, dass ich ohne AJAX in der $_POST variable Serverseitig abfragen könnte ermitteln, ohne dessen ID oder Struktur zu kennen. Diese sollen dann übertragen werden, im besten Fall so, dass ich diese in der $_POST Variable wieder finde.

Also:

HTML:
<form id="AjaxForm" action="foo.php" method="post">
  <input name="foo" type="text" value="bar">
  <input name="answer" type="text" value="42">
</form>

Soll so in der foo.php abgefragt werden können:

PHP:
echo $_POST['foo']; //Ausgabe: bar
echo $_POST['answer']; //Ausgabe: 42

So ist es aktuell.

Nun kommt jedoch noch Ajax ins Spiel:

Code:
$(#AjaxForm).on('submit', function(e) {
    e.prevent.Default();
$.ajax({
    url: 'eineseite.php',
    type: 'POST',
    //$_POST['foo']
    data: {foo: bar, answer: 42}
    success: function(result) {
        $('#box').load(result);
    }
});
})

Was mir aber wichtig ist:
data: {foo: bar, answer: 42} soll automatisch gefüllt werden.

Uns zwar nicht in dem ich jedes einzelne Input kenne (was ich nicht tue) sondern automatisch. Gerne mit einer Javascript Suchfunktion, allerdings, darf diese keine Annahmen enthalten, dass das <input name="foo"> exestiert.

Also im Prinzip soll nix anderes passieren, außer das Formular wie beim Standardverhalten abzusenden, ohne für jedes Formular extra Javascript zu erzeugen, was nur auf dieses Formular gedacht ist.

Also Ähnlich dem Asp.net Updatepanel

Code:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>
        <asp:Textbox id="Foo">Bar</asp:Textbox>
        <asp:Textbox id="Answer">42</asp:Textbox>
    </ContentTemplate>
</asp:UpdatePanel>

Ich hoffe ich konnte das ganze jetzt ein bisschen verdeutlichen.

Vielen Dank für eure Mühe.
 
Vielen Dank. Du verstehst mich richtig ;)

Hättest du da vielleicht einen Link für mich, wie man Elemente finden kann? Wie gesagt, mit JS hatte ich bisher noch nicht viel am Hut. Um ehrlich zu sein, weiß ich garnicht wie ich dass nennen soll, wenn ich es auf google finden möchte :(

So was?
HTML:
<form id="foobar">
    <input type="text" value="foo" />
    <input type="text" value="bar" />
    <input type="text" value="baz" />
</form>

Code:
function myArr() {
    var foobar = [];
    $('#foobar').find('input').each(function() {
         foobar.push( $(this).attr('value') );
    });
    return foobar;
}

var baz = myArr();
console.log(baz);
 
Ja genau =)

Ich werde es mir gleich mal zu gemüte führen. Muss mich erstmal mit den einzelnen Befehlen auseinandersetzen, damit ich dass auch verstehe.

Vielen vielen lieben Dank!

//Edit: Wie kann ich ein Thema als Erledigt setzen? Hier hat sich ja einiges geändert...
 
Werbung:
Nein bitte, es gibt in Formularen noch andere Elemente als INPUT.
Schau dir das Beispiel an und versuche bitte auch zu verstehen, warum ich dir was anrate und spiele mit den Tipps rum, die ich dir gebe:
HTML:
<!doctype html>
<html>
<head>
<title>Titel</title>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function () {
	$("#button").click(function () {
		var form = document.getElementsByTagName("form")[0];
		$(form.elements).each(function () {
			alert($(this).val());
		});
	});
});
</script>
</head>
<body>
<form action="index.php" method="post">
<input type="text" name="a">
<input type="text" name="b">
<input type="text" name="c">
<select name="s">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>
<input type="button" value="Test" id="button">
</form>
</body>
</html>

Hier der JS-Teil syntaxhighlighted:
PHP:
$(document).ready(function () {
	$("#button").click(function () {
		var form = document.getElementsByTagName("form")[0];
		$(form.elements).each(function () {
			alert($(this).val());
		});
	});
});

Gib im Formular ein paar Sachen ein, um dir im Klaren darüber zu sein, wie du das abstrakt lösen kannst. Außerdem hast du ein inline-JS-loses Beispiel für einen Klick.
 
Hallo, vielen Dank nochmal. Dank eurem Input habe ich jetzt sogar noch eine sexy Lösung zum Serialisieren der Formulardaten in der Jquery Doku finden können:

.serialize() | jQuery API Documentation
Code:
    $("#AjaxForm").on('submit', function(e) {

        var url = "/foo.php";

        $.ajax({
            type: "POST",
            url: url,
            data: $("#AjaxForm").serialize(),
            success: function(data)
            {
                alert(data);
            }
        });

        return false;
    });
 
Werbung:
Hallo, ich versuche jetzt gerade die Geschichte mit den Links noch zum Laufen zu bringen.
Will aber in Verbindung mit Ajax leider nicht so richtig klappen.

Folgender Code zum Ajaxifizieren von einem Link funktioniert:

Code:
    $('.useajax').on('click', function (e) {
        var url = $(this).attr('href') + '?ajax=true';
        $.getJSON(url, function (data) {
            $('#AjaxContent').html(data.Content);
            document.title = data.Title;
        });
        e.preventDefault();
    });

Das Problem ist nur, wenn ich den Seiteninhalt mit Ajax nachlade, sind die Onclick Events nicht mehr gebunden. Also habe ich mir gedacht, dass ich das ganze in eine Funktion auslagere:

Code:
function BindAjax() {
    $('.useajax').on('click', function (e) {
        var url = $(this).attr('href') + '?ajax=true';
        $.getJSON(url, function (data) {
            $('#AjaxContent').html(data.Content);
            document.title = data.Title;
        });
        e.preventDefault();
    });
}

... Und das ganze nocheinmal zusätzlich im Success Handler aufrufe:

Code:
$("#AjaxForm").on('submit', function (e) {

    var url = $("#AjaxForm").attr('action') + '?ajax=true';

    $.ajax({
        type: 'POST',
        url: url,
        data: $(this).serialize(),
        dataType: 'json',
        success: function (data) {
            $('#AjaxContent').html(data.Content);
            document.title = data.Title;
            BindAjax();
        }
    });
    return false;
});

Also insgesammt:

Code:
/**
 * Versendet ein Formular mit der ID AjaxForm per Ajax
 */
$("#AjaxForm").on('submit', function (e) {

    var url = $("#AjaxForm").attr('action') + '?ajax=true';

    $.ajax({
        type: 'POST',
        url: url,
        data: $(this).serialize(),
        dataType: 'json',
        success: function (data) {
            $('#AjaxContent').html(data.Content);
            document.title = data.Title;
            BindAjax();
        }
    });
    return false;
});

/**
 * Lässt einen Ladebalken bei einem Ajax Request erscheinen
 */
$(document).ready(function () {
    BindAjax();
    $(this).ajaxStart(function () {
        $('body').append('<i id="AjaxLoader" class="icon-spinner icon-spin icon-5x"></i>');
    });
    $(this).ajaxStop(function () {
        $('#AjaxLoader').remove();
    });
});

/**
 * Bindet alle nötigen Elemente mit Ajax
 */
function BindAjax() {
    $('.useajax').on('click', function (e) {
        var url = $(this).attr('href') + '?ajax=true';
        $.getJSON(url, function (data) {
            $('#AjaxContent').html(data.Content);
            document.title = data.Title;
        });
        e.preventDefault();
    });
}

Aber das will nicht funktionieren. So bald der Content nachgeladen wird, sind die darin enthaltenen Links nicht mehr mit Ajax gekoppelt. Woran könnte das liegen?

//Edit: Habe die falsche Funktion angegeben
 
Zuletzt bearbeitet:
Ich stecke hier gerade in einer anderen Sache und mag mich da jetzt nicht hineindenken, aber im Gegensatz zu $(sel).click(function() {}) funktioniert $(sel).on('click', function(){}) auch bei Elementen, die nach dem Aufbau des DOM nachgeladen werden.
 
Zurück
Oben