How to update with AJAX a list after the action of a remote form?

Asked

Viewed 816 times

4

I have a problem I’ve never had in Java but I’m almost going crazy in Rails. I’m developing a project where there are users and groups. So I created a separate model for relationship N:N between users and groups.

In the group show page I created the group description, below appears the partial form _groupsuser to allow the group creator to add users to that group. Below all this I rendered the partial to display the list of users belonging to the group.

The project has a slightly different structure because I am using partials to avoid replicating the same logic in the control and view so I would like to avoid messing around with the structure and focus only on updating the listing once I have the answer 'ajax:complete'. In case I created in the control the create method:

def create
    if group.user == current_user       
        @groupsuser = Groupsuser.new(groupsuser_params)
        @groupsuser.group = group
        if @groupsuser.save
            flash[:notice] = 'User was successfully add.'
        else
            flash[:alert] = 'User cannot be add.'
        end
    else
        flash[:notice] = "You didn't have permition."
    end
    head :ok
end

I would like to update using only ajax similar to java update method with type facelets:

    <p:commandButton value="All" id="btnAll" process="@all" update="grid"   
                actionListener="#{personBean.savePerson}"/>

For example:

$('create_button').onClick('ajax:complete', render(@group));

to refresh the full page or

$('create_button').onClick('ajax:complete', "Comando mágico para atualizar apenas a div");
  • 1

    What problem did you find? If it doesn’t work, how exactly doesn’t it work? What happens to you?

  • So, I’m not very feral in Avascript but tried everything that is way and the user is added in the table groupsuser perfectly. However, it does not update the page automatically. When I have update manually appear the :notice comments and the user in the listing, but I would like to implement a way where as soon as I click add the page already updates to show the notification and the user in the listing. I already tried to use render and redirect_to (despite losing notification) but does not update the page automatically.

  • I don’t know if this idea of mine works because I’ve been taking a look at the English OS and I found people arranging adverse solutions for me does not work because the groupsuser route is within the groups in Routes.rb. Does not have a way to update the page along with the information coming from the @gropsuser backend?

1 answer

1


First of all, study at Gem Cancan to implement permissions.

With Cancan, the code of your method would look like this:

def create
    @groupsuser = Groupsuser.new(groupsuser_params)
    @groupsuser.group = group
    if @groupsuser.save
        flash[:notice] = 'User was successfully add.'
    else
        flash[:alert] = 'User cannot be add.'
    end
end

Now to register user by Ajax, first add the option remote: true to your registration form. With this, you do not need to add JS code to the POST form with Ajax.

Then add the code at the end of the create action. This code indicates that the request will be of the type javascript.

respond_to do |format|
    format.js
end

Finally, create the create.js.erb view, which contains the JS code that should be executed in the request response. It must be something like:

$('div#users-container').html('<%= j render(@group.users) %>');

With this code, you don’t need to add JS Switch "in hand". The option remote: true is available from the library jquery_ujs.

  • So I implemented your suggestion and realized that you are running ok but in the render of create.js.erb you are directing to a route that is not valid. Actionview::Template::Error (Missing partial group/users/user

  • I tried to change the render to $('div#users-container').html('<%= j render(group_path) %>'); and solved the route problem but was missing the :id parameter that serves to load the group in group_model = Group.find(params[:id])&#xA; @group = GroupPresenter.new(group_model, self)&#xA; @usergroups = Groupsuser.where(group: group_model)

  • You must add the :id en route. An example would be: '/groups/:id/users'

  • In the routes.rb? There’s another question too. I don’t need to access the users because the show.html.erb where are these features that I am doing is inside the 'views/groups/show.html.erb' directory and the 'create.js.er'b I had to create inside of views/**group**/groupsusers/create.js.erb , would not only change the render and send the :id as: :id => @group.id ?

  • I tried with ´$('div#users-container').html('<%= j render group_path(@group) %>');´ and the following error appears: '´ActionView::Template::Error (The partial name (/pt-BR/groups/21) is not a valid Ruby identifier; make sure your partial&#xA;name starts with a lowercase letter or underscore, and is followed by any combination of letters, numbers and underscore&#xA;s.)

  • @brunowff, the method render receives the path of a view and not of a route. Read it here before. The method render should receive the path of the partial that creates the div with all its users. For example, render partial: 'groups/users', renders the file app/view/groups/_users.html.erb.

  • Yes but as I’m passing the value of @usergroups through <%= render partial: 'groupsusers', locals: {usergroups: @usergroups}, remote: true %> and listing through <% @usergroups.each do |g| %> when I only rescan the partial _groupsusers.html.erb the value of @usergroups is nil and does not define each method. ActionView::Template::Error (undefined method each' for nil:NilClass):

  • remote: true is an option of form_for, not of render.

  • 1
Show 4 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.