views:

119

answers:

1

I'm in the process of migrating from Prototype to jQuery and moving all JS outside of the view files. All is going fairly well with one exception. Here's what I'm trying to do, and the problem I'm having. I have a diary where users can update records in-line in the page like so:

  • user clicks 'edit' link to edit an entry in the diary
  • a get request is performed via jQuery and an edit form is displayed allowing the user to modify the record
  • user updates the record, the form disappears and the updated record is shown in place of the form

All of that works so far. The problem arises when:

  • user updates a record
  • user clicks 'edit' to update another record
    • in this case, the edit form is shown twice!
    • In firebug I get a status code 200 when the form shows, and then moments later, another edit form shows again with a status code of 304

I only want the form to show once, not twice. The form shows twice only after I update a record, otherwise everything works fine. Here's the code, any ideas? I think this might have to do with the fact that in food_item_update.js I call the editDiaryEntry() after a record is updated, but if I don't call that function and try and update the record after it's been modified, then it just spits up the .js.erb response on the screen. That's also why I have the editDiaryEntry() in the add_food.js.erb file. Any help would be greatly appreciated.

diary.js

jQuery(document).ready(function() {

  postFoodEntry();
  editDiaryEntry();
  initDatePicker();

});

function postFoodEntry() {
  jQuery('form#add_entry').submit(function(e) {
    e.preventDefault();
    jQuery.post(this.action, jQuery(this).serialize(), null, "script");
    // return this
  });
}
function editDiaryEntry() {
  jQuery('.edit_link').click(function(e) {
    e.preventDefault();
    // This should look to see if one version of this is open...
    if (jQuery('#edit_container_' + this.id).length == 0 ) {
      jQuery.get('/diary/entry/edit', {id: this.id}, null, "script");
    }
  });
}

function closeEdit () {
  jQuery('.close_edit').click(function(e) {
    e.preventDefault();
    jQuery('.entry_edit_container').remove();
    jQuery("#entry_" + this.id).show();
  });
}
function updateDiaryEntry() {
  jQuery('.edit_entry_form').submit(function(e) {
    e.preventDefault();
    jQuery.post(this.action, $(this).serialize(), null, "script");

  });
}
function initDatePicker() {
  jQuery("#date, #edit_date").datepicker();
};

add_food.js.erb

jQuery("#entry_alert").show();
jQuery('#add_entry')[ 0 ].reset();
jQuery('#diary_entries').html("<%= escape_javascript(render :partial => 'members/diary/diary_entries', :object => @diary, :locals => {:record_counter => 0, :date_header => 0, :edit_mode => @diary_edit}, :layout => false ) %>");
jQuery('#entry_alert').html("<%= escape_javascript(render :partial => 'members/diary/entry_alert', :locals => {:type => @type, :message => @alert_message}) %>");
jQuery('#entry_alert').show();
setTimeout(function() { jQuery('#entry_alert').fadeOut('slow'); }, 5000);
editDiaryEntry();

food_item_edit.js.erb

jQuery("#entry_<%= @entry.id %>").hide();
jQuery("#entry_<%= @entry.id %>").after("<%= escape_javascript(render :partial => 'members/diary/food_item_edit', :locals => {:user_food_profile => @entry}) %>");
closeEdit();
updateDiaryEntry();
initDatePicker();

food_item_update.js

jQuery("#entry_<%= @entry.id %>").replaceWith("<%= escape_javascript(render :partial => 'members/diary/food_item', :locals => {:entry => @entry, :total_calories => 0}) %>");
jQuery('.entry_edit_container').remove(); 
editDiaryEntry();
+1  A: 

Maybe you should be using the live function instead of binding to the click once. I am not sure if it will help but it will sure alleviate the need to bind the click event again after updating the page.

nathanvda
Thanks @nathanvda, that definitely worked!
aressidi