Ajax and Django forms - javascript

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

Related

How do I write to an HTML file using expressjs

Ok, this sounds crazy, but let me explain. I want a user to be able to push a button, and then the html file is edited in such a way that it a NEW p element is created, and stays there PERMENENTLY (eg on reload and for EVERYONE to see). Any way on how I could do that.
Again I am using node.js/express, and html/js/css.
It really depends upon exactly what you're doing.
Conceptually, you would probably use some sort of template system for generating your HTML files (like Jade, Dust, EJS, Handlebars, Nunjucks, PUG, etc..) and then you store some state in a database and use a query from the database as input to the template whenever you render a particular page.
So, when you add an item to the database, it will show up in all future renders of the page.
So, your button would trigger a form post to your server which would add an item to the database and the response from the form post would be a rendering of the page after adding the item to the database. All future renders of the page from all users would also show those same items in the rendered page.

Rails API - helpers for AJAX

I have a normal rails app website, but on some pages I need to use AJAX.
I already have some working AJAX Javascript code using jQuery, but so far I haven't used any rails helper to do that, writing strings corresponding to paths manually.
But is there a more convenient way to do it in javascript ? Suppose I have a javascript function which takes an ID as argument, and must call an AJAX action. So far I've been doing it this way
var url = "/tags/tagID"
function getTag(tag_id){
$.get(url.replace("tagID", tag_id) +'.json')
.fail(function(data){
alert('Oops error !');
})
.success(function( data ) {blabla ] )
}
Is it possible to rename the .js to .js.erb and use path helpers ? So I could get rid of this url variable and write
routes.rb
resources :tags
tags.js.erb
$.get(tag_path("tagID").replace("tagID", tag_id)....
Or is there a more convenient way to do this ? I only need very little AJAX, so I don't want to use a frontend framework (Angular, etc.), just jQuery
EDIT My scenario
A user searches for a given tag thanks to an autocomplete searchbar. This searchbar will return the ID somehow.
The user can select several tags this way, and their IDs will be stored in an array. Now, upon clicking a button, I want to send a query to a non-RESTful (with the ID array as parameter) controller action via AJAX. For now I will focus on sending one item at a time (so just one ID string), for it is easier/more reactive.
This action is actually going to look in my models for projects and ingeneers that possess this tag, and return a JSON with formatted results.
Yes, you can use *.js.erb to use Rails helpers. Rails provides some handy helpers to work with Ajax. Normally with rails you can use them by using the the tag remote: true.
In your case something like
<%= link_to 'Tags', tags_path(<tag.id>), remote: true %> (roughly),
Read more about using Rails helpers with Ajax here, and this explains it nicely.
Update
Rails is using CSRF token to validate requests (except GET), so if you are going to use pure HTML/JavaScript, you want to add the token to your request. Have a look at this post on the same.
I agree there is no out-of-the-box way of doing that, but there are few workarounds.

Django modify model instance from HTML

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.

How do you call a Django view with parameters from JavaScript?

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.

rails js/ajax updating div not properly updating with information

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.

Categories

Resources