views:

1687

answers:

2

So i have my destroy command. The problem is I don't want my users to be able to delete this category if it contains items. So I have an if statement in my destroy method. That works all great, but I'm using AJAX to have the page not load and using a destroy.js.erb file. My method is below:

def destroy
    @promotion_type = PromotionType.find(params[:id])

    if Promo.find_by_promotion_type_id(params[:id]).nil?
    @promotion_type.destroy

    respond_to do |format|
      format.html { redirect_to(promotion_types_url) }
      format.js  {render :layout => false }
      format.xml  { head :ok }
    end
    else
      respond_to do |format|
        format.js  {}
      end
    end
  end

This is my javascript(jquery):

$('a.delete').click (function(){
    if(confirm("Are you sure?")){
        var row = $(this).closest("tr").get(0);
        $.post(this.href, {_method:'delete'}, null, "script");
        $(row).hide();
        return false;
    } else {
        //they clicked no.
        return false;
    }

One of my problems is that once they click yes, it hides the row and AJAX deletes its. If I didn't hide it, it would be deleted but since the page is doesn't refresh, it looks like it wasn't deleted, so I hide it for the effect. The only problem with this solution is when I get to my categories. I don't want users to delete it if it has items inside it. I can't throw ruby code in my javascript file, and I can't (or don't know of a way) to throw javascript variables or $(this) into a .js.erb file.

The code runs correctly for the most part, but it hides the row now even if it failed to delete it. So i was going to throw an alert('Cannot be delete'); into my .js.erb file, but that alert fires regardless of whether it was or wasn't deleted. I'm sure there's a better solution to do all this, but I don't know it.

A: 

Why don't you just return true or false depending on whether it was deleted? Define a callback in your $.post to handle this.

$.post(yourURL, yourDATA, function(data){ myCallback(data); }, "text");

function myCallback(data) {
    if( data === "true" )
        ...
    else
        ...
}

I used "text" as a response format for demonstration. You might want something more like "json". The "script" format as you have will treat your response as javascript; since you said you copied that from somewhere, I don't think that' what you really need. IMO, what is returned should only be data, as you get with "xml", "text", or "json" formats. You can find more on the jQuery docs page.

geowa4
Can you go more indepth? I got the .post code from another site and added the rest so I'm not sure how it works.
Mike
A: 

Like geowa4 says you can do the following

 $('a.delete').click (function(){
        if(confirm("Are you sure?")){
            var row = $(this).closest("tr").get(0);
            $.post(
               this.href, 
               {_method:'delete'}, 
               function(data){$(row).hide();}, 
               "script"
            );
            // Move from here to the callback
            //$(row).hide();
            return false;
        } else {
            //they clicked no.
            return false;
        }
 }

As an alternative you could simple have the JS "hide" code in your .js.erb file along with the alert. You will also need to pass a variable (@destroyed) to erb and then use an if statement for weather to fire the alert based on the @destroyed variable.

def destroy
    @promotion_type = PromotionType.find(params[:id])

    if Promo.find_by_promotion_type_id(params[:id]).nil?
      @deleted = true
      @promotion_type.destroy

      respond_to do |format|
        format.html { redirect_to(promotion_types_url) }
        format.js  {render :layout => false }
        format.xml  { head :ok }
      end
    else
      @deleted = false
      respond_to do |format|
        format.js  {}
      end
    end
end
Will
It works for the most part. But it is still hiding it even if it's not deleting it. I can't throw $(row).hide(); into the .js.erb file because row isn't defined. function(data)${$(row).hide();} is hiding the row regardless. I'm not sure way (data) is there because it is never used.
Mike