Variable scope in aspx page - scope

Why is that the scriptPath variable is out of scope in the bottom of the code?
Shouldn't it be in scope throughout this page? In MVC, if I mark this on top of the page like
#{
string scriptPath = "assets/scripts/",
gkoConfig = "GkoConfig.js";
}
it is available throughout the current View. What am I missing now that I'm back to WebForms for a while?
If I change the code position, It get's weirder as inside the <head> I no longer have access to teh variable, but I do have, inside the <body> now... :-/

When you declare a variable in a Web Forms .aspx file, you’re actually declaring a local variable inside an auto-generated rendering method. ASP.NET generates separate rendering methods for all tags marked runat="server", so you actually get a separate method for your head element. Now, the variable you declare can only exist in one of these methods - hence the 'weird' behavior.
You can see how this works if you pre-compile your application using aspnet_compiler.exe. You will get compiled DLL files for each of your web forms pages; just open one of those up in Reflector to see the generated code. I wrote a minimal equivalent of your code with the variable declared outside the head tag, and here’s the top-level render method that I got:
private void __Render__control1(HtmlTextWriter __w, Control parameterContainer)
{
string str = "scripts/";
__w.Write("\r\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n\r\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\r\n");
parameterContainer.Controls[0].RenderControl(__w);
__w.Write("\r\n<body>\r\n ");
parameterContainer.Controls[1].RenderControl(__w);
__w.Write("\r\n <script type=\"text/javascript\" src=\"");
__w.Write(str);
__w.Write("jquery-1.4.1.min.js\"></script>\r\n</body>\r\n</html>\r\n");
}
You see that the variable that I declared (here named str) is scoped to this method, and it's calling other methods to render the head (and a form element marked runat="server".)
A quick and dirty solution might be to simply remove the runat="server" from your head tag; however, I’d recommend that you declare a protected variable in your code-behind class for this. Adding a line like this to your code-behind file would work:
protected string scriptPath, gkoConfig;
You can then use these variables anywhere in your Web Forms code.

You could also declare your constants like this:
<script runat="server">
private const string scriptPath = "assets/scripts/";
private const string gkoConfig = "GkoConfig.js";
</script>

I suspect the head of the ASPX page gets processed separately from the body.
This problem is easily solved - all you need to do is use a class field in the code-behind with the access level set to protected.

Related

I want to create an angular app to show live code preview like Jsbin

I'm creating the Angular app which lets user save his html code (maybe it has style and script tag to control the view) and there is a live preview next to it. User can save the code and other users can come to see the code and the preview. I also worry about the security because of script tag and I want the script to work only with the code that user provides (Not allow to control or get the data in the parent frame). So I need some suggesting of how to do it.
I have tried the preview with iFrame by giving the value through the 'srcdoc' property, but it looks like the security is bad.
You would not need to use an iframe in that situation, you can just render an HTML string inside of a div element using the innerHtml input like so:
<div [innerHTML]="htmlString"></div>
Where htmlString is a string containing the HTML code. You will have to sanitize the content of that variable with the DomSanitizer.
constructor(private domSanitizer: DomSanitizer){}
...
ngOnInit() {
this.htmlString = this.domSanitizer.bypassSecurityTrustHtml(yourHTMLString);
}

Compiling Jade partial with different data

I am using gulp to compile Jade for a static website. There is a single gulp task that compiles all the jade files into HTML files.
I am creating a 10 step process, each a single page of HTML with "previous" and "next" buttons
I want to create a partial like below
a(href="#{prev}") Back
a(href="#{next}") Continue
For each page, the prev and next values change. Is there a way to call the partial from within each page's jade with custom prev and next values?
I am assuming, like how you bind data in handlebars template and compile, I can have a different locals object for each page and render the same partial with different data.
Am I approaching this wrong or is this something possible with jade? All answers I can see are related to using express with Jade. I'm only creating a static website, just the HTML alone infact.
If you're including the partial within larger Jade templates via include then it's simply a matter of changing the locals for the larger template you're rendering.
gulp.src('./templates/template-that-includes-a-partial.jade')
.pipe(gulpJade({
locals: {
prev: 'some value',
next: 'some other value'
}
})
.dest('./build/templates/');
Something like that should work. The partial view should have access to the same locals as the parent view that includes it.
I found out that you can define Jade variables using - in the parent template and call the partial with this data
- var prev = "a.html"
- var next = "b.html"
include partials/_var
And then use interpolation in the partial to use corresponding values
a(href="#{prev}") Prev
a(href="#{next}") Next
This way, I can call the same partial in different parent templates but pass in varying values for each page.

Add target property for dropdownnode in Widget Container

I would like to add a target (e.g. _blank) property for a basicLeafNode on the Widget Container from the extension library.
I do not see the property for this.
Instead I could use the onClick property and return an URL. But then I still would have no target defined.
I could add a postScript method
var target = url;
view.postScript("window.open('"+target+"','_blank')")
but this fires when the container is loaded.
Can I add a target property without using the onClick Property?
In case I use the onClick property what method should I use or how I prevent the postscript is executed when the container is loaded?
The basicLeafNode doesn't currently provide a target property. You have 2 courses of action:
implement your own custom node as Michael suggested (hard)
use a class on the link e.g. "newpageopen" and add an onPageReady script that selects all a elements with the calss newpageopen and add the target property to the resulted HTML.
Something like this:
require(["dojo/ready","dojo/query"], function(ready){
ready(function(){
dojo.query("a.newpageopen").attr("target", "_blank");
});
});
Hope that helps;
To make this list of solutions a bit longer here another on wich does not require dojo or jquery:
Instead of using your code as SSJS like:
var target = url;
view.postScript("window.open('"+target+"','_blank')")
You can use the Client Side Code and add SSJS code in #{javascript:}' wich i think is the shortest solution on this Problem. Here a hardcoded example:
<xe:basicLeafNode>
<xe:this.onClick><![CDATA[window.open('#{javascript: return "http://www.google.com";}','_blank');]]></xe:this.onClick>
</xe:basicLeafNode>
the above example will also work with viewScope variables or SSJS funktions:
<xe:basicLeafNode>
<xe:this.onClick><![CDATA[window.open('#{javascript: return viewScope.url;}','_blank');]]></xe:this.onClick>
</xe:basicLeafNode>
You can add the target attribute using JavaScript. It's kind of inconvenient way but would work.
You can use dojo.query to query the HTML output generated by basicLeafNode on the Widget Container. Once you get the node of <a> then you can add attribute using dojo.attr.
One problem you might face is that the ID generated by XPages contains the character :, which will not work so you would have to escape it.
function escapeColon(controlID) {
return controlID.replace(/:/g, "\\3A");
}
So your code would be something like:
dojo.addOnLoad(function() {
dojo.attr(dojo.query(escapeColon("#{id:ID_of_basicLeafNode}") + " > a")[0], "target", "_blank");
});
The code escapeColon("#{id:ID_of_basicLeafNode}") + " > a" would generate a CSS selector. Here I am assuming that basicLeafNode on the Widget Container would generate something like this <div id="_id1:basicLeafNode"><a href=".... So the CSS selector would search for a tag with that ID and inside it the <a> tag. You would have to modify this based on the output that is generated.
As I said its a bit inconvenient. Also I haven't tested this code.

How can you add in Javascript resources at the very bottom of an xpage?

I need to include a javascript file right at the end of the xpage so it gets loaded after the XSP.addOnLoad event code which is generated automatically e.g.
XSP.addOnLoad(function() {
XSP.attachEvent....
}
<script src="my.js">
Ideally I want to include it as part of a theme but if I do that it goes into the HEAD section
So can I either..
-Specify in a theme to insert the link to a client side js resource at the bottom of the page rather than the head
-Include a resource on an xpage directly so it goes after the auto-generated code
NB: This it needed in order to get an xpages app working with Foundations
http://foundation.zurb.com/docs/
I need to include the foundations js file after the events have been bound to the fields
Thanks!
Try adding a script block in the end with this code:
XSP.addOnLoad(function() {
document.write('<script src="my.js">');
}
However this may execute before the generated XSP.addOnLoad. You could then try a small hack like this:
XSP.addOnLoad(function() {
setTimeout(document.write('<script src="my.js">'), 200);
}

asp.net webpages content block and helper differences

In asp.net webpages framework what is the difference between using a content block versus a helper?
They both seem to be used to output HTML to multiple pages. They both can contain code and both can pass parameters.
Are there other differences? When should you use a helper versus a content block?
More info:
With Content Blocks we create a .cshtml (for example _MakeNote.cshtml) file to hold the content we want to insert into a page. Then we use:
#RenderPage("/Shared/_MakeNote.cshtml")
to insert the content into a page. We can pass parameters to the content block like this:
#RenderPage("/Shared/_MakeNote.cshtml", new { content = "hello from content block" })
It's somewhat like an include file, but I think does not share scope with the parent page.
With Helpers we create a .cshtml page in the App_Code folder (for example MyHelpers.cshtml) and place methods in that page which we want to call. The method looks something like this:
#helper MakeNote(string content) {
<div>#content</div>
}
The helper is called by using:
#MyHelpers.MakeNote("Hello from helper")
There isn't a lot of difference functionally. Helpers need to go into an App_Code folder - unless you download VWD or Visual C# Express and compile a binary - and the App_Code folder doesn't translate well to the MVC framework. Of course, that's only relevant if you want to upgrade to MVC at some point.
I would use a helper for generic functional snippets like your MakeNote. I would use a "content-block" (partial, really) for repeated site-specific sections of a page.

Resources