Twitter-like content submission and update
Greetings. I'm creating a quotation service now and encouraged such a problem while trying to make twitter-like data submission and display: all my ajax requests are executed twice. I'm using jQuery as follows:
i've tried
.click()
,.live("click", function())
and.one("click", function())
handlers with "submit" button. All of them executed query twice. And yes, the.one("click", function())
too.i set timeout function to check for new quotes and it is executed twice too
What's wrong with my JS/RoR code?
You can see all m开发者_运维技巧y sources at github.
Any help would be great.
UPD: Here's my form resulting HTML:
<div class="msg"></div><br />
<form accept-charset="UTF-8" action="/quotes" class="new_quote" id="new_quote" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="authenticity_token" type="hidden" value="vD6hAOmZjenRFw1aO1yH75K9K7WTFneJuP3H7sOR/Qw=" /></div>
<div class="field">
<label for="quote_author">Author</label><br />
<input id="quote_author" name="quote[author]" size="30" type="text" />
</div>
<div class="field">
<label for="quote_body">Body</label><br />
<textarea cols="60" id="quote_body" name="quote[body]" rows="8"></textarea>
</div>
<div class="field">
<label for="quote_approved">Approved</label><br />
<input name="quote[approved]" type="hidden" value="0" /><input id="quote_approved" name="quote[approved]" type="checkbox" value="1" />
</div>
<div class="actions">
<input id="quote_submit" name="commit" type="submit" value="Create Quote" />
</div>
</form>
And here's my javascript:
onerror = function moo(msg, url, line) {
//alert('Error: ' + msg + '\nURL: ' + url + '\nLine: ' + line);
}
function moo() {
var cnt = 0, type = "";
var id = $("div.quote:first").attr("id");
$.getJSON("/after/" + id, function(data) {
var cnt = data.length;
if (cnt > 0)
$(".msg").css("backgrount-color", "#ffff00").text(cnt + " new quotes added. Please, update").fadeIn('slow').delay(20000).fadeOut('slow');
});
setTimeout("moo()", 30000);
}
$(document).ready(function() {
var to = setTimeout("moo()", 30000);
$.getJSON("/author_list", function(data) {
$("#quote_author").autocomplete({ source: data, minLength: 1 })
});
$("form.new_quote > .actions > [type=submit]").live("click", function() {
$.post('/ajax_new', $('form.new_quote').serialize(), function(resp) {
resp = $.parseJSON(resp);
if (resp[0].done == "ok") {
$(".msg").css("background-color", "#00fe00").text("Ok").fadeIn('slow').delay(5000).fadeOut('slow');
$("#quote_author,#quote_body").each(function(i,e) {
$(this).val("");
});
}
});
return false;
});
});
I have looked through your sources. IMHO the better way to achieve your goal is to do it in the Rails way. I mean that you already use jquery rails script. So you can easily stick to UJS with RJS approach in your rails 3 application:
In form:
form_for(@quote, :remote => true) do |f|
In controller:
def create
@quote = Quote.new(params[:quote])
respond_to do |format|
if @quote.save
format.html { redirect_to(@quote, :notice => :quote_created) }
format.xml { render :xml => @quote, :status => :created, :location => @quote }
format.js
else
format.html { render :action => "new" }
format.xml { render :xml => @quote.errors, :status => :unprocessable_entity }
format.js
end
end
end
In create.js.erb (below is HAML syntax):
- if @quote.errors.any?
$('#data_form').html('#{escape_javascript(render(:partial => "form"))}');
- else
$('ul.data_grid').prepend('#{escape_javascript(render :partial => "quote", :locals => { :quote => quote })}');
You can wrap your form with #data_form
and quotes list with ul.data_grid or change selectors in create.js.erb
. Also in that file you can clear form on success and show flash messages or whatever you need here.
After all don't forget to throw out this code from application.js (it's unnecessary any more):
$("form.new_quote > .actions > [type=submit]").live("click", function() {
$.post('/ajax_new', $('form.new_quote').serialize(), function(resp) {
resp = $.parseJSON(resp);
if (resp[0].done == "ok") {
$(".msg").css("background-color", "#00fe00").text("Ok").fadeIn('slow').delay(5000).fadeOut('slow');
$("#quote_author,#quote_body").each(function(i,e) {
$(this).val("");
});
}
});
return false;
});
精彩评论