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

- Tomáš Votruba
 - Moderator | 1114
 
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
 
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
 
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)

- Tomáš Votruba
 - Moderator | 1114
 
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
 
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 | 668
 
ř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
 
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>