Morning all.
I have the following javascript in my code in front
<script type="text/javascript" src="~/VDSReporting/jquery.js"></script> <script type="text/javascript">
function ShowImage() {
document.getElementById('tbxProdAC')
.style.backgroundImage = 'url(/images/vds/progress.gif)';
document.getElementById('tbxProdAC')
.style.backgroundRepeat = 'no-repeat';
document.getElementById('tbxProdAC')
.style.backgroundPosition = 'right';
}
function HideImage() {
document.getElementById('tbxProdAC')
.style.backgroundImage = 'none';
}
</script>
How do I go about 'converting' this and only having it present in c# code behind?
Please excuse my ignorance, I'm completely out of my depth here!
If this is a progress image you are showing (seems so from the image name), then why would you want to do that server side? That will kind of defeat the whole purpose of a progress image. This seem like it belong on the client side, so keep it there.
Update
You don't need to use the code behind to render the script just to get the client id's. You can do something like this:
function ShowImage() {
document.getElementById('<%=tbxProdAC.ClientID%>')
.style.backgroundImage = 'url(/images/vds/progress.gif)';
document.getElementById('<%=tbxProdAC.ClientID%>')
.style.backgroundRepeat = 'no-repeat';
document.getElementById('<%=tbxProdAC.ClientID%>')
.style.backgroundPosition = 'right';
}
function HideImage() {
document.getElementById('<%=tbxProdAC.ClientID%>')
.style.backgroundImage = 'none';
}
Here I use <%=tbxProdAC.ClientID%> to get the id of the control. This is a lot more readable then using the code behind to render the script.
I need some javascript to be run from the server side and this worked for me -
if (!this.ClientScript.IsStartupScriptRegistered("StartDown"))
{
string scriptString = #"alert(""some javascript"");location.href='MyPage.aspx';";
this.ClientScript.RegisterStartupScript(Page.GetType(), "StartDown", scriptString, true);
}
Hope this helps..
Related
I have a trouble to get angular working with .Net partial postbacks.
Question is basically same to this : Re-initialize Angular bindings after partial postback
Basically I have a tab on which I have angular app, then I have second tab with some c# control, I have to do partial postback between tabs and when I am going back to my app, there is nothing.
I have tried routing with ngView then I have tried $route.reload() (it goes to the controller and I can see that the template is being pulled down but the result on the page is none). Then I tried compile(templateCache.get(lazyTableControllerRoute.current.templateUrl))(scope) as mentioned here. Nothing.
Please help :)
After each postback I am putting on page this html :
LiteralControl lazyControl = new LiteralControl("<div ng-app=\"LazyLoadingApp\" style=\"padding:10px\" ng-controller=\"LazyTableController\" ng-view><lazy-table> </lazy-table></div>");
Controls.Add(lazyControl);
And some config constants like templateUrl.
Here is my code :
var app = angular.module('LazyLoadingApp', ['ui.bootstrap', 'ngRoute'], function ($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
});
app.config(function ($routeProvider, $locationProvider, tableTemplateUrl) {
$routeProvider.when('/Page.Web.UI/sptl_project.aspx', {
controller: 'LazyTableController',
templateUrl: tableTemplateUrl,
});
// configure html5 to get links working on jsfiddle
$locationProvider.html5Mode(true);
});
//**This objects I am using after partial postback to check in the console if e.g. $route.reload() works..**
var lazyTableControllerRoute = null;
var templateCache = null;
var compile = null;
var scope = null;
app.directive('lazyTable', ['tableTemplateUrl',
function (tableTemplateUrl) {
return {
name: 'lazyTable',
priority: 0,
restrict: 'E', // E = Element, A = Attribute, C = Class, M = Comment
templateUrl: tableTemplateUrl
};
}
]).controller('LazyTableController', ['$scope', '$rootScope', 'lazyFactory', 'opsPerRequest', 'header', '$route', '$templateCache', '$compile',
function ($scope, $rootScope, lazyFactory, opsPerRequest, header, $route, $templateCache, $compile) {
lazyTableControllerRoute = $route;
var loadingPromise = null;
templateCache = $templateCache;
compile = $compile;
scope = $scope;
(...) rest is not important
UPDATE:
I was trying with require.js.. (Again, it's working after full page load.) My idea was to bootstrap element after partial postback.
I built simple test case that in Update Panel along with my app there is simple button, just making partial postback. After click (when app disappeared) I tried in console:
angular.bootstrap(document, ['LazyLoadingApp'])
But then I got error which I cannot remove:
App Already Bootstrapped with this Element 'document'
Here is plunker for app in require.js way (but please keep in mind that it's just for code review purpose..)
don't use ng-app and angular.bootstrap all together at once.
did you compile "ng-app", if so don't.
ngtutorial.com/learn/bootstrap
Alright ! Problem solved.. So in order to work with partial postbacks you need to :
Define app like this: (remember that you have to remove ng-app from html !)
<base href="/">
<asp:UpdatePanel ID="updatePanel" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Button ID="fire" runat="server" Text="fire!" />
<div id="parent" > <div id="boodstapped" ng-view ></div></div>
</ContentTemplate>
</asp:UpdatePanel>
Instantiate app like this:
var app = angular.module('LazyLoadingApp', ['ui.bootstrap', 'ngRoute']);
jQuery(document).ready(function ($) {
var prm = Sys.WebForms.PageRequestManager.getInstance();
function EndRequestHandler(sender, args) {
jQuery('#parent').children().remove();
jQuery('#parent').append('<div id="boodstapped" ng-view ></div>');
angular.bootstrap(jQuery('#boodstapped'), ['LazyLoadingApp']);
}
prm.add_endRequest(EndRequestHandler);
});
Then when you will try to do partial postback EndRequestHandler will bootstrap app again. What's important to remove previously bootstrap element, to avoid angular "already bootstrapped" error.
Click Here for more information.
Though the other answers probably do work I've found that best course of action is to try to not be in a 'mixed' state of .net controls and angular controls that depend on interaction between the two.
The process for this is undocumented at best... and you end up writing a lot of code to accommodate simple things.
I wouldn't recommend doing the following for long and only suggest it as a temporary/transitional solution and I know this may not solve every case .... but note you can always attack this problem from the dot.net side as follows and redirect back to the page you are on...
protected void cbChecked_My_DotNet_CallBack(object sender, EventArgs e)
{
DoDotNetStuff();
if(NeedToSignalToAngular){
response.redirect(yourpage.aspx?yourparams=xxx)
}
}
This question already has answers here:
Calling JavaScript Function From CodeBehind
(21 answers)
Closed 9 years ago.
I am trying to learn asp.net. Assuming that I have this code:
if (command.ExecuteNonQuery() == 0)
{
// JavaScript like alert("true");
}
else
{
// JavaScript like alert("false");
}
How to I can invoke JavaScript from C# code behind? How to do that by putting that JavaScript in Scripts directory which is created by default in MS Visual Studio?
Here is method I will use from time to time to send a pop message from the code behind. I try to avoid having to do this - but sometimes I need to.
private void LoadClientScriptMessage(string message)
{
StringBuilder script = new StringBuilder();
script.Append(#"<script language='javascript'>");
script.Append(#"alert('" + message + "');");
script.Append(#"</script>");
Page.ClientScript.RegisterStartupScript(this.GetType(), "messageScript", script.ToString());
}
You can use RegisterStartupScript to load a javascript function from CodeBehind.
Please note that javascript will only run at client side when the page is render at client's browser.
Regular Page
Page.ClientScript.RegisterStartupScript(this.GetType(), "myfunc" + UniqueID,
"myJavascriptFunction();", true);
Ajax Page
You need to use ScriptManager if you use ajax.
ScriptManager.RegisterStartupScript(Page, Page.GetType(), "myfunc" + UniqueID,
"myJavascriptFunction();", true);
Usually these "startupscripts" are handy for translations or passing settings to javascript.
Although the solution Mike provided is correct on the .Net side I doubt in a clean (read: no spaghetti code) production environment this is a good practice. It would be better to add .Net variables to a javascript object like so:
// GA example
public static string GetAnalyticsSettingsScript()
{
var settings = new StringBuilder();
var logged = ProjectContext.CurrentUser != null ? "Logged" : "Not Logged";
var account = Configuration.Configuration.GoogleAnalyticsAccount;
// check the required objects since it might not yet exist
settings.AppendLine("Project = window.Project || {};");
settings.AppendLine("Project.analytics = Project.analytics || {};");
settings.AppendLine("Project.analytics.settings = Project.analytics.settings || {};");
settings.AppendFormat("Project.analytics.settings.account = '{0}';", account);
settings.AppendLine();
settings.AppendFormat("Project.analytics.settings.logged = '{0}';", logged);
settings.AppendLine();
return settings.ToString();
}
And then use the common Page.ClientScript.RegisterStartupScript to add it to the HTML.
private void RegisterAnalyticsSettingsScript()
{
string script = GoogleAnalyticsConfiguration.GetAnalyticsSettingsScript();
if (!string.IsNullOrEmpty(script))
{
Page.ClientScript.RegisterStartupScript(GetType(), "AnalyticsSettings", script, true);
}
}
On the JavaScript side it might look like this:
// IIFE
(function($){
// 1. CONFIGURATION
var cfg = {
trackingSetup: {
account: "UA-xxx-1",
allowLinker: true,
domainName: "auto",
siteSpeedSampleRate: 100,
pluginUrl: "//www.google-analytics.com/plugins/ga/inpage_linkid.js"
},
customVariablesSetup: {
usertype: {
slot: 1,
property: "User_type",
value: "Not Logged",
scope: 1
}
}
};
// 2. DOM PROJECT OBJECT
window.Project = window.Project || {};
window.Project.analytics = {
init: function(){
// loading ga.js here with ajax
},
activate: function(){
var proj = this,
account = proj.settings.account || cfg.trackingSetup.account,
logged = proj.settings.logged || cfg.customVariablesSetup.usertype.value;
// override the cfg with settings from .net
cfg.trackingSetup.account = account;
cfg.customVariablesSetup.usertype.value = logged;
// binding events, and more ...
}
};
// 3. INITIALIZE ON LOAD
Project.analytics.init();
// 4. ACTIVATE ONCE THE DOM IS READY
$(function () {
Project.analytics.activate();
});
}(jQuery));
The advantage with this setup is you can load an asynchronous object and override the settings of this object by .Net. Using a configuration object you directly inject javascript into the object and override it when found.
This approach allows me to easily get translation strings, settings, and so on ...
It requires a little bit knowledge of both.
Please note the real power of tis approach lies in the "direct initialization" and "delayed activation". This is necessary as you might not know when (during loading of the page) these object are live. The delay helps overriding the proper objects.
This might be a long shot, but sometimes I need a c# property/value from the server side displaying or manipulated on the client side.
c# code behind page
public string Name {get; set;}
JavaScript on Aspx page
var name = '<%=Name%>';
Populating to client side is generally easier, depending on your issue. Just a thought!
<%--Confirmation Box--%>
<script type="text/javascript" language="javascript">
function alertbox() {
if (confirm("Are you sure?") == true)
{
document.getElementById('<%= hdnYesNo.ClientID %>').value = "YES";
}
else
{
document.getElementById('<%= hdnYesNo.ClientID %>').value = "NO";
}
}
</script>
How to rewrite this code in C# as codebehind? I would like have a confirm box with yes or no buttons.
protected void Page_Load(object sender, System.EventArgs e)
{
string csName = "PopupScript";
Type csType = this.GetType();
ClientScriptManager csm = Page.ClientScript;
if (!csm.IsStartupScriptRegistered(csType, csName)) {
StringBuilder sb = new StringBuilder();
sb.Append("<script>");
sb.Append("function alertbox() {");
sb.Append("if (confirm('Are you sure?') == true) ");
sb.Append("{");
sb.Append("document.getElementById('" + hdnYesNo.ClientID + "').value = 'YES';");
sb.Append("}");
sb.Append("else");
sb.Append("{");
sb.Append("document.getElementById('" + hdnYesNo.ClientID + "').value = 'NO';");
sb.Append("}");
sb.Append("</script>");
csm.RegisterStartupScript(csType, csName, sb.ToString());
}
}
you can use like this way
Page.ClientScript.RegisterStartupScript(this.GetType(), "Confi", "if(confirm('Are you sure?') == true){ document.getElementById('txtValue').value ='YES';}else{document.getElementById('txtValue').value ='NO';}", true);
You can use ClientScriptManager class and its methods, for example RegisterClientScriptBlock. Depends on when you want the javascript to execute.
See details here:
http://msdn.microsoft.com/en-us/library/System.Web.UI.ClientScriptManager_methods.aspx
You need javascript for this, it's not possible in code behind. Code behind is run on the server before the page is sent to the user, javascript is run on the user's computer.
If you want to get access to their answer in code behind (possible and straightforward), you can use ajax or you can postback.
If you want to have this popup to come up when you press on a .Net asp:button control, then you can put a javascript function in the "OnClientClick" attribute of the control.
EDIT: If you need help with any of the above, let us know and help will be provided :).
EDIT2: Due to the discussion below, I guess I should clarify: You can (obviously) construct javascript on the server side before passing it to the client, but the example you gave is NOT a case where you should be doing that (an example of where this might be a good idea would be a script that has variables read from a database or something similar that doesn't need to be dynamic between page loads).
another option is to create the script in the /View folder and user razor for generating the script.
then you could point to the page in the tag like
<script src="~/ScriptGenerator/MyScript" />
for pointing the controller ScriptGeneratorController that expose the action MyScript
Any one can help me..I want to pass the C# value to javascript..I only get pass 2 values only to the javascript..I dont know how to pass a tbSTime,tbETime and tbIndo2..Please help me..Thank You
This is code behind:
{
// get the meeting info based on the id
int id = Convert.ToInt32(Request["id"]);
MeetingClass.MeetingInfo m = MeetingClass.MeetingInfo.GetInfo(id);
// fill data
tbtitle2.Value = m.Title;
tbdate2.Value = m.Date.ToShortDateString();
tbSTime.Value = m.StartTime.ToShortTimeString();
tbETime.Value = m.EndTime.ToShortTimeString();
tbIndo2.Value = m.Desc;
}
And this is javascript:
function getInfo() {
$('#<%=tbtitle.ClientID%>').val($('#<%=tbtitle2.ClientID%>').val());
$('#<%=tbdate.ClientID%>').val($('#<%=tbdate2.ClientID%>').val());
}
From what I can tell on your code, you are setting an asp:HiddenField (since you are using .Value) and then using that to populate your asp:TextBox w/ jQuery. If that is the case, then you need to do something like this.
$('#<%=aspTextBoxName1.ClientID%>').val($('#<%=tbSTime.ClientID%>').val());
$('#<%=aspTextBoxName2.ClientID%>').val($('#<%=tbETime.ClientID%>').val());
$('#<%=aspTextBoxName3.ClientID%>').val($('#<%=tbIndo2.ClientID%>').val());
Where aspTextBoxName1, aspTextBoxName2, aspTextBoxName3 are the names of your new textboxes.
I don't know if you really need those hidden form fields, there are easier ways to do this if you don't.
in controller:
ViewBag.tbSTime = tbSTime;
in view:
$('#<%=tbtitle.ClientID%>').val("<%= ViewBag.tbSTime %>");
Iam sorry but iam not sure what exactly you need, but from what i understood i can provide you with this:
If You want to send some value from Server side variables to Javascript function one way you can do this as follows,
function abc(x,y)
{
//Do you things here
}
and from server side call javascript code as follows
string a=textbox1.text;
string b=textbox2.text;
ScriptManager.RegisterStartupScript(this, GetType(), "displayalertmessage", "abc("+a+","+b+");", true);
This isn't working:
Response.Write(" DELETE ");
<script language="javascript" type="text/javascript">
function Delete(path) {
path1 = unescape(path);
var myObject = new ActiveXObject("Scripting.FileSystemObject");
var myFolder = myObject.GetFolder(path1);
myFolder.Delete();
alert("Welcome");
}
</script>
But this worked.
Response.Write(" DELETE ");
<script language="javascript" type="text/javascript">
function Delete() {
alert("Welcome");
}
</script>
I tried with onclick for Delete() to get just ALERT it worked well.
But it isn't working when add the parameters.Can you help me please.Trying for this from long time please.
First of all, \u is escpae code for a hex digit. So better re-format it.
Second, href=view.aspx?type=notes is not a valid html syntax too. Double quotes please.
Third, please put some code to check if your javascript variables (myObject,myFolder) are valid (not null) before invoke any method against them.