Context:
I've created a GET request in my route folder that sends html. It will be used for a ajax request:
router.get(url, function(){
res.send("<p>Some Text</p>");
})
My idea/doubt/problem is the following, is it possible to use a partial view in order to generate the html that I want and send it?
I have a partial view with the code i need, that's used in the main rendering, and it's frustrating to edit the code in two different sections.
I've found the way:
res.render(view, function(err, html){
if(!err){
res.send(html);
}
});
If the callback function is used, the default behaviour of rendering the page is canceled.
Related
I have searched for this, tried the accepted solutions from the questions stackoverflow has suggested might work and I am here as a last resort, after trying everything I can think of or find.
I would like a button on my razor page to send a post request, via an ajax function I am obliged to use, and return a razor page with no layout.
HTML
<button id="myawesomebutton">Go get a partial</button>
javascript
var myawesomeajaxobject=new ajax('/myawesomeurl');
myawesomeajaxobject.done=function(dat)
{
document.getElementById('myawesomediv'),innerHTML=dat
}
myawesomeajaxobject.go('myawesomeparameter01=1&myawesomeparameter02=2');
The AJAX object I am obliged to use adds the following headers:
Content-type, application/x-www-form-urlencoded
Access-Control-Allow-Origin, *
As well as adding a '?' followed by a unix time code to the url endpoint.
It is my understanding the request mus first be sent to the cshtml.cs class behind the razor page which will then redirect to my partial.
No matter what I name my C# method, onPost, myawesomeurl, many other names, I get a 404 error instead of rendering the partial inside myawesomediv.
I have attempted to add an anti forgery token, set CORS values on the server to 'accept all' and tried sending the request directly to the partial's onPost but I'm getting nowhere.
UPDATE.
I have added:
services.AddRazorPages().AddRazorPagesOptions(options =>
{
options.Conventions.ConfigureFilter(new IgnoreAntiforgeryTokenAttribute());
});
to my Startup.
My javascript reads:
var myawesomeajaxobject=new ajax('/myawesomeurl');
myawesomeajaxobject.done=function(dat)
{
document.getElementById('myawesomediv'),innerHTML=dat
}
myawesomeajaxobject.go('handler=myawesomeurl&myawesomeparameter01=1&myawesomeparameter02=2');
This is the handler method in the cshtml.cs file:
public void OnPostmyawesomeurl()
{
//myawesomecoded added, so I have a break point to hit.
}
and I'm still getting a 404.
Is this actually possible in razor pages?
It looks like you are making a POST request to a named handler method. The handler still needs On[Http Method] incorporated into its name so that it can be found. If it is a POST request, the name of the handler method should be OnPostMyAwesomeUrl.
You also need to handle the fact that Request verification is built in to Razor Pages, so you either need to include the token in your AJAX request (https://www.learnrazorpages.com/security/request-verification#ajax-post-requests-and-json), or disable it for that page entirely (https://www.learnrazorpages.com/security/request-verification#opting-out):
[IgnoreAntiforgeryToken(Order = 1001)]
public class IndexModel : PageModel
{
...
}
Thank you everyone for your input. This is how I achieved the desired results.
HTML
<button id="myawesomebutton">Go get a partial</button>
javascript
var myawesomeajaxobject=new ajax('/myawesomeurl');
myawesomeajaxobject.done=function(dat)
{
document.getElementById('myawesomediv'),innerHTML=dat
}
myawesomeajaxobject.go('/shared/myawesomepartial/?handler=myawesomehandler&myawesomeparameter01=1&myawesomeparameter02=2');
Startup
services.AddRazorPages().AddRazorPagesOptions(options =>
{
options.Conventions.ConfigureFilter(new IgnoreAntiforgeryTokenAttribute());
});
myawesomepartial.cshtml.cs
public void OnPostmyawesomehandler(MyAwesomeModel myawesomemodel)
{
//Do something with myawesomemodel and return myawesomepartial.cshtml
}
It was just a question of making the URL and endpoint method names match up.
This link have a similar answer which works fine but some changes required above answer works fine, but my objective is a little bit different, I wanted to pass the variable from partial view who contains image URL, I want to use that URL in the main view somewhere. the scenario is, calling ajax to load the partial view and displaying in modal, partial view having a lot of ajax which calling controller for fetching folder and files from the server, on the response of ajax I got an image file URL in the partial view, now I want to pass that URL into the main view, how to do that?
the main view -> works fine
enter code here
$(document).ready(function (){
$("#button1").click(function ()
{
$("#modalbodypopup").load("/ControllerName/GetPartial");
jQuery.noConflict();
$('#imagePopup').modal('show');
});
});
</script>
controller -> works fine
enter code here
public IActionResult GetPartial()
{
return PartialView("~/Views/Shared/_FileManager.cshtml");
}
partial view calling different controller who returning HTML who have a lot of link and folders name and image file name now on the calling of ajax from the partial view, after a successful response, I got a file URL in the variable inside partial view javascript side which I want to pass to the main view because I am displaying that image there.
There are a couple of ways you can do this. Your GetPartial() method can do:
return PartialView("_FileManager");
And as long as the file is in the shared folder, MVC works out the path.
You can also return the contents of a file directly:
var file = File.ReadAllBytes(..);
return File(file, "image/png");
This allows you to stream the image url directly into the browser.
The function I have written works fine and the value correctly writes to my terminal onSubmit, however I'm struggling to piece together why this code isn't updating my html.
router.post('/index', function(req, res, next) {
// ...Get form values, do calculations to get toCost value.
console.log('$' + toCost);
$(document).ready(function() {
var output = document.getElementById('cost');
output.innerHTML = toCost;
});
res.location('/');
res.redirect('/');
})
I receive the following error and jquery is loading fine.
$ is not defined
Admittedly this is an over-engineered node/express app. The code snippet lives wrapped in a route file, inside a post request.
How do I get my value onto the html?
Jade layout
extends layout
block content
form(...)
div#cost
The normal way to do this would be as follows:
router.post('/index', function(req, res) { <<< 'next' removed (only needed if using middleware)
// ...Get form values, do calculations to get toCost value.
console.log('$' + toCost);
res.render('indexTemplate', {cost: toCost}); <<< pass toCost through to jade as 'cost'
});
Then in your jade file for the indexTemplate you can reference the 'cost' variable passed in like this:
indexTemplate.jade:
extends layout
block content
form(...)
div#cost #{cost} <<< adds the cost variable to page
Then the value of toCost will appear in the resulting page.
No jQuery is required on the server side.
jQuery is made for DOM manipulations and there's no DOM on a server.
Try using 'jsdom'.
jQuery is made for client side scripting, not for server-side client manipulations.
It seems that you're trying to make changes on client-side from your backend. It doesn't work that way.
You could create a variable on backend for storing calculation result. And get this value by get query from client-side
You're tring to reach DOM (that is on client side) from NodeJS on a server side. It doesn't work that way.
As the title says, I am trying to dynamically load content in a view using ajax requests. I know this can be done if you are using html elements e.g. ("#div_place").html(<p>...). The problem lies when I would like to load some php/blade objects into a div for instance. Is this possible or is there a different way to go about achieving the result I want.
This is pretty straightforward. Assuming you're using jQuery...
create a route that will respond to the AJAX call and return an HTML fragment
Route::get('test', function(){
// this returns the contents of the rendered template to the client as a string
return View::make("mytemplate")
->with("value", "something")
->render();
});
in your javascript:
$.get(
"test",
function (data) {
$("#my-content-div").html(data);
}
);
After some digging some more I found this which helped me to solve the problem.
You have to use the .load("url/page/...") via jquery and then set a route in the routes.php file that displays a view with the data that needs to be loaded e.g.
Route::get('/url/page/...', function(){
return View::make('test');
});
This returns the necessary php code which needed to be loaded dynamically, cheers.
I'm going to perform 2 AJAX calls:
Load HTML partial template.
Load JSON data for template and render it into loaded template.
JSON should be loaded separate from template because user can trigger some kind of "refresh" action. Template can't be loaded on the first page load because there is tab control on the page and every tab should be loaded "on demand".
So let's say some function loadData was called. So I need to do the following:
If template is already loaded then GOTO step 3.
Send AJAX for template using $().load and AJAX for JSON data using $.getJSON at the same time. The fact is we can send both them together without waiting for template is loaded, am I right?
If JSON is loaded then check if template is already here. If so then render data into template. Else wait for template is loaded and then render data on success.
So I wonder what is the best practice for such activity? Is there any complete solution for it?
Thank you in advance.
Yes. You can use jQuery Deferreds (http://api.jquery.com/category/deferred-object/) to coordinate all this.
JS Code:
var templatePromise = null;
function loadData() {
if (!templatePromise) {
templatePromise = $.get('templateUrl');
}
var dataPromise = $.getJSON('dataUrl');
$.when(templatePromise, dataPromise)
.done(function (template, data) {
// you have both template and data.
})
.fail(function () {
// either the template or the data failed to be fetched properly.
});
}