I am building an off-canvas overlay to show all the comments on a blog. I want to use ajax so that users can post and see the update of the comments section without reloading the page.
I have been using ejs syntax for my HTML files but when it goes to ajax, I don't know how to let the back end server recognize the data through the "erl" attribute in ajax.
my ajax code
$("#commentBtn").on("click", () => {
$.ajax({
url: "/home/<%=blog.title%>/comment", <--- I want to send the title attribute of the blog to backend
contentType: "application/json",
success: (response) => {
let commentElem = $("#showComments");
response.comments.forEach(comment => {
commentElem.append('\
<h2>'+comment.id+'</h2>\
<h3>'+comment.content+'</h3>\
');
});
}
})
})
related HTML code
<button type="button" id="commentBtn" uk-toggle="target: #offcanvas-usage">show comment</button>
my router
router.get("/home/:title/comment", async(req, res) => {
await Blog.findOne({title: req.params.title}, (err, foundBlog) => {
if(err) {
console.log(err);
} else{
*do the send comment things ....*
}
})
})
The problem now is the router cannot recognize req.params.title, I think it is the ajax issue that it didn't send the title of the blog to the router. so that the router cannot find the specific blog for me.
Is there any ajax syntax to let my router to use req.params.title?
Thanks in advance!
I'm not familiar with ejs, but can you use template literals?
url: `/home/${blog.title}/comment`
More info here
Related
I am new to this. I am trying to build a website where users can follow/unfollow each other. Like/Unlike posts.
I am using Node js and MySQL.
I know how to make users add new posts by using a form and this will direct them to a POST route and there I can do the back-end stuff. But how can I add a follow button similar to Twitter/Instagram that changes dynamically when a user clicks on it without refreshing the page.
I thought of something like this in front-end "Profile.ejs file"
<form action="/follow" method="POST">
<input class="btn btn-primary a-btn-slide-text" name="follow" type="submit" value="Follow"/>
</form>
But then I am not able to pass in the information for the user I am trying to follow in the back-end (e.g user_id) and not able to change the button value to "unfollow". This is what I thought I would do on the back-end:
app.post("/follow", function(req, res){
var follow = {follower_id:currentUser.id, followee_id:user_id};
connection.query('INSERT INTO follows SET ?', follow , function(err, result) {
if (err) throw err;
res.redirect("/");
});
});
Any idea on how I can achieve this? Also are there any resources/websites/courses that I could learn from on how to use dynamic/javascript stuff like this with nodejs?
You should use Ajax in your front-end template to send a request to your back-end.
Something like that (you don't need to put it in a form):
<button type="button" id="follow">Follow</button>
<script type="text/javascript">
$("#follow").click(function(){
$.ajax({
url: '/follow',
type: 'GET',
dataType: 'json',
success: function(data, status){
// Here you can change your button text using jQuery
}
});
});
</script>
Then, in your back-end:
app.get("/follow", function(req, res) {
var follow = {follower_id:currentUser.id, followee_id:user_id};
// Do stuff here, call your database, etc.
res.send({ msg: "User followed/unfollowed!" });
});
Your Ajax method will receive this message: { msg: "User followed/unfollowed!" }
let's say I have this route for my rendered HTML:
app.get('/profile/:id', function (req, res) { // my route
res.render('profile', { id: Number(req.params.id) }); // render the file and set a variable
});
and in my client side javascript file for the profile page I want to get data from the server. I request the data when loading the page by sending a user id to the server and the server returns a user object:
$(document).ready(function() {
var user = null;
$.ajax({
type: 'GET',
url: '', // This one is missing here
dataType: 'json'
}).done(function(data){
user = JSON.stringify(data);
});
console.log(user.name);
});
And my server would handle this function:
app.get('', function (req, res) { // missing route
var userId = ; // This is missing
var userObj = getUserById(userId);
res.send(userObj);
});
What route do I have to use? Tutorials say I have to pass in the route like /profile/:id but this route already exists?
I tried defining a new route like:
app.get('/reqUser/:id', function (req, res) { // Ajax route
res.send(getUserById(Number(req.params.id)));
});
and for my Ajax call I pass in the url http://localhost:8888/reqUser/12345 but this seems to be wrong because user is still null after using the Ajax call.
So how can I define a route handling the page and the Ajax call?
Edit: First off, you'll want to fix the bug in your client-side JS, where you are attempting to print user.name before user has been fetched from the server. You can fix this by moving your console.log statement into the done() callback like so:
$(document).ready(function() {
var user = null;
$.ajax({
type: 'GET',
url: '', // This one is missing here
dataType: 'json'
}).done(function(data){
user = JSON.stringify(data);
console.log(user.name); // log here
});
});
Regarding your routes question, you have several options. Below are two common solutions to this problem:
Create a separate api route to distinguish your API requests from your page requests. For example, app.get('/api/profile/:id, (req, res) => {...});'
Add a URL parameter to your AJAX calls specifying the format you want the response to be in, with the default being the page's HTML. For example, your AJAX would send a GET request to the URL /profile/2012?format=json, which would return the profile's information in JSON.
Personally, I prefer the first option, as it makes intent more clear.
lets say I have
router.get('/read', function(request, response) {
res.send({"result": "Success sent from routes/index.js."});
});
how do I output a template with the data. If I use res.send() I can't use res.render() right?
If my users are at /read and click a button to send some data with ajax I want to display that data in another template on /read
Edit: One way to get around this is to make a string when you return the data (or maybe not)
success : function(data){
$(".fillIn").html("<p style = 'color:green;'>" + data + "</p>")
}
I don't want a string.
The pic shows that on one page "/" there are 2 buttons and by clicking each button you can send data and that data can be displayed on the right depending on which button was clicked, a form with some data filled in or a table filled in with some data. I use ajax to send the data on click..There will be different forms with different styles. That's why I want to add in a template. I could do that with HTML using .load() I think but I cant figure out how do with that jade.
Here's my other Question
In your index.js file, use the following to capture GET and POST requests and render different responses:
app.get('/read', function(req, res, next){
res.render('emptyFormTemplate');
});
app.post('/read', function(req, res, next){
res.render('dataTableTemplate', {
name: req.body.name,
email: req.body.email
});
});
On the client-side, you you can something like this to POST the data to /read. You would include this script in emptyFormTemplate in the above example.
$('#myForm').submit(function(event){
var formData = {
'name' : $('input[name=name]').val(),
'email' : $('input[name=email]').val()
};
$.ajax({
type: 'POST',
url: '/read',
data: formData,
dataType: 'json'
});
});
I want to know the content type of a given url input by the user inside my Javascript code. Actually, I have a drop-down list (html,csv,xls etc.) and I want to make it so when the user inputs an url, I want to detect the type of the content of the url and based on this type I want to set the value of my drop-down list (html,csv,xls etc.). I know, I can get the content type using Ruby like this :
require 'open-uri'
str = open('http://example.com')
str.content_type #=> "text/html"
or, also, I could use curl to get the content and then parse it to know the content type. But, I need to do this inside my Javascript code because of my need explained above. Any thought ?
EDIT_1 :
I tried this code in my javascript :
$("#wiki_form_url").change(function(){
$.ajax({
type: "GET",
url: "content.rb",
data: {
// input_url: $("#wiki_form_url").val()
},
dataType: "html"
}).done(function (data) {
// `data` contains the content-type
alert('Success !!!');
}).fail(function () {
alert("failed AJAX call");
});
});
I have a ruby script content.rb inside which I do :
require 'open-uri'
str = open('http://www.ofdp.org/benchmark_indices/25')
str.content_type
But, it does not seem to work. I am getting Ajax failure. May be it's because of url path of the script content.rb ? How should I specify a script path here ? (Relative or absolute)
The same origin policy prevents you from using client side JavaScript to directly discover information about arbitrary URIs (URIs you control are a different story).
You'll need to get that information with another technology, such as your server side Ruby.
You could do this by simply submitting a form to the server and returning a new webpage to the browser.
If you don't want to leave the page, then you can pass the data using Ajax. There are no shortage of Ajax tutorials out there, here is a good one from MDN.
Here's an example of an AJAX call:
$(document).ready(function () {
$("#button_check").on("click", function () {
$.ajax({
type: "GET",
url: "Your URL",
data: {
input_url: $("#textbox_id").val()
},
dataType: "html"
}).done(function (data) {
// `data` contains the content-type
alert(data);
}).fail(function () {
alert("failed AJAX call");
});
});
});
Where your HTML is something like:
<input type="text" id="textbox_id" />
<input type="button" id="button_check" value="Submit" />
And your Ruby code would be something like:
require 'open-uri'
class TestController < ApplicationController
def index
req = open(params[:input_url])
render :text => req.content_type
end
end
I have never used RoR before, so I have no idea if this is right or works in the slightest. But it's what I could quickly conjure up when scrambling through several tutorials. It's simply the concept you seem to be looking for. You'll need to figure out how to map a URL to this method, and then update the AJAX option url to use that.
So in the Javascript code - in the done method, that means the whole AJAX request was successful and the data variable should contain the result from the Ruby code req.content_type.
Atlast I could figure out the whole thing with the great help of #Ian. Here is my completed code : In javascript file :
$("#wiki_form_url").change(function () {
$.ajax({
type: "GET",
url: "/wiki_forms/content",
data: {
input_url: $("#wiki_form_url").val()
},
dataType: "text"
}).done(function (data) {
// `data` contains the content-type
alert('Success');
console.log(data);
// alert(data);
}).fail(function () {
alert("failed AJAX call");
});
});
Inside my wiki_forms controller I created a new method named content :
def content
req = open(params[:input_url])
render :text => req.content_type
end
Then added a new route in routes.rb file :
get "/wiki_forms/content" => 'wiki_forms#content'
and used /wiki_forms/content as the ajax request url. And, everything is working nicely now.
What is the bestHi everyone, a MVC3 newbie here! please take a look at these:
in my View page, i have there:
<div id = "AccounStatusDiv" class="display-field">
#Html.DisplayFor(m => m.AccountStatus)
<input id="btnBool" type="button" class="btnGrid ActStatBtn" value="#(Model.AccountStatus ? "Deactivate" : "Activate")" onclick="ChangeStatus()"/>
</div>
and a script:
<script type="text/javascript">
function ChangeStatus() {
$.post('#Url.Action("SetAccountStatus", "User")',
{ UserName: "#(Model.UserName)",
accountStatus: "#(Model.AccountStatus)" });
// change the display of the AccounStatusDiv elements, or maybe just reload the div element if possible. is it?
}
</script>
while in my Display Template, i have there:
<div id = "AccountStatusDiv" style="display:inline-block;">
<img src="#Html.Custom().ResolveImage((bool)Model ? imgPositive : imgNegative)" alt="#Model" />
<label> #ResourceManager.Localize(resource, display)</label>
</div>
in the controller:
public ActionResult SetAccountStatus(string userName, bool accountStatus)
{
SecurityManager.GetMembershipProvider().SetStatus(userName, !accountStatus);
return AjaxResult.JsonRedirect("/User/ViewUser?username=" + userName);
}
The results are shown only after I reload the page.
I want to display the updated img, label and btnBool elements right after clicking the btnBool without reloading the whole page. What is the best way in such case?
Please post your code suggestions, it would be a great help for me!
Thanks in advance!
You're only using $.post() to send data (request) to the server. AJAX can be two-fold: send a request, and receive the corresponding response. In your code, you're not receiving data back (or, at least, making the necessary arrangements so that you are).
If the SetAccountStatus action of your UserController is set to return some data back (maybe through return Json(), or similar), you can modify the $.post() call to receive it, and have your Javascript react accordingly using a callback function.
var data = {
UserName: "#Model.UserName",
accountStatus: "#Model.AccountStatus"
};
var call = $.post(
'#Url.Action("SetAccountStatus", "User")',
data
);
// set the success callback here
call.success(function (m) {
// the [m] variable contains the data returned by the server
// during the resolution of your call
// this will be called when your AJAX call succeeds,
// and you can use this opportunity to update the HTML DOM with new data
});
this is to event click in button and without refresh page
$("#btnBool").click(function(e){
e.preventDefault();
//to do your code, you can use `$.ajax` to request and get response from server
$.ajax({
url: '#Url.Action("SetAccountStatus", "User")',
type:"GET",
dataType: 'json',
data: { UserName: "#(Model.UserName)",accountStatus: "#(Model.AccountStatus)" },
async:'true',
success:function (data) {
alert(data);
//success to parsing json if you data type of your response is json
}
});
}
you can use web service to send request and get response from server , and to request,get response from server you can use $.ajax() in jquery http://api.jquery.com/jQuery.ajax/