Passing a variable from .ejs file back to express.js - node.js

I am working upon the project using node.js with express.js framework and view engine set to "ejs". The project's functions is to:
1. Get an input from a user.
2. Using the input send the request to the website's API.
3. Print the certain data from that API (including the ID to be used later).
4. When user clicks on the item (that is an 'a' tag) in the list consisting of the aforementioned data - use the ID of this item to send another request to the same website to get a more detailed info about the item.
I am stuck at the step 4. And the question is: How to send this id from the .ejs file to post request in node.js when the user clicks on the item?
Doing it the other way is simple: response.render("view name", {nodeJsVar: ejsVar}); But how to pass it back?
Thanks for the help!

First of all, you cannot send any data "from the .ejs file" - what you can do is to send it from the browser, that has a rendered HTML (and possibly JavaScript) and not EJS.
You can do it with some client-side JavaScript in which case you can do whatever you want.
You can do it by embedding the variable's value in a URL as a route parameter or a query parameter if you're using standard <a href="..."> links.
You can put a hidden input in a form if you're using forms and buttons.
You can put it in any part of the request if you're using AJAX.
Just to make sure you know what is what because it can be confusing - here X is a path parameter:
http://localhost/something/X
and here X is a query parameter:
http://localhost/something?x=X

try this (assuming you use jQuery):
$.ajax({
url: '/routename_to_handle_id',
type: 'POST',
data: { id: id }
}).done(function(response){
//callback to handle if it's successful
})

Related

How to give a browser extension all text data input into that browser?

I'm experimenting with Chrome browser extensions. I want to be able to take any text input into the browser (through the URL bar of the browser or onto text boxes on social media sites and so on) and send that text to a server. I'm wondering if this is possible in chrome and what functions I need to use to achieve this?
I suspect the logic of the extension would work something like this: any time a link is clicked where there is text in an input form / text box, extract that text or form input and send it using some JS requests library to a server.
Which Chrome API function can be used to get the text input into a form?
You can get DOM information (input, textareas, etc) using content_script which has direct access to the web page data. URL data can be accessed through either the popup.js or background.js using the chrome API chrome.tab.query.
In the past I have had the best luck using MutationObservers, this looks at real-time changes to the web page (or wherever you specify you want the observer to be). Then you can send that data to the server.
small example.
function extractinputdata() {
var inputdata = document.getElementById('some specfic HTML element')
if (inputdata != null) {
new MutationObserver(function(){
//when a change has been made to the element or its children, you can record the new data
}).observe(inputdata, {characterData: true, childList: false, subtree:true});
}
}

Rendering a user modified page using PhantomJS

My use case is: a user goes onto a webpage and modifies it by either filling in a form, populating the page with data from the database, or dragging around some draggables on the page. He can then download the page he modified as pdf. I was thinking of using PhantomJS to do the conversion from html to pdf.
I understand the basic functionality of PhantomJS and got the basic example working but in all the examples I've seen, either a local file or a url is passed in. Example:
page.open('./test.html', function () { ... }
How would I render the page that is getting modified by a user using PhantomJS? I have 2 ideas:
Have the url change as the user modifies the page, and simply pass in the url. For example, the url contains the position of a draggable div.
Send the modified html to back-end, save it, and run PhantomJS
Do these solutions make sense? I'm hoping there would be a simpler way.

Difference between the <a> tag and get request

I have a perhaps simple question. What would be the difference between an <a> tag and a normal GET request with any element. I know the <a> tag automatically sends you to the url specified in its href attribute. So I assume that a Get request does something similar in it's success callback (as demonstrated below)
But let's say that I also want to send some information along with a normal get request when a for example <span> element is clicked on so I write:
$('span').click(() => {
$.ajax({
url: '/someurl',
type: 'GET',
data: {
title: someTitle,
email: someEmail
},
success: (data) => {
window.location = '/someurl';
}
});
});
Is there any way to achieve this with an <a> tag? Sending information to the server so it's available in req.query.title and req.query.email ?
Doing the ajax request above will run my app.get('/someurl',(req,res)=>{})twice because I am sending a GET request to send the data (title and email) and then I am making another GET request when I write window.location = '/someurl' How can I redo this so that it only sends the GET request ONCE but also allows for the sending and storing information to the req object AND ensures that the browser is now displaying /someurl.
Just create the appropriate query string in the URL you put in the href of the <a> tag and it will work just like your ajax call. Suppose someTitle has the value of "The Hobbit" and someEmail has the value of foo#whatever.com, then you can construct that URL like this:
Click Me
A number of non-letter characters have to be escaped in URLs. In the above URL, the space is replaced with %20 and the # with %40. In your particular example, you could open the network tab in the chrome debugger and see the EXACT URL that Chrome was sending for your ajax call, copy that to the clipboard and insert it into your <a> tag.
Here's a table that shows what characters have to be replaced in a query string component (the part after & or after =):
I'm just wondering then, aside from semantic reasons, is there any other advantages to using an a tag instead of anything else?
<a> tags are understood by all sorts of machines that may read your page such as screen readers for the disabled or crawlers indexing your site. In addition, they work automatically with browser keyboard support, Ctrl-click to open a new tab. Whereas a piece of Javascript may not automatically support any of that functionality. So, basically, if the <a> tag can do what you need it is widely preferred because it has so much other default functionality that can be necessary or handy for users.
Hello

Reusing Yesod widgets in AJAX results

I'm writing a very simple Yesod message list that uses AJAX to add new list items without reloading the page (both in the case of other users modifying the database, or the client themselves adding an item). This means I have to encode the HTML structure of the message items in both the Halmet template (when the page loads initially) and the Julius template (for when the dynamic addition happens). They look something like this:
In homepage.hamlet:
$if not $ null messages
<ul id=#{listId}>
$forall Entity mid message <- messages
<li id=#{toPathPiece mid}>
<p>#{showMarkdown $ messageText message}
<abbr .timeago title=#{showUTCTime $ messagePosted message}>
And in homepage.julius:
function(message) {
$('##{rawJS listId}').prepend(
$('<li>')
.attr('id', message.id)
.append('<p>' + message.text + '</p>')
.append($('<abbr class=timeago />')
.attr('title', message.posted).timeago())
.slideDown('slow')
);
}
I'd love to be able to unify these two representations somehow. Am I out of luck, or could I somehow abuse widgets into both generating an HTML response, and filling in code in a JavaScript file?
Note: Of course, I understand that the templates would have to work very differently, since the AJAX call is getting its values from a JS object, not from the server. It's a long shot, but I thought I'd see if anyone's thought about this before.
I think it's something of a AJAX best-practice to pick one place to do your template rendering, either on the server or client. Yesod is (currently) oriented toward doing the rendering on the server.
This can still work with AJAX replacement of contents, though. Instead of getting a JSON response from the POST, you should get a text/html response that contains the result of rendering the template on the server with the values that would have been returned via JSON and then replacing the innerHTML of the DOM node that's being updated.
If you want to support both JSON and HTML responses (to support 3rd party applications via API or something) you would have to make the format of the response be a function of the request; either appending ".json" or ".html" to the URL or including a HTTP header that lists the specific document type required by the client.
It would be nice if Yesod provided a 'jwhamlet' template or something that would render the HTML via javascript in order to support client rendering, but I'm not aware of one. That's not to say there isn't one I'm not aware of, though, so keep an eye open for other answers.
If you wanted to make such a thing, you might try tweaking the hamlet quasi-quote code so that instead of expanding the quasi-quotes to an html-generating function, it expanded them to a JSON-generating function and a pre-rendered chunk of text that's a template in mustache-style such that the JSON returned by the function would provide the correct context for the template to be rendered the way you want.

I'm looking for a Sharepoint Webpart that can query a list for an RSS feed URL, then display it

Basically what I have a List that will be maintained by the user that has a field that contains a link to an RSS feed.
I tried using the OOTB RSS and it's great, but you have to specify the feed URL and I need that to be based on user selection. For example, the user will select from a list a feed they want to view and this should take them to the feed reader page which will use their selection to get the feed URL and display this on the page.
An alternative which is not a general Sharepoint solution is to use jquery.
Is the list visible on the page or is it "just" a list in Sharepoint?
Of course you might need some kind of proxy to do this in order to call the rss-feeds if they are placed on another server. But you will send the performance to the client instead of the server which is a plus..
My solution was to use the WebPartPages Web Service (SaveWebPart) to change the definition of the web part to use the new feed URL whenever a feed is clicked on.
I created a javascript function the will accept the feed URL and proceed to the page where the feed is displayed. The new feed will not be loaded until the next time you visit the page, therefore if you are already on it you will need to reload, thus the redirect.
For more information on the format of the request and the web part XML format see the following page.
http://msdn.microsoft.com/en-us/library/ms774839%28v=office.12%29.aspx
function SetFeed(feedURL){
var webPartGUID = $("#<WebPartID>").attr('webpartid');
// This is where you set the page URL, Full Web Part XML (including path to FEED),
// storageKey (webPart GUID), and storage type (none, personal, shared)
var soapEnv = "<FULL SOAP XML>";
jQuery.ajax({
url: "http://<SITE PATH>/_vti_bin/WebPartPages.asmx",
type: "POST",
dataType: "xml",
data: soapEnv,
beforeSend: function(xhr) {
xhr.setRequestHeader("SOAPAction",
"http://microsoft.com/sharepoint/webpartpages/SaveWebPart")
},
complete: function(xData, status){
window.location='REDIRECT TO FEED PAGE';
},
contentType: "text/xml;charset='utf-8'"
});
}

Resources