Deep Jain
Deep Jain

Reputation: 47

ajax response in web2py

i am working on adding ajax to comments in my webpage. following are the functions and the view file

def normalajax():
    news=db(db.newsfeed.id>0).select(orderby=~db.newsfeed.created_on)
    return dict(news=news)

def new_post():
    form=SQLFORM(db.newsfeed)
    if form.accepts(request.vars, formname=None):
        news=db(db.newsfeed.created_by==auth.user_id).select(orderby=~db.newsfeed.created_on)
        return DIV(news)
    elif form.errors:
        return TABLE(*[TR(k, v) for k, v in form.errors.items()]) 


{{extend 'layout.html'}}

<form id="myform">
  <input name="body" id="body" />
  <input type="submit" />
</form>
 <script>$('textarea').css('width','600px').css('height','50px');</script>

<script>
jQuery('#myform').submit(function() {
  ajax('{{=URL('new_post')}}',
       ['body'], 'target');
  return false;
});

</script> 

<div id="target">
 {{for post in news:}}
 <div style="background: #ffffff; margin-bottom: 5px; padding: 8px;">
 <h3>{{=db.auth_users[post.created_by].first_name}}</h3> On {{=post.created_on}}:
  {{=MARKMIN(post.body)}}

 </div>    
 {{pass}}

</div>

The problem is that, when i post a new comment, the entire div is replaced by the new content,without all the styling which i have given in the for loop

i have given the links of screenshots: this is before posting comment: https://skydrive.live.com/redir?resid=AFF5DF0EB4A5BCD5!122&authkey=!AFg6utSsGLyYRG4&v=3&ithint=photo%2c.png

this is after posting comment: https://skydrive.live.com/redir?resid=AFF5DF0EB4A5BCD5!123&authkey=!AJyroKLQLp5ssPs&v=3&ithint=photo%2c.png

after posting comment, the ajax response replaces contents of div target, how do i access the response and display it like it is dislayed before posting...

Upvotes: 1

Views: 4180

Answers (2)

Anthony
Anthony

Reputation: 25536

Once the page is in the browser, you cannot execute Python code on it. The Python code in your original template does not exist once the page is in the browser -- that has all been executed to generate pure HTML source code. When you submit the form, the new_post function returns DIV(news), which gets converted to HTML. That HTML replaces the content of the "target" div on the page. When you generate an Ajax response, you have to generate the final HTML on the server and send that to the browser -- the browser does not do any template processing.

In any case, a better approach would probably be to use Ajax components. Not tested, but something like:

def news():
    return dict()

def news_list():
    if request.args(0) == 'user':
        query = db.newsfeed.created_by == auth.user_id
    else:
        query = db.newsfeed.id > 0
    news = db(query).select(orderby=~db.newsfeed.created_on)
    return dict(news=news)

def new_post():
    form = SQLFORM(db.newsfeed)
    if form.process().accepted:
        url = URL('default', 'news_list.load', args='user')
        response.js = "$.web2py.component('%s', target='news');" % url
    return dict(form=form)

In /views/default/news.html:

{{extend 'layout.html'}}
{{=LOAD('default', 'new_post.load', ajax=True)}}
{{=LOAD('default', 'news_list.load', ajax=True, target='news')}}

In /views/default/news_list.load:

{{for post in news:}}
 <div style="background: #ffffff; margin-bottom: 5px; padding: 8px;">
 <h3>{{=post.created_by.first_name}}</h3> On {{=post.created_on}}:
  {{=MARKMIN(post.body)}}
{{pass}}

In /views/default/new_post.load:

{{=form}}

In the above code, news.html is the main page, and it contains two Ajax components -- one for the form, and one for the news list. Initially, the news list component loads all the news posts (you might consider limiting that or paginating if there are many posts). When the form is submitted, it returns some Javascript via response.js, which gets executed after a successful submission. The Javascript calls $.web2py.component() in the browser, which reloads the news list component in the "news" div by calling the news_list() function with "user" as a URL arg (the "user" arg is a flag that tells the news_list() function to return only the posts of the current user).

Upvotes: 3

gauravp
gauravp

Reputation: 178

apply same css to your Ajax response to get the same view

this css is missing from ajax reponse.

view this example

$.ajax({
  url: "test.html",
  cache: false
})
 .done(function( result) {
 $( "#results" ).append( result); // or replace your "result" coming from server
});

Upvotes: 0

Related Questions