I want to create a Facebook-like page where in if user scroll down the page fetch old post without refreshing. I have done this earlier using Ajax and appending the HTML pag
My other answer you linked in your question contains all the details and tricks you need to implement the "Load more..." functionality: Dynamically refresh a part of the template when a variable is updated golang
Yes, it's not trivial, but it's not that hard / complex either. That answer discusses different ways / alternatives, but obviously a solution only needs one.
Here I show a working solution. The Load more button here will not "remember" what were the last posts returned, it will just retrieve 2 new posts. Think about how you could implement sending back the last ID, and when more is requested, send records following that.
The complete, runnable application code can be found here on the Go Playground. Of course you can't run it on the Go Playground, save it locally and run it on your computer.
So, we'll work with the following Post
entities:
type Post struct {
User, Time, Text string
}
I'm gonna use the following template:
Posts
{{block "batch" .}}
{{range .posts}}
{{.Time}} {{.User}}: {{.Text}}
{{end}}
{{end}}
It contains a The javascript function for making an AJAX call is detailed in my linked another answer. The handler that executes this template: And the And that's about it. It's a working application. Entering 09:42:29 Bob: The weather is nice. Pressing the Load more button, the content in the browser will be refreshed dynamically, without page reload. The new content: 09:42:29 Bob: The weather is nice. Pressing it again: 09:42:29 Bob: The weather is nice.{{block "batch" .}}
block for listing posts, and also renders a placeholder for the next batch (var t = template.Must(template.New("").Parse(page))
var lastTime = time.Now()
func produceTime() string {
lastTime = lastTime.Add(time.Second)
return lastTime.Format("15:04:05")
}
func postsHandler(w http.ResponseWriter, r *http.Request) {
// Put up some random data for demonstration:
data := map[string]interface{}{"posts": []Post{
{User: "Bob", Time: produceTime(), Text: "The weather is nice."},
{User: "Alice", Time: produceTime(), Text: "It's raining."},
}}
var err error
switch r.URL.Path {
case "/posts/":
err = t.Execute(w, data)
case "/posts/more":
err = t.ExecuteTemplate(w, "batch", data)
}
if err != nil {
log.Printf("Template execution error: %v", err)
}
}
produceTime()
just produces monotonic increasing timestamp strings, so the output will look like something sensible.main()
function to register the handler and start the server:func main() {
http.HandleFunc("/posts/", postsHandler)
panic(http.ListenAndServe(":8080", nil))
}
http://localhost:8080/posts/
in a browser, you'll see:
Posts
09:42:30 Alice: It's raining.
Load more
Posts
09:42:30 Alice: It's raining.
09:42:31 Bob: The weather is nice.
09:42:32 Alice: It's raining.
Load more
Posts
09:42:30 Alice: It's raining.
09:42:31 Bob: The weather is nice.
09:42:32 Alice: It's raining.
09:42:33 Bob: The weather is nice.
09:42:34 Alice: It's raining.
Load more