This is my first question. I am in stack overflow almost every day, but this is the first time I can't find the answer by myself and have to post it here.
I am creating pages with Ext.Net dynamically (in VB.net if it matters), based on a XML configuration, with all kind of controls and any number of them. So, for each field in the XML, I create the control and assign an ID to it (the ID is from the XML). I have a "submit" button that, when clicked, parse the XML again, get the ID of each field, and gets the control for this ID with Ext.Net.X.GetCmp. Then, once I have the control, I get the value and do some stuff with it. Everything works like a charm except for the control type FileUploadField. According to this, for some reason, GetCmp doesn't work with FileUploadField.
So, my question is: Is there some way to get a FileUploadField control based on it's ID? And, just to know, why GetCmp doesn't work with this kind of control?
Thank you very much in advance, and sorry for my bad english.
EDIT:
Ok, I have updated my Ext.Net to the latest version (2.2). Everything now looks strange, but it doesn't matter, if it works. Besides the appearance, I don't see any change in the behavior. GetCmp is still giving me the same. By the way, X.GetCmp(Of Ext.Net.FileUploadField)(ControlID) gives me a FileUploadField, not null, even if I don't create the control. The only thing, is that hasFile=false always, and the filebytes are empty.
EDIT 2:
I have run your example code and it works like a charm. I start thinking that the "isUpload" is the key. I Have been googling all the day trying to see where and why do I have to write this {isUpload=true}, but I didn't see anything useful. Can you explain it to me a little bit? Is only for DirectMethods? Is mandatory? Thanks a lot!
EDIT 3:
I feel sooooo stupid now. It works. Just added a simple isUpload:true in the DirectMethod call in a javascript. So many days to solve this stupid thing. For the next guy: check your isUpload ;).
So, my question is: Is there some way to get a FileUploadField control based on it's ID?
Only recreating that control. You render a control during one AJAX request (DirectEvent/DirectMethod) and it doesn't persist during another AJAX request unless you recreate it manually. It behaves the same as standard ASP.NET controls.
Controls can be recreated in Page_Init and must be recreated with the same IDs. In this case, a control's LoadPostData should extract a correct value from a POST collection. Here is a related discussion.
And, just to know, why GetCmp doesn't work with this kind of control?
It doesn't work in Ext.NET v1, but works in Ext.NET v2. Here is a sample below.
Though, it just extracts a file from the POST. X.GetCmp<>() returns a proxy control, it is not a real control. It is just a convenient way to extract POST values of dynamically rendered controls and, also, updates those controls on client (changing its properties and calling its methods).
<%# Page Language="C#" %>
<%# Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
<script runat="server">
protected void RenderFileUploadField(object sender, DirectEventArgs e)
{
FileUploadField fileUploadField = new FileUploadField()
{
ID = "FileUploadField1",
Width = 300,
Listeners =
{
Change =
{
Handler = #"App.direct.GetFileName(this.id, {
isUpload : true
});"
}
}
};
this.Form.Controls.Add(fileUploadField);
fileUploadField.Render();
}
[DirectMethod]
public void GetFileName(string id)
{
X.Msg.Alert("FileName", X.GetCmp<FileUploadField>("FileUploadField1").PostedFile.FileName).Show();
}
</script>
<!DOCTYPE html>
<html>
<head runat="server">
<title>Ext.NET v2 Example</title>
</head>
<body>
<form runat="server">
<ext:ResourceManager runat="server" />
<ext:Button
runat="server"
Text="Create a FileUploadField"
OnDirectClick="RenderFileUploadField" />
</form>
</body>
</html>
you could use simple javascript:
var fileinput = document.getElementById("fileinput");
as javascript does only search the DOM you need to be careful. each Ext.Net component will get a bunch of wrappers and sub-components and "unnecessary" siblings/parents/children (for header, label, bottom- and topbar and so on..)
if you have given an ID to the control you should be able to fetch it via:
App.{control-id}
this will return the constructor. you should be able to fetch FileBytes from ExtJS anytime using the App namespace (see BREAKING CHANGES)
the finished get for the FileBytes would look like this:
App.{control-id}.FileBytes
Related
I'm looking for a way to inject a custom script into the _Layout.cshtml purely from code. _Layout.cshtml cannot know anything about it. Just like Browser Link does it.
You simple write this:
app.UseBrowserLink();
And this gets injected into the body at runtime.
<!-- Visual Studio Browser Link -->
<script type="application/json" id="__browserLink_initializationData">
{"requestId":"a717d5a07c1741949a7cefd6fa2bad08","requestMappingFromServer":false}
</script>
<script type="text/javascript" src="http://localhost:54139/b6e36e429d034f578ebccd6a79bf19bf/browserLink" async="async"></script>
<!-- End Browser Link -->
</body>
There is no sign of it in _Layout.cshtml.
Unfortunately Browser Link isn't open source so I can't see how they have implemented it. Browser Link source now available
So I was wondering how it was done?
It's not open source, but you can easily decompile it to see how it works.
From a comment in the source code:
This stream implementation is a passthrough filter. It's job is to add links to the Browser Link connection scripts at the end of HTML content. It does this using a connection to the host, where the actual filtering work is done. If anything goes wrong with the host connection, or if the content being written is not actually HTML, then the filter goes into passthrough mode and returns all content to the output stream unchanged.
The entire thing seems pretty involved, but doesn't seem to use anything not available out of the box, so I guess it can be possible to code a similar thing.
Razor allows you to do this quite easily - you can even use a flag.
Example:
In your controller:
ViewData["RegisterCustomCode"] = "true";
In your View (.cshtml):
#if (ViewData["RegisterCustomCode"] == "true")
{
<text>
<script src="..."></script>
</text>
}
Episerver always wrap shared block in a tag. I would like to get rid of this. So if in my LinkBlock has a Template with only
link
I would not get a
<div>link</div>
in the view for a user.
If this is not possible how can I change <div> to any other tag, or put a CssClass on it. Like it is possible in not shared blocks:
<EPiServer:Property runat="server" PropertyName="RightContentArea" CustomTagName="aside" CssClass="column-2 sidebar"></EPiServer:Property>
I believe it is the rendering of the ContentArea property which adds the div tags around the blocks it contains.
EPiServer suggests that in order to preserve the editing functionality of the block elements themselves they need to have the div around them.
A possible solution might be for you to do your own custom rendering of content areas, but depending on the kind of block templates you're using it can be tricky to get editing to work. The example in the link is for rendering multiple blocks of the same type.
You can use the CustomTagName and CssClass properties of the Property control to format the container element.
You may also use RenderSettings to modify container elements of child elements (where applicable).
I use this trick in cshtml:
#RenderBlocks(Model.CurrentPage.Content1)
#* ---------------------------------------------------------------------------------- *#
#* Render ContentArea without addition DIVs that EpiServer embed. That breaks layout a lot. *#
#helper RenderBlocks(EPiServer.Core.ContentArea content) {
if(null != content){
var blocks = content.FilteredContents.ToArray();
foreach(var block in blocks){
#Html.PropertyFor(x => block)
}
}
}
You can choose the tag using the CustomTagName attribute on the Property Control
Alternatively, if you wanted to remove the tag, you could use a control adapter. A good example is found here
You can also create a custom content area that doesn't render the divs when edited in live mode and only renders them in edit mode.
If you only need to do this once or twice I would still recommend going with the ChildrenCustomTagName route as it's a bit mroe flexible. If you need to do this a lot and you can't change your CSS easily then I would go custom content area. If you are interested in how to remove the div's I wrote a blog post and a sample site on github here Extra divs in content area how to remove them ?
Since i wasn't able to remove the <div>'s i didn't want, i put my own CSS class on them. This did the trick for me in Webforms. (If anyone still uses it)
Use <RenderSettings ChildrenCssClass="yourCssClass" />
<EPiServer:Property runat="server" PropertyName="RightContentArea"CustomTagName="aside" CssClass="column-2 sidebar"><RenderSettings ChildrenCssClass="yourCssClass"></RenderSettings></EPiServer:Property>
I need to create a code to change an example text to a user-defined value when the user types in an input field (Similar to the preview field when writing a question on Stack Overflow).
This needs to be achieved without the use of HTML5 or Flash as the users will be running IE8, not all will have Flash plug-ins installed.
As such I have started by looking at DHTML to achieve the desired effect. Currently I can change the example text when a user types in the input field but only to a pre-defined value ("Example" in the code below), how should I edit this code to display the user-defined value?
JS
function changetext(id)
{
id.innerHTML="Example";
}
HTML
<form>
Content:<input type="text" id="input" onkeyup="changetext(preview)" />
</form>
<p id="preview">No content found</p>
You need to have something like this in the function:
function changetext(id){
var info = document.getElementById('input').value();
id.innerHTML = info;
}
This js is not fully correct. I would highly recommend you start using a javascript library like jQuery. It makes this a menial task.
Edited:
jQuery will work in IE8 just fine. in jQuery you will not need to attach js to your input. The code would look like this.
$('#input').click(function(){
$('#preview).html(this.val());
});
It is a lot cleaner and doesnt have js in the html.
The situation is that I have a page that uses some AJAX calls to retrieve content from the server, then puts those results into a chunk of html generated by another script. The problem is, I can't select with watin any of the elements of this new piece of html. It can be viewed in the browser, and comes up when I hit F12 and scan through the code, but still WatiN can't see it.
Is this because WatiN only scans through the html source of the page, and not the current version of the HTML? I think a similar situation would be:
html -
<script type="text/javascript">
$('#foo').html("gak");
</script>
...
<div id="foo">bar</div>
then when I try and assert -
Assert.IsTrue(browser.Div("foo")).ContainsText("gak"));
it will return false.
Any ideas on this? or is my best option to just write a bunch of jQuery, and browser.Eval() it?
I test AJAX pages quite a bit. The key is to wait until the asnyc postback has completed. If you have
Assert.IsFalse(browser.Div("foo")).ContainsText("gak");
browser_action_that_changes_bar_to_gak
>> Here you need to wait <<
Assert.IsTrue(browser.Div("foo")).ContainsText("gak");
In the "wait" section you can do a System.Threading.Thread.Sleep(numberOfMilliseconds) <- this is not the best way, but it is really simple. Once you determine that waiting is what you need to do, a better way to wait is to poll the status rather than way numberOfMilliseconds each time. I believe different AJAX libraries do things differently, but what works for me is really similar to this: http://pushpontech.blogspot.com/2008/04/ajax-issues-with-watin.html
I put the JavaScript into an Eval() in a helper function in the my base Page class rather than having to inject it into every page like the article did.
.
my Base Page class contains:
public bool IsInAsyncPostBack()
{
const string isAsyncPostBackScript = "Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()";
return bool.Parse(this.Document.Eval(isAsyncPostBackScript));
}
And then my WaitForAsyncPostback is basically the same as in the linked post, but I added a max wait time. Before going to Page classes (awesome; do it!) I made these static functions somewhere else and it worked too.
This is almost surely a timing issue. The jQuery has not updated when you test. Rather than introducing any artificial pause or wait it's best to wait for something to show that your AJAX has worked as expected.
In this case a WaitUntil should do the job nicely:
Assert.IsTrue(browser.Div("foo")).WaitUntil(c => c.Text.Contains("gak")));
This works for most updates and the like. Another common waiting pattern is on data loading say, where you'd have a spinning wheel displayed. Then you could wait until this wheel is gone with a something like:
WaitUntil(c => c.Style.Display == "none");
I am using an .aspx page as cluetip bound to an anchor tag. I need to pass a parameter from anchor to this page and then call a WCF service to populate my template with returned JSON. I tried putting body onload function but that doesnt seems to work.
Thanks
Koby.
response to comment
You want to use the .mouseenter() event. This new event in 1.4 is better than .blur() which is what you will see in most examples (and probably why you can find it, a search of blur jquery popup should give you lots of examples). But mouseenter is better in the lastest jQuery
Docs: (very nice example code at the bottom of the page.)
http://api.jquery.com/mouseenter/
old version
just add the function to the onclick handler. You can do this in jquery with something like this
$(selector).click(function () {
code to do stuff (call wcf and populate)
you can use $(this) to see what was clicked on. ("passed" as you put it)
});
see fab new jQuery docs http://api.jquery.com/click/