I have a Gridview with buttons for removing data rows. I'm trying to implement a modal popup via jQueryUI Dialog so that after clicking "Remove Data" the user gets prompted and if they click yes, the row gets removed, if no, nothing happens. It seems that if I don't add a "return false" to the onClientClick, the row will be removed as soon as the button is clicked, regardless. If I include return false, I'm not sure how I can get the gridviewrow command to actually happen. Here are some current snippets:
In script tag:
function ShowPopup() {
$(function () {
var message = "Are you sure you want to Remove Data?";
$("#dialog").html(message);
$("#dialog").dialog(
{
title: "Data Removal Confirmation",
buttons: {
Yes: function () {
return true;
},
No: function () {
$(this).dialog('close');
}
},
modal: true
});
});
}
Dialog Div:
<div id="dialog" style="display: none">
Gridview Button:
<asp:TemplateField HeaderText="Reject">
<ItemTemplate>
<asp:Button
ID="btnRemove"
runat="server"
Text="Remove Data"
CssClass="inherited, RemoveData"
CommandName="RemoveData"
Style="white-space: normal;"
OnClientClick="javascript: ShowPopup();return false;"
CommandArgument="<%# ((GridViewRow) Container).RowIndex %>" />
</ItemTemplate>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:TemplateField>
Codebehind:
else if (e.CommandName == "RemoveData")
{
int affected = 0;
affected = DAL.RemoveFileUploadItem((Guid)Session["UserId"], UploadId.ToString());
BindAll();
gv_PostUpload.DataSource = null;
string FileName = UploadId.ToString() + "-" + gvDashboard.DataKeys[index]["FileName"].ToString();
string mypath = Path.Combine(Global.data_directory, #"Watch"); // Server.MapPath("~/Data/Watch/");
string totalfn = Path.Combine(mypath, FileName);
if (File.Exists(totalfn))
File.Delete(totalfn);
DAL.LogActivity("Attempt removing file " + gvDashboard.DataKeys[index]["FileName"].ToString(), Utilities.GetCurrentPageFromURL(), Session["UserId"].ToString());
int affected = 0;
affected = DAL.RemoveFileUploadItem((Guid)Session["UserId"], UploadId.ToString());
if (affected != 0)
{
DAL.LogActivity(gvDashboard.DataKeys[index]["FileName"].ToString() + " removed ", Utilities.GetCurrentPageFromURL(), Session["UserId"].ToString());
}
BindAll();
gv_PostUploadZ.DataSource = null;
plnView.Visible = false;
plnViewZ.Visible = false;
plnErrorView.Visible = false;
}
Here are the modified buttons based on #albert-d-kallal's answer:
<asp:TemplateField HeaderText="Reject">
<ItemTemplate>
<asp:Button
ID="btnRemove"
runat="server"
Text="Remove Data"
CssClass="inherited, RemoveData"
CommandName="RemoveData"
CommandArgument="<%# ((GridViewRow) Container).RowIndex %>" />
</ItemTemplate>
<ItemTemplate>
<asp:Button
ID="btnRemove2" ClientIDMode="Predictable"
runat="server"
Text="Remove Data"
CssClass="inherited, RemoveData"
Style="white-space: normal;"
OnClientClick='<%# "ShowPopUp(" + ((GridViewRow) Container).RowIndex + ");return false;" %>' />
</ItemTemplate>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:TemplateField>
After the above modification, here is what I now am seeing n browser tools when inspecting that the button:
<input type="submit" name="ctl00$mainContent$gvDashboard$ctl02$btnRemove2" value="Remove Data" onclick="ShowPopUp(0);return false;" id="ctl00_mainContent_gvDashboard_ctl02_btnRemove2" class="inherited, RemoveData" style="white-space: normal;">
Ok, first up?
jQuery.ui and MOST web code these days is NON blocking. That means the jQuery.UI dialog DOES NOT halt code. Near all code runs - and runs without blocking (async).
So, if you use anything but the alert() dialog, you can't block code, and return true, or false.
So, what to do?
Well, it means we have to display the dialog, and THEN AFTER the user makes the choice, we have to fire/trigger/click/run code to do the delete.
So, I would suggest that your delete button does NOT run the row index changed, and execute that code. In theory, you would say pass some PK row value to the js on a click. Get the yes/no using the jQuery dialog, and THEN call some code to do the delete.
So, that button can not really return true/false to THEN allow the button code (server side) to run.
I can think of quite a few ways to do this. However, you can trick the grid, and have jQuery "click" on the button AFTER you determined yes (ok) or cancel.
This quite much means we need a "differnt" button. But, we could just "hide" the existing delete button (but leave it in place), and simply place our javascrip button right below that button.
So, lets hide your button with style="display:none" (FYI - can't use visible, since that would mean the browser never renders the button).
So, lets do this:
<asp:TemplateField>
<ItemTemplate>
<asp:Button
ID="btnRemove"
runat="server"
Text="Remove Data"
style="Display:none"
CommandName="RemoveData"
CommandArgument="<%# ((GridViewRow) Container).RowIndex %>" />
</ItemTemplate>
</asp:TemplateField>
so we style button = none (it will not display). I also removed the CssClass - again since the button is "hidden", we don't care.
Now, lets drop in our button that we REALLY click on!
Lets put it right below above in the markup:
<asp:TemplateField>
<ItemTemplate>
<asp:Button
ID="btnRemove2"
runat="server"
Text="Remove Data"
CssClass="inherited, RemoveData"
Style="white-space: normal;"
OnClientClick='<%# "ShowPopUp(" + Container.DisplayIndex.ToString + ");return false;" %>'
</ItemTemplate>
</asp:TemplateField>
So, above is a dummy button - note the return = false; we don't want it to run any sever side code - and the return = false means no post back occurs.
But, NOTE one big deal? We passed the row index to that click event.
So, our jQuery.ui dialog can now look like this:
function ShowPopUp(ix) {
var message = "Are you sure you want to Remove Data?";
var mydiv = $('#dialog');
mydiv.html(message);
mydiv.dialog({
autoOpen: false, modal: true, title: 'Data Removal Confirmation', width: '30%',
position: { my: 'top', at: 'top+150' },
buttons: {
'Yes': function () {
// first, close the dialog
$('#dialog').dialog('close');
btn = $('#GridView1_btnRemove_' + ix.toString());
btn.click();
},
'No': function () {
$('#dialog').dialog('close');
}
}
});
// Open the dialog
mydiv.dialog('open');
}
Note how now we have code for the ok, and cancel buttons.
Note how we have to close the dialog.
And note that last whopper - we select the button based on the row, and click it.
Now, I not really sure if above is the best. I would perhaps consider NOT using the fake button click - Might have just as well done a js postback and passed the row index with a postback argument. (this would mean in the page on-load event, you would pick this post-back up - you can google _dopostback().
Note also one did not need the "script" in front of the OnClickClick.
But, the above should work.
So, keep in mind:
the jQuery.ui code is NON blocking - it does not wait. When you call it, it runs right though and THEN displays the dialog - the code does not halt, nor is it blocked. As a result, we can't return true, or false (to allow the server side code to run).
If the jQuery.ui dialog WAS blocking, then the return of true/false could be used - but that code does not block/wait.
But, by passing the row index, we ARE able to select the hidden button, and click() fire it. As noted that's somewhat ok of "approaching a kluge" idea here. However, since you KNOW existing code works, that's why I went with the button click trick here.
I used GridView1, as the grid name - change it to what you are using.
Ok, it's a bit hacky, but I was able to use some of #albert-d-kallal's suggestions above, but had to come up with some other code that would anchor the correct rowindex values to the actual buttons that were wired to the .Net event handlers. I did this by just making the "fake/hidden" buttons have a text value of the row index. In order to hide the column that .Net creates for that button, I had to use some custom CSS. Here are the final code snippets:
JS:
function ShowPopUp(ix) {
$(function () {
var message = "Are you sure you want to Remove Data?";
var mydiv = $('#dialog');
mydiv.html(message);
mydiv.dialog(
{
//autoOpen: false,
title: "Data Removal Confirmation",
modal: true,
width: '30 %',
position: { my: 'top', at: 'top+150' },
buttons: {
Yes: function () {
// first, close the dialog
$('#dialog').dialog('close');
btn = $("[id$=btnRemove]")[ix.toString()];
btn.click();
},
No: function () {
$('#dialog').dialog('close');
}
},
});
});
}
Item Templates for the buttons:
<asp:TemplateField ControlStyle-CssClass="visiblyHidden" FooterStyle-CssClass="visiblyHidden" HeaderStyle-CssClass="visiblyHidden" ItemStyle-CssClass="visiblyHidden" HeaderText="">
<ItemTemplate>
<asp:Button
ID="btnRemove"
runat="server"
Text='<%# ((GridViewRow) Container).RowIndex + "" %>'
CssClass="inherited, RemoveData"
CommandName="RemoveData"
CommandArgument="<%# ((GridViewRow) Container).RowIndex %>" />
</ItemTemplate>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:TemplateField>
<asp:TemplateField HeaderText="Reject" FooterStyle-CssClass="rejectHideLeftBorder" HeaderStyle-CssClass="rejectHideLeftBorder" ItemStyle-CssClass="rejectHideLeftBorder">
<ItemTemplate>
<asp:Button
ID="btnRemove2"
runat="server"
Text="Remove Data"
ClientIDMode="Static"
Style="white-space: normal;"
OnClientClick='<%# "ShowPopUp(" + ((GridViewRow) Container).RowIndex + ");return false;" %>' />
</ItemTemplate>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:TemplateField>
CSS:
.visiblyHidden {
width: 0 !important;
padding: 0 !important;
border: 0 !important;
}
.rejectHideLeftBorder {
border-left: 0 !important;
}
My problem is after I click a button in update panel and close the window, "beforeunload" event not fire, while when I click another button this event fires properly.
Here is my code:
function dontlogout() //for postback refreshes
{
postback = true;
alert(postback);
}
$(window).bind('beforeunload',function() {
if(postback==false)
{
//my logout code here;
}
else
{
postback = false;
}
});
<asp:Button runat="server" ID="cmdOut" OnClientClick="dontlogout();" Text="next" OnClick="cmdOut_Click"></asp:Button>
<asp:UpdatePanel runat="server" ID="updQuestion" >
<ContentTemplate>
<asp:Button runat="server" ID="cmdNext" OnClientClick="dontlogout();" Text="next" OnClick="cmdNext_Click"></asp:Button>
</ContentTemplate></asp:UpdatePanel>
when i click cmdOut button no problem and when close browser my log out code executed, but when i click cmdNext in update panel and then close the browser my log out code not executed.
How can I solve this problem?
You have to return in the function callback of onbeforeunload
$(window).bind('beforeunload',function() {
if(postback==false)
{
//my logout code here;
// 👈🏼 Ok you can leave because you dont return
}
else
{
postback = false;
return "You cannot leave"; //👈🏼 You cannot leave
}
});
Add the 'Triggers' tag just before the end tag of the update panel
<asp:UpdatePanel runat="server" ID="updQuestion" >
<ContentTemplate>
<asp:Button runat="server" ID="cmdNext" OnClientClick="dontlogout();" Text="next" OnClick="cmdNext_Click"></asp:Button>
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="cmdNext" />
</Triggers>
</asp:UpdatePanel>
SCRIPT
<script type="text/javascript">
$(function () {
$(".ttip").hide();
$(".txttwo").keyup(
function () {
var one = $(this).val();
$(".ttip").fadeIn().text(one);
});
$(".txttwo").blur(
function () {
var one = $(this).val();
$(".ttip").hide();
});
});
</script>
CODE:
<asp:GridView ID="GridView1" runat="server" EnableModelValidation="True">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<p class="ttip bubble" class="bubble"></p>
<asp:TextBox ID="abc" class="txttwo tipin" runat="server" ></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
FIDDLE
http://jsfiddle.net/w96LX/7/
Also it would be just great if someone can tell me how can I set the width of bubble such that it expands according to the length of text.
I get tooltip for all the textboxes because I have used class. I need to show tooltip just for the one at a time.
Just use $(this).attr("id") to get the ID of an element. Also, apped display:inline-block; width: auto; to make the bubble as big as the content: http://jsfiddle.net/w96LX/26/
Update:
I did not see an ID in your HTML, just the server side code. You will need to append the ID to a HTML element to receive it. Or you generate inline javascript, that is calling a method to set the ID.
I call the following javascript function in an update panel which refresh my page although it is in an update panel!!
<script type="text/javascript" language="javascript">
function get_emp_num(source, eventArgs) {
var txt_emp_num = "<%= txt_RequestEmpNum.ClientID %>";
document.getElementById(txt_emp_num).value = eventArgs.get_value();
__doPostBack("<%=txt_RequestEmpNum.ClientID %>");
}
function get_person_num(source, eventArgs) {
var txt_person_num = "<%= txt_RequestPersonNum.ClientID %>";
document.getElementById(txt_person_num).value = eventArgs.get_value();
__doPostBack("<%=txt_RequestPersonNum.ClientID %>");
}
</script>
I don't want this script to change the partial post back behavior of my update panel .how to do that ?
What is your postback control and is it setup as an async trigger on the update panel? Based on the code you posted, I suspect that txt_RequestEmpNum and txt_RequestPersonNum are text boxes. Those controls don't natively support postbacks. What you need is a hidden button on the page that your javascript will "click" to send the postback. Something like this:
<asp:UpdatePanel ID="UpdatePanel2" runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" />
</Triggers>
<ContentTemplate>
<asp:TextBox ID="txt_RequestEmpNum" runat="server" />
<asp:TextBox ID="txt_RequestPersonNum" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
<div style="display: none;">
<asp:Button id="Button1" runat="server" OnClick="Button1_Click" />
</div>
<script>
function get_emp_num(source, eventArgs) {
// I am unsure what your intent was with the code here so I removed it
__doPostBack("<%=Button1.UniqueID %>", "");
}
function get_person_num(source, eventArgs) {
// I am unsure what your intent was with the code here so I removed it
__doPostBack("<%=Button1.UniqueID %>", "");
}
function refresh_using_jquery() {
__doPostBack($('#<%=Button1.ClientID %>').attr('name'), '');
}
</script>
If you're looking to not do a full page postback then you'll want to implement a solution that uses AJAX. I would go with using jQuery because it makes using AJAX somewhat easier (in my opinion, anyway).
I've designed a web page in asp.net. And in that page i placed html control too like <a> & <div>. I have written one java script function which is hiding the <div> when i'm clicking on the <a> tag. Its working fine. But when i'm clicking on the asp.net button then page refresh occur again. And it is loading my previous design of the page. I set the display:none of the <div> at the design time. so it is hiding my <div> again when occuring any other server side event. And i don't want let it happen.
Javascript function-
<script language="javascript" type="text/javascript">
function toggle5(showHideDiv, switchTag) {
try {
'<%Session["temp"] = "'+more+'"; %>';
var ele = document.getElementById(showHideDiv);
var imageEle = document.getElementById(switchTag);
if (ele.style.display == "block") {
ele.style.display = "none";
imageEle.innerHTML = 'More';
}
else {
ele.style.display = "block";
imageEle.innerHTML = 'Less';
}
}
catch (err) {
alert("Error");
}
}
</script>
html code is-
<div id="divSearch" style="float:left;height:100%;width:100%;">
<span style="float:right;height:27px;"><a id="displayText" href="#" onclick="javascript:toggle5('toggleText', 'displayText');">More</a></span>
</div>
<div id="toggleText" style="display:none;height:100%;width:100%;">
<div id="divCalls" style="width:24%;float:left;height:30%;">
<span style="float:left;width:100%;color:#3b5998;">
<asp:CheckBox ID="chkNoCall" runat="server" Text="No call made in "
AutoPostBack="True" oncheckedchanged="chkNoCall_CheckedChanged"/>
<asp:TextBox ID="txtNoCall" runat="server" Width="12%" Enabled="False"></asp:TextBox><span> days</span></span>
</div>
</div>
C#.net code of the Checkbox-
protected void chkNoCall_CheckedChanged(object sender, EventArgs e)
{
if (chkNoCall.Checked == true)
{
txtNoCall.Enabled = true;
}
else
{
txtNoCall.Enabled = false;
txtNoCall.Text = "";
}
}
How to solve this problem?
thanks
put this data inside the updatepanel like this
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<span style="float:left;width:100%;color:#3b5998;">
<asp:CheckBox ID="chkNoCall" runat="server" Text="No call made in "
AutoPostBack="True" oncheckedchanged="chkNoCall_CheckedChanged"/>
<asp:TextBox ID="txtNoCall" runat="server" Width="12%" Enabled="False"></asp:TextBox><span> days</span></span>
</ContentTemplate>
</asp:UpdatePanel>
hope this help
In your button click event, return false. this will prevent postback.
Use ajax to get the server side data instead of submitting the page.
Try one of the following:
remove runat=server from the component (a component with runat=Server always submits a form.
use standard html controls
use javascript for html controls
it it's a component with autopostback feature; make autopostback=false