We want to use our content editable, taking advantage of the generated routes with the following in router.ex:
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :put_secure_browser_headers
end
pipeline :api do
plug :accepts, ["json"]
end
scope "/", TextEditor do
pipe_through :browser # Use the default browser stack
get "/", PageController, :index
resources "/posts", PostController
end
and the controller functions, namely create:
def create(conn, %{"post" => post_params}) do
changeset = Post.changeset(%Post{}, post_params)
case Repo.insert(changeset) do
{:ok, _post} ->
conn
|> put_flash(:info, "Post created successfully.")
|> redirect(to: post_path(conn, :index))
{:error, changeset} ->
render(conn, "new.html", changeset: changeset)
end
end
However we don't want to use the generated form, we are then attempting to test this with divs and the jquery method $.post:
<div id="newPost" contenteditable="true">write here</div>
<div id="button" class="btn btn-primary">Save</div>
<script type="text/javascript">
$(document).ready(function(){
$("#button").click(function() {
var post = $("#newPost").html();
$.post( "/posts/post", { title: post })
.done(function() {
alert( "Data Loaded: " );
});
});
});
</script>
However we are not getting the alert or any data inserted into our database. What are we missing?
EDIT: In the browser pipeline we removed the cross forgery plug because of a csrf token error.
data : A plain object or string that is sent to the server with the request. success : A callback function that is executed if the request succeeds.it takes as an argument the returned data. It is also passed the text status of the response.
A standard form submit sends a new HTTP request (POST or GET) and loads the new page in the browser. In Ajax, the data is sent to the server (POST or GET) in the background, without affecting the page at all, and the response is then received by javascript in the background, again without affecting the page at all.
AJAX just uses a combination of: A browser built-in XMLHttpRequest object (to request data from a web server) JavaScript and HTML DOM (to display or use the data)
Try the following:
$.post( "/posts", { post: { title: post } })
Your controller expects the parameters to be nested under a key of post
def create(conn, %{"post" => post_params}) do
I wouldn't recommend doing so, but you can change your controller to:
def create(conn, %{} = post_params) do
To look for parameters without the root post
key. However having the post
key means you can have additional parameters unrelated to the form easily.
I also would not recomment disabling the CSRF check. You can submit with the CSRF token easily by storing it in a meta tag:
<meta name="csrf" content="<%= Plug.CSRFProtection.get_csrf_token() %>">
And then adding it as a header to your post request:
var csrf = document.querySelector("meta[name=csrf]").content;
$.ajax({
url: "/posts",
type: "post",
data: {
post: { title: post } })
},
headers: {
"X-CSRF-TOKEN": csrf
},
dataType: "json",
success: function (data) {
console.log(data);
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With