Use multiple fields for mailto: link in gridview - c#

I'm trying to build a gridview field that displays a name and links to an email address with a subject. I first tried to make this work using DataNavigateUrlFormatString, but apparently using a : in a DataNavigateUrlFormatString breaks the link, so unfortunately the code below leaves me with an empty link.
string[] UrlFields = { "bidd_name", "Email", "bidd_number", "bidd_desc", "Bidds_id" };
LinkField = new HyperLinkField();
LinkField.HeaderText = "Buyer";
LinkField.DataTextField = "buyer";
LinkField.HeaderStyle.CssClass = "GVpadding";
LinkField.ItemStyle.CssClass = "GVpadding";
LinkField.DataNavigateUrlFields = UrlFields;
LinkField.DataNavigateUrlFormatString = "mailto:{1} ?subject={2} {3}";
Next I tried using Eval() and NavigateUrl, but the code below gives me this error "Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control."
EmailLinkField.NavigateUrl = "mailto:" + (string)Eval("Email") + "?subject=" + (string)Eval("bidd_number") + " " + (string)Eval("bidd_desc");
I did a little research on the error and found out that I might have to use a RowDataBound method, but I'm not sure how to go about this. Could calling the method below after building out the field change the URL to the desired value?
protected void grddata_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
HyperLink hyp = (HyperLink)e.Row.FindControl("EmailLinkField");
hyp.NavigateUrl = "mailto:" + (string)Eval("Email") + "?subject=" + (string)Eval("bidd_number") + " " + (string)Eval("bidd_desc");
}
}
If so, how do I go about calling it? I'm not sure what parameters I need to use with it when doing something like this.
grddata_RowDataBound(null, null);
Using the nulls generates a "Object reference not set to an instance of an object." error and I don't know what value the sender or e should be.
If anybody could help me get these emails links generated it would be greatly appreciated. I have very little experience with C#, and haven't done all that much coding in general, so feel free to treat me like a child.

simply use a templated column will fix your issue
https://msdn.microsoft.com/en-us/library/bb288032.aspx

Related

Asp.net Custom Table Cell ClientID not set

I have a class derived from WebControls.TableCell.
When the Text property is set, I call a method that dynamically adds asp:Panels and asp:LiteralControls to the Cell. I want to reference these controls in Javascript, so naturally I tried using the ClientId of the panels in my JS functions. However, these controls have no ClientId set (the string is empty). Why is this? How do I force the ClientIds to be set?
As a temporary solution, I set the ClientIDMode to "static" and created the IDs on my own, but this is not satisfactory because it's hard to reference those IDs in JS. Why? If you assign, for example, "12345" to one control, it gets changed on client side to something like "MainContent_123456". This is bad because the "MainContent" part is not fixed; thus I never know for sure what the real Id on the client side will be. Currently, I can get the control with jQuery using $ctrl = $('[id$='12345']');, but this is dirty because it would get any control that has '123456' in its id.
So, back to the original question: how do I get my ClientIds set automatically for my panels in my custom TableCells?
Edit: Code added
protected void Page_Load(object sender, EventArgs e)
{
this.ClientIDMode = System.Web.UI.ClientIDMode.Static;
}
Code in the method that adds the controls to the custom TableCell:
Panel remainingTextPanel = new Panel();
remainingTextPanel.ID = Guid.NewGuid().ToString();
remainingTextPanel.Style["display"] = "none";
LiteralControl remainingText = new LiteralControl(myText.Substring(initialStringLength, myText.Length - initialStringLength));
remainingTextPanel.Controls.Add(remainingText);
this.Controls.Add(remainingTextPanel);
Panel linkBtnPanel = new Panel();
LinkButton lnkBtn = new LinkButton() {Text = "...", OnClientClick = "toggleDynamicText('" + remainingTextPanel.ID + "'); return false;" };
lnkBtn.Font.Bold = true;
linkBtnPanel.Controls.Add(lnkBtn);
this.Controls.Add(linkBtnPanel);
And the JS Code:
function toggleDynamicText(id) {
$ctrl = $('[id$=' + id + ']');
$(document).ready(function () {
$ctrl.toggle(1000);
});
}
Without seeing any code it's difficult to say what's going on but to access your controls using jQuery you can do the following:
$("#<%=myElement.ClientID%>")
This way it doesn't matter what .NET assigns as the ID.

Changing dropdown items text before asp.net autopostback

I am taking over a project in which a client has some annoying issues.
They have a dropdown that autopostbacks on change to place the selected text into a t-sql query. Any value that has an apostrophe is causing an query error due to not being escaped
I do not have access to compiled code, but was hoping to write a quick band-aid fix to on selected changed, before posting replace an apostrophe to a double apostrophe to escape it as it goes into query.
I wrote a javscript ddl.change function that works at changing the text.
This however is not working even though the apostrophe does change into two. I was wondering if someone could help understand why.
I have two thoughts of scenarios causing the issue.
On autopostback, it triggers before javascript change function does, therefore passing the original value before javascript has a change to modify it.
The server side code only understands what it originally placed into the dropdown and therefore no matter how much I manipulate the client code, it will only see what it placed?
Can anyone confirm either of these scenarios?
Help would be appreciated!
EDIT: I REVERSE ENGINEERED THE CODE, YES ITS VERY UGLY (AND SQL INJECTABLE) BUT IS NOT MINE AND I CANNOT MODIFY IT
C# Code
protected void ddls_SelectedIndexChanged(object sender, EventArgs e)
{
if (this.ddls.SelectedIndex == 0)
{
this.pnlA.Visible = false;
}
else
{
this.pnlA.Visible = true;
string text = Common.GetSql("~/Sql/" + this._Conn + "/PropertyAddressReverseSearch.sql", false, true).Split(new char[]
{
Conversions.ToChar(this._Delimiter)
})[4];
text = string.Concat(new string[]
{
"SELECT * FROM (",
text,
") a WHERE StreetName='",
this.ddls.SelectedItem.Text,
"' "
});
this.Bind(this.ddla, text);
this.ddla.Items.Insert(0, new ListItem("I'm not sure of the house number...", Conversions.ToString(-1)));
this.ddla.Items.Insert(0, new ListItem("", Conversions.ToString(0)));
this.map.Visible = false;
}
}
Javscript + Control
<asp:dropdown runat="server" id="ddls" autopostback="true">
<script type="javascript/text">
$(document).ready(function() {
$("select[id$='adsearch_ddls']").change(function() {
var ddlsValue = $("select[id$='adsearch_ddls'] option:selected").text();
ddlsValue = ddlsValue.replace(/'/g,"\'\'");
$("select[id$='adsearch_ddls'] option:selected").text(ddlsValue);
return false;
});
});
</script>
You can not modify (or add/remove) the Select/dropdown list items client-side, and simply get the same server-side items, with ASP.NET Webforms when viewstate is enabled.
Unless you send back the modified items in another way, like for example in this answer where list items are copied to a hidden field:
function SaveList()
{
//Clear the hidden field
var hField = document.getElementById('<%= YourHiddenField.ClientID %>');
hField.value = '' ;
var selectedList = document.getElementById('<%= YourDropDownList.ClientID %>')
for(i = 0; i < selectedList.options.length; ++i)
{
hField.value = hField.value + ',' + selectedList.options[i].value;
}
That is, assuming by "On selected index change calls server side code" you mean a postback is triggered?
Disabling the ViewState will cause other problems (like SelectedIndexChanged not triggering, etc).
You could handle the selection change through your own (AJAX) postback. But the difference between server- and client-side list items would still remain.

C# how to show available data one by one in textbox

Hi I am using HtmlAgilityPack to scrap some data from web using c# . Here is the code :
private void button1_Click(object sender, EventArgs e)
{
var url = this.textBox1.Text;
var webGet = new HtmlWeb();
var document = webGet.Load(url);
var metaTags = document.DocumentNode.SelectNodes("//meta");
if (metaTags != null)
{
foreach (var tag in metaTags)
{
var name = tag.Attributes["name"].Value;
var content = tag.Attributes["content"].Value;
this.textBox2.Text = name + " : " + content;
}
}
}
its getting a link from textbox1 and showing the output to textbox2 . Its showing the last available data . I can concate the available data but it will show all data at once. Actually I want to show one data when it is available while others are being processed so that user can realize the scrapping progress.Would anyone please help ??
Assuming the first half of your code is correct, this will show the data one-by-one. Most likely, the foreach loop is executing too quickly for you to notice the "one-by-one" effect.
You could apply an artificial delay if you need to display each result long enough for someone to read. Maybe with a Timer or something similar.
An alternative is to use a multi-line textbox (for example a RichTextBox) and place each result on a new-line. Or a ComboBox, which won't take up as much room. These options allow you to keep the data, without having to overwrite it.
You can user Timer control to delay the display of next value in the loop.
You can also use BackgroundWorker to get this done. However this would add complexity to your code. Please look at Beginners Guide to Threading in .NET: Part 5
Or you can use Thread.Sleep(xx) which will delay the execution for the milliseconds you specify.
Thread.Sleep(2000);
this.textBox2.Text += name + " : " + content + Environment.NewLine;

textboxes lose value on postback

i have about 4 textboxes on my webpage...some are asp:textboxes while others are input type="text".
the input textbox is populated through a javascript popup calender control while asp.net textbox is populated by typing. The initial values of these textboxes are retrieved from a database.
When a user changes these values, they are not saved and the textboxes are cleared out after the submit button is clicked. Please help resolve this confusion. Thanks.
thanks for your reply but it is still not working.....
i have put this code in my page load event
if (Page.IsPostBack)
{
if (ViewState["stock"] != null)
TextBoxMaterial.Text = ViewState["stock"].ToString();
if (ViewState["supplier"] != null)
TextBoxSupplier.Text = ViewState["supplier"].ToString();
if(ViewState["matTime"] != null)
TextBoxMatTime.Text = ViewState["matTime"].ToString();
if(ViewState["prodTime"] != null)
TextBoxProdTime.Text = ViewState["prodTime"].ToString();
if (ViewState["shipTime"] != null)
TextBoxShipTime.Text = ViewState["shipTime"].ToString();
if(ViewState["cmr"] != null)
cmrDue.Value = ViewState["cmr"].ToString();
if(ViewState["kc"] != null)
kcDue.Value = ViewState["kc"].ToString();
}
and also put the below code in the onclick event for the button
ViewState["stock"] = TextBoxMaterial.Text;
ViewState["supplier"] = TextBoxSupplier.Text;
ViewState["matTime"] = TextBoxMatTime.Text;
ViewState["prodTime"] = TextBoxProdTime.Text;
ViewState["shipTime"] = TextBoxShipTime.Text;
ViewState["cmr"] = cmrDue.Value.ToString();
ViewState["kc"] = kcDue.Value.ToString();
string prodLine = DDProdLine.SelectedValue;
string stock1 = DDMaterial.SelectedValue;
string stock2 = ViewState["stock"].ToString();
string supplier = ViewState["supplier"].ToString();
string billet = RBBillet.SelectedValue;
string matTime1 = ViewState["matTime"].ToString();
string matTime2 = DDMatTime.SelectedValue;
string prodTime1 = ViewState["prodTime"].ToString();
string prodTime2 = DDProdTime.SelectedValue;
string shipTime1 = ViewState["shipTime"].ToString();
string shipTime2 = DDShipTime.SelectedValue;
CultureInfo cultureInfo = CultureInfo.CurrentCulture;
string format = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern.ToString();
string cmr = ViewState["cmr"].ToString();
string kc = ViewState["kc"].ToString();
string x = cmr.Substring(3, 2);
string y = cmr.Substring(0, 2);
string z = cmr.Substring(6, 4);
string x1 = kc.Substring(3, 2);
string y1 = kc.Substring(0, 2);
string z1 = kc.Substring(6, 4);
string finalCmr = x + "/" + y + "/" + z;
string finalKC = x1 + "/" + y1 + "/" + z1;
DateTime dt = DateTime.ParseExact(finalCmr, format, cultureInfo);
DateTime cr = DateTime.ParseExact(finalKC, format, cultureInfo);
string custDate = dt.ToString("dd/mm/yyyy");
string kcDate = cr.ToString("dd/mm/yyyy");
string id = Request.QueryString["id"];
bool success = true;
TextBoxProdComment1.Text = stock2 + "," + supplier + matTime1 + "," + prodTime1 + "," + shipTime1 + "," + custDate
+ "," + kcDate;
try
{
success = CRTopButtons.SaveProdTable(id, prodLine, stock1, supplier, billet, matTime1, matTime2, prodTime1,
prodTime2, shipTime1, shipTime2, custDate, kcDate);
}
catch (Exception e)
{
TextBoxProdComment2.Text = e.Message;
System.Diagnostics.Trace.Write(e.StackTrace);
}
the textboxes still clear out and none of it is readonly..........
please help
I had a similar problem and The Solution to "Losing data changed by javascript during postback"
is best described by this article
ViewState and Readonly Property of Textbox
for example let's say we have this asp.net control:
<asp:TextBox ID="txtName" runat="server" EnableViewState= "false" ReadOnly="true" />
if you change the value of this control through javascript in the client side it will not be propagated via postback in the serverside...whatever you do with javascript unless you remove readonly="true". Now there is a solution to this problem as described in the article above.
Simply put this in the PageLoad event
if (!IsPostBack)
txtName.Attributes.Add("readonly","readonly");
and you're done. Just don't forget to remove ReadOnly="true" or Enable="false" if your intent was to disable the control from editing just use the snippet above. Don't forget to remove Enable="false" if you put it on.
Another thing I ran into... If you're using an ASP.NET TextBox Control (for example), and it's READONLY or DISABLED, the postback won't catch the changed value.
Per my issue, I was changing the value of the control thru javascript and even though the browser rendered the change, on the postback, the control still retained the original value.
Seems a common problem too... javascript kicks off a custom ASCX calendar control and result is injected by javascript, into the textbox. Users shouldn't be allowed to directly modify textbox value...
string strDate = Request.Form["id_of_input_element"].ToString();
I ultimately used the above to um, "reset" the control, after the postback, to it's changed value!
The <input> textboxes won't save their state after postback. ASP.NET does not handle that for you.
If you put code in your Page_Load event to set the values of the ASP.NET textboxes, the values that were posted back will not be saved, because Page_Load happens after the child control states are restored in the ASP.NET page lifecycle. The values are already restored by ASP.NET, but you are overwriting their restored values.
The correct thing to do to fix #2 is to check Page.IsPostBack before loading your initial state, like this:
if ( !Page.IsPostBack )
{
// set the textbox initial states from the database
}
UPDATE:
There are two ways to solve problem #1. One thing you could do is to use the Request.Form[] collection to retrieve the posted back value manually, like this:
string strDate = Request.Form["id_of_input_element"].ToString();
The other thing you could do, and this is what I'd recommend if you can, is to change the <input> element to an ASP.NET textbox, and hook up any client-side Javascript events to that. Then ASP.NET will completely handle your postback.
i found this when looking for an answer to the same type of problem and now that i found my problem i thought it could help someone else putting it here.
in my case i had a tag <form> inside the <form> of my controls, so, if you didnt resolve your problem with above i sugest search for a <form> lost inside your <form>.
hope it helps for some cases.
If I get you're asking for right, I think you're trying to make those textboxes readonly. If so, I had this problem before and solved it by making the textboxes readonly using C# not ASP.NET, I just added lines like textboxName.Attributes.Add("readonly", "readonly"); in the Page_Load and it worked just fine. This solution I found here on Stackoverflow
instead of TextBoxPassword.Text=Password
use
TextBoxPassword.Attributes["value"]=Password
It seems that your viewstate is disabled. Enable the viewstate in Page directive.

Gridviewcell to textbox not working

I have the following working so far in C# on my Gridview called GridView1. It works when I put it in the onSelectedIndexChanged.
HostTextbox.Text = GridView1.SelectedRow.Cells[0].Text;
but since this posts back to the server I want to avoid it because I will be doing it for cells[0] to cells[10]. So, I looked into Javascript. I googled around and found various solutions and this is the one I have "semi-working" so far.
My C# looks like this:
int myRowIdx = 0; // class variable
protected void OnRowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes.Add("ondbclick", "sample('" + myRowIdx.ToString() + "')");
}
myRowIdx++;
}
In my Javascript I inserted alerts to tell me where the problem happpens. It looks like this:
function sample(rowIn) {
alert("A");
var gViewID = '<%= GridView1.ClientID %>';
alert("B");
var gView = getElementById(gViewID);
alert("C");
var gViewRow = gView.rows[rowIn];
alert("D");
var gViewRowColumn = gViewRow.cells[0];
alert("E");
var displayCell = gViewRowColumn.innerText;
alert("F");
alert(displayCell);
}
B is the last alert I see. I can't seem to figure this out. I looked carefully into it and still no success. Please help.
I don't understand what you mean with "I want to avoid it because I will be doing it for cells[0] to cells[10]". You could do that for each cell in the selected row successively. So you only need one Postback.
According to your Javascript problems, you could simply pass the tr(GridViewRow) as js-variable to your sample-function. Therefore you only have to pass this as parameter:
e.Row.Attributes.Add("ondbclick", "sample(this)");
and in your js-function:
function sample(tr) {
var gViewRowColumn = tr.cells[0];
var displayCell = gViewRowColumn.innerText;
alert(displayCell);
}
Use Item Template Panel for grid view.
ex.http://msdn.microsoft.com/en-us/library/aa479353.aspx
Use the onrowcommand event for get the values.
like..
Event
{
if(e.commandname="Edit")
{
}

Categories

Resources