continuation: Entry level javascript with rails: updating a div on form submit (3.1/jquery)
I'm able to return 'something' now, just not what I want.
CONTROLLER
class ThisController < ApplicationController
respond_to :js
def update
#do stuff
if resource.save
respond_with(resource)
end
end
VIEWS/RESOURCE
update.js.coffee
$(".testdiv").text('<%= escape_javascript(render(:partial=>"resource"))%>')
_resource.slim
p= resource
p whhhhy
Basically, I have a form that posts remote (i.e. remote=true) that updates a db field and then the update controller returns that field. This form posts, the data changes, and when I change the text in _resource.slim the text will change....but the 'p= resource' does not get evaluated at all. I want the .testdiv to watch for changes made via the form.
So, I've been able to rig a minimal version one step closer to what I want....only I can't actually get variables to pass into the template. Closest tutorial I've referenced, but I'm not actually using the code, just trying to get a working ajaxy version within something I have that was already working.
I cannot see the problem atm, but it isn't right. I don't have access to manipulating the resource variable, but I am unable to. It seems simple enough (though I'd like to do with out a partial and extra files in views/resource, just put js in the assets/controller.js.coffee)
As stated in the comment, I changed the local variable to an object variable. This resolved the issue.
Related
I want to know if it is possible to directly modify and save a model instance in the HTML Template and not via a view and extra URL.
My user has a Boolean Property, I want to display it as a toggle button on the website and the user should be able to toggle it on or off without leaving the website or reloading it.
class User(AbstractBaseUser, PermissionsMixin):
...
autoplay_enabled = models.BooleanField(default=True)
...
Is this possible without an extra view or form?
Basically I just need to set
request.user.autoplay_enabled = False (or True)
and then save() it
If I can't modify the object directly in the HTML template is it at least possible to just execute a function I have defined somewhere in my Python code, without having the need to create a new view?
What you're asking doesn't make any sense at all. HTML is just sent to the browser for display. You can't do anything "from HTML" without making some kind of request to the server, and the server won't do anything unless that request is received by some code - eg a view connected to a URL.
If you want something to happen without refreshing the page, you need to use Ajax. You can use a simple Ajax POST to a view that toggles the value and saves it - it only needs a dozen lines of code between front and back end.
So I have a simple game, in the index.erb, the code is as follows:
<div class="battleInfo">
<h2> Your HP: <%= #my_knight.hp %> </h2>
<h2> Dragon HP: <%= #my_dragon.hp %> </h2>
<h1> <%= #results %> </h1>
</div>
I want to use Jquery in the public folder as app.js, to update the HP info so we can see the whole run down of the characters and how they die.
The JS code:
function postHP() {
$(".battleInfo").append(my_knight.hp);
$(".battleInfo").append(my_dragon.hp);
};
I get an error that my_knight is not defined. If I use #my_knight, it says the # is an illegal character.
It's my first week of Ruby and I'm not sure how to get this to work and can't find the answer online.
I guess the basic question would be how to get info from js into sinatra.
I have the CSS working just fine.
Any help is appreciated, thanks
Firstly, you need to understand what is happening where/when. Firstly, client is making a request. Rails receives a request, instantiate controller, which sets instance variables. Then rails gets your erb file, finds all <%.. %> blocks and substitute/execute commands in there. This results in pure HTML which is being send back to the customer.
When customer receives html, it loads all the css and javascript files referenced in this html. This javascript has absolutely no access to controller's instance variables - it has no idea they have ever existed, it has no idea it is rails application, doesn't know what controller is etc.
The most common way to pull any sort of data back to the view is to send an AJAX - this means that the browser will make an additional call to your server, which will return a JSON object, understandable by javascript and which can be used to update the loaded HTML.
There are number of steps to implement this. First of all, you need to create a new action in your controller, like update_hp or sth. Then you have to trigger AJAX call with your javascript and define a handler (functions) to handle successful response from the server. This handler will most likely update the requested fields.
You can see some examples on how to build AJAX request here, and some details on building json responses here. The topic is too broad to describe it here. Give it a go and come back when you're stuck.
I'm running rails 4.0.4. I have a form I'm using a partial in to add a subset of fields. The user has the option to remove those fields and replace them with other fields once they're on the page. I'd like to be able to add those fields back in in the event that they want to undo their decision.
Render isn't available in javascript files (which seems odd for js.erb files). I've gotten as far as using the following to read the text of the file into a variable.
var master_quantity = "<%= data='';File.open("#{Rails.root}/app/views/shared/_a2a_master_quantity.html.erb","r").each_line{|x| data+=x};data %>";
Unfortunately escape_javascript doesn't appear to be available in the asests folder either, so I'm unable to use this string as it breaks the javascript.
Anyone have any suggestions on cleaning the string or alternate methods to get the partial into my javascript?
You could try,
controller = ActionController::Base.new
controller.send(:render_to_string, '/shared/a2a_master_quantity')
Whatever you pass to render_to_string above are params for that method.
You may or may not need that leading '/' for '/shared'.
If I understand your question, and the partial never changes, you won't need to get it from the server. Just hide it in CSS (such as with JQuery's $('#selector').hide() )
On the other hand, if you need Ruby to customize your partial each time the user restores it, you can send an AJAX request from the browser to your server to request a new version of the partial.
Add a line to a suitable controller action that renders your partial:
render :partial => 'a2a_master_quantity' and return if request.xhr?
Make a suitable XML HTTP Request in your JavaScript to get this partial (such as JQuery's $.ajax().)
Then use JavaScript to add it to the DOM in the appropriate place.
I'm looking to capture and save the state of a page (Django template + backend) after the user makes some modifications (through JQuery) to the appearance of the page. Now that I've gotten hold of the innerHTML using a JS variable, I need to send it over to the Django view that will do the saving. How do I call this Django view and pass it the JS variable?
P.S: First ever question on stackoverflow, please let me know if the question isn't clear or is improperly formatted.
Handiest way to get started is to first make a proper form and a django view that reacts to it ("request.post"). The form should have fields for whatever you're changing in the page.
Next up, submit that form's variables from your page with jquery.ajax.
So the idea is to isolate the various problems:
What should be the form parameters?
Get a view running that makes the actual changes.
Get the javascript working.
I'd like to add Ajax to my admin form for editing a model. The model has a list field. I would like the Ajax to create a list of inputs with add and remove buttons, automatically calling back to the server when the user clicks "add" or "remove".
What I'm stuck on is: how does the widget know what the backing model is? If it doesn't know, how can it update the values? (I would want to provide Urls like api/remove-list-item?pk=foo&item=bar to the front end.)
This makes me think that it doesn't fit with the general Django framework philosophy to be doing this. Instead, perhaps I should be keeping the values locally and sending them through the same validation process as the rest of the data. But I'm a bit unsure of how to do this.
I am doing something similar to this (although not in an admin form). I'm not sure if it is a recommended way of doing things...but it does seem to work for me.
I have an action set on a html form in the template that calls a view which basically has the sole task of updating the data in the database and returning a "success" (or whatever I happen to want it to return).
On the template side of things I also use the jquery form plugin, which I use to update the div to show the new value.
Again, I'm not sure if this is the way others would recommend, but I do feel it seems to make sense....and it does seem to work just fine.
In urls.py, make a rule like:
(r'^api/remove-list-item/(?P<id>\d+)$', 'yourApp.views.remove'),
then in the yourApp.views have something like:
from django.shortcuts import get_object_or_404, redirect
def remove(request, id):
dbObj = get_object_or_404(YourModel, id=id)
dbObj.active = False # Or whatever you want to do with the object
dbObj.save()
return redirect('some-view')
You can then make queries like /api/remove-list-item/123