Wednesday, March 21, 2012

passing a non-databound column to javascript

I have a gridView with a template field that looks like this
<asp:TemplateField HeaderText="">
<ItemTemplate>
<a href="http://links.10026.com/?link=javascript:OpenHelp('<%# Eval("Status") %>')">
<img alt="Click for help." src="http://pics.10026.com/?src=help\help.gif" border="0px"
width="12px"/>
</a>
</ItemTemplate>
</asp:TemplateField>
This works great in a test grid where status is actually bound to the
database. However in the real case Status is not bound but is a column
populated based on complex logic from many fields. I know the whole Eval thi
s
is for databound stuff, but how do I pass it when it is not databound? The
"Status" column is another template field with header text = "Status".You can perform any operations using the <%# %> using page or static utility
classes/methods that you could using, say, <%= %> or in your code behind.
Perhaps the best solution would be to do something like this:
public static class MyDataManager
{
public static string GetComplexStatus(object val1, object val2, object
val3)
{
// Do any normal logic you would do to determine what the status is
// then return it to the caller.
return string.Format("{0} : {1} : {2}", val1, val2, val3);
}
}
Then on your page, you could call this like:
<asp:TemplateField HeaderText="Status">
<ItemTemplate>
<a href="http://links.10026.com/?link=java script:OpenHelp('<%#
MyDataManager.GetComplexStatus(Request.Url, Eval("MyField1"),
this.protectedPageVariable1) %>')">
<img alt="Click for help." src="http://pics.10026.com/?src=help\help.gif" border="0px"
width="12px"/>
</a>
</ItemTemplate>
</asp:TemplateField>
This example shows pulling values that are not necessarily databound, but
perhaps are page variables (protected +), properties, other methods, static
methods or properties, and maybe even another data bound field.
Hope this helps.
Chad Scharf
_______________________________
http://www.chadscharf.com
"rlm" wrote:

> I have a gridView with a template field that looks like this
> <asp:TemplateField HeaderText="">
> <ItemTemplate>
> <a href="http://links.10026.com/?link=java script:OpenHelp('<%# Eval("Status") %>')">
> <img alt="Click for help." src="http://pics.10026.com/?src=help\help.gif" border="0px"
> width="12px"/>
> </a>
> </ItemTemplate>
> </asp:TemplateField>
> This works great in a test grid where status is actually bound to the
> database. However in the real case Status is not bound but is a column
> populated based on complex logic from many fields. I know the whole Eval t
his
> is for databound stuff, but how do I pass it when it is not databound? The
> "Status" column is another template field with header text = "Status".
>
Chad, thanks. Is there a way to simply reference the value/string that is
already in the table cell on the rendered page, and pass that to javascript?
Sure...
In your header, or somewhere before the databound control (repeater,
datagrid, etc), place something like this:
<script type="text/javascript">
<!--
var myVal;
//-->
</script>
Then inside of your <ItemTemplate />:
...
<ItemTemplate>
<script type="text/javascript">
<!--
myVal = '<%# Eval("ColumnName") %>';
//-->
</script>
<%-- Or you could use it in this fashion --%>
<asp:Button runat="server" ID="myButton" Text="Click Me"
OnClientClick='<%# string.Format("alert('{0}');return false;",
Eval("ColumnName")) %>' />
</ItemTemplate>
Chad Scharf
_______________________________
http://www.chadscharf.com
"rlm" wrote:

> Chad, thanks. Is there a way to simply reference the value/string that is
> already in the table cell on the rendered page, and pass that to javascrip
t?
>
Chad,
I will try these suggestions out later today, but I don't see how this last
one is much different than my first post "javascript:OpenHelp('<%#
Eval("Status") %>')" which does not work. The Eval on the non bound Template
Field did not work. I guess I am still missing something in my understanding
.
This line
myVal = '<%# Eval("Status") %>';
produces this error
DataBinding: 'System.Data.DataRowView' does not contain a property with the
name 'Status'.
because the field is not databound.

> <ItemTemplate>
> <script type="text/javascript">
> <!--
> myVal = '<%# Eval("ColumnName") %>';
> //-->
> </script>
>
OK, I misunderstood the actual issue you were having; my apologies. I've run
into this issue a few times in the past when binding a DataTable or DataSet
to a databound control.
Are you using a SqlDataSource control, binding via code behind, etc? Please
ensure that the column "Status" is in your select list, if it is not, then
your code below would fail with this error. If you are using Typed datasets,
please ensure that the property settings for the Status column is
pass-through to the associated DataView, especially if it is a calculated
column or relies on an expression for its value.
Set a break-point in the Control_ItemDataBound event and explore your item's
datasource to ensure this column is present.
If the column/value is indeed there, you may as I have done in the past use
a typed expression to retrieve it and see how that works for you, e.g.:
<%# ((System.Data.DataRowView)Container.DataItem).Row["Status"] %>
Thanks,
Chad Scharf
_______________________________
http://www.chadscharf.com
"rlm" wrote:

> This line
> myVal = '<%# Eval("Status") %>';
> produces this error
> DataBinding: 'System.Data.DataRowView' does not contain a property with th
e
> name 'Status'.
> because the field is not databound.
>
>
To expand on this a little further going back, I do want to point out that
your ItemTemplate is still a DataBound field, even if it is keying off of th
e
"Status" column which is not directly from your Database itself.
The Eval(); method is intended to pull a property or reference point from a
data item, which inheritly is the assigned object from the enumerator bound
to your control. This object, whether it is a DataRowView or perhaps a custo
m
class, must contain the property or accessor for the Eval("") expression you
provided, if it does not you will reiceve that databinding error.
It sounds as if your "Status" column is a calculated field within a typed
DataSet, or is added via another method in your code. If this is true, use
the debugger to trace your databinding events to ensure this column is being
generated properly, that the AcceptChanges(); method is called on your
DataSet - OR - for pending changes or for safety sake, use the .Select()
method on your DataTable rather than allowing the DataBinding evaluator call
the DataRowView:
...
DataRow[] source = myTable.Select();
if (source.Length > 0)
MyDataBoundControl.DataSource = myTable.Select();
else
MyDataBoundControl.DataSource = null; // zero length collections not
allowed
MyDataBoundControl.DataBind();
...
Let me know what you find.
Chad Scharf
_______________________________
http://www.chadscharf.com
"Chad Scharf" wrote:
> OK, I misunderstood the actual issue you were having; my apologies. I've r
un
> into this issue a few times in the past when binding a DataTable or DataSe
t
> to a databound control.
> Are you using a SqlDataSource control, binding via code behind, etc? Pleas
e
> ensure that the column "Status" is in your select list, if it is not, then
> your code below would fail with this error. If you are using Typed dataset
s,
> please ensure that the property settings for the Status column is
> pass-through to the associated DataView, especially if it is a calculated
> column or relies on an expression for its value.
> Set a break-point in the Control_ItemDataBound event and explore your item
's
> datasource to ensure this column is present.
> If the column/value is indeed there, you may as I have done in the past us
e
> a typed expression to retrieve it and see how that works for you, e.g.:
> <%# ((System.Data.DataRowView)Container.DataItem).Row["Status"] %>
> Thanks,
> --
> Chad Scharf
> _______________________________
> http://www.chadscharf.com
>
> "rlm" wrote:
>
I have not been able to force the "Status" field into the default view. Ther
e
is no such fielld in the table, and debugging has not helped me.
Anyone can reproduce this in less than three minutes(if they already have a
database to connect to) with the following steps
1. create new web application
2. drop on a grid view
3. Choose datasource (sql)
4 connect to any table and select some fields
5. On gridView tasks choose Edit Columns
6. Add a template field
7. Change its header text to status
8. use RowDataBound event to set the value in that field with something like
this
e.Row.Cells[2].Text = "happy";
9. Pass that fields value to a javascript function like this
<ItemTemplate>
<a href="http://links.10026.com/?link=java script:OpenHelp('<%# Eval("Status") %>')">
Text
</a>
</ItemTemplate>
Oooh, that's what you meant by "not databound." That makes sense now and so
does the exception and what you're trying to accomplish.
You can do this many ways, however the easiest is to do the following:
e.Row.Cells[2].Text = string.Format("<a href=\"\"
onclick=\"java script:OpenHelp('{0}');return false;\">{0}</a>", status);
When you set the Text of a cell in a DataBound row inside of a GridView, you
would be replacing the content of that cell (inlcuding whatever the
ItemTemplate specified) anyways.
Other ways you can accomplish this are with protected page level variables
to store the databound value in, then in your ItemTemplate use the <%# myVar
%> syntax instead of Eval("").
Thanks,
Chad Scharf
_______________________________
http://www.chadscharf.com
"rlm" wrote:

> I have not been able to force the "Status" field into the default view. Th
ere
> is no such fielld in the table, and debugging has not helped me.
> Anyone can reproduce this in less than three minutes(if they already have
a
> database to connect to) with the following steps
> 1. create new web application
> 2. drop on a grid view
> 3. Choose datasource (sql)
> 4 connect to any table and select some fields
> 5. On gridView tasks choose Edit Columns
> 6. Add a template field
> 7. Change its header text to status
> 8. use RowDataBound event to set the value in that field with something li
ke
> this
> e.Row.Cells[2].Text = "happy";
> 9. Pass that fields value to a javascript function like this
> <ItemTemplate>
> <a href="http://links.10026.com/?link=java script:OpenHelp('<%# Eval("Status") %>')">
> Text
> </a>
> </ItemTemplate>
>

0 comments:

Post a Comment