Po jenom odeslání snippetu stejný formulář již neajaxuje

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Tomáš Votruba
Moderator | 1114
+
0
-

Mám formulář cngButton, kliknu, odešle se ajaxem v pořádku a do $cngStart se dá čas odeslání.

Jedná se podobný systém jako by mělo tlačítko zobrazit/schovat.

Po prvním odeslání mi ale již neajaxuje, čím to?

<?php
{snippet}
	{if !$cngStart}
		{control cngButton}
	{else}
		{control cngButton}
	{/if}
{/snippet}
?>
newPOPE
Člen | 648
+
0
-

To vyzera ze tam len nemas JS kod ktory to urobi :-). Ty totiz zmenis DOM dokumentu a to odpali jQuery handlery pokial nie su naviazane napr metodou live(...)

ta ti zaruci ze aj po zmene domu to bude fungovat.

Je to vystrel do vzduchu, dal si dost malo kodu. A hlavne problem citim v JScripte…

Tomáš Votruba
Moderator | 1114
+
0
-

První odeslání mi funguje. Snippet se přepíše – nastaví se hodnota (původně tam byl jiný form, který se vypsa), url se nezmění. Proto předpokládám, že je js v pořádku.

Ale je možné, že autor testovat vše také pouze na jednom odeslání, proto raději přikládám.

jquery.nette.js (z distribuce Nette, ke konci by mohl být problém, který máš zřejmě na mysli)

<script>
/**
 * AJAX Nette Framwork plugin for jQuery
 *
 * @copyright   Copyright (c) 2009 Jan Marek
 * @license     MIT
 * @link        http://nettephp.com/cs/extras/jquery-ajax
 * @version     0.2
 */

jQuery.extend({
	nette: {
		updateSnippet: function (id, html) {
			$("#" + id).html(html);
		},

		success: function (payload) {
			// redirect
			if (payload.redirect) {
				window.location.href = payload.redirect;
				return;
			}

			// snippets
			if (payload.snippets) {
				for (var i in payload.snippets) {
					jQuery.nette.updateSnippet(i, payload.snippets[i]);
				}
			}
		}
	}
});

jQuery.ajaxSetup({
	success: jQuery.nette.success,
	dataType: "json"
});


/**
 * AJAX form plugin for jQuery
 *
 * @copyright  Copyright (c) 2009 Jan Marek
 * @license    MIT
 * @link       http://nettephp.com/cs/extras/ajax-form
 * @version    0.1
 */

jQuery.fn.extend({
	ajaxSubmit: function (callback) {
		var form;
		var sendValues = {};

		// submit button
		if (this.is(":submit")) {
			form = this.parents("form");
			sendValues[this.attr("name")] = this.val() || "";

		// form
		} else if (this.is("form")) {
			form = this;

		// invalid element, do nothing
		} else {
			return null;
		}

		// validation
		if (form.get(0).onsubmit && !form.get(0).onsubmit()) return null;

		// get values
		var values = form.serializeArray();

		for (var i = 0; i < values.length; i++) {
			var name = values[i].name;

			// multi
			if (name in sendValues) {
				var val = sendValues[name];

				if (!(val instanceof Array)) {
					val = [val];
				}

				val.push(values[i].value);
				sendValues[name] = val;
			} else {
				sendValues[name] = values[i].value;
			}
		}

		// send ajax request
		var ajaxOptions = {
			url: form.attr("action"),
			data: sendValues,
			type: form.attr("method") || "get"
		};

		if (callback) {
			ajaxOptions.success = callback;
		}

		return jQuery.ajax(ajaxOptions);
	}
});



$("a.ajax").live("click", function (event) {
    event.preventDefault();
    $.get(this.href);
});

$("form.ajax").livequery("submit", function () {
	$(this).ajaxSubmit();
	return false;
});

$("form.ajax :submit, form .ajax:submit").livequery("click", function () {
	$(this).ajaxSubmit();
	return false;
});
</script>

Edit, koukám, že tam se bere livequery.js, tak níže:

<script>
/*! Copyright (c) 2009 Brandon Aaron (http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * Version: 1.1.0-pre
 * Requires jQuery 1.3+
 * Docs: http://docs.jquery.com/Plugins/livequery
 */

(function($) {

$.extend($.fn, {
	livequery: function(type, fn, fn2) {
		var self = this, q;

		// Handle different call patterns
		if ($.isFunction(type))
			fn2 = fn, fn = type, type = undefined;

		// See if Live Query already exists
		$.each( $.livequery.queries, function(i, query) {
			if ( self.selector == query.selector && self.context == query.context &&
				type == query.type && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) )
					// Found the query, exit the each loop
					return (q = query) && false;
		});

		// Create new Live Query if it wasn't found
		q = q || new $.livequery(this.selector, this.context, type, fn, fn2);

		// Make sure it is running
		q.stopped = false;

		// Run it immediately for the first time
		q.run();

		// Contnue the chain
		return this;
	},

	expire: function(type, fn, fn2) {
		var self = this;

		// Handle different call patterns
		if ($.isFunction(type))
			fn2 = fn, fn = type, type = undefined;

		// Find the Live Query based on arguments and stop it
		$.each( $.livequery.queries, function(i, query) {
			if ( self.selector == query.selector && self.context == query.context &&
				(!type || type == query.type) && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) && !this.stopped )
					$.livequery.stop(query.id);
		});

		// Continue the chain
		return this;
	}
});

$.livequery = function(selector, context, type, fn, fn2) {
	this.selector = selector;
	this.context  = context;
	this.type     = type;
	this.fn       = fn;
	this.fn2      = fn2;
	this.elements = [];
	this.stopped  = false;

	// The id is the index of the Live Query in $.livequery.queries
	this.id = $.livequery.queries.push(this)-1;

	// Mark the functions for matching later on
	fn.$lqguid = fn.$lqguid || $.livequery.guid++;
	if (fn2) fn2.$lqguid = fn2.$lqguid || $.livequery.guid++;

	// Return the Live Query
	return this;
};

$.livequery.prototype = {
	stop: function() {
		var query = this;

		if ( this.type )
			// Unbind all bound events
			this.elements.unbind(this.type, this.fn);
		else if (this.fn2)
			// Call the second function for all matched elements
			this.elements.each(function(i, el) {
				query.fn2.apply(el);
			});

		// Clear out matched elements
		this.elements = [];

		// Stop the Live Query from running until restarted
		this.stopped = true;
	},

	run: function() {
		// Short-circuit if stopped
		if ( this.stopped ) return;
		var query = this;

		var oEls = this.elements,
			els  = $(this.selector, this.context),
			nEls = els.not(oEls);

		// Set elements to the latest set of matched elements
		this.elements = els;

		if (this.type) {
			// Bind events to newly matched elements
			nEls.bind(this.type, this.fn);

			// Unbind events to elements no longer matched
			if (oEls.length > 0)
				$.each(oEls, function(i, el) {
					if ( $.inArray(el, els) < 0 )
						$.event.remove(el, query.type, query.fn);
				});
		}
		else {
			// Call the first function for newly matched elements
			nEls.each(function() {
				query.fn.apply(this);
			});

			// Call the second function for elements no longer matched
			if ( this.fn2 && oEls.length > 0 )
				$.each(oEls, function(i, el) {
					if ( $.inArray(el, els) < 0 )
						query.fn2.apply(el);
				});
		}
	}
};

$.extend($.livequery, {
	guid: 0,
	queries: [],
	queue: [],
	running: false,
	timeout: null,

	checkQueue: function() {
		if ( $.livequery.running && $.livequery.queue.length ) {
			var length = $.livequery.queue.length;
			// Run each Live Query currently in the queue
			while ( length-- )
				$.livequery.queries[ $.livequery.queue.shift() ].run();
		}
	},

	pause: function() {
		// Don't run anymore Live Queries until restarted
		$.livequery.running = false;
	},

	play: function() {
		// Restart Live Queries
		$.livequery.running = true;
		// Request a run of the Live Queries
		$.livequery.run();
	},

	registerPlugin: function() {
		$.each( arguments, function(i,n) {
			// Short-circuit if the method doesn't exist
			if (!$.fn[n]) return;

			// Save a reference to the original method
			var old = $.fn[n];

			// Create a new method
			$.fn[n] = function() {
				// Call the original method
				var r = old.apply(this, arguments);

				// Request a run of the Live Queries
				$.livequery.run();

				// Return the original methods result
				return r;
			}
		});
	},

	run: function(id) {
		if (id != undefined) {
			// Put the particular Live Query in the queue if it doesn't already exist
			if ( $.inArray(id, $.livequery.queue) < 0 )
				$.livequery.queue.push( id );
		}
		else
			// Put each Live Query in the queue if it doesn't already exist
			$.each( $.livequery.queries, function(id) {
				if ( $.inArray(id, $.livequery.queue) < 0 )
					$.livequery.queue.push( id );
			});

		// Clear timeout if it already exists
		if ($.livequery.timeout) clearTimeout($.livequery.timeout);
		// Create a timeout to check the queue and actually run the Live Queries
		$.livequery.timeout = setTimeout($.livequery.checkQueue, 20);
	},

	stop: function(id) {
		if (id != undefined)
			// Stop are particular Live Query
			$.livequery.queries[ id ].stop();
		else
			// Stop all Live Queries
			$.each( $.livequery.queries, function(id) {
				$.livequery.queries[ id ].stop();
			});
	}
});

// Register core DOM manipulation methods
$.livequery.registerPlugin('append', 'prepend', 'after', 'before', 'wrap', 'attr', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove');

// Run Live Queries when the Document is ready
$(function() { $.livequery.play(); });

})(jQuery);
</script>

V dalším js to, myslím, nebude. Žádný interně přidaný nemám.

Edit: ještě zkusím pořadí načítání js souborů.

Editoval Schmutzka (13. 9. 2011 18:24)

arron
Člen | 464
+
0
-

Probléje v tom, že po přepsání toho formuláře po přijetí snippetu se na tento „nový“ formulář „nenavěsí“ odesílací JS.

iguana007
Člen | 970
+
0
-

Pokud tam je livequery, tak by to nemělo vadit. O to se právě stará ten livequery plugin. Já mám full-ajax administraci a normálně mi to šlape. Spíše bych zkusil postupně deaktivovat všechny ostatní javascripty na té stránce, jestli ti to nějaký nepřebíjí.

Tomáš Votruba
Moderator | 1114
+
0
-

arron napsal(a):

Probléje v tom, že po přepsání toho formuláře po přijetí snippetu se na tento „nový“ formulář „nenavěsí“ odesílací JS.

Jsi si jist? Jak na to?

iguana007 napsal(a):

Pokud tam je livequery, tak by to nemělo vadit. O to se právě stará ten livequery plugin. Já mám full-ajax administraci a normálně mi to šlape. Spíše bych zkusil postupně deaktivovat všechny ostatní javascripty na té stránce, jestli ti to nějaký nepřebíjí.

Nepomohlo.

Nemáte nějaké hotové/funkční řešení?

joe
Člen | 313
+
0
-

Po AJAXovém odeslání formuláře se na ten tag <form> podívej přes FireBug (nebo jiného pomocníka v jiném prohlížeči), jestli má přiřazenou událost onsubmit. Pokud má, zapni si zachování výpisu chybové konzole a zkus ho odeslat znovu, bude chyba v JS, která jejím vzniknutím přeruší JS a klasicky formulář odešle.

bojovyletoun
Člen | 667
+
0
-

řeším to tak, že po každém updateSnippets volám znovu handlery (handlers), které navěsí událost.
Nejsem v jquery moc zběhlý, proto můj kód vypadá prasácky (die+live, měl jsem problémy s vícenásobným navěšením.. Máte tip na tutoriál na toto téma?), ale ummí: 1. navěsit eventy dynamicky přidaným prvkům, 2. refreshnutým prvkům.
Otázka nakonec vyřeší tohle definitivně livequery?

		$('a.ajax').initSnippet(); //snippety
		$('form').initForm(); // validace

		//$('form.live').liveSubmit(); //triggger submit při eventu (vstup)
		$('form.ajax').ajaxSubmit(); //
		$('form.iframe').iframeSubmit(); // jako form.ajax umí multi file upload na pozadí

handlery většinou volají metody onStart(zešedne prvek, aspinner), onComplete(updatesnippets, odstraní třídu loading)

Editoval bojovyletoun (29. 9. 2011 23:08)

Tomáš Votruba
Moderator | 1114
+
0
-

Zatím pomohlo v jquery.nette.js upravit dole následující:

<script>
...

/* old
$("a.ajax").live("click", function (event) {
    event.preventDefault();
    $.get(this.href);
});
*/

$(function(){
	$("a.ajax").live("click", function() {
		$.get(this.href);
		return false;
	});


//	$("form.ajax").livequery("submit", function () { old
	$("form.ajax").live("submit", function () {
		$(this).ajaxSubmit();
		return false;
	});

});
</script>