<body>
<asp:Repeater ID="ProductView" runat="server">
<ItemTemplate>
<asp:Label ID="lblOrderId" runat="server" Text='<%# Eval("OrderId") %>' />
<asp:LinkButton ID="bbtnDelete" CssClass="MordersButton" runat="server" UseSubmitBehavior="false" Text='<%#Eval("PaymentStatus") %>'></asp:LinkButton>
<asp:Button ID="btnDelete" runat="server" Text="Delete" OnClick="DeleteRecord" UseSubmitBehavior="false" />
</ItemTemplate>
</asp:Repeater>
<div id="dialog" style="display: none" align="center">
Do you want to delete this record?
</div>
<script type="text/javascript">
$(function () {
$("[id*=btnDelete]").removeAttr("onclick");
$("#dialog").dialog({
modal: true,
autoOpen: false,
title: "Confirmation",
width: 350,
height: 160,
buttons: [
{
id: "Yes",
text: "Yes",
click: function () {
$("[id*=btnDelete]").attr("rel", "delete");
$("[id*=btnDelete]").click();
}
},
{
id: "No",
text: "No",
click: function () {
$(this).dialog('close');
}
}
]
});
$("[id*=btnDelete]").click(function () {
if ($(this).attr("rel") != "delete") {
$('#dialog').dialog('open');
return false;
} else {
__doPostBack(this.name, '');
}
});
});
</script>
</body>
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
FlavorImage1Bind();
}
}
protected void DeleteRecord(object sender, EventArgs e)
{
RepeaterItem item = (sender as Button).Parent as RepeaterItem;
int addressID = int.Parse((item.FindControl("lblOrderId") as Label).Text);
ClientScript.RegisterStartupScript(this.GetType(), "alert", "alert('Record Deleted.')", true);
}
private void FlavorImage1Bind()
{
SqlCommand cmd = new SqlCommand("DC_ManageOrders_Select", cn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#Userid", "1");
cmd.Parameters.AddWithValue("#FilterType", "3");
SqlDataAdapter DA = new SqlDataAdapter(cmd);
DA.Fill(dt);
// dt = sliderhelper.GetsliderImage();
ProductView.DataSource = dt;
ProductView.DataBind();
}
In the repeater control the orderid starts with 1080,
each control has a delete button, I clicked orderid 2031 delete button and in the confirmation dialog box clicked yes.
Once clicked yes the deleted statement gets fired with the orderid 1080 (actually I need to delete the orderid 2031)
Can someone please help to solve this?
Ok, a few things.
First - your title? This is not JUST JavaScript.
You are using jQuery - it should be tagged as such.
You are ALSO using jQuery.UI - it should be tagged as such.
and specific, out of hte jQuery.UI library, you are using the jQuery.UI dialog
Ok, now that been cleared up?
Next up?
I been coding for a long time. As a result, code WHEN possible should avoid things like document.onReady.
And we should try and avoid say having jQuery kind of, sort of, perhaps attach some click event to some button in some magic way. Now, don't get me wrong, document reedy, and magic jQuery selector functions that just run all by themselves like magic? Not too bad, but those that kind of pick out some control and THEN add some click stuff? I telling you now, REALLY make a effort to avoid such code.
This is also why I don't use the bootstrap dialogs. I think they look great, but you specify a bunch of classes - and some how, and somewhere by some feat of magic that makes a dialog pop up? (wow - just TRY to debug that kind of mess). I love bootstrap, but I quite much settled on the jQuery.UI dialog - and now I can write code that humans can read, but MORE important humans can also follow.
Now the key point here? (when we can avoid that fancy footwork, do so! - so this is not always! - but at least try!!!).
So, when building code? We place a button on the form. We have that button when clicked on run some code. And as noted, we should have a simple define of that function to run, and setup that information AT that location, and button in code. The result is code all of a sudden becomes enjoyable and fun again. It also means that you drop in a button, specify the functions to run (client side, and server side). And then you are quite much done.
Ok, next up:
in asp.net, when you use the onClientClick() event, you can VERY nice control if the server button code is to run, or not.
If the js function returns true, then your server side button click code will run (code behind).
And if the js function returns false, then your server side button click code will NOT run.
So, this means we simply want to specify a simple function for that button click, and ALSO a OnClientClick() event is also specified.
That function will return true/false, and that's quite much all we need to do.
Now, of course these days, jQuery.UI (and most new web widgets are async and they don't wait. However, that will not matter here.
so, say markup is this:
<asp:Button ID="btnDelete" runat="server" Text="Delete"
OnClick="DeleteRecord" UseSubmitBehavior="false"
OnClientClick = "return mydeleteprompt(this)" />
The above is ALL you need.
So, if the js function mydeleteprompt returns true, then the server side code you have will run
And VERY NICE that you using the btn.parent trick to get the repeater row - GREAT on your part!!! This is a great idea, and then you just drop in a button, use btn.Parent, and you can then just 100% ignore the repeater event model, and just code as if you dropped any old button on the form, and then attached a server side code behind event.
Love that trick/idea you using. Well done!!!
Ok, so, now lets build that js function - have it pop the jQuery dialog.
<script>
mydelpromptok = false
function mydelprompt(btn) {
if (mydelpromptok) {
return true
}
var myDialog = $("#mydelprompt")
myDialog.dialog({
title: "Confirm delete",
modal: true,
width: "320px",
resizable: false,
appendTo: "form",
autoOpen: false,
buttons: {
ok: function () {
myDialog.dialog("close")
mydelpromptok = true
btn.click()
},
cancel: function () {
myDialog.dialog("close")
}
}
})
myDialog.dialog('open')
return false
}
Note the "trick" here. Since jQuery.UI dialogs do NOT wait, then when you click on that standard asp.net button, the above dialog js routine runs. It will pop the dialog, and of course return false (so the server side code don't run/trigger).
Now, the dialog is displayed. Either you hit the ok button in dialog, or the cancel. Well, for cancel, we just close the dialog - nothing will happen.
But, if we hit Ok? Then we set our flag = true, and simply click the the SAME button again!!!! now the code will call this routine again, but this time, our flag = true, and thus the server side code will run.
So my "fake" coding standard is
function name = mycool()
and thus my flag for such functions will by mycoolok (I add the word "ok" to that function as a simple true/false flag.
But anyway, whatever you like - the trick here is that flag, and thus we save a hairy cat ball of code.
Enjoy:
Edit: ---------------------
Ok, so lets try this without a repeater. Lets do a proof of concept, and ensure that a simple button on a form, and a jQuery.UI dialog works.
So, we drop in a button, a cute "div" that will be the dialog, and then our js code to pop this dialog.
if we answer "ok", then the server side button code will run, if we don't ok /confirm the dialog, we will NOT run the server side code.
So, we have this markup:
<asp:Button ID="cmdDelete" runat="server" Height="30px"
OnClick="Button1_Click" Text="Dialg test" Width="130px"
OnClientClick="return mydialog(this)" ClientIDMode="Static"/>
<div id="MyFunDialog" style="display:none">
<h2>Really do the button click?</h2>
<h3>Ok = run server buttion</h3>
<h3>cancel - don't run button code</h3>
</div>
<script>
myokok = false
function mydialog(btn) {
if (myokok) {
return true
}
// lets pop jquery.UI dialog
var mydiv = $("#MyFunDialog")
mydiv.dialog({
modal: true, appendTo : "form",
title: "Really do this?", closeText : "",
width: "400px",
buttons: {
' ok ': function () {
mydiv.dialog('close')
myokok = true
btn.click() // click button again
},
' cancel ': function () {
mydiv.dialog('close')
}
}
});
return false
}
</script>
And then we click on the button - lets wire up the server side (code behind) for this example. Our button code will thus be this:
protected void Button1_Click(object sender, EventArgs e)
{
Response.Write("<h2>This is the server button click</h2>");
}
ok, now when we run this test simple example? you get this:
So, get the above working. Start blank page - test that you have jQuery.UI installed and working.
once you get the above working, then you can use the approach in your application over and over - it is a GREAT design pattern.
Now ONLY when you are able to get the above working?
Ok, then, lets try this with a repeater, and see how it works much the same.
--------- repeater example ----------------
Now, as noted, if you do this inside of a repeater ? It quite much the same.
With a repeater, we would have say this:
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<div style="border-style:solid;color:black;width:300px;float:left">
<div style="padding:5px;text-align:right">
Hotel Name: <asp:TextBox ID="txtHotelName" runat="server" Text ='<%# Eval("HotelName") %>' Width="150px" />
<br />
First Name: <asp:TextBox ID="txtFirst" runat="server" Text ='<%# Eval("FirstName") %>' Width="150px" />
<br />
Last Name: <asp:TextBox ID="txtLast" runat="server" Text ='<%# Eval("LastName") %>' Width="150px" />
<br />
City: <asp:TextBox ID="txtCity" runat="server" Text ='<%# Eval("City") %>' Width="150px" />
<br />
Active: <asp:CheckBox ID="chkActive" runat="server" Checked = '<%# Eval("Active") %>'/>
<asp:HiddenField ID="PK" runat="server" Value = '<%# Eval("ID") %>'/>
<asp:Button ID="cmdDelete" runat="server" Text="Delete" style="margin-left:20px"
OnClientClick="return mydelprompt(this)"
OnClick="cmdDelete_Click"/>
</div>
</div>
<div style="clear:both;height:4px"></div>
</ItemTemplate>
</asp:Repeater>
</div>
<div id="mycoolconfirmdialog" style="display:none">
<h2>About to delete hotel</h2>
<h3>This cannot be un-done</h3>
</div>
<script>
myokok = false
function mydelprompt(btn) {
if (myokok) {
return true
}
// lets pop jquery.UI dialog
var mydiv = $("#mycoolconfirmdialog")
mydiv.dialog({
modal: true, appendTo : "form",
title: "Confirm delete of Hotel", closeText : "",
width: "400px",
buttons: {
' ok ': function () {
mydiv.dialog('close')
myokok = true
btn.click() // click button again
},
' cancel ': function () {
mydiv.dialog('close')
}
}
});
return false
}
</script>
And our code to load this looks like this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadData();
}
}
public void LoadData()
{
using (SqlCommand cmdSQL = new SqlCommand("SELECT * FROM tblHotels ORDER by HotelName",
new SqlConnection(Properties.Settings.Default.TEST4)))
{
cmdSQL.Connection.Open();
Repeater1.DataSource = cmdSQL.ExecuteReader();
Repeater1.DataBind();
}
}
And now lets add (fill out) the delete button code:
protected void cmdDelete_Click(object sender, EventArgs e)
{
// delete the row from database
Button btn = (Button)sender;
RepeaterItem gRow = (RepeaterItem)btn.Parent;
string PK = ((HiddenField)(gRow.FindControl("PK"))).Value;
using (SqlCommand cmdSQL = new SqlCommand("DELETE FROM tblHotels WHERE ID = #ID",
new SqlConnection(Properties.Settings.Default.TEST4)))
{
cmdSQL.Parameters.Add("#ID", SqlDbType.Int).Value = PK;
cmdSQL.Connection.Open();
cmdSQL.ExecuteNonQuery();
}
LoadData(); // re-load repeater
}
note very careful - we had to add a hidden field to hold the database PK "id". If you are concerned about security and don't want the PK id to be existing in the client browser side? Then dump the Repeater, and use a ListView. They work VERY similar - almost identical, but ListView (and grid views) have DataKeys option to hold the PK - and thus you do NOT have to put the PK in the markup, or expose it to client side.
Regardless, the results now look like this:
Try changing this.name in the line where you do __doPostBack to
__doPostBack(this.id, '');
You are sending the name of the button which would be the same for each of the items in the repeater, the id is unique. It may be the reason why the first item is the one that is deleted.
I'm trying to upload a file onchange event of the "Fileupload" control inside gridview.
Means when ever user uploads the file, there itself I needs to save the file content in DB.
So, I had mannually called the click event of the button control on the change of fileupload control But its throwing as like exception like "Invalid postback or callback argument...."
my gridview code :
<asp:GridView runat="server" ID="grd" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="StudentID" HeaderText="Student ID" />
<asp:BoundField DataField="StudentName" HeaderText="Name" />
<asp:TemplateField HeaderText="Upload">
<ItemTemplate>
<asp:FileUpload ID="FileUpload1" runat="server" EnableViewState="true" onChange="FileUploadCall(this)" />
<asp:Button ID="btnUpload" Text="Upload" runat="server" OnClick="Upload" Style="display: none" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
My script Code :
<script type="text/javascript">
function FileUploadCall(fileUpload) {
if (fileUpload.value != '') {
var a = $('#<%=grd.ClientID %>').find('[id*="btnUpload"]');
a.click();
}
}
</script>
My Hidden Button mannual click creation in cs file :
protected void Upload(object sender, EventArgs e)
{
Button btn = sender as Button;
GridViewRow gvr = (GridViewRow)btn.Parent.Parent;
FileUpload lbleno = (FileUpload)gvr.FindControl("FileUpload1");
lbleno.SaveAs(Server.MapPath("~/Uploads/" + Path.GetFileName(lbleno.FileName)));
//lblMessage.Visible = true;
}
Your jquery code that gets the button to upload may be the reason.
Since you said you are using a gridview, so there could be multiple rows each having its own fileupload and button controls. You need to get the button control associated with this row in grid view. To get the associated button, you should be using the jquery code like below, since the associated button immediately follows the fileupload control.
if (fileUpload.value != '') {
var a = $(fileUpload).next("[id*='Button1']");
a.click();
}
The easiest way is to assign the onchange event from code behind so you can get the correct button easily. So create a RowDataBound event for the GridView.
<asp:GridView ID="grd" runat="server" OnRowDataBound="grd_RowDataBound">
Then in the RowDataBound method, use FindControl to locate and cast the FileUpload and the Button. In the method you can assign the change event to trigger a PostBack of the corresponding button.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
//check if the row is a datarow
if (e.Row.RowType == DataControlRowType.DataRow)
{
//use findcontrol to locate the controls in the row and cast them
Button btn = e.Row.FindControl("btnUpload") as Button;
FileUpload fu = e.Row.FindControl("FileUpload1") as FileUpload;
//assign the button postback to the change of the fileupload
fu.Attributes.Add("onchange", "__doPostBack('" + btn.UniqueID + "','')");
}
}
Your implementations is fine only change:
a.click(); => a[0].click(); //important!!
and I hope no binding is happening in the postback:
if (!IsPostBack)
{
var list = new List<Student>();
list.Add(new Student() {StudentID = 1, StudentName = "111"});
list.Add(new Student() {StudentID = 2, StudentName = "222"});
grd.DataSource = list;
grd.DataBind();
}
I've tested it works totally fine!
I have Parent repeater which contains another child repeater.
For simplicity let's say that the child repeater contains text box and Requiredvalidator.
Simple example of the markup:
<asp:Repeater ID="rpt1" runat="server">
<HeaderTemplate>
....
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="lbl1" runat="server" CssClass=".."></asp:Label>
<div class="..">
<asp:Repeater ID="rpt2" runat="server">
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
<div class="...">
<asp:TextBox ID="txt21" runat="server" CssClass="..." MaxLength="7" CssClass="ErrorMessage" ErrorMessage="*" />
<asp:RequiredFieldValidator ID="rfv21" runat="server" CssClass="ErrorMessage" ErrorMessage="*" />
</div>
</ItemTemplate>
<FooterTemplate>
</FooterTemplate>
</asp:Repeater>
</div>
</ItemTemplate>
<FooterTemplate>
</FooterTemplate>
</asp:Repeater>
I create a method like this to get the second repeater's RequiredField id:
function getId(){
var myId = document.getElementById('<%= rfv21.ClientID %>');
}
but of course it didn't work and there was an exception:
The name control-name Does Not Exist in the Current Context
So how can i do this?
I want to mention that the business need for me is that when the onchange, onkeyup, onkeydown events fires for the txt21 it will get it's equivalent rfv21 and enbale it:
I create this method which fires for onchange, onkeyup, onkeydown events changed:
function txt21_onChange(txtbox) {
var newValue = this.value;
var oldValue = this.oldvalue;
var myRfv2 = document.getElementById('<%= rfv2.ClientID %>');
if (newValue != oldValue) {
ValidatorEnable(myRfv2, true);
}
}
and i update txt21 to be:
<asp:TextBox ID="txt21" runat="server" CssClass=".." MaxLength="7" onkeyup="javascript: txt21_onChange(this);this.oldvalue = this.value;" />
but this line want work:
var myRfv2 = document.getElementById('<%= rfv2.ClientID %>');
as i explained before.
I think Item.FindControl(..) may help but how can we use it in this case?
You can bind the javascript function call from Repeater Repeater.ItemDataBound event.
Code Bahind
void R1_ItemDataBound(Object Sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
TextBox txt21 = (TextBox)e.Item.FindControl("txt21");
RequiredFieldValidator rfv21 = (RequiredFieldValidator)e.Item.FindControl("rfv21");
txt21.Attributes.Add("onclick", "txt21_onChange('" + txt21.ClientID + "','" + rfv21.ClientID + "'" )
}
}
Javascript
function txt21_onChange(txt21ID, rfv21ID)
{
txt21ID = document.getElementById(txt21ID);
rfv21ID = document.getElementById(rfv21ID);
//The above are TextBox and RequiredFieldValidator objects of row of TextBox that triggered change event.
//You can use these object
}
The problem here is that there going to be many such controls, one per each row of each child repeater. All will have slightly different generated IDs. So instead of querying them by id (impossible), you can use jQuery to quickly find them relatively to the txt that fired an event:
function txt21_onChange(txtbox) {
var rfv2 =
$(textbox) // gives you the jquery object representing the textbox
.closest("div") // the parent div
.find("id*='rfv2'"); // the element you are looking for, id contains rfv2
This answers the immediate question in this thread on how to get hold of the element. But I am not sure it will solve your bigger problem of enabling/disabling validation. You cannot easily do so with server side controls in javascript. Besides, validator is not disabled by default in your code. Although I believe all this is worth a separate question here on SO>
I have a button with OnClick event on my web page.
<asp:TextBox ID="tbMailID" runat="server" Width="250px"></asp:TextBox>
<asp:Button ID="btnSubmit" runat="server" OnClick="btnSubmit_Click" Text="Submit" />
C# code:
protected void btnSubmit_Click(object sender, EventArgs e)
{
bool IsGmail = CheckMailId(tbMailID.Text);
if(!IsGmail)
{
string strScript = "confirm('Mail id is not from gmail, do you still want to continue?');";
ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "strScript", strScript, true);
}
SendMail();
}
The page accepts a mail id in textbox and on submit sends a mail.
But if mail-id is not an gmail id (validated by CheckMailId) i want to show a confirmation box to user whether he/she wants to get a mail, based on the Yes/No clicked.
But the javascript will get call after the submit event is served and mail is sent.
if i add a return SendMail() will never get calls
ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "strScript", strScript, true);
return;
What could be a possible solution here?
Note: the code posted is simplified version of my real use case.
CheckMailId - is just a name to show, it calls up many other functions and do few db process. So incorporating that in javascript, i would like to avoid.
You can call a script befroe event lke this:-
<script type="text/javascript">
function Confirm() {
var yourstring = document.getElementById('<%= tbMailID.ClientID %>').value;
if (/#gmail\.com$/.test(yourstring)) {
return true;
}
else
{
if (confirm("Mail id is not from gmail, do you still want to continue?") == true)
return true;
else
return false;
}
}
</script>
strong text
<asp:Button ID="btnSubmit" runat="server" OnClientClick="return Confirm();" OnClick="btnSubmit_Click" Text="Submit" />
I have the following code:
<telerik:GridTemplateColumn DataField="JOB_CODE"
<EditItemTemplate>
<input type="text" ID="JOB_CODETextBox" runat="server"
value='<%# Eval("JOB_CODE") %>' readonly="readonly"
onclick="$('#basic-modal-content').modal({
appendTo:'form', persist: true,
onClose: function (dialog)
{
/*
I want to assign here a value to the textbox control
like this: JOB_CODETextBox = 'something...'
I tried this:
$find('<%= JOB_CODETextBox.ClientID %>').value = 'something..'
but it didn't work!! the find function returns [null]
*/
$.modal.close();
}
} );" />
Any help!!
This should work:
$('#'+'<%= JOB_CODETextBox.ClientID %>').val('something');
or (C# only):
$('<%= "#" + JOB_CODETextBox.ClientID %>').val('something');
or using JavaScript/ECMAScript:
document.getElementById('<%= JOB_CODETextBox.ClientID %>').value = 'something';
I'm not familiar with the telerik control you are using so I'm going to assume it's similar to other databound controls. Operating with that in mind, here is an example using a Repeater control.
here's the markup
<asp:Repeater ID="rpt1" runat="server">
<ItemTemplate>
<input type="text" id="JOB_CODETextBox" runat="server" />
</ItemTemplate>
</asp:Repeater>
in this situation, I usually generate the javascript server side.
System.Text.StringBuilder js = new StringBuilder();
js.AppendLine(" <script>");
// we'll store all the control references in a list
// since there will be one for each item in the repeater
js.AppendLine(" var JOB_CODETextBox_list = [];");
for (int j = 0; j < this.rpt1.Items.Count; j++)
{
System.Web.UI.HtmlControls.HtmlGenericControl JOB_CODETextBox;
// try to locate the copy of the control local to each item
JOB_CODETextBox = (HtmlGenericControl)this.rpt1.Items[j].FindControl("JOB_CODETextBox");
if (JOB_CODETextBox != null) // make sure you found something
{
js.AppendFormat("JOB_CODETextBox_list.push(document.getElementById('{0}'));", JOB_CODETextBox.ClientID);
js.AppendLine();
}
}
js.AppendLine(" </script>");
this.Page.ClientScript.RegisterStartupScript(typeof(Page), "JOB_CODE", js.ToString(), false);
that should generate a script that gets a reference to all instances of that input control within the Repeater. after it runs, you can access the items client side like
JOB_CODETextBox_list[n].value = 'something';