Stop IE users typing into the file upload input - asp.net

My testers have discovered that if you type free text into a file upload input then none of the buttons on the page work until that text is removed (so the page cannot be submitted).
I am able to replicate this with the following ASPX code (with no code behind):
<%# Page Language="C#" AutoEventWireup="true" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<form id="form1" runat="server">
<div>
<asp:FileUpload ID="fuTest" runat="server" />
<asp:Button ID="btnSubmit" runat="server" Text="Submit" />
</div>
</form>
</body>
</html>
(Note that I haven't bound any handlers to the page; despite this, the page is submitted when the submit button is clicked only if no text is entered into the upload text box)
Is there any way to prevent users from typing free text into a file upload control? It seems that this is only possible in IE - Firefox and Chrome natively prevent text from being entered into upload input fields.
I've seen solutions elsewhere which suggest hiding input and replacing it with a label / button combo, but this seems like it might cause more problems and work inconsistently across browsers.
Any thoughts?

As per #Jer's suggestion, I was able to prevent input into the file upload without breaking any of the other functionality by handling keypress events on the upload. Using jQuery:
$(document).ready() {
$('input:file').keypress(function() {
return false;
});
}

I'm not sure if this would work as expected, but have you tried: <input readonly="readonly">

The accepted answer is perfectly fine for all the existing file controls.
But in most of the practical situations, we provide functionality to add more file controls on the fly so that users can select more than one file.
Key for the solution in this case was the .live function.
The solution will be as follows:
$('input:file').live('keypress', function() { return false; });

Related

SItecore Field renderer not working in page editor

Field renderer was working fine on mvc but now we moved to web pages, and i am converting my layouts & renderings to webpages but field renderer are not working in page editor mode but in published mode looking fine. page editor screen shot is attached.
Field rendered as
<sc:Text ID="Title" Item="<%# ((Sitecore.Data.Items.Item)Container.DataItem) %>" Field="Navigation Title" runat="server" />
and
<%# FieldRenderer.Render(Container.DataItem as Sitecore.Data.Items.Item, "Navigation Title") %>
tryied both but same result :) any help would be appreciated.
I have av vague memory of seeing this error before. If I remember right, the problem was that Sitecore couldn't do all its Page Editor magic properly by inserting scripts etc into the html header and body. It's worth I try to just verify that your layout forms a proper html document and having the head and a form accessible from the server, such as this:
<!DOCTYPE html>
<html>
<head runat="server">
</head>
<body>
<form runat="server">
</form>
</body>
</html>
I was a long time ago I used webforms with Sitecore, so I don't remember exactly what components Sitecore hooks into in order to make the editor works, but having a page structure as above should be good to go.
Hope it helps
// Mikael

fileupload not working on window.showModalDialog

I am looking to open a aspx page to act an an image uploader.. this is the code I use to open the page:
$("#btnUpload").on("click", function (s) {
s.preventDefault();
var id = $('#hdnId').val();
var response = window.showModalDialog("/imageUpload.aspx/", id);
alert(response);
});
the page opens fine and looks like this:
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<label>Choose New Image:</label>
<br/>
<asp:FileUpload ID="imageUploader" runat="server"></asp:FileUpload>
<asp:Button id="UploadButton" OnClick="UploadButton_Click" Text="Upload file" runat="server"></asp:Button>
</div>
</form>
</body>
</html>
The fileupload renders ok on the page - but the choose file button doesn't work at all! ive watched in chrome & there are no jquery errors on page load or on click of the choose file button.
I've done a bit of googling and found that ajax and update panels are dodge with the fileuploader - But i'm not using either :-/
anyone know whats occurring here?? many thanks
I was having the same exact issue with the Chrome modal dialog. This is a Chrome v26 issue. You can take a look at following url for chrome bug tracker details.
https://code.google.com/p/chromium/issues/detail?id=225365
However they’ve fixed the defect but according to them it'll take up to 6 weeks to include fix into release. You can get the Chrome canary version to verify.
https://www.google.com/intl/en/chrome/browser/canary.html

Juice UI - Height, MaxHeight properties not having affect

Educating myself about Juice UI and have an issue with some of the properties of juice:Dialog control, hopefully it is a noob thing.
Iam Using VS 2010, .net 4.0 as required, created new ASP.net empty web application to keep it simple.
I have installed Juice UI using NuGet, no issues with install.
My aspx page is below, nothing added to code behind.
I can successfully open the dialog using the button, so next step was to have a play with the different dialog properties.
In the Juice:Dialog control I have added the property Height="300px". As I understand it this should open the dialog with a height of 300px. The dialog actually opens 'collapsed' ie I can't see the text at all and the dialog is sized as if you had resized it using the resizing handle to it's minimum height.
What am I missing here?
Edit : Ok if I put
$("#dialog").dialog({ height: 500 });
in the click event I can set the size when my button clicked. So this must mean the properties of the dialog control are only relevant if AutoOpen=True ie the dialog opens on the initial page load. Am I close?
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Employees.aspx.cs" Inherits="JuiceSkeleton.Employees" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div>
<button id="accept" runat="server" class="open-dialog" type="button">
Accept</button>
<juice:Button ID="acceptButton" runat="server" TargetControlID="accept" />
</div>
<div id="dialog" class="basic-dialog" runat="server">
<p>
Default Dialog says No!
</p>
</div>
<juice:Dialog Draggable="True" ID="dialogButton" Height="300px" runat="server" TargetControlID="dialog"
AutoOpen="False" />
</form>
</body>
<script type="text/javascript">
// Respond to the click
$(".open-dialog").click(function (e) {
e.preventDefault();
// Open the dialog
$(".basic-dialog").dialog("open");
});
</script>
The problem is that the property only takes a numeric value. However, because jQuery UI Dialog accepts "auto" as a value, we had to make the property type dynamic to accept numbers and "auto". Dropping the "px" unit decl. from your value will give you the correct output.
However, due to a problem with internal code, this will throw an exception in the current version.
The issue has been tracked here, https://github.com/appendto/juiceui/issues/23, and a fix has already been committed. The next maintenance release will contain this fix. At the moment, your workaround using javascript will work just fine. When the next release is out, you'll be able to use that property as per usual.

Asp.Net Add UserControl to a Page

I have an ASP.Net web site and on one of the pages I'm using a repeater to render several iterations of a UserControl, that UserControl contains a second UserContol that has two text boxes that my User must enter information into. I want to be able to have my user push a button and add another instance of the second UserControl (with the two textboxes) to my original UserControl, so that the user has 4 textboxes displayed on the screen for the first UserControl. The problem I am seeing if I try to add the second UserControl to a given iteration of the first, is that the page postback causes any other of these second user controls to be deleted from the page.
Does anyone know of a way to do this using JQuery? I've had three posts that describe how to solve this problem using server side dynamic controls, and/or AJAX, but we've decided to focus on a JQuery solution because this server side mechanism is too costly in terms of resources for us.
I've been working on the suggestion by Zincorp below, and now have the JQuery working to clone a textbox, but having trouble using the server side Request.Form collection to iterate over the controls. Can anyone give adivce on how to iterate over the Request.Form collection?
OK, I think the problem with iterating over the controls using the Request.Form.AllKeys collection turned out to be that I was using an HTML Textbox, rather than an ASP TextBox Control. Apparently the Request.Forms.AllKeys collection only contains ASP controls, not HTML controls.
The problem I am seeing now is that when I clone the control in JQuery, and then submit my page with the submit button, the 2 controls have the same ID, and so are combined (I think) by http into one ASP TextBox Controls containing both values, with a comma delimiter (e.g.- 40,20). Anyone know how to get a new ID assigned to the cloned ASP TextBox?
Here is the updated markup in a sample ASP.Net web appliction:
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label runat="server" ID="ProjectDisplay" Text="Project" />
<asp:TextBox ID="ProjectValue" runat="server" ></asp:TextBox>
<div id="mydiv" ></div>
<br />
<br />
<br />
<input id="AddProject" type="button" value="Add Project" />
<br />
<br />
<asp:Button ID="Submit" runat="server" Text="Submit" onclick="Submit_Click" />
</div>
</form>
</body>
</html>
<script language="jquery" src="js/jquery-1.3.2.js" type="text/javascript"></script>
<script type="text/javascript" >
$(document).ready(function() {
$("#AddProject").click(function() {
var x = $("#ProjectValue").clone();
x.appendTo("#mydiv");
});
});
</script>
And here is the updated server side code where I'm trying to iterated over items in the Request.Form collection to get information from it:
public partial class _Default : System.Web.UI.Page
{
protected void Submit_Click(object sender, EventArgs e)
{
foreach (string s in Request.Form.Keys)
{
object x = Request.Form[s];
}
}
}
Before choosing a solution for the problem, consider the problem first:
You effectively need to:
1) Duplicate controls/markup on the client-side
2) Obtain these values on the server-side on a postback
3) For each of the added "user controls" on the client-side, add them as children of the first user control on the server side.
I'm not going to give the code, but here are some ideas:
1) Use jQuery's .clone() method (http://api.jquery.com/clone/) to duplicate the markup being rendered by the usercontrol containing the textboxes. Perhaps wrap them in a div without runat="server" to so that you can easily obtain it by ID. You'll probably need to then recursively iterate through the children in the cloned element and append a # to them to avoid any conflicting identifiers. (eg. nameTextBox_1, nameTextBox_2, etc.)
2) On a postback, use the Request.Form collection on the server side to obtain the textbox values. Iterate through it and snag all of the items whose keys start with "nameTextBox_".
3) For each added "user control" on the client side, create the actual user control on the server side, assign to it the values entered in the textboxes, and then add it to the child controls of the first one. This way the state is maintained upon returning to the user.
The short answer is that you would have to add the controls before the ViewState is initialized.
The video on this site has a nice guide on adding dynamic controls. http://www.asp.net/%28S%28wnmvzu45umnszm455c1qs522%29%29/learn/ajax-videos/video-286.aspx
This is probably not a ViewState issue. That may be the first place to look, but after that you need to make sure that your dynamic controls are actually being CREATED on each load.
Generally speaking, the ViewState is only responsible for restoring STATE to existing controls (hence the name). It is not responsible for recreating controls.
I believe you are experiencing a viewstate problem. Your dynamic controls are not being persisted. If you haven't already, read Dave Reed's excellent article Truly Understanding Viewstate. Pay particular attention to the section "5. Initializing dynamically created controls programmatically" which applies to the trouble you are experiencing.

Does Javascript in the html body execute when encountered?

I have inherited an ASP.net codebase and I have very limited ASP.net skills. I am struggling to understand why something works and also why it only works in IE.
The following code appears in a page :-
<%# Page Language="C#" AutoEventWireup="true" CodeFile="map.aspx.cs" Inherits="Romtrac.auth_map" Culture="auto" UICulture="auto" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>
<% = Resources.Resource.map %>
</title>
</head>
<body>
<form id="adminlw_map_form" action="<%=geturl()%>" method="post" >
<% = Resources.Resource.loading %>...
<textarea name="xml" id="xml" runat="server" style="display:none" cols="1" rows="1"></textarea>
</form>
<script language="javascript" type="text/javascript" >
//submit main form immediately
document.getElementById('adminlw_map_form').submit();
</script>
</body>
</html>
This code runs fine in ASP.net. The form is automatically submitted and the page returned is rendered correctly within an Iframe. My question is;
1) Does the javascript within the body just get executed when it is encountered? Is this good practice or should it be executed in response to an event?
2) Why does this not work in other browsers?
Yes
The javascript is being executed before the browser has fully rendered the page. In this case, the form has not been rendered and is not accessible via the DOM.
The execution needs to happen after the DOM is fully loaded by the browser and can be implemented by encapsulating the call within a function and calling that function via the onload event of the body or by using a javascript library like jquery to hook into the load event of the page.
1) Yes, No. jQuery does it best with it's $(document).ready() function, but you should wait for the page to finish loading before running Javascript.
2) Do #1 and you won't need to worry about this. However I'll leave the floor open to someone with a better answer.
Some browsers prevent the submission of a form without user interaction in the page's load 9it's a security risk). I've had this issue a number of times in the past. I would combine the page's load, with a window.setTimeout of say 100ms.
<body onload="window.setTimeout( document.getElementById('adminlw_map_form').submit, 100)">
....
Remember when using JavaScript to keep it unobtrusive. There are still people out there who have JS switched off and your page should not really on it. It should serve as an enhancement.
Same as Mike Robinson's answer but surely you can just use <body onload="myfunction();">?

Resources