Editable Dropdown in C# - c#

I need to create a dropdownlist where in the user can select a value from the dropdownlist or type the value in.
Exactly like the "Where do you come from ? " dropdown in the below link :
http://www.dhtmlgoodies.com/scripts/form_widget_editable_select/form_widget_editable_select.html
I know it is a common question and there are similar queries on stack overflow as well but I couldn't find a simple working solution.
I have referred the following links :
http://www.codeproject.com/Articles/8578/Editable-Dropdown-DHTML-Behavior
http://www.codeproject.com/Articles/290218/Custom-ASP-NET-Editable-DropDownList
http://codeverge.com/asp.net.web-forms/editable-dropdown-list-c/392261
Has anyone worked on this before and give me an idea as to how I can proceed ?

Another solution is as follows
You could use the Ajax Control Toolkit Nuget
Step 1:
Add the Ajax Control Toolkit from the Nuget Packages in your references
Step 2:
If you do not get the Ajax Control Toolkit controls into your Toolbox, you need to create a separate Tab and name it Ajax Toolkit Controls.
Then right click on it and select choose items.
Browse to location where the Ajax Control Toolkit's dll is located, select it.
You will see set of controls getting populated into the window.
Select Ok, this will result into populating the tab with the Ajax Control Toolkit Controls.
Step 3:
Since Ajax Toolkit Controls are an extra add-on package, you need to register them as a part of the page using them.If installed as a nuget, this step can be neglected.
<%# Register assembly="AjaxControlToolkit" namespace="AjaxControlToolkit" tagprefix="ajaxToolkit" %>
Note: The tagprefix should match the tagprefix used by you in your program for the AjaxControlToolkit Controls.
Step 4:
Add the ScriptManager Control, It is required for providing support for client-side AJAX features. As a result it loads and registers the Microsoft AJAX library to enable the features.
<asp:ScriptManager ID="ScriptManager1" runat="server" />
Step 5:
Proceed by adding the ComboBox from the toolbox and configure it by linking it to your database using the SQLDataSource
The complete source code is as follows
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="AjaxComboboxSample.aspx.cs" Inherits="StacksEmptied.AjaxComboboxSample" %>
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<style type="text/css">
#ComboBox1_ComboBox1_OptionList {
width: 10% !important;
}
</style>
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<ajaxToolkit:ComboBox ID="ComboBox1" AppendDataBoundItems="True" runat="server" AutoCompleteMode="Suggest" DataSourceID="SqlDataSource1" DataTextField="Fruits" DataValueField="Fruits" MaxLength="0" Style="display: inline;">
</ajaxToolkit:ComboBox>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:FruitsConnectionString %>" SelectCommand="SELECT * FROM [Fruits]"></asp:SqlDataSource>
</div>
</form>
</body>
</html>
I have tested this code on all the below settings Testing Environment:
Chrome Browser Version 43.0.2334.0 dev-m (64-bit)
Internet Explorer 11
Firefox 36.0.1
Visual Studio 2013 edition

You can try using JqueryUI Autocomplete Combobox.
It will let you type in text as well as select the item of your choice from a dropdown.
As an extra feature it lets you use the autocomplete feature to get a enhance UI experience.
I am attaching a demo which is coupled with bootstrap 3.3.4
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<link href="https://jqueryui.com/resources/demos/style.css" rel="stylesheet" />
<style>
.custom-combobox {
position: relative;
display: inline-block;
}
.custom-combobox-toggle {
position: absolute;
top: 0;
bottom: 0;
margin-left: -1px;
padding: 0;
}
.custom-combobox-input {
margin: 0;
padding: 5px 10px;
}
.ui-state-default,
.ui-widget-content .ui-state-default,
.ui-widget-header .ui-state-default {
border: 1px solid #421D1D;
background: #ffffff url("images/ui-bg_glass_75_e6e6e6_1x400.png") 50% 50% repeat-x !important;
font-weight: normal;
color: #555555;
}
/* Corner radius */
.ui-corner-all,
.ui-corner-top,
.ui-corner-left,
.ui-corner-tl {
border-top-left-radius: 0px !important;
}
.ui-corner-all,
.ui-corner-top,
.ui-corner-right,
.ui-corner-tr {
border-top-right-radius: 0px !important;
}
.ui-corner-all,
.ui-corner-bottom,
.ui-corner-left,
.ui-corner-bl {
border-bottom-left-radius: 0px !important;
}
.ui-corner-all,
.ui-corner-bottom,
.ui-corner-right,
.ui-corner-br {
border-bottom-right-radius: 0px !important;
}
</style>
<script>
(function($) {
$.widget("custom.combobox", {
_create: function() {
this.wrapper = $("<span>")
.addClass("custom-combobox")
.insertAfter(this.element);
this.element.hide();
this._createAutocomplete();
this._createShowAllButton();
},
_createAutocomplete: function() {
var selected = this.element.children(":selected"),
value = selected.val() ? selected.text() : "";
this.input = $("<input>")
.appendTo(this.wrapper)
.val(value)
.attr("title", "")
.addClass("custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left")
.autocomplete({
delay: 0,
minLength: 0,
source: $.proxy(this, "_source")
})
.tooltip({
tooltipClass: "ui-state-highlight"
});
this._on(this.input, {
autocompleteselect: function(event, ui) {
ui.item.option.selected = true;
this._trigger("select", event, {
item: ui.item.option
});
},
autocompletechange: "_removeIfInvalid"
});
},
_createShowAllButton: function() {
var input = this.input,
wasOpen = false;
$("<a>")
.attr("tabIndex", -1)
.attr("title", "Show All Items")
.tooltip()
.appendTo(this.wrapper)
.button({
icons: {
primary: "ui-icon-triangle-1-s"
},
text: false
})
.removeClass("ui-corner-all")
.addClass("custom-combobox-toggle ui-corner-right")
.mousedown(function() {
wasOpen = input.autocomplete("widget").is(":visible");
})
.click(function() {
input.focus();
// Close if already visible
if (wasOpen) {
return;
}
// Pass empty string as value to search for, displaying all results
input.autocomplete("search", "");
});
},
_source: function(request, response) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
response(this.element.children("option").map(function() {
var text = $(this).text();
if (this.value && (!request.term || matcher.test(text)))
return {
label: text,
value: text,
option: this
};
}));
},
_removeIfInvalid: function(event, ui) {
// Selected an item, nothing to do
if (ui.item) {
return;
}
// Search for a match (case-insensitive)
var value = this.input.val(),
valueLowerCase = value.toLowerCase(),
valid = false;
this.element.children("option").each(function() {
if ($(this).text().toLowerCase() === valueLowerCase) {
this.selected = valid = true;
return false;
}
});
// Found a match, nothing to do
if (valid) {
return;
}
// Remove invalid value
this.input
.val("")
.attr("title", value + " didn't match any item")
.tooltip("open");
this.element.val("");
this._delay(function() {
this.input.tooltip("close").attr("title", "");
}, 2500);
this.input.autocomplete("instance").term = "";
},
_destroy: function() {
this.wrapper.remove();
this.element.show();
}
});
})(jQuery);
$(function() {
$("#combobox").combobox();
$("#toggle").click(function() {
$("#combobox").toggle();
});
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<div class="ui-widget">
<select id="combobox" class="form-control">
<option value="">Select your option</option>
<option value="Apple">Apple</option>
<option value="Banana">Banana</option>
<option value="Cherry">Cherry</option>
<option value="Date">Date</option>
<option value="Fig">Fig</option>
<option value="Grape">Grape</option>
<option value="Kiwi">Kiwi</option>
<option value="Mango">Mango</option>
<option value="Orange">Orange</option>
<option value="Pumpkin">Pumpkin</option>
<option value="Strawberry">Strawberry</option>
<option value="Tomato">Tomato</option>
<option value="Watermelon">Watermelon</option>
</select>
</div>
</div>
</form>
</body>
</html>
I have tested this code on all the below settings
Testing Environment:
Chrome Browser Version 43.0.2334.0 dev-m (64-bit)
Internet Explorer 11
Firefox 36.0.1
Visual Studio 2013 edition
Hope this solves your issue.

This JQuery plugin will solve your problem, it turns DropDown lists into auto-complete like fields, even though it changes the HTML structure of the select element ASP.NET is still able to detect which option was selected.
Source: https://github.com/indrimuska/jquery-editable-select
OBS: To persist data to postback you need to bind the events associated with postback with JavaScript, make the "Combo Box" a dropdownlist again (with the persisted value).
Sample Usage:
$('#editable-select').editableSelect();
<link href="//rawgithub.com/indrimuska/jquery-editable-select/master/dist/jquery-editable-select.min.css" rel="stylesheet">
<select id="editable-select">
<option>Alfa Romeo</option>
<option>Audi</option>
<option>BMW</option>
<option>Citroen</option>
</select>
<script src="//code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="//rawgithub.com/indrimuska/jquery-editable-select/master/dist/jquery-editable-select.min.js"></script>

Related

Under what circumstances would styles not work in a CSS file but will work in a page header?

Pretty simplistic markup. I want to add a box with rounded corners to my form. So, I have this CSS markup:
#rcorners2 {
width:800px;
height:150px;
background:lightGrey;
border-radius: 10px 10px 10px 10px;
border: 2px solid black;
overflow:hidden;
}
It's "called" from this div:
<div id="rcorners2">
<table>
<tr>
<td>Blah</td>
<td>Blah</td>
</tr>
</table>
</div>
My app has a CSS file, so I added that markup to it. Nothing happens. No markup, the form loads with a generic square table in it.
I move the markup to the header section of my page and it works fine.
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
<link rel="stylesheet" href="Content/themes/base/jquery-ui.css">
<!-- <link rel="stylesheet" href="/resources/demos/style.css"> -->
<script src="Scripts/jquery-ui-1.11.0.js" type="text/javascript"></script>
<!-- <script src="Scripts/jquery-1.8.2.min.js" type="text/javascript"></script>
<script src="Scripts/jquery-ui-1.8.24.min.js" type="text/javascript"></script> -->
<!--//**********************************
// Comment Character Count
//********************************** -->
<script type="text/javascript">
function textCounter(field, countfield, maxlimit) {
setTimeout(function () {
if (field.value.length > maxlimit)
field.value = field.value.substring(0, maxlimit);
else
countfield.value = maxlimit - field.value.length;
}, 0);
}
</script>
<script>
$(function () {
var icons = {
header: "ui-icon-circle-arrow-e",
activeHeader: "ui-icon-circle-arrow-s"
};
$("#accordion").accordion({
icons: icons,
collapsible: true
});
} );
</script>
<style>
#rcorners2 {
width:800px;
height:150px;
background:lightGrey;
border-radius: 10px 10px 10px 10px;
border: 2px solid black;
overflow:hidden;
}
</style>
</asp:Content>
Any idea why it's working in one spot and not the other? This is a multi-page C#/ASP.net app running on IE9 (although I eventually need to get it running on IE11, Chrome and Firefox too, but that's for later).
It is usually a good idea to press Ctrl + F5 together after editing external CSS or JS files. This will force the browser to download the files again instead of reading them from cache.

How to fire JavaScript Event after UpdateProgress is disposed on ASP.NET c#?

I have a webform where I have a javascript function that evaluates whether or not it should display a div...
here's the function...
function viewCalendars()
{
if (document.getElementById('ddlDates').value == '5')
{
document.getElementById('divSpecificDates').style.display = 'inline';
}
else
{
document.getElementById('divSpecificDates').style.display = 'none';
}
return;
}
I also added this to my form
<body onload="viewCalendars();">
//Everything
</body>
So even if there was a postback, it will show the div if the dropdownlist has an specific value selected.
However, I recently added both an updatepanel and an updateprogress... and now I think that the will not work anymore since a postback will not occur.
Here's what I have now...
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Consumptions.aspx.cs" Inherits="Station.Consumptions" %>
<%# Register TagPrefix="ew" Namespace="eWorld.UI" Assembly="eWorld.UI, Version=1.9.0.0, Culture=neutral, PublicKeyToken=24d65337282035f2" %>
<!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>
Lista De Consumos
</title>
<link href="css/Style.css" type="text/css" rel="stylesheet"/>
<style type="text/css">
#blur
{
width: 100%;
background-color: black;
moz-opacity: 0.5;
khtml-opacity: .5;
opacity: .5;
filter: alpha(opacity=50);
z-index: 120;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
#progress
{
border: black 1px solid;
padding: 5px;
z-index: 100;
width: 250px;
position: absolute;
background-color: #fff;
-moz-opacity: 0.75;
font-family: Tahoma;
font-size: 11px;
font-weight: bold;
text-align: center;
}
</style>
<script type="text/javascript">
function viewCalendars()
{
if (document.getElementById('ddlDates').value == '5')
{
document.getElementById('divSpecificDates').style.display = 'inline';
}
else
{
document.getElementById('divSpecificDates').style.display = 'none';
}
return;
}
</script>
</head>
<body onload="viewCalendars();">
<form id="form1" runat="server">
<asp:ScriptManager ID="sm" runat="server">
</asp:ScriptManager>
<asp:UpdateProgress ID="UpdateProgress1" runat="server">
<ProgressTemplate>
<div id="blur">
</div>
<div id="progress">
<asp:Image ID="imgLoading" GenerateEmptyAlternateText="true" runat="server" ImageUrl="~/images/loading.gif" />
</div>
</ProgressTemplate>
</asp:UpdateProgress>
<asp:UpdatePanel ID="upd" runat="server">
<ContentTemplate>
<asp:DropDownList ID="ddlDates" CssClass="tbox" runat="server">
</asp:DropDownList>
<div runat="server" id="divSpecificDates" style="display: none; width: 100%; z-index: 1000;">
</div>
<asp:Button Text="Filtrar" CssClass="btn" runat="server" ID="btnFilter" onclick="btnFilter_Click" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnFilter" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
</form>
</body>
</html>
So, I noticed that after you click the btnFilter button, it's function will be triggered, while the updateprogress is visible, but after it disappears (and the btnFilter function is completed) divSpecificDates is not visible when it should be visible. I suppose that I have to call viewCalendars() after everything is done...
How and where do I have to call for this function??
UPDATE:
I just got rid of the updateprogress... and it's still not working, so I guess the problem is not there... probably it's on the updatepanel
When the UpdatePanel is updated, the DOM is change, and you need to re-run the initialization's that you do when you load a page. This are done with javascript function that asp.net includes when you add the UpdatePanel. So remove the onload from the body and use the pageLoad.
So remove the onload from this line
<body onload="viewCalendars();">
and add this script
<script>
function pageLoad() {
viewCalendars();
}
</script>
Similar how to keep javascripts after UpdatePanel partial postback
Reference : Ajax Client Side Life Cycle Events

Asp.net Checkbox OnCheckedChanged not fired when JQuery checks check box

Thank you for taking the time to read and review my post. I've done a lot of Google searching but have yet to find the answer to my jquery/asp.net question. My issue is I'm trying to replace the standard check box with an on/off image. There is a neat tutorial about doing this here. My issue is that my asp OnCheckedChanged check box event is not being called when Jquery places a check in the check box.
ASP.NET Master Page Scripts that works
<link href="~/Styles/jquery.tzCheckbox.css" rel="stylesheet" type="text/css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript" src="<%#ResolveUrl("~/Scripts/jquery.tzCheckbox.js") %>"></script>
<script type="text/javascript" src="<%#ResolveUrl("~/Scripts/script.js") %>"></script>
Aspx Page with Checkbox
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<asp:DetailsView ID="DetailsView1" runat="server" Height="16px" Width="575px">
<Fields>
<asp:TemplateField>
<EditItemTemplate>
<asp:CheckBox ID="Edit_CheckBox1_CB" runat="server" AutoPostBack="true" OnCheckedChanged="Edit_CheckBox1_CB_Clicked" />
</EditItemTemplate>
<InsertItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" />
</InsertItemTemplate>
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Fields>
</asp:DetailsView>
JQuery Script called script.js
(function ($) {
$.fn.tzCheckbox = function (options) {
// Default On / Off labels:
options = $.extend({
labels: ['ON', 'OFF']
}, options);
return this.each(function () {
var originalCheckBox = $(this),
labels = [];
// Checking for the data-on / data-off HTML5 data attributes:
if (originalCheckBox.data('on')) {
labels[0] = originalCheckBox.data('on');
labels[1] = originalCheckBox.data('off');
}
else labels = options.labels;
// Creating the new checkbox markup:
var checkBox = $('<span>', {
className: 'tzCheckBox ' + (this.checked ? 'checked' : ''),
html: '<span class="tzCBContent">' + labels[this.checked ? 0 : 1] +
'</span><span class="tzCBPart"></span>'
});
// Inserting the new checkbox, and hiding the original:
checkBox.insertAfter(originalCheckBox.hide());
checkBox.click(function () {
checkBox.toggleClass('checked');
var isChecked = checkBox.hasClass('checked');
// Synchronizing the original checkbox:
originalCheckBox.attr('checked', isChecked);
checkBox.find('.tzCBContent').html(labels[isChecked ? 0 : 1]);
if (isChecked) {
originalCheckBox.attr('checked', isChecked);
}
});
// Listening for changes on the original and affecting the new one:
originalCheckBox.bind('change', function () {
checkBox.click();
});
});
};
})(jQuery);
CSS file
.tzCheckBox{
background:url("../Images/background01.png") no-repeat right bottom;
display:inline-block;
min-width:60px;
height:33px;
white-space:nowrap;
position:relative;
cursor:pointer;
margin-left:14px;
}
.tzCheckBox.checked{
background-position:top left;
margin:0 14px 0 0;
}
.tzCheckBox .tzCBContent{
color: white;
line-height: 31px;
padding-right: 38px;
text-align: right;
}
.tzCheckBox.checked .tzCBContent{
text-align:left;
padding:0 0 0 38px;
}
.tzCBPart
{
background:url("../images/background01.png") no-repeat left bottom;
width:14px;
position:absolute;
top:0;
left:-14px;
height:33px;
overflow: hidden;
}
.tzCheckBox.checked .tzCBPart{
background-position:top right;
left:auto;
right:-14px;
}
Last Note
Everything works as needed, I just can't seen to get the page to auto post when JQuery checks the check box. Thank you again for your help!
Changes made through javascript will not fire events such as onclick or onchange. What you will need to do is fire the event yourself once you change the value of checked. I am not familiar with the particulars of .net's OnCheckedChanged, but let's assume in the html it turns into onchange (you will need to verify this through viewing the source). You would do something like this:
originalCheckBox.attr('checked', isChecked);
originalCheckBox.change(); // will call the onchange code

paste functionality in google chrome and safari

I am unable to paste the content to a textbox whose property "Textmode"is multiline this issue is happening in google chrome and safari browsers
For safe side, implement clipboard functionality using ZeroClipboard, works on all browser, irrespective of any browser copy - paste feature.
See its usage below. Download and extract the Zeroclipboard in your project
<script src="zeroclipboard/ZeroClipboard.js" type="text/javascript"></script>
<script type="text/javascript" >
ZeroClipboard.setMoviePath('zeroclipboard/ZeroClipboard.swf');
<script language="JavaScript" type="text/javascript">
var clip = null;
function init() {
clip = new ZeroClipboard.Client();
clip.setHandCursor(true);
clip.addEventListener('load', function(client) {
});
clip.addEventListener('mouseOver', function(client) {
// update the text on mouse over
clip.setText(document.getElementById('TextBox1').value);
});
clip.addEventListener('complete', function(client, text) {
Label1.innerText = document.getElementById('TextBox1').value + ' Copied to clipboard.';
});
clip.glue('divbutton', 'divcontainer');
}
</script>
1. Don't forget to set <body onLoad="init()">
2. Set the clip.SetText method in onchnage event of the textbox. <td align="left">
<asp:TextBox ID="TextBox1" runat="server" Width="218px" onchange="clip.setText(this.value)"></asp:TextBox>
</td>
3. <div id="divcontainer" style="position: relative; top: 0px; left: 0px; width: 193px;">
<div id="divbutton" class="mybutton">
<b>Copy To Clipboard...</b></div>
</div> in case use need to some button's illusion on page.

IE (6 & 7) iFrame Querystring Parameters Set In .NET MVC Page Not Working, Seemed Stripped, But Appear In Tact On Page Source

We're using .NET MVC, and we're trying to dynamically (through the controller) set the iFrame's URL. This worked fine on FireFox and Chrome, but not Ie. On Ie only the first case site lets the user log through correctly. The v10 and v9 sites don't. All sites use querystring params to log in. Their source looks like this (unsuccessful source in IE) - no visible difference.
Also, we tried that whole IE7 Security setting Enabled for navigating to frame within another domain - that wasn't the problem; it still doesn't work. Also doesn't work on IE6. Same results as in the screenshots below.
Also Html Encoding hasn't worked (not shown, but tried).
Any ideas would be so awesome!
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1"><title>
</title>
<style type="text/css">
td {
font-family: Arial;
font-size: small;
}
</style>
</head>
<body>
<form action="/Account/Navigate" method="post">
<table style="align: right; width: 100%;">
<tr>
<td align="right">
<input type="submit" name="butSubmit" value="WN" />
<input type="submit" name="butSubmit" value="MyDg" />
<input type="submit" name="butSubmit" value="V9" />
</td>
</tr>
</table>
<iframe id="displayFrame" src="http://my.totallyinsecuretopostthis.com/Login.aspx?&uname=sdavis&pword=04ab" style="width: 100%; height: 95%;"></iframe>
</form>
</body>
</html>
successful source in IE7:
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1"><title>
</title>
<style type="text/css">
td {
font-family: Arial;
font-size: small;
}
</style>
</head>
<body>
<form action="/Account/Navigate" method="post">
<table style="align: right; width: 100%;">
<tr>
<td align="right">
<input type="submit" name="butSubmit" value="WN" />
<input type="submit" name="butSubmit" value="MyDg" />
<input type="submit" name="butSubmit" value="V9" />
</td>
</tr>
</table>
<iframe id="displayFrame" src="http://www.totallyinsecuretopostthis.com/users/428/login/700bc1c8d837f30fdbc03cfc03b58c02" style="width: 100%; height: 95%;"></iframe>
</form>
</body>
</html>
Code snippet (first View, then Controller):
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<SingleSignOnUser>" %>
<%# Import Namespace="Wingnut.Data.Model"%>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title></title>
<style type="text/css">
td {
font-family: Arial;
font-size: small;
}
</style>
</head>
<body>
<% using (Html.BeginForm("Navigate", "Account", FormMethod.Post)) { %>
<% TempData["username"] = Model.WingnutUserEmail; %>
<% TempData["password"] = Model.PasswordHash; %>
<table style="align: right; width: 100%;">
<tr>
<td align="right">
<!-- always display this, but when click, make sure you are authenticated; else, prompt for correct
wingnut password -->
<input type="submit" name="butSubmit" value="WN" />
<% if (Model.IsV10User()) { %>
<input type="submit" name="butSubmit" value="MyDg" />
<% } %>
<% if (Model.IsV9User()) { %>
<input type="submit" name="butSubmit" value="V9" />
<% } %>
</td>
</tr>
</table>
<% string url = ViewData["iFrameURL"].ToString(); %>
<% if (ViewData["iFrameURL"].ToString() != "popup") { %>
<iframe id="displayFrame" src="<%=ViewData["iFrameURL"]%>" style="width: 100%; height: 95%;"></iframe>
<% } %>
(now Controller code:)
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Navigate(string butSubmit) {
_service = new SSOUserService();
SingleSignOnUser wnUser = _service.GetValidUser(TempData["username"].ToString(), TempData["password"].ToString());
ViewData["iFrameURL"] = "http://www.usatoday.com";
try {
//if you are supposed to bypass the intersect page...
if (wnUser != null) {
switch (butSubmit) {
case "WN":
if (wnUser.IsWingnutUser())
ViewData["iFrameURL"] = string.Format("http://www.totallyinsecuretopostthis.com/users/{0}/login/{1}", wnUser.WingnutId, wnUser.WingnutToken);
else {
// do popup to capture this person's correct, but uncaptured, Wingnut password
// try to authenticate, if can, save, and proceed
// else, give error message / popup finally
ViewData["iFrameURL"] = "popup";
ViewData["popupText"] = "Oops. During the Totallyinsecuretopostthis's recent Single Sign On effort, we require that you enter your Totallyinsecuretopostthis" +
"password for us here one time only for authentication to SomePlace:";
}
break;
case "MyDg":
if (wnUser.IsV10User()) {
ViewData["iFrameURL"] =
string.Format(#"http://my.totallyinsecuretopostthisv10.com/Login.aspx?&uname={0}&pword={1}",
wnUser.V10UserCredentials.LoginName,
wnUser.V10UserCredentials.Password);
}
break;
case "V9":
if (wnUser.IsV9User()) {
ViewData["iFrameURL"] =
string.Format(
#"https://login.totallyinsecuretopostthisv9.com/clients/OtherPages/ExternalSignIn.aspx?UserName={0}&Password={1}",
wnUser.V9UserCredentials.LoginName, wnUser.V9UserCredentials.Password);
}
break;
}
}
}
catch (Exception ex) {
ModelState.AddModelError("Errors", ex.Message);
}
return View("Navigation", wnUser);
}
Finally I found a hack / resolution - I never did get the iFrame src="mystring" to work, but I did create a hack. B/c the site we're trying to navigate to, we own; so on that site we created a 'mirror' page. The pages look identical
1 - my original page with the iFrame, but not I have an HREF, and when you click to go where I originally wanted...
2 - you hit that login page, and are logged in... but I added querystring params to this login page (we also own this site), and if sso=true, and you are authenticated, you are redirected to...
3 - a page on the Site B with an iFrame that looks identical to the page on Step #1.
It's a hack, and a lot more work, but it 'works,' and is the best for the user's experience that we could ultimately create.
*** Thank you to you guys who provided answers, as well as anyone looking. I appreciate the help so much!
Use HttpUtility.HtmlAttributeEncode to encode the ampersand in the URL:
ViewData["iFrameUrl"] = HttpUtility.HtmlAttributeEncode( string.Format( ... ) );
I would suggest doing it while rendering the <a> tag in the view instead of hardcoding it in the controller.
It's not something to do with the "?&" at the beginning of the querystring?
Try just: http://my.totallyinsecuretopostthis.com/Login.aspx?uname=sdavis&pword=04ab

Categories