TYPO3 open actionlink in same container - javascript

I've run into a little Problem with my TYPO3 Extension I created with the Extension Builder.
The Extension generates a Calendar and shows a list of upcoming events.
Calendar with listed events
code list.html
<div id="dncalendar-container"></div>
<f:flashMessages />
<div class="tx_tbpartnereventcal">
<f:for each="{events}" as="event">
<f:link.action class="event-cont" action="show" controller="Events" arguments="{events : event}" target="popup">
<span class="event-title">{event.title}</span> <span class="event-date"><f:format.date format="Y-m-d">{event.date}</f:format.date></span><br>
</f:link.action>
</f:for>
</div>
<!--<f:debug>{_all}</f:debug>-->
<f:format.raw>{scriptDates}</f:format.raw>
<script type="text/javascript">
//script to generate calendar
</script>
the list is created via the standard listAction in the controller and the elements can be clicked to show detailed information about each event.
However, when clicking on a linked Listitem, it reloads the pluginarea with the deatailed information as a new page. I would prefer it if the div.tx_tbpartnereventcal would just change the content of itself to the detailed information.
I have no idea however, how to get that working with ajax in TYPO3 or if there is another way.
Code controller action list and show:
/**
* action list
*
* #return void
*/
public function listAction()
{
$events = $this->eventsRepository->findAll();
$this->view->assign('events', $events);
/* get all events and turn into json for js calendar */
$allNotes ='';
/** #var Event $event */
foreach ($events as $event) {
$tempArr=array("date"=>$event->getDate()->format("Y-m-d"), "note" =>$event->getTitle(), "description" => $event->getLink(), "optional"=> "stuff");
$allNotes .= json_encode($tempArr).",";
}
/* create script to use data in js in .html */
$script = "
<script>
var jsondate = [".$allNotes."];
</script>
";
/* send js script to list.html to insert into js calendar */
$this->view->assign('scriptDates', $script);
}
/**
* action show
*
* #param \TBPartnerNet\TbPartnerTerminkalender\Domain\Model\Events $events
* #return void
*/
public function showAction(\TBPartnerNet\TbPartnerTerminkalender\Domain\Model\Events $events)
{
$this->view->assign('events', $events);
}
Am thankfull for any help!

There are basically 3 ways to achieve client-side dynamic on that element:
1) Introduce a kind of web service that produces the data to show (as JSON):
requires an AJAX endpoint in TYPO3 and client-side (JavaScript) building of the template (plain JavaScript or simple [e.g. mustache] or other [e.g. angular, vue] template-libraries).
2) Introduce a kind of web service that produces the HTML of the plugin:
requires an AJAX endpoint in TYPO3 and some JavaScript
3) Fetch the whole page (HTML) by AJAX and only replace your calendar part in the DOM:
requires no changes to TYPO3 but a little JavaScript
code example:
# register click handler for the date links on parent element (which will
# not change, thus you do not have to reregister the events after replacing the links)
$('.tx_tbpartnereventcal').on(
'click',
'.event-cont',
function(ev) {
ev.preventDefault()
# https://api.jquery.com/jQuery.ajax/
$.ajax(
[
url: ev.target.href
]
).done(
function(data) {
var $newPage = $(data),
newPluginHtml = $newPage.find(.tx_tbpartnereventcal).html()
$('.tx_tbpartnereventcal').html(newPluginHtml)
# you notice a JavaScript to generate the calendar -
# maybe you could call it here
}
)
}
)
3) is easiest to implement from your current point but of course is not the most performant way.
For 1) and 2) you need an AJAX endpoint. For v8 and below this is unelegant: Either the so-called pageType-approach or a helper extension like helhum/typoscript-rendering or the so-called eID-approach (not recommended!). For v9 we have middlewares which makes providing web services a lot cleaner.

Related

Inserting WordPress shortcode into JS through AJAX request

I am trying to insert WordPress shortcode into JS but haven't managed so far. I found some jQuery code that I needed to translate into vanilla JS and I am pretty sure I did not do the right thing since it's not working. I do not fully understand the code I came across, which means I need some help understanding where I've gone wrong and why my shortcode isn't showing on my site. Maybe the PHP code is not correctly linked to the JS file, I'm not too sure.
The goal is to have the shortcode (a WP form in this case) show in the modal when it's clicked on. Any help is greatly appreciated!
Here is the jQuery code (AJAX request):
$.ajax({
url: `<?php echo admin_url('admin-ajax.php'); ?>`,
type: "GET",
data: {
action: "runThisPhpFunction",
},
success: function (data) {
$("#trigger_target").html(data);
},
});
And here is my JS code for the modal, into which I am trying to place the shortcode:
function newsletterModal() {
const ajaxurl = `<?php echo admin_url('admin-ajax.php'); ?>`;
const btn = document.querySelector("#menu-item-2745");
btn.setAttribute("id", "trigger_my_shortcode");
const modal = document.createElement("div");
modal.setAttribute("id", "trigger_target");
modal.classList.add("modal");
modal.innerHTML = `<div class="modal-content">
<span class="close">×</span>
<h2>Sign up to our newsletter</h2>
<h5>And get hold of your 10% discount!</h5>
<p>insert [wpforms id="1703"] here</p>
</div>`;
btn.onclick = function (e) {
e.preventDefault();
modal.style.display = "block";
document
.querySelector("#trigger_my_shortcode")
.addEventListener("click", (e) => {
e.preventDefault();
fetch(ajaxurl, {
type: "GET",
data: {
action: "runThisPhpFunction",
},
success: function (data) {
document.querySelector("#trigger_target").html(data);
},
});
});
};
modal.querySelector(".close").onclick = function () {
modal.style.display = "none";
};
window.onclick = function (e) {
if (e.target == modal) {
modal.style.display = "none";
}
document.body.appendChild(modal);
};
}
And the functions.php code:
function runThisPhpFunction() {
if ( isset($_REQUEST) ) {
echo do_shortcode( '[wpforms id="1703"]' );
}
die();
}
add_action( 'wp_ajax_runThisPhpFunction', 'runThisPhpFunction' );
add_action( 'wp_ajax_nopriv_runThisPhpFunction', 'runThisPhpFunction' );
There is quite a lot going on with your code, so the answer won't be short.
It's generally a good practice to split your code up into smaller functions which all have their specific purpose. So I've taken the liberty to rewrite some functions so that they will help you in getting where you need to go.
The code below works as followed: The buildModal function builds all the HTML for your modal and can take a form as an argument. That form should be text because it needs to be interpolated (combined) with your other elements in the same string.
The buildModal function will be called from the getFormAndBuildModal function. The getFormAndBuildModal function uses fetch to send a request to the server and interprets the response as text. This text is your form, which will be passed to the buildModal to build the modal with the form in it.
The button with the #menu-item-2745 will be the trigger to send the request and build the form.
Working this way means that every time that you would click on your button it would call the server, build a new modal and show it on the page. Then when closing the modal, it removes the modal from the page.
I've tried to explain as much as possible of what's happening in the code and what each step is doing. If some things are still unclear, please let me know and I'll try to clear it up.
function buildModal(form) {
const modal = document.createElement("div");
modal.id = "trigger_target"
modal.classList.add("modal");
/**
* Create close button here so we can attach the
* event listener without having to select it later.
*/
const modalClose = document.createElement("span");
modalClose.classList.add("close");
modalClose.addEventListener("click", function() {
/**
* Remove the modal completely from the document.
* This isn't mandatory and you can change it if you'd like.
*/
modal.remove();
});
const modalContent = document.createElement("div");
modalContent.classList.add("modal-content");
/**
* The form will be a string of HTML that gets injected
* into another string of HTML here below. The innerHTML setter
* will then parse the entire string, with form, to HTML.
*/
modalContent.innerHTML = `
<div class="modal-content">
<h2>Sign up to our newsletter</h2>
<h5>And get hold of your 10% discount!</h5>
<p>${form}</p>
</div>`;
/**
* First append the close button, then the content.
*/
modal.append(modalClose, modalContent);
/**
* Return the HTML modal element.
*/
return modal;
}
Here I've added how to use PHP in JavaScript and a way to tackle the issue with selecting the button. There are two solutions to this problem, one is here at the second comment and the other solution is in the PHP snippet after this one.
/**
* Check the PHP snippet at the bottom how this gets here.
* This is the result of the array turned into JSON and then
* placed into the document with wp_add_inline_script.
*
* Sidenote: __wp__ looks ugly, but it will make sure that if
* a browser might get updated and a new property is added to the
* window object, it will never overwrite or break anything because
* the name is so unique.
*/
const ajaxurl = __wp__.ajax;
/**
* Select the button and listen for the click event.
* When clicked, fire the getFormAndBuildModal function.
*
* Update: with selecting elements it is paramount that the element is
* above the <script> tag in the document.
* Otherwise the element would not yet exist and the result would come up empty.
* Another way is to wait for the document to give a signal when every element has been rendered with the DOMContentLoaded event.
*/
// document.addEventListener('DOMContentLoaded', function(event) {
// const button = document.querySelector("#menu-item-2745");
// button.addEventListener("click", getFormAndBuildModal);
// });
const button = document.querySelector("#menu-item-2745");
button.addEventListener("click", function(event) {
event.preventDefault();
getFormAndBuildModal();
});
function getFormAndBuildModal() {
/**
* Fetch uses the GET method by default.
* All you need to do is to add the action to the URL
* so that WP knows what action to call on the server.
*/
fetch(`${ajaxurl}?action=runThisPhpFunction`)
/**
* Fetch can take while to load, so it uses a promise.
* With .then() we say what happens after fetch is finished.
* Fetch gives us a response object as a result, which we need to inspect.
*/
.then(response => {
/**
* If the response has gone wrong, show an error.
*/
if (!response.ok) {
throw new Error("runThisPhpFunction request has failed");
}
/**
* Otherwise we use the content that the response has send us.
* Currently the "body" (your form) of the response is just bits and bytes.
* We can tell the response how we want to use the response.
* With the .text() method we turn the raw data into a string.
* That string can later be used as HTML. :)
*/
return response.text();
})
/**
* response.text() also returns a promise, just like fetch. So to go to the next step
* we use another .then() function. In here we have our form in a string.
* Now we can build the modal and pass the form as an argument. The modal
* will be build and the form turned into HTML and put in the correct position.
* When the buildModal function is done it returns the result.
* Now append it to the body and it's done.
*/
.then(form => {
const modal = buildModal(form);
document.body.append(modal);
});
}
Here I've added a couple more additions to enqueueing the script and how to turn PHP into JavaScript the right way. ;)
function enqueue_my_custom_script() {
/**
* Instead of printing PHP variables directly inside JavaScript,
* you could use this method to let PHP do that for you.
* The array here below we be turned into a JSON string,
* which will later be turned into a JavaScript object that you
* can use in your main script.
*/
$wp_js_data = json_encode(
array(
'ajax' => admin_url( 'admin-ajax.php' ),
)
);
/**
* The last parameter of wp_register_script (there are 5) will
* determine if the script will be placed in the <head> tag when
* the value is false, or before the end of the </body> tag when
* the value is true. The latter will make sure that your JS executes
* AFTER all other HTML elements have been rendered. With this you don't
* have to listen for the DOMContentLoaded event in JavaScript.
*
* Use get_stylesheet_directory_uri() to get the path to your child
* theme directory instead of hard linking to your sheet. This will
* output the URL to the directory of your style.css file of your theme.
*/
wp_register_script( "scriptjs", get_stylesheet_directory_uri() . "/script.js", array(), null, true );
/**
* Here we create a global variable on the window object. This makes
* the data is available in every JavaScript file. Here we insert the JSON string
* that will be turned into a usable JS object.
*
* Be sure to output this script BEFORE the "scriptjs" file.
*/
wp_add_inline_script( "scriptjs", "window.__wp__ = {$wp_js_data}", "before" );
/**
* This used to be the first line. wp_register_script only registers
* the script but does not output it. This enables you to do something
* like wp_add_inline_script before outputting the script.
* wp_enqueue_script makes sure that the registered script will be
* placed in the document.
*/
wp_enqueue_script( "scriptjs" );
}
add_action( "wp_enqueue_scripts", "enqueue_my_custom_script" );

POST Slim Route not working

I'm using Slim for development. All my GET routes are working just fine, but whenever I use POST, I get "unexpected result". Please have a look at how I've implemented slim and that "unexpected error".
index-routes.php (index root file)
<?php
require 'Slim/Slim.php';
\Slim\Slim::registerAutoloader();
$app = new \Slim\Slim(array(
'debug' => true
));
require_once 'site-index.php';
require_once 'routes/default-routes.php';
$app->contentType('application/json');
$app->run();
?>
routes/default-routes.php
<?php
$app->post('/login',function(){
echo 'AllHailSuccess!';
})
?>
origin of POST request called via AJAX
function try1()
{
var value1 = "afsfesa";
API.call('/login','text','POST',function(data){console.log(data)},{var1:value1});
}
AJAX Call API
var API = {
call:function(url,returnType,reqType,callback,data){
var data = (!!data) ? data : {};
var callback = (!!callback) ? callback : function(){};
$.ajax({
dataType: returnType,
type:reqType,
crossDomain: true,
xhrFields: { withCredentials: true },
url: url,
data:data,
success:callback,
error:function(data){
console.log("Error!");
console.log(data);
}
});
}
}
"Unexpected error": When I execute try1(), THE POST ROUTE DOES GETS EXECUTED SUCCESSFULLY but the contents (The entire code in plain-text) of site-index.php (Which I called in root index-routes.php file) also gets logged along with it. The reason why I imported site-index.php in the first place, is because it acts like a "main stage" for my site. It's the only page I want to load and user navigates within it.
I want to know:
Why I'm getting this type of output?
Is my approach alright? I think importing my main-stage file from index- routes is causing this. Is there any other way of doing this?
Any help is appreciated. Thank you.
Your Slim calls are going to return anything that is displayed on the page.
There are a few ways to work around this:
Nest all of your page renders inside the route and don't render full pages for AJAX routes.
Modify your AJAX calls to search the returned DOM to find the relevant information.
In your example shown, AllHailSuccess! will be displayed after all of the content in site-index.php
Many people use templating software to render their pages and then use a service to render their page via the template. For more basic sites, I would recommend you create a simple service to display content.
Here's a simple example of a Viewer class I use in my project(s)
class Viewer {
/**
* Display the specified filename using the main template
* #param string $filepath The full path of the file to display
*/
public function display($filepath) {
//set a default value for $body so the template doesn't get angry when $body is not assigned.
$body = "";
if (file_exists($filepath)) {
$body = get_include_contents($filepath);
} else {
//You want to also return a HTTP Status Code 404 here.
$body = get_include_contents('404.html');
}
//render the page in the layout
include('layout.php');
}
}
/**
* Gets the contents of a file and 'pre-renders' it.
* Basically, this is an include() that saves the output to variable instead of displaying it.
*/
function get_include_contents($filepath, $params = array()) {
if (is_file($filepath)) {
ob_start();
include $filepath;
$ret = ob_get_contents();
ob_end_clean();
return $ret;
}
return false;
}
Your routes that you want to display the page layout to the user should look something like this now:
$app->get('/', function() {
(new Viewer())->display('home.html');
});
This is by no means a comprehensive solution because it does not address proper HTTP status codes and files are referenced directly in your code which can get messy, but it's a good starting point and its quick to mock something like this up.
If you want to continue in this direction, I would recommend you take a look at the Slim v2 Response Documentation and create a class that constructs and returns Response objects. This would give you much more flexibility and power to set HTTP status codes and HTTP Return headers.
I highly recommend checking out Slim v3 Responses as well because Slim 3 uses PSR-7 Response objects which are standard across multiple frameworks.

ZF2 jQuery datepickers not working in ajax dialogs

Some actions on my zend framework 2 web application open via a dialog. I use this method when processing an action that is called with ajax:
/**
* Display content only on ajax call.
* #param \Zend\Mvc\MvcEvent $e
*/
public function onDispatch(\Zend\Mvc\MvcEvent $e)
{
$app = $e->getParam('application');
$layout = $app->getMvcEvent()->getViewModel();
if($app->getRequest()->isXmlHttpRequest()) {
$controller = $e->getTarget();
$controller->layout('application/ajax/ajax');
$layout->setTerminal(true);
}
}
The problem is that the datetime pickers of jquery do not seem to work. Because this HTML gets added dynamically to the page.
I think a solution might be to modify this onDispatch method so it also re-includes some of the JS-files. Or is there a better way? I just thought that adding the JS-files hard-coded into my ajax.phtml file would also work.
But again, i would like to know if there is a better approach exists, like reloading the js on the page or something.
Yeah, one way is to add the scripts to your ajax.phtml.
Something I did a while ago is to send the required scripts as a response header:
$requiredScripts = array(
'/some/js/file.js',
'/another/js/file.js'
);
$this->getResponse()->getHeaders()
->addHeaderLine('x-scripts: ' . json_encode($requiredScripts));
Then in your js:
// globally listen for the ajax-requests
$(document).ajaxSuccess(function(res, status, xhr) {
var requiredScripts = xhr.getResponseHeader("x-scripts");
if (requiredScripts) {
jQuery.each(requiredScripts, function(index, scriptSrc) {
jQuery.getScript(scriptSrc);
});
}
});

how to call a function in code behind from an external .js file

i am developing a website in dotnet.
//function to close SearchSchool.aspx
function CloseSchoolSearch()
{
//storing values
window.close();
//call function in code behind
}
This is a javascript function in an external .js file ,using this function i am storing some values in some hidden controls in an aspx page and closing pop window ,after that i want to execute a function in code behind.and remind one thing,i can't include this function .aspx page contaning that method i want to call.Can anyone guide me how to do this
As i understand the question, you are talking about 2 very different things.
the .ASPX page is rendered on the server and the javascript code is rendered at the client side.
for you to call a function from the aspx page from JS means that you need to make a call to the server to render your page is some other manner with a parameter you mentioned in your call.
only then will the server re-render the page (can be ajax as well) and invoke these methods.
other then that, the server side code is not being sent to the client side.
On the client side:
you can use any framework or implement your own. i'll use jquery for simplicity
/* attach a submit handler to the form */
$("#form_name").submit(function(event) {
/* stop form from submitting normally */
event.preventDefault();
/* get some values from elements on the page: */
url ="<server url>";
var $inputs = $('#form_name :input');
var dataString="";
$inputs.each(function() {
if (this.type != "submit" && this.type != "button")
dataString += (this.name +"="+ $(this).val() +"&").trim();
});
/*Remove the & at the end of the string*/
dataString = dataString.slice(0, -1);
/* Send the data using post and put the results in a div */
$.post( url, dataString,
function( data ) {
}
);
the serialize function will work as well just add its output instead of the dataString.
I understand you want to call a javascript function defined inside the HTML page using <script></script> from an externally loaded .js file.
Just make sure the internal javascript function is available when your external JS is loaded.
If you want to call a function localFoo() defined inside the HTML code, then do this:
// Check for the function availability
if(typeof localFoo != undefined) {
localFoo(arg);
}

Call ASP.NET function from JavaScript?

I'm writing a web page in ASP.NET. I have some JavaScript code, and I have a submit button with a click event.
Is it possible to call a method I created in ASP with JavaScript's click event?
Well, if you don't want to do it using Ajax or any other way and just want a normal ASP.NET postback to happen, here is how you do it (without using any other libraries):
It is a little tricky though... :)
i. In your code file (assuming you are using C# and .NET 2.0 or later) add the following Interface to your Page class to make it look like
public partial class Default : System.Web.UI.Page, IPostBackEventHandler{}
ii. This should add (using Tab-Tab) this function to your code file:
public void RaisePostBackEvent(string eventArgument) { }
iii. In your onclick event in JavaScript, write the following code:
var pageId = '<%= Page.ClientID %>';
__doPostBack(pageId, argumentString);
This will call the 'RaisePostBackEvent' method in your code file with the 'eventArgument' as the 'argumentString' you passed from the JavaScript. Now, you can call any other event you like.
P.S: That is 'underscore-underscore-doPostBack' ... And, there should be no space in that sequence... Somehow the WMD does not allow me to write to underscores followed by a character!
The __doPostBack() method works well.
Another solution (very hackish) is to simply add an invisible ASP button in your markup and click it with a JavaScript method.
<div style="display: none;">
<asp:Button runat="server" ... OnClick="ButtonClickHandlerMethod" />
</div>
From your JavaScript, retrieve the reference to the button using its ClientID and then call the .click() method on it.
var button = document.getElementById(/* button client id */);
button.click();
The Microsoft AJAX library will accomplish this. You could also create your own solution that involves using AJAX to call your own aspx (as basically) script files to run .NET functions.
I suggest the Microsoft AJAX library. Once installed and referenced, you just add a line in your page load or init:
Ajax.Utility.RegisterTypeForAjax(GetType(YOURPAGECLASSNAME))
Then you can do things like:
<Ajax.AjaxMethod()> _
Public Function Get5() AS Integer
Return 5
End Function
Then, you can call it on your page as:
PageClassName.Get5(javascriptCallbackFunction);
The last parameter of your function call must be the javascript callback function that will be executed when the AJAX request is returned.
You can do it asynchronously using .NET Ajax PageMethods. See here or here.
I think blog post How to fetch & show SQL Server database data in ASP.NET page using Ajax (jQuery) will help you.
JavaScript Code
<script src="http://code.jquery.com/jquery-3.3.1.js" />
<script language="javascript" type="text/javascript">
function GetCompanies() {
$("#UpdatePanel").html("<div style='text-align:center; background-color:yellow; border:1px solid red; padding:3px; width:200px'>Please Wait...</div>");
$.ajax({
type: "POST",
url: "Default.aspx/GetCompanies",
data: "{}",
dataType: "json",
contentType: "application/json; charset=utf-8",
success: OnSuccess,
error: OnError
});
}
function OnSuccess(data) {
var TableContent = "<table border='0'>" +
"<tr>" +
"<td>Rank</td>" +
"<td>Company Name</td>" +
"<td>Revenue</td>" +
"<td>Industry</td>" +
"</tr>";
for (var i = 0; i < data.d.length; i++) {
TableContent += "<tr>" +
"<td>"+ data.d[i].Rank +"</td>" +
"<td>"+data.d[i].CompanyName+"</td>" +
"<td>"+data.d[i].Revenue+"</td>" +
"<td>"+data.d[i].Industry+"</td>" +
"</tr>";
}
TableContent += "</table>";
$("#UpdatePanel").html(TableContent);
}
function OnError(data) {
}
</script>
ASP.NET Server Side Function
[WebMethod]
[ScriptMethod(ResponseFormat= ResponseFormat.Json)]
public static List<TopCompany> GetCompanies()
{
System.Threading.Thread.Sleep(5000);
List<TopCompany> allCompany = new List<TopCompany>();
using (MyDatabaseEntities dc = new MyDatabaseEntities())
{
allCompany = dc.TopCompanies.ToList();
}
return allCompany;
}
Static, strongly-typed programming has always felt very natural to me, so at first I resisted learning JavaScript (not to mention HTML and CSS) when I had to build web-based front-ends for my applications. I would do anything to work around this like redirecting to a page just to perform and action on the OnLoad event, as long as I could code pure C#.
You will find however that if you are going to be working with websites, you must have an open mind and start thinking more web-oriented (that is, don't try to do client-side things on the server and vice-versa). I love ASP.NET webforms and still use it (as well as MVC), but I will say that by trying to make things simpler and hiding the separation of client and server it can confuse newcomers and actually end up making things more difficult at times.
My advice is to learn some basic JavaScript (how to register events, retrieve DOM objects, manipulate CSS, etc.) and you will find web programming much more enjoyable (not to mention easier). A lot of people mentioned different Ajax libraries, but I didn't see any actual Ajax examples, so here it goes. (If you are not familiar with Ajax, all it is, is making an asynchronous HTTP request to refresh content (or perhaps perform a server-side action in your scenario) without reloading the entire page or doing a full postback.
Client-Side:
<script type="text/javascript">
var xmlhttp = new XMLHttpRequest(); // Create object that will make the request
xmlhttp.open("GET", "http://example.org/api/service", "true"); // configure object (method, URL, async)
xmlhttp.send(); // Send request
xmlhttp.onstatereadychange = function() { // Register a function to run when the state changes, if the request has finished and the stats code is 200 (OK). Write result to <p>
if (xmlhttp.readyState == 4 && xmlhttp.statsCode == 200) {
document.getElementById("resultText").innerHTML = xmlhttp.responseText;
}
};
</script>
That's it. Although the name can be misleading the result can be in plain text or JSON as well, you are not limited to XML. jQuery provides an even simpler interface for making Ajax calls (among simplifying other JavaScript tasks).
The request can be an HTTP-POST or HTTP-GET and does not have to be to a webpage, but you can post to any service that listens for HTTP requests such as a RESTful API. The ASP.NET MVC 4 Web API makes setting up the server-side web service to handle the request a breeze as well. But many people do not know that you can also add API controllers to web forms project and use them to handle Ajax calls like this.
Server-Side:
public class DataController : ApiController
{
public HttpResponseMessage<string[]> Get()
{
HttpResponseMessage<string[]> response = new HttpResponseMessage<string[]>(
Repository.Get(true),
new MediaTypeHeaderValue("application/json")
);
return response;
}
}
Global.asax
Then just register the HTTP route in your Global.asax file, so ASP.NET will know how to direct the request.
void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapHttpRoute("Service", "api/{controller}/{id}");
}
With AJAX and Controllers, you can post back to the server at any time asynchronously to perform any server side operation. This one-two punch provides both the flexibility of JavaScript and the power the C# / ASP.NET, giving the people visiting your site a better overall experience. Without sacrificing anything, you get the best of both worlds.
References
Ajax,
jQuery Ajax,
Controller in Webforms
The Microsoft AJAX library will accomplish this. You could also create your own solution that involves using AJAX to call your own aspx (as basically) script files to run .NET functions.
This is the library called AjaxPro which was written an MVP named Michael Schwarz. This was library was not written by Microsoft.
I have used AjaxPro extensively, and it is a very nice library, that I would recommend for simple callbacks to the server. It does function well with the Microsoft version of Ajax with no issues. However, I would note, with how easy Microsoft has made Ajax, I would only use it if really necessary. It takes a lot of JavaScript to do some really complicated functionality that you get from Microsoft by just dropping it into an update panel.
It is so easy for both scenarios (that is, synchronous/asynchronous) if you want to trigger a server-side event handler, for example, Button's click event.
For triggering an event handler of a control:
If you added a ScriptManager on your page already then skip step 1.
Add the following in your page client script section
//<![CDATA[
var theForm = document.forms['form1'];
if (!theForm) {
theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
//]]>
Write you server side event handler for your control
protected void btnSayHello_Click(object sender, EventArgs e)
{
Label1.Text = "Hello World...";
}
Add a client function to call the server side event handler
function SayHello() {
__doPostBack("btnSayHello", "");
}
Replace the "btnSayHello" in code above with your control's client id.
By doing so, if your control is inside an update panel, the page will not refresh. That is so easy.
One other thing to say is that: Be careful with client id, because it depends on you ID-generation policy defined with the ClientIDMode property.
I'm trying to implement this but it's not working right. The page is
posting back, but my code isn't getting executed. When i debug the
page, the RaisePostBackEvent never gets fired. One thing i did
differently is I'm doing this in a user control instead of an aspx
page.
If anyone else is like Merk, and having trouble over coming this, I have a solution:
When you have a user control, it seems you must also create the PostBackEventHandler in the parent page. And then you can invoke the user control's PostBackEventHandler by calling it directly. See below:
public void RaisePostBackEvent(string _arg)
{
UserControlID.RaisePostBackEvent(_arg);
}
Where UserControlID is the ID you gave the user control on the parent page when you nested it in the mark up.
Note: You can also simply just call methods belonging to that user control directly (in which case, you would only need the RaisePostBackEvent handler in the parent page):
public void RaisePostBackEvent(string _arg)
{
UserControlID.method1();
UserControlID.method2();
}
You might want to create a web service for your common methods.
Just add a WebMethodAttribute over the functions you want to call, and that's about it.
Having a web service with all your common stuff also makes the system easier to maintain.
If the __doPostBack function is not generated on the page you need to insert a control to force it like this:
<asp:Button ID="btnJavascript" runat="server" UseSubmitBehavior="false" />
Regarding:
var button = document.getElementById(/* Button client id */);
button.click();
It should be like:
var button = document.getElementById('<%=formID.ClientID%>');
Where formID is the ASP.NET control ID in the .aspx file.
Add this line to page load if you are getting object expected error.
ClientScript.GetPostBackEventReference(this, "");
You can use PageMethods.Your C# method Name in order to access C# methods or VB.NET methods into JavaScript.
Try this:
if(!ClientScript.IsStartupScriptRegistered("window"))
{
Page.ClientScript.RegisterStartupScript(this.GetType(), "window", "pop();", true);
}
Or this
Response.Write("<script>alert('Hello World');</script>");
Use the OnClientClick property of the button to call JavaScript functions...
You can also get it by just adding this line in your JavaScript code:
document.getElementById('<%=btnName.ClientID%>').click()
I think this one is very much easy!
Please try this:
<%= Page.ClientScript.GetPostBackEventReference(ddlVoucherType, String.Empty) %>;
ddlVoucherType is a control which the selected index change will call... And you can put any function on the selected index change of this control.
The simplest and best way to achieve this is to use the onmouseup() JavaScript event rather than onclick()
That way you will fire JavaScript after you click and it won't interfere with the ASP OnClick() event.
I try this and so I could run an Asp.Net method while using jQuery.
Do a page redirect in your jQuery code
window.location = "Page.aspx?key=1";
Then use a Query String in Page Load
protected void Page_Load(object sender, EventArgs e)
{
if (Request.QueryString["key"] != null)
{
string key= Request.QueryString["key"];
if (key=="1")
{
// Some code
}
}
}
So no need to run an extra code
This reply works like a breeze for me thanks cross browser:
The __doPostBack() method works well.
Another solution (very hackish) is to simply add an invisible ASP button in your markup and click it with a JavaScript method.
<div style="display: none;">
<asp:Button runat="server" ... OnClick="ButtonClickHandlerMethod" />
</div>
From your JavaScript, retrieve the reference to the button using its ClientID and then call the .Click() method on it:
var button = document.getElementByID(/* button client id */);
button.Click();
Blockquote

Categories

Resources