I have javascript code like this:
<a href="javascript:window.history.back()"...
When I test my website (using HTML5, MVC4) in a browser, it works fine. But when I run it in an Android/iPhone app using a embedded browser my back link doesn't work.
Is there a way to simulate a history.back using razor, like Url.Action?
You can save a previous page url in session. Something like this:
public ActionResult SomeCoolController(SomeCoolClass parameters) {
//some logic
var previousPageUrl = Session["PreviousPageUrl"];
if(previousPageUrl == null)
Session["PreviousPageUrl"] = Request.Url;
var isTimeToChangePreviousUrl = Session["IsTimeToChangePreviousUrl"];
if(isTimeToChangePreviousUrl != null) {
if(isTimeToChangePreviousUrl) {
Session["IsTimeToChangePreviousUrl"] = false;
Session["PreviousPageUrl"] = Request.Url;
} else {
Session["IsTimeToChangePreviousUrl"] = true;
}
} else {
Session["IsTimeToChangePreviousUrl"] = false;
}
//some return
}
Also to don't always copy/paste this code you can write your own SuperDupaActionResult which will be inherit from ActionResult and contain the code above (as a method for example).
Related
My home page has a couple of links: one for English version and the other for French version. Something like this:
<a class="ensite" href="/en">English</a>
<a class="ensite" href="/fr">French</a>
I want to use JavaScript to remember the last choice made by visitors and when they come again, they don't have to choose the language one more time because I want them to be autoredirected to the preferred language using cookies.
P.S. the visitors are strangers, not registered users. I want to store cookies in visitors' browsers, not in the database. Please, help me by providing me with the full solution.
Gelerally, the idea is: set handlers on links and upon clicking save preferred version into localStorage. Then every time user loads any page of your site, just check, whether the url contains the language context ("en"/"fr") the user chose before. If yes - do nothing, user opened the right version; if not - redirect him to the previously saved version. The following is a Vanilla approach (not properly tested). You will have to tweak it (attachEvent etc.) or use jQuery library to implement similar ideas in a shorter and more cross-browser way.
<a class="ensite" href="/en">English</a>
<a class="ensite" href="/fr">French</a>
JS:
function LanguageManager(selector) {
this.langLinks = document.querySelectorAll(selector);
}
LanguageManager.prototype.setHandler = function() {
var self = this;
this.langLinks.forEach(function(langLink) {
langLink.addEventListener("click", self.handler, false);
});
}
LanguageManager.prototype.redirect = function() {
var link = storageManager.restoreDataFromStorage();
if(link && !~window.location.href.indexOf(link)) window.location.href = link;
}
LanguageManager.prototype.handler = function() {
var e = event || window. event;
var elem = e.target || e.srcElement;
if(e.preventDefault) e.preventDefault(); else e.returnValue = false;
storageManager.saveDataToStorage(elem.href);
location.href = elem.href;
}
function StorageManager() {
this.storageName = "languageVersion";
this.storageData = null;
}
StorageManager.prototype.isStorageAvailable = function(type) {
try {
var storage = window[type], x = '__storage_test__';
storage.setItem(x, x);
storage.removeItem(x);
return true;
} catch(e) { return false; }
}
StorageManager.prototype.saveDataToStorage = function(data) {
if(!this.isStorageAvailable('localStorage')) {
this.storageData = data;
return false;
}
try {
localStorage.setItem(this.storageName, JSON.stringify(data));
return this.storageName;
} catch(e) {
this.storageData = data;
return false;
}
}
StorageManager.prototype.restoreDataFromStorage = function() {
if(this.storageData) return this.storageData;
return JSON.parse(localStorage.getItem(this.storageName));
}
var storageManager = new StorageManager();
var languageManager = new LanguageManager(".ensite");
languageManager.setHandler();
languageManager.redirect();
Also notice, that there may be issues depending on how you implement language contexts on your site. You can start with my code on your own and tweak it or find someone else to get this properly done.
Just tested this, it works perfect.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<a class="ensite" href="" onclick ="localStorage.setItem('language','en')">English</a>
<a class="ensite" href="" onclick = "localStorage.setItem('language','fr')">French</a>
<script>
$(document).ready(function(){
var language = (localStorage.getItem('language') == null)? 'en' : localStorage.getItem('language');
console.log(language);
})
</script>
I got the following code which was written into a Chrome Extension (Javascript?)
;
(function() {
function findCaptcha() {
return document.querySelector('.g-recaptcha') || document.getElementById('g-recaptcha');
}
function completeCaptch(intervalID) {
intervalID = setInterval(function() {
if (findCaptcha() != null) {
findCaptcha()
.remove();
clearInterval(intervalID);
}
}, 200);
}
var loadedID = null;
if (location.hash === '#checkout' || location.pathname === '/checkout') {
completeCaptch(loadedID);
}
var stateID = null;
window.addEventListener('popstate', function(event) {
stateID = null;
clearInterval(stateID);
if (location.hash === '#checkout' || location.pathname === '/checkout') {
completeCaptch(stateID);
}
}, false);
})();
Reading this code is simple enough, it calls the function completeCaptch with some sort of ID that is irrelevant and then calls the function findCaptch if it is present (return document.querySelector('.g-recaptcha') || document.getElementById('g-recaptcha');) and simply removes the document.ID by calling .remove();
This is code that bypasses reCAPTCHA in a demo and I was wondering if it is possible to convert this code (whatever it was written in) to C# if I were to use a .net WebBrowser.
Using a .net WebBrowser I would be able to getElementById but would I be able to call .remove() in C#?
Thanks.
Checkout the HtmlAgilityPack library. It's a fantastic library for dealing with HTML DOMs, allowing you to do something like this:
doc.DocumentNode.SelectSingleNode("/xpath/to/node").Remove();
We are implementing an app where we have communication between Javascript and c#. Our UIWebView has a button to invoke some native functionality. On a UIWebView i have an handler on ShouldStartLoad.
webView.ShouldStartLoad = myHandler;
bool myHandler (UIWebView webView, NSUrlRequest request, UIWebViewNavigationType navType)
{
}
This gets called everytime page loads. Indeed, i would like to only call it from an event from WebView such as on a button click.
From Javascript i have
window.location.href = "myapp://action?par1=abc&par2=def";
How to call a particular function from custom url?
Calling JavaScript from c#
I am trying to call back JavaScript from c# but it is not calling TestShow() function
wkWebView.EvaluateJavaScript(string.Format("TestShow()"), (r, e) =>
{
Console.WriteLine("In EvaluateJavaScript");
if (e != null) Console.WriteLine(e);
});
JavaScript side i have a Alert but it is not showing that alert
function TestShow()
{
alert("Hello! I am an alert box!!");
}
You can either continue using UIWebView and parse the NSUrlRequest to see if it is the call you're looking for. Then return true/false accordingly.
A better option would be to use WKWebView and create a custom message handler. Something like this:
1) Implement IWKScriptMessageHandler (tested on the default UIView created by Xamarin UIViewController)
public class UniversalView : UIView, IWKScriptMessageHandler
{
public void DidReceiveScriptMessage(WKUserContentController userContentController, WKScriptMessage message)
{
var msg = message.Body.ToString();
System.Diagnostics.Debug.WriteLine(msg);
}
}
2) Create user controller with a handler for "myapp" (this = the IWKScriptMessageHandler)
var userController = new WKUserContentController();
userController.AddScriptMessageHandler(this, "myapp");
3) Create a config with the controller
var config = new WKWebViewConfiguration
{
UserContentController = userController
};
4) Create the WKWebView with the config
var webView = new WKWebView(new CGRect(10, 100, 500, 500), config);
5) Call "myapp" from your JS code
<html><head><meta charset = "utf-8"/></head><body>
<button onclick="callCsharp()">Click</button>"
<script type="text/javascript">
function callCsharp(){
window.webkit.messageHandlers.myapp.postMessage("action?par1=abc&par2=def");
}</script></body></html>";
EDIT: In regards to evaluating JS from C# you need to be sure the HTML page has finished loading or otherwise the call will result in an error. You can handle navigation events by implementing IWKNavigationDelegate
public class UniversalView : UIView, IWKScriptMessageHandler, IWKNavigationDelegate
{
[Export("webView:didFinishNavigation:")]
public void DidFinishNavigation(WKWebView webView, WKNavigation navigation)
{
webView.EvaluateJavaScript("callCsharp()", (result, error) =>
{
if (error != null) Console.WriteLine(error);
});
}
Assign it to the WKWebView you created:
var webView = new WKWebView(new CGRect(10, 100, 500, 500), config)
{
WeakNavigationDelegate = this
};
I have a controller that is returning a pdf file, this is temporary save in a local folder. It is possible to open a print dialog directly with out open the pdf file using javascript??
public ActionResult LoadDownloadAndPrint(string Download)
{ return File(System.IO.File.ReadAllBytes(target);)
The file is saved in C:\Windows\Temp\3ac416b7-7120-4169-bc4d-61e105ec197c\output.pdf
I've have tried to used embed tag like in this thread Print PDF directly from JavaScript but did not work I guess because is a local place where the file is stored.
After a lot of researching finally get it using iframe. This code was very helpful http://www.sitepoint.com/load-pdf-iframe-call-print/
I have an empty hidden iframe in my view.
This is working in Chrome, FF, but not in IE
Search.openPrintDialog = function () {
var printJobIds = $("input:checkbox[name='Print']:checked").map(function () { return this.value; }).get().join(',');
if (printJobIds.length > 0)
{
JSUtil.BlockUI();
print('/' + JSUtil.GetWebSiteName() + '/Search/LoadDownloadAndPrint?Print=' + printJobIds)
}
return false;
}
function print(url) {
var _this = this,
iframeId = 'iframeprint',
$iframe = $('iframe#iframeprint');
$iframe.attr('src', url);
$iframe.load(function () {
_this.callPrint(iframeId);
});
}
//initiates print once content has been loaded into iframe
function callPrint(iframeId) {
var PDF = document.getElementById(iframeId);
PDF.focus();
PDF.contentWindow.print();
JSUtil.UnBlockUI();
}
I am using iframe to open new .aspx page from parent page. child page is using ajaxcontroltoolkit(ajax CalendarExtender). Now on form submit, I want to close iframe and return to parent page. For that I am using following code.
ClientScript.RegisterStartupScript(this.GetType(), "scriptid", window.parent.location.href='ViewVendors.aspx'", true);
This works file if I remove ajax control from child page but does not work with ajax control.
I want to use calenderExtender and iframe both. How can I use it and what is the problem for such so called abnormal behavior.
This is the code for my submit button event handler.
protected void btnUpdate_Click(object sender, EventArgs e)
{
try
{
objVendor.VendorID = Convert.ToInt64(Request.QueryString["Id"]);
objVendor.Name = txtName.Text;
objVendor.BillingAddress = txtBillingAddress.Text;
objVendor.ShippingAddress = txtShippingAddress.Text;
objVendor.ContactPersonName = txtContactPerson.Text;
objVendor.ContactNumber = txtContactNumber.Text;
objVendor.EmailID = txtEmailID.Text;
objVendor.VendorSinceDate = Convert.ToDateTime(txtVendorDate.Text);
objVendor.IsActive = Convert.ToBoolean(rdblStatus.SelectedValue);
objVendor.Logo = FileUpload();
int intResult = objVendor.UpdateVendor();
if (intResult > 0)
{
ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "window.parent.location.href='ViewVendors.aspx'", "scriptid", true);
//ClientScript.RegisterStartupScript(this.GetType(), "scriptid", "window.parent.location.href='ViewVendors.aspx'", true);
}
}
catch (Exception ex)
{
lblMessage.Text = ex.Message;
lblMessage.CssClass = "ERROR";
}
}
//Edit
Now my code works fine as long as I am not adding calender extender to the child page.
When I add calender extender in child page it shows error "The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>)". If I remove calender extender, again it works well. By doing some googling, I found that <% %> in Javascript tag is creating problem. How can I solve it and why calender control is creating problem in such cases?
Here is the code for my script.
<script type="text/javascript">
function uploadStarted() {
$get("imgDisplay").style.display = "none";
}
function uploadComplete(sender, args) {
var imgDisplay = $get("imgDisplay");
// var imgPhoto = $get("#imgPhoto");
var imgPhoto = document.getElementById('<%=imgPhoto.ClientID %>');
imgDisplay.src = "images/loader.gif";
imgPhoto.style.display = "none";
imgDisplay.style.cssText = "";
var img = new Image();
img.onload = function () {
imgDisplay.style.cssText = "height:100px;width:100px";
imgDisplay.src = img.src;
};
img.src = "<%=ResolveUrl(UploadFolderPath) %>" + args.get_fileName();
}
</script>
You need to register your JavaScript using the ScriptManager instance on your page - which you should already have if you're using AJAX. It has its own RegisterStartupScript method that you can use.