Django editing a user generated object - ajax

I'm trying to figure out how to do an inline editing for a user-generated object, what the rough procedure (no code just steps), and whether or not there's some way to do this without AJAX - of course it wouldn't be "inline" anymore.
Say the user object is just 1 line of text and 1 image. Something like,
class UserObject(models.Model):
text = models.CharField()
image_path = models.CharField()
If I were to use AJAX, would this be how it'd go? (sorry this is vague, I can figure out the details just trying to see if I understand the concepts correctly)
Create a form, populate it with an instance of the object belonging to the current user
Next to the image, I'd have, say, a "remove" button, which triggers an AJAX call to a URL that's something like project/remove/ab12345 that's connected to a view that handles it.
Wait for the AJAX call to be done
Then somehow remove the image and buttons, maybe by just deleting the div that contains it all
Is that right??
Also, what if I don't want to use AJAX? Would it go something like this?
Create a form, populate it with an instance of the object belonging to the current user
Next to the image, I'd have, say, a "remove" button, which directly links to the URL that's something like project/remove/ab12345 that's connected to a view that handles it
After the view deletes the image, it goes back to the editing page, which just refreshes and the image is no longer there.
Any pointers would be greatly appreciated!! I can figure out the details of the coding, just wondering if I am getting the concepts right.

An object created by a user is really no different from one you create yourself (except you have to be suspicious of potentially malicious input!). The simplest way to be able to edit objects outside the admin interface is to use the built-in UpdateView. Similarly you can delete them with a DeleteView. If you want to restrict you can edit objects you can user the PermissionRequiredMixin from django braces.

OK since I posted this ultra-vague question I'm going to answer it.
AJAX-free:
The AJAX free version is pretty much as I described, create a view and a URL that deletes the image and goes right back to the referring page. Next going to try the AJAX version, which basically requires a view that returns some kind of a signal of failure or success.
urls.py
url('^project/remove_image/(?P<image_id_string>[0-9A-Fa-f]+)/$', pbrand.views.ProjectRemoveImageView.as_view(), name='project_remove_image'),
views.py
class ProjectRemoveImageView(View):
redirect_url = '/project/edit' # the editing url
def get(self, request, image_id_string, *args, **kwargs):
# ... some checks on permissions
image.delete()
return HttpResponseRedirect(self.redirect_url + "/" + project.id_string)
inside the template
<a class = "btn btn-default btn-sm" href="{% url 'project_remove_image' i.id_string %}" role="button">remove</a>

Related

Rails form, load new record page rather than redirecting to it

I'm creating my first app in rails.
Basically, I have a new customer form, normally when you enter a new customer you are redirected to the record you created.
However as I am loading all my pages via ajax I want to load the new record in rather than re-direct to it.
I already have the form firing via ajax, I just need to know how I can access the new record URL to load it into my container.
Hope that makes sense. Thanks in advance!
You can add an option :remote => true to your form_for helper method, so that instead of page redirect the form gets posted via ajax.
For Ex :
<%= form_for(#post, :remote => true) do |f| %>
...
<% end %>
Then create a new template named create.js.erb which will get rendered after create method has been executed.
In this template, you can display the details of the new record you created.
For Ex :
$('some_element').replaceWith('<%=#posts.name %>');
Edit: You mentioned using load in your javascript. I would generally avoid this as you're making two round trips to the server. 1) Create 2) Get html to load into a div. Additionally, if there is an error that happens, it will be more difficult to catch and do the "good thing", whatever that might be.
Once you've added the remote: true option to your form, you need to deal with what happens on the server side of things.
Assuming your using REST, you'll have a controller with a create action in it. Normally, this method is creating the item and then subsequently returning the HTML for the create page. Instead of this, we need to create a javascript view for the action. This will tell the calling page what to when this action is hit.
Let's assume your form has a div called "new_record_form" and that you have another div called "new_records". You'll want to blank out the form elements in the form, effectively resetting it. You'll also want to add the new record to the "new_records" div.
To add the record to the new records div, you might do something like this.
$("#new_records").append("#{#new_record.name}");
When you submit the form, you should see this added. One great way to debug issues is to use the inspector. If you're in chrome, right click anywhere, inspect element and select network. Do this prior to form submission. You'll be able to see the ajax call and the response. Your logs will also be helpful.
Don't forget to blank out the form as well.
Note: You mentioned all your pages are ajax, but I highly suggest you evaluate if this makes 100% sense due to the various issues that result. Not saying this is the best article on the subject but might be worth a read.

How to navigate to the Edit route after New in a Spine stack

I'm using Spine.Stack and I'm trying to find the best way to end up at the Edit page for a new record that gets created. The spine/rails example on the site shows #navigate going back to the index listing, but I need to end up on the edit page the the record I've just created. Currently I have
item = WorkRequest.fromForm(e.target)
if item.save()
#navigate '/work_requests', item.id, 'edit' if item
Now this does end up on the edit page but because the model is an Ajax one it then saves to the server and gets the server side ID, but at the point I call #navigate the item.id is the client side ID (c-##). Therefore the URL I end up at is /work_requests/c-##/edit which has no sever side equivalent.
As far as I can see, I have two options
Wait for the Ajax to respond and then navigate to edit with the server generated ID
Call navigate, but then update the URL once the Ajax save responds (when the edit form gets re-rendered with the server side ID.
Option 2 seems best in the spirit of the non-blocking interface, but I need to be sure that if the user does anything in the meantime, that the ID's will all sort themselves out. Option 1 seems safer but does force the user to wait for the save to complete before being able to edit it.
As a side note; the reason for the immediate edit is to create one or more child items (like lines on an invoice) and these all use the nested resource path /work_requests/:id/work_request_lines
Any help greatly appreciated, cheers.

ASP MVC 3 prevent multiple inserts on page refresh

Let's say I have a simple ASP MVC3 list controller, with an add method, with an id parameter.
List:
http://localhost/MVCAPP/ListFoo/
Add method
http://localhost/MVCAPP/ListFoo/Add?id=1
In my Add method, I update my Viewmodel with the added element, then makes a call to:
return View("ListFoo", viewModel);
The updated list is displayed, and everything's almost fine.
The problem is that with such a return, the URL in the address bar is still
http://localhost/MVCAPP/ListFoo/Add?id=1
And if the user hits F5, another item will be added, which I'd like to prevent.
I know I can filter out such a behavior in the controller, but I'd rather prefer to redirect the browser address bar to:
http://localhost/MVCAPP/ListFoo/
Do you know any way to do this?
By the way, I'm not sure trying to control the address bar content is the right way to look at this issue...
Use the Action.RedirectToAction method to redirect the client after the work is done in the controller.
Besides that, you could use POST as FormMethod to send data to the server.
That is why you need to use PRG: Post-Redirect-Get when you are doing any such form post.
Have a look here.
So the best option is to redirect the user to a GET method to display the page.

CodeIgniter jQueryUI dialog form example

I am trying to use CodeIgniter and jQuery-ui dialog to create a modal window with form to update user information.
The process should be like:
1. Press a button on a view page.
2. A modal window pops up.
3. Inside the window is a form that a user can fill.
4. If the user filled something before, the information should be shown in corresponding field
5. Click the update button on the modal window to save the changes to database.
Can anyone provide a good sample of this process?
I used ajax to pass the data but it didn't work when I was trying to update the data to the database. It would be nice if an example of how to pass data from ajax to php and how php handle that.
Thanks,
Milo
well the jquery bit for post(), get(), ajax() works the same in any measure you would normally use it.. key difference here is with CI you can't post directly to a file-name file-location due to how it handles the URI requests. That said your post URL would be the similar to how you would access a view file normally otherwise
ie: /viewName/functionName (how you've done it with controllers to view all along. post, get, ajax doesnt have to end in a extension. I wish I had a better example then this but I can't seem to find one at the moment..
url = '/home/specialFunction';
jQuery.get(url, function(data) {
jQuery("#div2display").html(data);
});
in the case of the above you notice despite it not being a great example that. you have the url with 2 parameters home and specialFunction
home in this case is the controller file for home in the control folder for the home file in views the specialFunction is a "public function" within the class that makes the home controller file. similar to that of index() but a separate function all together. Best way I have found to handle it is through .post() and a callback output expected in JSON cause you can form an array of data on the php side json_encode it and echo out that json_encode and then work with that like you would any JSON output. or if your just expecting a sinlge output and not multiples echoing it out is fine but enough of the end run output thats for you to decide with what your comfortable doing currently. Hopefully all around though this gives you some clairity and hopefully it works out for you.

MVVM Light: Where do I instantiate a class from a model and how do I update/access it?

Right now, I'm working on my first WP7 app and have run into some questions, which I haven't been able to answer despite reading what I could find online. Please consider an app that has a main page, a parameters page and a results page. In the parameters page, the user can enter or update numbers in various textboxes. Hitting the back button takes the user back to the main page, where there is a button called "Calculate". Hitting that button should take the data, perform a calculation with it and take the user to the results page presenting a grid with the results.
In a file called Calculator.cs I have a class called Calculator inside a folder called Models. I also have my MainViewModel.cs, ParametersViewModel.cs, and ResultsViewModel.cs files inside the ViewModels folder and the corresponding MainPage.xaml, along with Parameters.xaml and Results.xaml inside a folder called Views. I'm assuming that all the data will be manipulated within the instance of the Calculator class and then a results set will be returned and directed to Results.xaml. I'm just at a loss as to where to instantiate the Calculator class, pass it data, then retrieve the results. I'm also somewhat puzzled how I will trigger the automatic navigation to the Results page when the calculation is done.
Any help with this would be greatly appreciated.
UPDATE: Passing a complex object to a page while navigating in a WP7 Silverlight application has some more info on the same subject. I can go into App.xaml.cs and add something like this:
public class Foobar
{
public string barfoo = "hah!";
}
public static Foobar myfoob = new Foobar();
Then access it from a ViewModel page, e.g. AboutViewModel.cs, like this:
public AboutViewModel()
{
string goo = App.myfoob.barfoo;
}
But at this point I'm still uncertain what unforseen effects that might have. I'm going to tackle serialization/tombstoning at this point to see what happens with either this approach or by using the same DataContext across pages. Otherwise, one of the posters in the link above mentioned serializing the params and passing them between pages. My concern there would be whether or not there is a character limit as with HTTP GET. Seems there is: URI Limits in Silverlight
There are of course lots of possible designs - and lots of them are correct in different ways!
Here's one I might use:
The Calculate button press should trigger the Navigate to the Results page
On navigate to, the Results page should show some animation (maybe just a progress bar)
On navigate to, the Results page should create a new ResultsViewModel, passing in the MainViewModel as parameters
the constructor (or some init method) of the ResultsViewModel should spark up a thread to do the calculation
when this calculation is complete, then the relevant properties of the ResultsViewModel will get set
at which point the databinding on the Results page will clear the animation and show the results
Other solutions are definitely available - will be interested to read what other people suggest and prefer.
As an aside, one thing to watch out for on your Results page is tombstoning - could be an interesting challenge!

Resources