First of all, sorry if I make mistakes in english...
I'm making a web with c#, and I have some problems for refresh the data displayed in the GridView
I'm getting the data throw the SqlDataSource defined at the aspx view:
<asp:SqlDataSource ID="PRODUCTOS_CON_STOCK" runat="server" ConnectionString="<%$ ConnectionStrings:XXXX %>" ProviderName="<%$ ConnectionStrings:XXX.ProviderName %>" DataSourceMode="DataSet" SelectCommand=" select EAN, CODART..... "> </asp:SqlDataSource>
When I click a button, I update some data in the database, and I want refresh de GridView with the new data, without reload the page.
I'm making: gridView.DataBind();, but that doesn't refresh the data in the GridView.
(At the database is updated)
The GridView is inside of an UpdatePanel.
I was trying some things, like:
Reassing the DataSourceID and make the gridView.DataBind();
Assing the DataSourceID in null, make the gridView.DataBind();, and alter reassing the DataSourceID and make the gridView.DataBind();
I tried too:
DataSourceSelectArguments argumentos = new DataSourceSelectArguments();
PRODUCTOS_CON_STOCK.Select(argumentos);
gridView.DataBind();
Set the UpdatePanel to updatemode="Always"
But any of all of that worked...
Someone can help me?
Thanks.
Why not dump the datasource setting on the page of PRODUCTOS_CON_STOCK.
I find that when you need to filtere, load, and play?
Just remove the data source from the markup. So, in your GridView, remove the data source id setting of PRODUCTOS_CON_STOCK, and then delete the data source.
You have to write a BIT more code, but you now have control over the data, and MORE important, control over which parameters you need and want.
So, say I have this markup:
A grid, and also a search/text box to filter the grid.
<asp:Label ID="Label1" runat="server" Text="Search for Fighter jet" Font-Size="Large"></asp:Label>
<asp:TextBox ID="txtSearch" runat="server" Style="margin-left:15px" Font-Size="Large">
</asp:TextBox>
<asp:Button ID="cmdSearch" runat="server" Text="search"
style="margin-left:15px" CssClass="btn" OnClick="cmdSearch_Click" />
<br />
<br />
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" CssClass="table" >
<Columns>
<asp:BoundField DataField="Fighter" HeaderText="Fighter" />
<asp:BoundField DataField="Engine" HeaderText="Engine" />
<asp:BoundField DataField="Thrust" HeaderText="Thrust" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField HeaderText="View">
<ItemTemplate>
<asp:ImageButton ID="btnImage" runat="server" Height="68px" Width="149px"
OnClientClick ="popimage(this);return false"
ImageUrl = '<%# Eval("ImagePath") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Note close - I did build this grid using the wizards. But I THEN removed the Datasource ID for the GV, and removed the Datasource that was created in the markup.
So, now my code to load is this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadGrid("");
}
void LoadGrid(string MySearch)
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand("SELECT * from Fighters ", conn))
{
if (MySearch != "")
{
cmdSQL.CommandText += #" WHERE Fighter LIKE #Fighter + '%'";
cmdSQL.Parameters.Add("Fighter", SqlDbType.NVarChar).Value = MySearch;
}
conn.Open();
DataTable rstData = new DataTable();
rstData.Load(cmdSQL.ExecuteReader());
GridView1.DataSource = rstData;
GridView1.DataBind();
}
}
}
And I get this:
And note the "optional" filter for the text box. If you type in some text, (I used a "like" match in sql), then the code is only this:
protected void cmdSearch_Click(object sender, EventArgs e)
{
LoadGrid(txtSearch.Text);
}
but, the idea here is often it is much better to dump the SqlDataSoruce placed in the markup, and roll + write your own code. The problem is you can try and set the data source in code, but ALSO WITH a data source on the page - they fight over each other. So, try the above idea - and remove the data source in the markup.
Finally I resolved the issue.
In my case, I was calling in the front, in AJAX, the C# method, that method is an WebMethod HttpPost
The issue was that I was saving in a Session the GridView and the SqlDataSource, and although I was executing the Select statement again, I was obtaining the old's values.
I was saving in a Session that information because the AJAX execute the method direct and the GridView and the SqlDataSource were null
Finally I tried to make a refresh from the GridVeiw by a button, and the info is updated correctly, so, I hided the button, and simulate the click button in AJAX:
$.ajax({
type: 'POST',
url: pageUrl,
data: JSON.stringify({ gridMod: gridMod }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function() {
document.getElementById("<%= btnReload.ClientID %>").click();
},
});
So, the click event call to LoadGrid();, and this one execute:
private void LoadGrid()
{
DataSourceSelectArguments argumentos = new DataSourceSelectArguments();
PRODUCTOS_CON_STOCK.Select(argumentos);
eanList.DataBind();
}
In this way, I can refresh the data "automatically" without clicking in any button
Related
After reading Formatting the DataList and Repeater Based Upon Data (C#) on Microsoft Website I found the following code sample.
protected void ItemDataBoundFormattingExample_ItemDataBound(object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
// Programmatically reference the ProductsRow instance bound
// to this DataListItem
Northwind.ProductsRow product =
(Northwind.ProductsRow)((System.Data.DataRowView)e.Item.DataItem).Row;
// See if the UnitPrice is not NULL and less than $20.00
if (!product.IsUnitPriceNull() && product.UnitPrice < 20)
{
// TODO: Highlight the product's name and price
}
}
}
However in the above I would like to know where Northwind.ProductsRow product is coming from. Is it from the Northwind database name or somewhere else.
this is a great question, and like some time travel movie, I REALLY WISH someone had and did explain how this works. You note that sometimes the "data source" of the datalist works, and sometimes it does not, and why is this so???
So, the data source comes from WHEN the control was "binded" or spoon fed the data source.
So, on page load, there is most likly some code that set-up and "binds" the data control. Or, it might be that a sqldatasource was dropped into the web page, but AGAIN, either way?
The page load will then trigger the row data bound event.
(ItemDataBound).
So, first BIG tip:
The e.Item.DataItem used IS ONLY available DURING the data bind process. That quite much means at data bind time and the ItemDataBound event.
So, WHEN you shove a data source INTO the GridView, Datalist, ListView, repeater etc controls? And use the data bound event (the name varies a wee bit, bu they all do the same thing), then the DataItemView is ONLY available DURING the row data bind process and hence you are 100% free to use that data source DURING the data bind event - BUT NOT AFTER!!!!!
After, binding has occured, you find that the the dataitem (and control datasoruce is NOW null!!!!). This is VERY different then desktop versions of such controls in .net (in desktop land, you actually can get/use/see the ACTUAL object used for each row!!! - and they persist!!!!
In web land, that data source is converted to a DataRowView.
However, what is the basic knowledge here?
Well, it means that your data control does NOT have to display or hide all of the columns from the database, but you ARE STILL FREE to use those additional columns for things like tax calculations, or for formatting controls based on OTHER columns that you have in the datasource BUT ARE NOT DISPLAYED!!!
And you see BOATLOADS of examples posted where people use hidden fields and all kinds of tricks, and they did that because they DID NOT KNOW the above!!!
Now, it not clear if you want to use a "datalist" control. They tend to be good for say one reocrd, or say several records in a "card like" view - not a table like layout.
So, for a table like layout, I suggest using ListView (most flexible), or for simple, and not too fancy, then use GridView.
But, DataList, listView, GridView, Repeater ? They all of this Row bound (or Item bound) event (they all are VERY close named).
And as noted, JUST like your question, in most cases this event can be used for addtional formatting.
Lets do this with a GridView - (since it easy).
So, say we have a grid of hotel names, but I want to highlight in say blue color ONLY hotels that are active. But I ALSO do NOT want to display the "active" column from the data base in that grid.
So, say this simple markup:
<style> .MyCenter {text-align:center;}</style>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" cssclass="table" OnRowDataBound="GridView1_RowDataBound">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" ItemStyle-Width="120px" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField HeaderText="View" >
<HeaderStyle CssClass="MyCenter"/>
<ItemStyle CssClass="MyCenter" />
<ItemTemplate>
<asp:Button ID="bView" runat="server" Text="View" CssClass="btn" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Now, our code to load, we have this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadGrid();
}
void LoadGrid()
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
string strSQL = "SELECT * FROM tblHotelsA ORDER BY HotelName";
using (SqlCommand cmdSQL = new SqlCommand(strSQL,conn))
{
conn.Open();
DataTable rstData = new DataTable();
rstData.Load(cmdSQL.ExecuteReader());
GridView1.DataSource = rstData;
GridView1.DataBind();
}
}
}
And we now have this:
So, lets use the ItemDataBound event (RowdataBound for Gridview) to highlight the Hotel name and descrption ONLY for Hotels that are active. As noted, we do NOT display "Active" column in the gridview, but with Row data bound event, we still have use of the FULL row.
So, we can add this code to the Row data bound event.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// get the full data row used for binding
DataRowView OneRow = e.Row.DataItem as DataRowView;
// lets highlist the hotel name + description
if ((bool)OneRow["Active"])
{
e.Row.Cells[3].BackColor = System.Drawing.Color.LightSteelBlue;
e.Row.Cells[4].BackColor = System.Drawing.Color.LightSteelBlue;
}
// that button is not centered "vertical", so lets do that
Button btn = e.Row.FindControl("bView") as Button;
DataControlFieldCell g = btn.Parent as DataControlFieldCell;
g.Style.Add("vertical-align", "middle");
}
}
And now we we get this:
So, what about the view item click? For that we could use a datalist as you have, and we could then hide the grid, display the datalist, and we would be quite much on our way with a grid to edit items, then right?
Coffee break - I'll be back in a bit to add the view + datalist to see/view/edit one item.
Ok, part 2 - using a datalist to display above click
Ok, so lets drop in a data list - with a div area (to hide and show).
So, ok, now our data list we drop in.
<div id="MyEditArea" runat="server" style="width:44%;margin-left:35px;padding:8px;border:solid;display:none">
<asp:Datalist ID="DataList1" runat="server" DataKeyField="ID" >
<ItemTemplate>
<style>
.iForm label {display:inline-block;width:95px}
.iForm input {border-radius:8px;border-width:1px;margin-bottom:10px}
.iForm textarea {border-radius:8px;border-width:1px;margin-bottom:10px}
.iForm input[type=checkbox] {margin-right:6px}
</style>
<div style="float:left" class="iForm">
<label>HotelName</label>
<asp:TextBox ID="txtHotel" runat="server" Text='<%# Eval("HotelName") %>' width="280" /> <br />
<label>First Name</label>
<asp:TextBox ID="tFN" runat="server" Text='<%# Eval("FirstName") %>' Width="140" /> <br />
<label>Last Name</label>
<asp:TextBox ID="tLN" runat="server" Text='<%# Eval("LastName") %>' Width="140" /> <br />
<label>City</label>
<asp:TextBox ID="tCity" runat="server" Text='<%# Eval("City") %>' Width="140" /> <br />
<label>Province</label><asp:TextBox ID="tProvince" runat="server" Text='<%# Eval("Province") %>'
f="Province" Width="75"></asp:TextBox> <br />
</div>
<div style="float:left;margin-left:20px;width:420px " class="iForm">
<label>Description</label> <br />
<asp:TextBox ID="txtNotes" runat="server" Width="400" TextMode="MultiLine"
Height="150px" Text='<%# Eval("Description") %>' ></asp:TextBox> <br />
<asp:CheckBox ID="chkActive" Checked='<%# Eval("Active") %>' Text=" Active" runat="server" TextAlign="Right" />
<asp:CheckBox ID="chkBalcony" Checked='<%# Eval("Balcony") %>' Text=" Has Balcony" runat="server" TextAlign="Right" />
<asp:CheckBox ID="chkSmoking" Checked='<%# Eval("Smoking") %>' Text=" Smoking Area" runat="server" TextAlign="Right" />
</div>
<div style="clear:both"></div>
<div style="float:left" class="iForm">
<asp:Button ID="cmdSave" runat="server" Text="Save" CssClass="btn" />
<asp:Button ID="cmdCancel" runat="server" Text="Cancel" CssClass="btn" style="margin-left:10px" />
</ItemTemplate>
</asp:Datalist>
And now our button click for the grid view - to display that one data list control + data.
Hum, started writing some code routine, so lets clean this up a bit.
Ok, so we now have this to load + format the gridview.
void LoadGrid()
{
GridView1.DataSource = MyRst("SELECT * FROM tblHotelsA ORDER BY HotelName");
GridView1.DataBind();
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// get the full data row used for binding
DataRowView OneRow = e.Row.DataItem as DataRowView;
// lets highlist the hotel name + description
if ((bool)OneRow["Active"])
{
e.Row.Cells[3].BackColor = System.Drawing.Color.LightSteelBlue;
e.Row.Cells[4].BackColor = System.Drawing.Color.LightSteelBlue;
}
// button is not centered "vertical", so lets do that
Button btn = e.Row.FindControl("bView") as Button;
DataControlFieldCell g = btn.Parent as DataControlFieldCell;
g.Style.Add("vertical-align", "middle");
}
}
void CenterControl(Control c)
{
DataControlFieldCell g = c.Parent as DataControlFieldCell;
g.Style.Add("vertical-align", "middle");
}
public DataTable MyRst(string strSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
And for the button click on the grid, we have this now:
protected void bView_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
GridViewRow gRow = btn.NamingContainer as GridViewRow;
int? PKID = GridView1.DataKeys[gRow.RowIndex]["ID"] as int?;
// Now load our datalist
string strSQL = "SELECT * from tblHotelsA WHERE ID = " + PKID;
DataList1.DataSource = MyRst(strSQL);
DataList1.DataBind();
// hide grid, show edit area
GridView1.Style.Add("display", "none");
MyEditArea.Style.Add("display", "normal");
}
So, now when we click on a row, we hide grid, show our data list control, and we now see/have this:
And just like the grid view, lets highlight the hotelname and description as light grey. Once again, we now use the data list row data bound event.
Say, this:
Note how we don't use .cells for the data list, but have to use find control.
protected void DataList1_ItemDataBound(object sender, DataListItemEventArgs e)
{
if ( (e.Item.ItemType == ListItemType.Item) |
e.Item.ItemType == ListItemType.AlternatingItem)
{
DataRowView gData = e.Item.DataItem as DataRowView;
if ((bool)gData["Active"])
{
TextBox txtHotel = e.Item.FindControl("txtHotel") as TextBox;
txtHotel.BackColor = System.Drawing.Color.LightSteelBlue;
TextBox txtDescript = e.Item.FindControl("txtNotes") as TextBox;
txtDescript.BackColor = System.Drawing.Color.LightSteelBlue;
}
}
}
And, you do have to check for item, and "alternating" item.
But, now, when we click on a grid row, we get this:
I'm trying to create a web page with the aps.net framework and I connect to the SQL server successfully and I want to display the data from the database in the Grid View and there are a search box and dropdown list but there is an error when I try to search
this is the error message:
Both DataSource and DataSourceID are defined on 'GridView1'. Remove one definition.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: Both DataSource and DataSourceID are defined on 'GridView1'. Remove one definition.
and my code viewpage1.aspx
the GridView
<asp:GridView ID="GridView1" runat="server" BackColor="White" BorderColor="#999999" BorderStyle="Solid" BorderWidth="1px" CellPadding="3" ForeColor="Black" GridLines="Vertical" OnSelectedIndexChanged="GridView1_SelectedIndexChanged" Format="dd/MM/yyyy" AllowSorting="True" AutoGenerateColumns="False" DataKeyNames="InvoiceID" DataSourceID="SqlDataSource3">
<AlternatingRowStyle BackColor="#CCCCCC" />
-and this the sqldatasource
<asp:SqlDataSource ID="SqlDataSource3" runat="server" ConnectionString="<%$ ConnectionStrings:connStr %>" SelectCommand="Select * from [Portal].[fn_GetInvoices] (#SearchText) where CompanyCode=#CompanyCode and InvoiceDate between #fromDate and #toDate">
<SelectParameters>
viewpage1.aspx.cs
sqlcomm.CommandText = sqlquery;
sqlcomm.Connection = sqlconn;
DataTable dt = new DataTable();
SqlDataAdapter adapter = new SqlDataAdapter(sqlcomm);
adapter.Fill(dt);
GridView1.DataSource = dt;
GridView1.DataBind();
This is a common error message.
I OFTEN use the wizards to build a gridview I use this:
From above, I choose create new data source.
I let the wizard run.
BUT THEN we wind up with some MESSAY sqldatasource in the web page. I do NOT like them, and they NEAR ALWAYS just cause you pain.
So, what I will then do this:
Remove the sqldata source from the web markup - you don't' need that mess anyway.
eg this:
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:CSharpWebApp.Properties.Settings.TEST4 %>"
SelectCommand="SELECT [ID], [Fighter], [Engine], [Thrust], [Description], [ImagePath]
FROM [Fighters]"></asp:SqlDataSource>
DELETE the above!!!!
Now WHEN you WILL use code to load up the Gridview? Then you ALSO must turn off (remove) the fact that you NOT GOING to use the sql data source anymore.
So in your GV, remove this:
So, all that error message is telling you is you are trying to set the data source in "code" but you ALREADY have a sql datasource setup in the markup.
So, get in the habit of blowing out and removing the sqldata source on the page, and ALSO remove the GV data source setting in the markup.
So, now say I will have this GV, and NOT have ANY data source in the markup in the web page. (and I recommend you do this). So, I still VERY often use the wizards. Even for a dropdown list, a gridview, repeaters, and even listview (my favorite).
So, run wizards - build the markup
Then blow out (remove) the SqlDataSource, and the
DataSourceID="SqlDataSource1" from the control (in this case gv).
So, as noted, you cannot have BOTH a DataSourceID="SqlDataSource1" and THEN try to use code. It is one or the other - and that's what the error message is telling you.
So, now we have this markup:
(and the wizards generated most of this for me!!!)
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" CssClass="table" >
<Columns>
<asp:BoundField DataField="Fighter" HeaderText="Fighter" />
<asp:BoundField DataField="Engine" HeaderText="Engine" />
<asp:BoundField DataField="Thrust" HeaderText="Thrust" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField HeaderText="View">
<ItemTemplate>
<asp:ImageButton ID="btnImage" runat="server" Height="68px" Width="149px"
OnClientClick ="popimage(this);return false"
ImageUrl = '<%# Eval("ImagePath") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Just nice clean markup - no Sqldatasource junk.
Now we are free to write normal code like a normal human, and we can fill the grid like this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadGrid();
}
void LoadGrid()
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand("SELECT * from Fighters", conn))
{
conn.Open();
DataTable rstData = new DataTable();
rstData.Load(cmdSQL.ExecuteReader());
GridView1.DataSource = rstData;
GridView1.DataBind();
}
}
}
And our results are now this:
Ok, so now lets add a search box above the GV to search the GV.
Say you can type in the first few chars of the Fighter jet name, and we want to filter by that:
So, drop in a text box above the GV, + search button.
We now have say this:
<asp:Label ID="Label1" runat="server" Text="Search for Fighter jet" Font-Size="Large"></asp:Label>
<asp:TextBox ID="txtSearch" runat="server" Style="margin-left:15px" Font-Size="Large"></asp:TextBox>
<asp:Button ID="cmdSearch" runat="server" Text="search"
style="margin-left:15px" CssClass="btn"
/>
<br />
<br />
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" CssClass="table" >
<Columns>
So, now the page with searching looks like this:
Say we search for Lockheed - but even just typing in Lock would be fine.
thus:
And now our code can say be this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadGrid("");
}
void LoadGrid(string MySearch)
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand("SELECT * from Fighters ", conn))
{
if (MySearch != "")
{
cmdSQL.CommandText += #" WHERE Fighter LIKE #Fighter + '%'";
cmdSQL.Parameters.Add("Fighter", SqlDbType.NVarChar).Value = MySearch;
}
conn.Open();
DataTable rstData = new DataTable();
rstData.Load(cmdSQL.ExecuteReader());
GridView1.DataSource = rstData;
GridView1.DataBind();
}
}
}
protected void cmdSearch_Click(object sender, EventArgs e)
{
LoadGrid(txtSearch.Text);
}
}
So, I am STRONG suggesting that you DUMP the sqldata source on the web page markup. Such Sqldata soruces on the page can be great for one time load or data display. But the VERY instant you want control, filters, and need to use code?
Quite much the SAME instant it is time to drop and toss out and remove the data source from the web markup. You be glad you did, and as you can see, you now have 100% EASY AND SIMPLE control of the data you shove into the GV, and that includes endless possible use of simple code and buttons to add filters etc. to that data.
GridView contains ShowDeleteButton CommandField along with other textbox fields.
I'm adding new row to this grid in C# that is adding new textboxes for each newly added row. How to add Delete link while adding new row?
<asp:GridView ID="Gridview1" runat="server" ShowFooter="true" OnRowDataBound="Gridview1_OnRowDataBound"
OnRowDeleting="Gridview1_RowDeleting" AutoGenerateColumns="false" ShowHeaderWhenEmpty="True" EmptyDataText="No Record Available">
<asp:TemplateField HeaderText="Question">
<asp:TextBox ID="txtQuestion" runat="server" Text='<%# Eval("Question") %>'></asp:TextBox>
</asp:TemplateField>
<asp:TemplateField HeaderText="Answer">
<ItemTemplate>
<asp:TextBox ID="txtAnswer" ReadOnly="true" Enabled="false" runat="server" Text='<%# Eval("Answer") %>'></asp:TextBox>
</ItemTemplate>
<FooterStyle HorizontalAlign="Right" />
<FooterTemplate>
<asp:Button ID="btnAddNewQuestionnaire" runat="server" Text="Add New Row" OnClick="btnAddNewQuestionnaire_Click" />
</FooterTemplate>
</asp:TemplateField>
<asp:CommandField ShowDeleteButton="true" />
</Columns>
</asp:GridView>
private void AddNewRow()
{
DataTable dt = new DataTable();
DataRow dr;
dt.Columns.Add(new System.Data.DataColumn("Question", typeof(String)));
dt.Columns.Add(new System.Data.DataColumn("Answer", typeof(String)));
foreach (GridViewRow row in Gridview1.Rows)
{
TextBox txtQuestion = (TextBox)row.FindControl("txtQuestion");
TextBox txtAnswer = (TextBox)row.FindControl("txtAnswer");
dr = dt.NewRow();
dr[0] = txtQuestion.Text;
dr[1] = txtAnswer.Text;
dt.Rows.Add(dr);
}
dt.Rows.Add(dt.NewRow());
dt.Rows[dt.Rows.Count - 1]["Question"] = "";
dt.Rows[dt.Rows.Count - 1]["Answer"] = "";
dt.AcceptChanges();
Gridview1.EditIndex = dt.Rows.Count - 1;
Gridview1.DataSource = dt;
Gridview1.DataBind();
}
I recommend that you simple add the delete button to each row. That way the user can easy delete a row.
I also recommend that you load the grid one time with the datatable, and then add the row to the datatable - NOT the grid.
I could write tuckloads of advantages of this approach. But some advantages are:
user does not get presented with multiple UI
user can edit any row on the grid - not have to hit edit, or save
a single un-do button can un-do all changes
a single SAVE button in ONE operation can save the WHOLE TABLE and change back to database
Your code to add a row, and the code to setup and create the database are seperate. This means that you can change the data table, or even have the source of the table come from sql server. And as noted, this also allows you to save the WHOLE table. The result is the user can edit one rows, many rows - tab around MUCH like a excel spreadsheet. When done, they can:
hit save - all data back to database
hit un-do - un-do all their edits
hit + (add row) - add a new row to edit
hit delete key - it will delete the row in question (but UN-DO STILL ACTIVE!!!).
so we have a far more pleasant way to edit.
And thus, I suggest you don't use the built in delete button. Drop in your own button - it will look nicer anyway. (and thus no edit button required either!!!!).
So, here is our markup:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton ID="ImageButton1" runat="server"
ImageUrl="~/Content/uncheck1.jpg" Height="35px" Width="45px"
OnClick="ImageButton1_Click"
MyRowID = '<%# Container.DataItemIndex %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Question">
<ItemTemplate>
<asp:TextBox ID="txtQuestion" runat="server" Text='<%# Eval("Question") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Answer">
<ItemTemplate>
<asp:TextBox ID="txtAnswer" runat="server" Text='<%# Eval("Answer") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<br />
<asp:Button ID="btnAddNewQuestionnaire" runat="server" Text="+Add New Row" OnClick="btnAddNewQuestionnaire_Click" />
When you drop the button (I used a image button), then in the code editor do this:
Note how RIGHT after you hit "=" then intel-sense pops up - choose create new event. It looks like NOTHING occurs, but if you flip over to code behind, you see a code sub was generated. You can't double click on the controls inside the grid, but you CAN create a event click for a button - or in fact any event for a standard asp.net control this way.
I also to save world poverties also added a custom attribute to that button called MyRowID - this will set the row index for that button.
Since the add new row button is OUTSIDE of the grid, then we can just double click on that button, and jump to the code behind.
Now, our code looks like this:
private DataTable MyTable = new DataTable();
protected void Page_Load(object sender, System.EventArgs e)
{
if (IsPostBack == false)
{
LoadGrid();
ViewState["MyTable"] = MyTable;
}
else
MyTable = ViewState["MyTable"];
}
public void LoadGrid()
{
MyTable.Columns.Add(new DataColumn("Question", typeof(string)));
MyTable.Columns.Add(new DataColumn("Answer", typeof(string)));
GridView1.DataSource = MyTable;
GridView1.DataBind();
}
protected void btnAddNewQuestionnaire_Click(object sender, EventArgs e)
{
DataRow MyRow = MyTable.NewRow;
MyRow("Question") = "my question";
MyRow("Answer") = "my ans";
MyTable.Rows.Add(MyRow);
GridView1.DataSource = MyTable;
GridView1.DataBind();
}
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
ImageButton btn = sender;
int RowID = btn.Attributes.Item("MyRowID");
MyTable.Rows(RowID).Delete();
GridView1.DataSource = MyTable;
GridView1.DataBind();
}
Note VERY carefull - we added a MyTable to the form class. Thus we have a persited table, and we operate against that table.
In fact, the EXACT same above desing can be used if the data came from SQL server. And not only MORE amazing, but we can NOW thus SAVE + SEND the whole table BACK to sql server in one update operation. (you just loop the grid, put values back into table, and execute one save).
And the above has no messy edit button to edit a row. and I suppose we COULD add for extra marks a delete conformation box - the user if they bump or hit delete button, they would get a confirm dialog box. That code could be this:
<asp:ImageButton ID="ImageButton1" runat="server"
ImageUrl="~/Content/uncheck1.jpg" Height="35px" Width="45px"
OnClick="ImageButton1_Click"
MyRowID = '<%# Container.DataItemIndex %>'
OnClientClick="return confirm('Delete this row?');"/>
So now when you hit delete row, you get this:
If you click ok - it deletes - cancel - nothing occurs.
So, you can save a LOT of code and complexity here with:
Persist the data table
Pass the row ID with the button
use the intel-sense trick to wire up a separate and specific button event code.
As noted, this whole above process would ALSO work if you load the table with data from sql server - the REST of the code "as is" will work.
And to save the data back to sql server, then you can as noted:
Pull data from grid back to that persisted table. And then with a data adaptor, ONE update command will send all changes back to sql server.
My question is how can i insert values into gridviews rows.Basically I have created a gridview in which i bound the footer and i want to insert values in the footer.I have create a 'textboxs','dropdownlist' and 'checkboxes'.I want when i insert value and press "Insert" button then values shown in the gridview and again i insert value and press button then show inserted values in the gridview.Here is my gridview image
and i also want to edit and delete rows as well.Here is my code :
aspx code
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
Height="104px" ShowFooter="True" Width="463px"
AutoGenerateDeleteButton="True" AutoGenerateEditButton="True">
<Columns>
<asp:TemplateField HeaderText="Column Name">
<FooterTemplate>
<asp:TextBox ID="name" runat="server"></asp:TextBox>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Data Type">
<FooterTemplate>
<asp:DropDownList ID="DropDownList2" runat="server">
</asp:DropDownList>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Allow Null">
<FooterTemplate>
<asp:CheckBox ID="allow_null" runat="server" />
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Primary Key">
<FooterTemplate>
<asp:CheckBox ID="primary" runat="server" />
</FooterTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and here is my aspx.cs code :
protected void Button1_Click(object sender, EventArgs e)
{
string name = TextBox1.Text;
string type = DropDownList1.Text;
string allow=Null.Text;
string primary = Primary.Text;
name = ((TextBox)GridView1.FooterRow.FindControl("TextBox2")).Text;
type = ((DropDownList)GridView1.FooterRow.FindControl("DropDownList2")).Text;
allow = ((CheckBox)GridView1.FooterRow.FindControl("allow_null")).Text;
primary = ((CheckBox)GridView1.FooterRow.FindControl("primary")).Text;
}
To use the GridView in this way, with input fields in the footer and a Insert Button that is outside the GridView, you need to make a manual Insert.
I don't know how you perform an Insert using the EF model as I don't currently use it. I guess you could say the "old" way is to use an instance of SqlConnection and SqlCommand. You would use code similar to this inside your Button Click event:
// This is VB. C# is similar, you will have to convert where needed
Using connection As New SqlConnection(connectionString)
Using command As New SqlCommand(queryString, connection)
command.Connection.Open()
command.CommandType = // Typically Text or StoredProcedure as needed
command.Parameters.AddWithValue("#parameter_name1", some_value_1)
command.Parameters.AddWithValue("#parameter_name2", some_value_2)
.
.
.
command.ExecuteNonQuery()
End Using
End Using
queryString is your sql INSERT statement or a stored procedure
command.Parameters is a collection of replaceable parameter in your INSERT statement or Stored Proc.
Addendum
A Gridview is a Data bound control so typically when you use a gridview it's bound to some backing data source. If you are not using a database then you are using some other construct.
If you are using, for example, a DataTable, you would add the new rows and columns to the DataTable using its row and column methods and then rebind the DataTable to the Gridview. You don't add rows and columns directly to a GridView.
See this other SO answer by JonH for an example
In case this helps this is based on the ASPSnippets but modified to be more like you might need. Note that instead of using a DataTable I am using a List where "Row" is a class. It is somewhat a matter of personal preference which one you use. The "Row" class is:
[Serializable]
public class Row
{
public string FieldName { get; set; }
public string FieldType { get; set; }
public Boolean FieldNullible { get; set; }
public Boolean FieldPrimaryKey { get; set; }
}
My names are different from your names. Note that the ASPSnippets sample does not use TemplateFields so I am not. I am not sure if you need to make the "allow"
and/or "primary" fields Boolean so I did not process them in the form. So the ASP.Net form I have is:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
Height="104px" Width="463px"
AutoGenerateDeleteButton="True" AutoGenerateEditButton="True">
<Columns>
<asp:BoundField DataField="FieldName" HeaderText="Name" ItemStyle-Width="120" />
<asp:BoundField DataField="FieldType" HeaderText="Type" ItemStyle-Width="120" />
</Columns>
</asp:GridView>
<br /><asp:Label ID="Label1" runat="server" Text="Name:"></asp:Label>
<br /><asp:TextBox ID="txtName" runat="server" />
<br /><asp:Label ID="Label2" runat="server" Text="Type:"></asp:Label>
<br /><asp:TextBox ID="txtType" runat="server" />
<br /><asp:Button ID="btnAdd" runat="server" Text="Add" OnClick="Insert" />
The code-behind is:
protected void Page_Load(object sender, EventArgs e)
{
if (this.IsPostBack)
return;
List<Row> Rows = new List<Row>();
ViewState["Rows"] = Rows;
BindGrid();
}
protected void BindGrid()
{
GridView1.DataSource = (List<Row>)ViewState["Rows"];
GridView1.DataBind();
}
protected void Insert(object sender, EventArgs e)
{
List<Row> Rows = (List < Row >)ViewState["Rows"];
Row r = new Row();
r.FieldName = txtName.Text.Trim();
r.FieldType = txtType.Text.Trim();
Rows.Add(r);
ViewState["Rows"] = Rows;
BindGrid();
txtName.Text = string.Empty;
txtType.Text = string.Empty;
}
One thing I do not like is that the GridView does not show until there is data in it. I assume you can fix that.
This does not implement the editing and deleting.
I have gridview showing columns BusRoute,BusNo and Action.Where action contains the linkbuttons to display another gridview.I want to display it in jquery dialog.My codes are.
ASPX Code:
First Gridview:
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lnkbtn" runat="server" OnClientClick="showDialog();">Shipment Status</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</div>
Second Gridview:
<div class="gridview_stop" id="popup">
<asp:GridView ID="Stops" runat="server" AutoGenerateColumns="False" CellPadding="6" Width="190px">
<Columns>
<asp:BoundField HeaderText="Bus Stop" DataField="StopName" HeaderStyle-BackColor="#006B89">
<HeaderStyle BackColor="#006B89" Font-Size="18px" Font-Bold="false"></HeaderStyle>
<ItemStyle BackColor="#E0E0E0" HorizontalAlign="Center" />
</asp:BoundField>
</Columns>
</asp:GridView>
</div>
Code Behind File:
protected void search_Click(object sender, EventArgs e)
{
DataSet ds = new DataSet();
SqlDataAdapter adapter = new SqlDataAdapter();
con.Open();
SqlCommand cmd = new SqlCommand("spGetRoutes", con);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#BusStop1", Source.Text);
cmd.Parameters.AddWithValue("#BusStop2", Destination.Text);
adapter.SelectCommand = cmd;
adapter.Fill(ds);
adapter.Dispose();
cmd.Dispose();
con.Close();
if (ds.Tables[0].Rows.Count > 0)
{
Route.DataSource = ds.Tables[0];
Route.DataBind();
Stops.DataSource = null;
Stops.DataBind();
Lblmsg.Text = "";
}
else
Lblmsg.Text = "No Direct Bus Between These Stop";
Lblmsg.ForeColor = Color.WhiteSmoke;
Route.Dispose();
Route.DataBind();
Stops.Dispose();
Stops.DataBind();
}
protected void Route_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes["onmouseover"] = "this.style.backgroundColor='aquamarine';";
e.Row.Attributes["onmouseout"] = "this.style.backgroundColor='white';";
e.Row.ToolTip = "Click last column for selecting this row.";
}
}
protected void OnSelectedIndexChanged(object sender, EventArgs e)
{
string Name = Route.SelectedRow.Cells[0].Text;
SqlDataAdapter adapter1 = new SqlDataAdapter();
DataSet ds1 = new DataSet();
string connetionString = "Data Source=.;Initial Catalog=BusService;uid=sa;Password=Murli#925";
SqlConnection connection = new SqlConnection(connetionString);
connection.Open();
SqlCommand cmd = new SqlCommand("spGetStops", connection);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
int BusNo= Convert.ToInt32(Name);
cmd.Parameters.AddWithValue("#BusNo",BusNo);
adapter1.SelectCommand = cmd;
adapter1.Fill(ds1);
adapter1.Dispose();
cmd.Dispose();
connection.Close();
Stops.DataSource = ds1.Tables[0];
Stops.DataBind();
}
Jquery Function:
<script type="text/javascript">
$("#lnkbtn").live("click",
function showDialog() {
$("#popup").dialog({
show: { effect: "fold", duration: 4000 },
hide: { effect: "fold", duration: 4000 },
});
return false;
});
$(document).click(function (event) {
if (!$(event.target).closest('#popup').length) {
if ($('#popup').is(":visible")) {
$('#popup').dialog('close');
}
}
})
</script>
Thanks & Regards.
Take a look at your rendered html when you run the page. Unless you set ClientIDMode to Static I doubt that your button ID's are $("#lnkbtn") but more like $("#gvWhatever_lnkbtn_0")
Set OnClientClick="showDialog();" or $("#lnkbtn").live("click", function showDialog(){...}) no need to do both.
Using a Server Control button to activate a popup usually doesn't work. Especially if GridView Row Selection is enabled. I can't tell if your first GridView has that feature enabled as I only see a portion of the listing. But what tends to happen is you trigger a postback while trying to display the popup so you never see the popup.
Also your second popup contains a gridview, which requires a databind. so you need to make sure the gridview is populated with the data before activating the popup
Two methods for showing a popup using jquery from within a Gridview:
A portion of a GridView markup with 2 TemplateField's
<asp:TemplateField HeaderText="Info">
<ItemTemplate>
<div>
<div class="rs-icon rs-icon-info tooltip-marker" role="button">
</div>
<div id="ContactInfo" style="display:none;">
<table id="tblContactDetail" class="ContactDetail Note">
<tr>
<td style="width: 80px">Name</td>
<td style="width: 100%">
<asp:Literal ID="Literal1" runat="server"
Text='<%# Eval("expert_name") %>' />
</td>
</tr>
.
.
.
</table>
</div>
</div>
<ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="CV">
<ItemTemplate>
<div id="divButtonViewCV" runat="server"
class="rs-icon rs-icon-cv" role="button"
onclick='<%# Eval("expert_cv_id", "ViewPDF({0})") %>' >
</div>
</ItemTemplate>
</asp:TemplateField>
In the above markup I'm setting up for two styles of "popup". The first Template uses jQueryUI ToolTip widget which is activated on mouseover/out. This is nice because it doesn't require a click which means no worries about a postback mucking up the works. The interesting thing here is that I'm using a div as button.
How it works: The div with the .tooptip-marker class is set up to activate a jqueryui tooltip which will display the contents of <div id="ContentInfo"> by grabbing the inner html of the sibling div of the activating button. Note that this div is styled as display:none; so that the content is available for the tooltip but hidden so the main GridView displays as normal.
For brevity, I included only a portion of the content of <div id="ContentInfo">. But It can contain anything really. In my code it's a simple <table> containing contact information fields (using bound <asp:Literal> controls) that are part of the primary GridView data source.
But this could just have easily been an embedded GridView with it's own data source that is bound in the OnRowDatabound event of the primary GridView.
The following jquery sets up the widget. See jQueryUI ToolTip widget for more complete documentation
$( function() {
$( document ).tooltip( {
items: ".tooltip-marker",
content: function() {
return $( this ).next().html();
},
position: {
my: "left top",
at: "right+5 top-5"
}
} )
} );
The second Template field is used to activate a popup. This is where you have to be careful about postbacks. Again I use a <div> styled as an icon and treated as a simple button because I've added onclick.
Clicking this button displays a popup so you can view a persons CV in PDF format. The PDF is stored in our database as a varbinary. Here I use another jquery addon, (colorbox), to display the PDF as a popup over the page.
In the ViewPDF() function below note that we prevent the "bubbling up" of the click event to the GridView by setting cancelBubble = true (for older IE) or a call to stopPropagation() (all other browsers).
In this code, colorbox sets up an iframe and passes the href parameter to its src attribute. I'm making a call to an .ashx page which is an asp Generic Handler which allows us to serve up other type of content without standard web page overhead. This could just as easily been configured to accept a standalone .aspx page where you could maybe place your secondary grid.
// This plain object is used by the call to colorbox(), please
// refer to colorbox documentation for details.
var colorboxDataExpertCV = {
height: "85%",
width: 900,
opacity: .30,
fixed: true,
iframe: true,
returnFocus: false,
href: ''
}
// ========================================================
// In the Template above, the onclick code:
// onclick='<%# Eval("expert_cv_id", "ViewPDF({0})") %>'
//
// Renders to:
// onclick="ViewPDF(12345)"
//
// PdfHandlerExpertsCV.ashx is an GenericHandler that retrieves
// the CV from our database and writes the byte array to the
// colorbox iframe as an "application/pdf" content type which
// triggers native browser pdf management either by internal
// viewer or installed PDF plugin
// ========================================================
function ViewPDF( p ) {
if ( event.stopPropagation )
event.stopPropagation();
else
event.cancelBubble = true;
if ( p && p > 0 ) {
colorboxDataExpertCV.href = "/PdfHandlerExpertsCV.ashx?cvid=" + p;
$.colorbox( colorboxDataExpertCV );
}
return false;
}
Addendum
Let me make it more clear, I need to bind the data in 2nd Gridview and
display this Gridview2 in Jquery dialog .This data will be binded and
displayed in dialog from on the click event of linkbutton inside
Gridview1
As I said above, you cannot bind a GridView (server side event) and then popup a jquery ui dialog (client side event) without introducing much more complexity. You have to make sure all the data you need for the popup is available by the time you're ready to hit the button that opens the dialog.
The simplest way to accomplish this is to embed GridView2 within GridView1 and take care of the binding all at once. It's not pretty or efficient and, depending on the number of items shown in each, can slow down the page. But if you have only a few lines for each it should be acceptable.
Embed GridView2 and DataSource2 in the <ItemTemplate> of a <TemplateField> of GridView1.
Bind GridView2 in the RowDataBound event of Gridview1 using an appropriate row field or datakey field from GridView1 and then calling GridView2.DataBind().
Add a element to the same TemplateField
Refer to the jquery dialog modal form example which shows how to trigger a dialog from a button click. In your case substitute the second GridView for the Form in the example.
IMPORTANT be mindful that gridview row item id's get "mangled" so you should not use id's in the jquery calls but use jquery selectors that are based on element name plus class markers, ie: $("button.marker") for a button defined like this: <button class="marker">.
Addendum: 2015-Jun-24
CSS (<head> tag)
<link rel="stylesheet" type="text/css" href="css/smoothness/jquery-ui.css" />
<script type="text/javascript" src="Scripts/jquery-2.1.4.min.js"> </script>
<script type="text/javascript" src="Scripts/jquery-ui-1.11.4.min.js"> </script>
<style>
.btn_styling {
text-align: center;
width: 32px;
margin: 2px;
cursor: pointer;
border: 1px solid gray;
border-radius: 3px;
/* add a background image to the div
to make the div look like a button */
/* background-image: url('...') */
}
.ui-dialog-titlebar-close {
display: none;
}
</style>
HTML (.aspx)
<form id="form1" runat="server">
<div style="width: 400px;">
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="user_id"
DataSourceID="SqlDataSource1">
<Columns>
<asp:BoundField DataField="user_name" HeaderText="User Name" SortExpression="user_name" />
<asp:TemplateField HeaderText="Info">
<ItemTemplate>
<div id="divButton" runat="server" class="btn_styling dialog-marker" title="This could also have been a <button> element or maybe an <img> element...anything really">X</div>
<div style="display: none;">
<asp:GridView ID="GridView2" runat="server"
AutoGenerateColumns="False"
DataSourceID="SqlDataSource2">
<Columns>
<asp:BoundField DataField="email" HeaderText="Email" SortExpression="email" />
<asp:BoundField DataField="add_edit_date" HeaderText="Date Added" SortExpression="add_edit_date" DataFormatString='{0:dd-MMMM, yyyy}'/>
<asp:BoundField DataField="add_edit_by" HeaderText="Added By" SortExpression="add_edit_by" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource2" runat="server"
ConnectionString="<%$ ConnectionStrings:YourConnectionString %>"
SelectCommand="SELECT email, add_edit_date, add_edit_by FROM tbl_users WHERE (user_id = #user_id)">
<SelectParameters>
<asp:Parameter Name="user_id" />
</SelectParameters>
</asp:SqlDataSource>
</div>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<RowStyle BorderColor="Blue" BorderStyle="Solid" BorderWidth="1px" />
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:YourConnectionString %>"
SelectCommand="SELECT top 10 user_id, user_name from tbl_users">
</asp:SqlDataSource>
</div>
<div id="dialogContainer">
</div>
</form>
Code Behind (VB):
Private Sub GridView1_RowDataBound(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim gv2 As GridView = DirectCast(e.Row.FindControl("GridView2"), GridView)
Dim sds As SqlDataSource = DirectCast(e.Row.FindControl("SqlDataSource2"), SqlDataSource)
sds.SelectParameters("user_id").DefaultValue = GridView1.DataKeys(e.Row.RowIndex).Value
gv2.DataBind()
End If
End Sub
jQuery to implement Dialog:
<script type="text/javascript">
var dialogOptions = {
autoOpen: false,
appendTo: "#dialogContainer",
modal: true,
height: "auto",
width: "auto",
title: "Dialog Title",
closeOnEscape: true,
buttons: {
Cancel: function() {
$( this ).dialog( "close" );
}
}
};
$( function() {
$( ".dialog-marker" ).on( "click", function() {
var d = $( this ).next( "div" ).first().dialog( dialogOptions );
d.dialog( "open" );
} );
} );
</script>