using http://blog.bernatfarrero.com/in-place-editing-with-javascript-jquery-and-rails-3/
The gem uses json to update, but how can I trigger my update.js.erb to update the different parts of my pages?
EDIT
Using this in an invoice page. every item in the invoice has a price field that can be updated with best_in_place.
I need to update the Total Price for line item and amount due for invoice only after field has been updated successfully.
Ended up with something like:
respond_to do |format|
if #item.update_attributes(params[:item])
format.html { redirect_to order_url(#item.order_id), :notice => "Successfully updated item." }
format.js { }
format.json { head :ok }
Edited best_in_place.js line #175
loadSuccessCallback : function(data) {
this.element.html(data[this.objectName]);
// Binding back after being clicked
$(this.activator).bind('click', {editor: this}, this.clickHandler);
if(this.objectName == "item") $.getScript('update.js'); // If its an item, call update.js.erb
},
I wanted to do the exact same thing with best_in_place pcasa. In the current version (1.0.2), the loadSuccessCallback function triggers an ajax:success event. That allows you to do this in your application.js:
$('.best_in_place')
.best_in_place()
.bind('ajax:success', function(e) {
// do your post-json call magic
});
You don't need a view update.js.erb. As ezkl already pointed out, you need to set the respond_to of your controller to json. In addition, you need to activate best-in-place in your public/javascripts/application.js
$(document).ready(function() {
jQuery(".best_in_place").best_in_place()
});
and add it in your view:
<td><%= best_in_place task, :name, :type => :input, :nil => "Click to edit" %></td>
I have a tutorial on Ajax with Prototype and JQuery on my own site - and the JQuery Part uses best-in-place: http://www.communityguides.eu/articles/15
Have you tried something along the lines of:
def update
#user = User.find(params[:id])
respond_to do |format|
if #user.update_attributes(params[:user])
format.html { redirect_to(#user, :notice => 'User was successfully updated.') }
format.json { head :ok }
format.js
else
format.html { render :action => "edit" }
format.json { render :json => #user.errors, :status => :unprocessable_entity }
end
end
end
I haven't tested this with the code in the tutorial, but the idea is that you have to tell the controller method to load the Javascript file. I'm not sure how this will interact with the redirect, but the principle is correct.
Related
I have a Jquery UI Datepicker function globally to use the calendar in all the pages.
I created a seperate javascript page like the following:
var showDatePickers = function() {
$('[data-field-type="date"]').datepicker({
dateFormat: "yy-mm--dd",
showOn: "both",
buttonImageOnly: true,
buttonImage: "/assets/blue-calendar-icon.png",
buttonText: "Calendar"
});
}
$(showDatePickers);
I just post my datepicker field in my view,
<div class="field">
<%= f.label :Renewal_Date %>
<%= f.text_field :Renewal_Date, readonly: 'readonly', data: {field_type: date}}
</div>
I call the above function to a seperate javascript file.
$(function() {
if ($('html.asset_contracts').length == 1) {
$(document.body).on('ajax:success', '.new_asset_contract, .edit_asset_contract', showDatePickers);
}
});
It is working fine when the page loads, edit and new action. But When the rails validation error displays the datepicker function not working. It showing the blank text_field.
FYI: It's an ajax page and the new, create, update and edit action is working as ajax pages. So, I added remote: true in my form and i have new.js, edit.js, create.js and update.js
It's my controller,
def create
#contract = Asset::Contract.new(params[:asset_contract])
respond_to do |format|
if #contract.save
format.html { redirect_to asset_contracts_path, notice: "Successfully Created" }
format.js
format.json { render json: #contract, status: :created, location: #contract }
else
format.html { render action: "new" }
format.js
format.json { render json: #contract.errors, status: :unprocessable_entity }
end
end
end
def update
#contract = Asset::Contract.find(params[:id])
respond_to do |format|
if #contract.update_attributes(params[:asset_contract])
format.html { redirect_to asset_contracts_path, notice: "Succesfully Updated" }
format.js
format.json { head :no_content }
else
format.html { render action: "edit" }
format.js
format.json { render json: #contract.errors, status: :unprocessable_entity }
end
end
end
Thanks
You're creating the datepickers like so:
$(document.body).on('ajax:success', '.new_asset_contract, .edit_asset_contract', showDatePickers);
However, this will only run if the AJAX call is successful, so you'll need a handler for errors as well.
It appears you're using namespaced events and I don't see that referenced in the jQuery documentation. You'll probably want to use the global ajax events (e.g., ajaxComplete, ajaxError, etc.).
You'll either need to attach a separate handler for ajaxError to handle the error case or just use the ajaxComplete event in place of ajax:success. Unless you need specific error handling, ajaxComplete is the way to go, since you will only need to write/maintain one handler. As of jQuery 1.8, Global events are triggered on the document. You'll need to attach your listener to the document without any other selectors:
$(document).on('ajaxComplete', showDatePickers);
You can read more about the jQuery AJAX events on the Ajax Events page.
I am just starting out with Rails and Ajax and I am facing some problems integrating Ajax and Jquery.
I have data which I want to display and update in my div using jQuery.
I have written in Jquery a table where I can drag and drag items.
Right now I am using default items. I want to retrieve this items with back end rails but I am not too sure about how I could do it.
This is the model. I want to show these in the table.
class SlotAllocation < ActiveRecord::Base
attr_accessible :group_index, :lesson_type, :timeslot_id
def as_json(options={})
{
:group_index =>self.group_index
:lesson_type =>self.lesson_type
:timeslot_id =>self.timeslot_id
}
end
This is the controller actions. I've added format.js to the index and update functions.
def index
#slot_allocations = SlotAllocation.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #slot_allocations }
format.js{ render :json => #slot_allocations }
end
end
def update
#slot_allocation = SlotAllocation.find(params[:id])
respond_to do |format|
if #slot_allocation.update_attributes(params[:slot_allocation])
format.html { redirect_to #slot_allocation, notice: 'Slot allocation was successfully updated.' }
format.json { head :no_content }
format.js { head :ok}
else
format.html { render action: "edit" }
format.json { render json: #slot_allocation.errors, status: :unprocessable_entity }
format.js { render :js => #slot_allocation.errors, :status => :unprocessable_entity }
end
end
end
In the view I have a table. It is working according to some default values I have placed in.
<table id='subjects' border="1">
<tbody></tbody>
</table>
Now I want to change these default values to the values I have in rails.
By trying to piece together certain info I got from codes from github.
I tried out this.
slots= {
url: '/slot_allocations'
}
To aid in my understanding I did something like that in JQuery just to see what information I could retrieve and it turns out that I get [object Object].
TryDiv(slots);
function TryDiv(slots){
var div = document.getElementById('tryout');
div.innerHTML = div.innerHTML + slots;
}
I am not too sure what is contained in that object and would appreciate it if someone could help me out on how I could retrieve the information I need from the model.
Any articles or code samples I could refer to would be appreciated as well.
I'm developing a webapp with Ruby 1.8.7 and Rails 2.3.5, which will manage some industrial process. One of the requirements is that, when someone wants to delete a registry, the delete task will have to make an update to one of the fields of the DB table. This field establishes if a record is active or not.
I have modified the default delete method generated by the scaffold:
def activar
#alarma = Alarma.find(params[:id])
respond_to do |format|
if #alarma.update_attribute(:estado_id => 1)
flash[:notice] = 'La alarma ha sido activada.'
format.html { redirect_to(#alarma) }
format.xml { head :ok }
else
format.html { render :action => "index" }
format.xml { render :xml => #alarmas }
end
end
end
def desactivar
#alarma = Alarma.find(params[:id])
respond_to do |format|
if #alarma.update_attribute(:estado_id => 2)
flash[:notice] = 'La alarma fue desactivada.'
format.html { redirect_to(#alarma) }
format.xml { head :ok }
else
format.html { render :action => "index" }
format.xml { render :xml => #alarmas }
end
end
end
where :estado_id => 1 is active, and :estado_id => 2 is deactive. However, when a I try to do the update, it doesn't change the attribute. Actually, it doesn't do anything.
Does anyone have a clue?
You should use update_attributes in your case
update_attributes(attributes) public
Updates all the attributes from the
passed-in Hash and saves the record.
If the object is invalid, the saving
will fail and false will be returned.
example:
#user.update_attributes(:status => 'active')
or #alarma.update_attribute(:estado_id, 2) if you want to use update_attribute
update_attribute(name, value) public
Updates a single attribute and saves
the record without going through the
normal validation procedure.
In our rails application we have a page where upon submit we save data in db. On this page, we have some fields which are dynamically generated and I see that in case of a validation error when page reloads it doesn't populate these fields with the values present upon posting.
In controller we have the following method defined for populating it:
def build_my_registration_type_memberships
#memberships = []
ListCache.my_registration_types.each do |my_registration_type|
#memberships << MyRegistrationTypeMembership.find_or_initialize_by_my_id_and_my_registration_type_id( #my.id, my_registration_type.id )
end end
In above method when my registration is opened in edit/view mode, it shows the values using this #membership method. But on posting in case of error it doesn't reload this with correct information. So my question is how could I repopulate #membership in case of an error on posting?
Thanks for help.
As, I understand you want some values available to your new method or the page that is rendered after if the create fails.
I assume you must have have the respond_to block in your create method. And you're doing this:
def create
...
respond_to do |format|
if #patient.save
format.html { redirect_to #object, :notice => "Object was successfully saved." }
format.xml { render :xml => #object, :status => :created, :location => #object }
else
format.html { render :action => :new }
format.xml { render :xml => #patient.errors, :status => :unprocessable_entity }
end
end
end
As you can notice, in the else part the new action is just rendered. Using some template the view is just delivered. Now, you just have to do whatever you're doing in the new action to make those values available, in the else part.
def create
...
respond_to do |format|
if #patient.save
format.html { redirect_to #object, :notice => "Object was successfully saved." }
format.xml { render :xml => #object, :status => :created, :location => #object }
else
format.html {
#memberships = []
ListCache.my_registration_types.each do |my_registration_type|
#memberships << MyRegistrationTypeMembership.find_or_initialize_by_my_id_and_my_registration_type_id( #my.id, my_registration_type.id )
end
render :action => :new
}
format.xml { render :xml => #patient.errors, :status => :unprocessable_entity }
end
end
end
And, the values you wanted will be available in the rendered form.
Better, you move to that code to a before filter or something, which makes those values available to those two methods (new and create).
Basically I am trying to capture the value of the form field before it is saved to the database. Then I intend to use that value in my controller to update a specific field in the database,
using
#taskforms.update_attribute('notes',
$notes)
I need to do this because I know of no other way to update that that does not require the full record to be validated.
The suggestion below to use #taskforms.save(false) is really not what I was looking for optimally. However it could work. However having and issue to get it to work.
What I am currently using (that works with validations)
def myupdate
#taskforms = Taskforms.find(params[:id])
respond_to do |format|
if #taskforms.update_attributes(params[:taskforms])
#taskforms.update_attribute('edited_at', Time.new )
flash[:notice] = 'Note was successfully updated.'
format.html { redirect_to(:controller => "taskforms", :action => "displayedit", :id => #taskforms.id) }
format.xml { head :ok }
else
format.html { render :action => "displayedit" }
format.xml { render :xml => #taskforms.errors, :status => :unprocessable_entity }
end
end
end
However when I try the save(false) it doesn't save and triggers validations anyway
def myupdate
#taskforms = Taskforms.find(params[:id])
if #taskforms.save(false)
#taskforms.update_attribute('edited_at', Time.new )
flash[:notice] = 'Note was successfully updated.'
format.html { redirect_to(:controller => "taskforms", :action => "displayedit", :id => #taskforms.id) }
format.xml { head :ok }
else
format.html { render :action => "displayedit" }
format.xml { render :xml => #taskforms.errors, :status => :unprocessable_entity }
end
end
I have never used Save in the past just the default respond_to do |format| so suspect my code is incorrect.
#taskforms.save(false) will save your model without any validations if that is your main goal.