How to dynamically load a partial view without using a controller? - ajax

There is a big chunk of html + js code. The goal is to load and show it only on a specific button click, so, there is no need in pre-loading it every time.
Normally, we can include a partial view dynamically by using jquery/ajax, but as far as I know it requires a controller. In this scenario, there is no need for a controller, as the data is static.
So, the question is: is it possible on a specific event (like button click) to include a partial view without going through a controller?
What we tried was giving the ajax request an address of partial view. However it didn't help.
<div class="reportWindow"></div>
<script type="text/javascript">
$("#feedback").click(function () {
$.ajax({
url: "#Url.Content("_Feedback")",
type: 'GET',
cache: false,
success: function (result) {
$("#reportWindow").html(result);
}
});
});
</script>

a Partial view that have cshtml extension is still a Razor view, even if the content inside of it is static, the server still needs to read it and convert its content to html (even if that means copy it exactly the way it is and send it back)
What you need is an html file, which in turn you can load dynamically with javascript or jQuery:
$("#feedback").click(function () {
$("#reportWindow").load('feedback.html');
});
Note that this will still ask the server for feedback.html, typically this won't match to any route then IIS will resolve the request by looking for a static pages called feedback.html!

Related

Asynchronous loading of partial view in Ember

I've created an Ember helper to allow for loading a dynamically generated partial view from a URL on the server. It looks like this:
Ember.Handlebars.helper('serverPartial', function(url, options) {
var template;
$.ajax(url, {
async: false,
success: function(templateText){
template = Ember.Handlebars.compile(templateText);
}
});
template(this, options);
});
And it's called from a parent Handlebars template like this:
{{serverPartial templateUrl}}
As you can see, the ajax call to retrieve the template from the server is a synchronous call, because I couldn't find any other way to return the template contents as expected by the Ember framework. Unfortunately, this synchronous call holds up the rendering of the entire parent template.
Is there a way to return a promise for the template, or any other way to allow partial views to load asynchronously or independently?
Thanks for the tip, #Rajat. I did end up using Views to accomplish this. I created a view container that initially loads a default child template, then that child loads in the actual contents from the server after it is inserted. Here's the approach I took:
App.LoadingView = Ember.View.extend({
didInsertElement: function(){
var container = this._parentView;
$.get('http://server/serverTemplate', function(data){
container.pushObject(Ember.View.create({
template: Ember.Handlebars.compile(data)
}));
container.removeObject(container.get('loadingView'));
});
},
template: Ember.Handlebars.compile('client awesome')
});
// inherit from ContainerView and initialize with default content
App.SnippetView = Ember.ContainerView.extend({
childViews: ['loadingView'],
loadingView: App.LoadingView.create()
});
I'm sure there are better ways to express this, but does the job at a minimum.
First, what you are trying to do with Handlebars helpers is not what they are intended to do. Handlebars helpers are strictly markup formatters and should be used for simple HTML adjustments.
Second, in typical ember apps, what you are trying to do is never done. There is no 'on-demand' fetching of templates.
This is because all templates are downloaded in one sweep when the app loads and live on client. They are precompiled to JavaScript functions and stored as Strings in the Ember.Handlebars hash.
They are downloaded when the app loads and then get evaluated when the view is rendered. In the meantime, they live simply as Strings.
Now if you still want to do what you are doing, I would recommend trying to do that in Views.

How to load page sections using Ajax and Jquery in ASP.Net MVC 3 razor view?

I am working on ASP.Net MVC 3 website which uses Razor view engine and Jquery
On homepage (or any page for that matter) I want to load sections of content using ajax, something like iGoogle.
I mean on page load
I want to call some HttpGet action methods each of which returns some
Html content
Until I get response these Div's showing "loading" graphics.
I am aware of Ajax.BeginForm and Ajax.ActionLink but in both the cases I need to click some UI element; I do not know how to use them on page load/ document.Ready?
I will be thankful even if I get some direction and not exact/complete code.
Okay, lets give you some direction, I'm going to show some code in jquery because its easy enough. lets go.
Html
<div id="SomeContent"> </div>
In your view
$(function(){ // this runs on on page load
LoadData('#SomeContent', #Url.Action("ActionName","ControllerName"));
});
in a javascript library file
function LoadData(target, url){
$.ajax({
beforeSend: startAnimation(target),
url : url,
success : function(result){ $(target).html(result); },
complete : stopAnimation(target)
});
}
function startAnimation(target){
//..add a loading image on top of the target
}
function stopAnimation(target){
// remove the animation gif or stop the spinning, etc.
}
your server side code
public ActionResult ActionName() {
... do things to get your model populated ...
return PartialView("SomeView", yourmodel);
}
additional thoughts:
this rough code loads a partial view into a div. The asychonous call begins when the dom is ready.
see http://api.jquery.com/jQuery.ajax/ for jquery ajax documentation
i like to use spin.js to show a loading icon becuase it is so darn easy and small.

What is the right away to update a panel using AJAX?

In MVC4 applications, I would like to update a panel using AJAX but using jQuery methods instead using AjaxExtensions from MVC.
But my problem is the updatePanelId.
I've seen several people use this to update it when has success:
success: function (response) {
var $target = $("#target");
var $newHtml = response;
$target.replaceWith($newHtml);
}
But when I do this, it forces me to use in every partial view that includes the id="target" at the root level of my razor view, and I guess that's not a good practice; I said this because I've realized when I use AjaxExtensions it doesn't happens, replace the update and it does not remove the panelId. But using jQuery it does.
Any idea to port the AjaxExtensions feature to jQuery?
You can use just:
$("#target").html(response); // it will just update content of the $("#target") container
Use jQuery's .load function. This will load the contents of the URL you specify into the target element. You can optionally specify a selector after the URL in load to only grab part of the target page.
$(function() {
$("#target").load("/MyURL");
});
JavaScript same origin policy applies to this.

How to get an AJAX call in my TYPO3 Extbase Extension?

I have trouble doing this, I've been looking for some manuals, but they don't seems to work for me (they're either or detailed enough or I'm too stupid, probably something from both).
So I want to start an AJAX call from my Fluid View HTML file by some event, then it should go for the action in some controller and return some value (any value would be fine for the moment, I just can't seem to get anything to work here when it comes to AJAX in Extbase).
With no details I can only guess what is your problem
First and most important thing is ... using FireBug to check what the problem with AJAX call is. It can be just wrong URL (action, controller etc...) or some problem in your action which doesn't return required output. FireBug will allow you to check where it stacks.
But most probably...
There is VERY important thing to remember while writing JS/CSS code directly into your Fluid view and unfortunately it's almost never mentioned:
Fluid uses braces to indicate that the string is a variable: {someVar}, therefore if you put AJAX or other JavaScript function into the Fluid template it will be most probably considered just as Fluid variable. This sample pasted to the template:
$.ajax({
url: "index.php"
data: "tx_myextension_plugin[controller]=MyController&tx_myextension_plugin[action]=getData&type=89657201"
success: function(result) {
alert(result);
}
});
Will be rendered just as:
$.ajax(Array);
Solution:
Escaping it directly in the template is hard, therefore it's definitely easier just to save all your JavaScript into separate file under Resources/Public directory of your extension, and include it with common HTML tag:
<script type="text/javascript" src="typo3conf/ext/yourext/Resources/Public/ajaxFunctions.js"></script>
$("#searchFach").change(function(){
$.ajax({
type: 'POST',
url:"fragen/controller/Question/searchQuestions",
data: {mainCategoryId:$("#searchFach").val()},
success: function(response) { $("#searchCategory").html(response);
},
});
});`

HTML 5 - Ajax popstate and pushstate

I am trying to figure out how to use this pushstate and popstate for my ajax applications. I know there are some plug ins but i am trying to learn how to use it in it's raw form at the moment. I am also aware that in the raw form it is not supported by IE. All that aside, I need some help understanding how to use it.
the pushstate portion of it is pretty simple. Right now i have:
function loadForm(var1,var2){
string = "xyz="+var1+"&abc="+var2;
history.pushState("", "page 1", string);
}
This changes my url just fine and adds it to my url stack. I have another function that looks like the following:
function loadForm2(var1,var2, var3){
string = "xyz="+var1+"&abc="+var2+"&123="+var3;
history.pushState("", "page 2", string);
}
The second function also changes the url when called. Now that i have that part i am trying to figure out how to use the popstate. Right now i have it as follows
window.popState = ajax;
function ajax(){
jQuery.ajax({
type: "get",
url: "../html_form.php",
data: string,
dataType: "html",
success: function(html){
jQuery('#Right_Content').hide().html(html).fadeIn('slow');
validate();
toolTip();
}
})
}
So if you can image my page with two links, one calls the loadForm function and the other link calls loadForm2 function. When i click each of the links the forms loads via ajax just fine and the url changes as it should. When I hit the back button, the url will roll back to the previous page's url BUT the page content loads the current form again instead of the previous form. When i hit the back button it is making an ajax call (firebug) as if it is trying to load the previous form but instead of running the previous ajax call it runs the current ajax call. So my url goes back to the previous url but the form that is loaded or the ajax call that is called is the same as the most recent page load (not the previous page load).
I am not sure what i am doing wrong and any help would be much appreciated.
You are doing something weird.
window.popState = ajax;
I am even surprised that ajax() gets even called.
The normal way of doing it is to register an event handler.
$(window).bind('popstate', function(event) {
var state = event.originalEvent.state;
}
See How to trigger change when using the back button with history.pushstate and popstate?
EDIT:
Basically you need to know which form to load when your state is changed. .originalEvent.state will contain this information which you can then pass on to your ajax call. It should also contain the respective string.
The problem in your approach is that string, always remained the one of the last newly loaded page. You need to read that string in event.orginalEvent.state. use console.log() to find it in that object.
EDIT 2:
Is there a way you can give me an example of what my code should look like. I think you understand what i am trying to accomplish.
Everytime the back button (or forward button) of the browser is clicked, you need to load the page from AJAX.
You have attempted to do this by saying:
window.popState = ajax;
This is dangerous as you are replacing a system function.
Instead you should register an event handler for when the state changes.
jQuery(window).bind('popstate', ajax);
Now everytime the back button is pressed, your ajax() function (should) get called.
So far this will only improve your approach to it, but not fix your problem.
The problem is that your original ajax() function refers to a global variable called string. This global variable has no memory of the previous states. Therefore everytime the original form gets loaded again and again.
But you already are correctly storing string in the state by doing:
history.pushState("", "page 1", string);
So when ajax is called, the browser will give it an event object, which contains all this information.
So all you need to do now is change your ajax() as follows:
function ajax(){
jQuery.ajax({
type: "get",
url: "../html_form.php",
data: document.location.search.substr(1),
dataType: "html",
success: function(html){
jQuery('#Right_Content').hide().html(html).fadeIn('slow');
validate();
toolTip();
}
})
}
Finally you should also stop using string as a global variable by using the var keyword and make sure the string contains a "?":
function loadForm(var1,var2){
var string = "?xyz="+var1+"&abc="+var2;
history.pushState("", "page 1", string);
}
This will reduce any future confusion about something almost working, but not working properly.

Resources