Converting from OnClientClicking to onClientClick - javascript

I currently have a JavaScript method that looks to see if the page is validated and if so allows the user to press a create button and throws a radconfirm, the problem i am having is that if i use a radButton this works perfectly but when using an ASP:Button it wont allow the radConfirm to show up and skips past it.
This is the method:
function ShowConfirm(clickedButton, args) {
var validated = window.Page_ClientValidate('POPgroup');
if (validated)
{
args.set_cancel(true);
function confirmCallBackFn(arg) {
if (arg == true) {
clickedButton.click();
}
}
var text = "Please make sure all fields are completed correctly as once" +
" accepted the proof of purchase will be submitted and no further " +
"changes will be allowed. Are you sure you wish to continue?";
radconfirm(text, confirmCallBackFn,350,100,null,"Confirm");
}
}
This is the button:
<asp:Button ID="AddProofOfPurchaseButton" runat="server" Text="Submit"
ValidationGroup="POPgroup" CssClass="claim_header_create_button"
OnClick="AddProofOfPurchaseButton_OnClick" OnClientClick="ShowConfirm(this);
return false;" />
How would i change this code to work with the asp button and not the radbutton? also why does this happen what is the difference between OnClientClicking(Telerik) to onClientClick(asp)

For anyone else that stumbles across the same problem the answer i found to my problem was this.
function ShowConfirm(button) {
var validated = window.Page_ClientValidate('POPgroup');
if (validated) {
function CallbackFn(arg) {
if (arg) {
__doPostBack(button.name, "");
}
}
var text = "Please make sure all fields are completed correctly as once" +
" accepted the proof of purchase will be submitted and no further " +
"changes will be allowed. Are you sure you wish to continue?";
radconfirm(text, CallbackFn, 350, 100, null, "Confirm");
}
}
And the button like this:
<asp:Button ID="AddProofOfPurchaseButton" runat="server" Text="Submit"
ValidationGroup="POPgroup" CssClass="claim_header_create_button"
OnClick="AddProofOfPurchaseButton_OnClick" OnClientClick="ShowConfirm(this); return false;" />

I also faced this problem few days back. Actually Radbutton's are set true for Autopostback by default, so if you want to achieve this in radbutton! then,
you need to change the postback property (you can change it in jscript later) and also the causesvalidation check.
<telerik:RadButton ID="AddProofOfPurchaseButton" Text="Submit" CssClass="claim_header_create_button" runat="server"
ValidationGroup="POPgroup" OnClientClicking="ShowConfirm" CausesValidation="false" AutoPostBack="false" OnClick="AddProofOfPurchaseButton_OnClick"></telerik:RadButton>
and also in script
function confirmCallBackFn(arg) {
if (arg == true) {
clickedButton.set_autoPostBack(true); //removed -->clickedButton.click();
} else { clickedButton.set_autoPostBack(false); }

Related

Confirmation Modal Box Javascript in repeater control (findcontrol value getting wrong)

<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.

When checking if value is selected from dropdownlist it exits the page

I have a checkbox and a dropdownlist and I am trying to check that if the checkbox is ticked, a value has been selected from the dropdownlist. That works fine but if the alert message pops up and I click OK to remove the message, it exits out of the page I was in. I want to say on the page same, I don't know why it is redirecting me somewhere else. Also if possible I would prefer if the error message ErrorMessage = "Please select" appeared instead of the alert box but that isn't the main issue here.
<tr>
<td class="Header">License Type</td>
<td></td>
<td>
<asp:DropDownList runat="server" ID="ddlHazLicenseType" CausesValidation="true" >
</asp:DropDownList>
<asp:CustomValidator id="CustomValidator2" runat="server"
ControlToValidate = "ddlHazLicenseType"
ErrorMessage = "Please select"
ValidateEmptyText="True"
ClientValidationFunction="validateHazLicenceType" >
</asp:CustomValidator>
</td>
</tr>
function validateHazLicenceType()
{
if (document.getElementById("<%=chkHazTrained.ClientID %>").checked)
{
var ddl = document.getElementById("ddlHazLicenseType");
var selectedValue = ddl.options[ddl.selectedIndex].value;
if ($("#ddlHazLicenseType")[0].selectedIndex <= 0)
{
alert("Please select a licence type");
}
}
}
Try something like
function validateHazLicenceType(oSrc, args) {
if (document.getElementById("<%=chkHazTrained.ClientID %>").checked) {
var ddl = document.getElementById("<%=ddlHazLicenseType.ClientID %>");
if (ddl.selectedIndex <= 0) {
args.IsValid = false
}
}
}
CausesValidation="true" seems to only cause validation when the selected index changes - which means if the initial selection is index 0, and the user never changes it, it won't validate as intended. You could try setting the DDL's selected index to -1 (so nothing is selected), but I don't think that solves the problem. You'll probably have to validate the DDL value somewhere else - on submission, perhaps?
Its been a while since I last worked with asp, and it would be nice to see the actual source (html) code. Anyway, 2 things come to mind:
1) Have your validation js function return false at the end
what happens is your validation function assumes the validation passed, and submits right after that. Returning false would prevent that to happen ( good thing to know on the side: return false means you stop the default action and stops event propagation)
2) Your submit onchange for the DDL may be somehow turned on

test if page is valid before running javascript

I have some javascript that "freezes" the screen when a submit button is pressed. This is to stop double clickers.
I have discovered that there is an issue if a validator control returns false, in that, the screen has "frozen", so the user can't fix the problem with their input data.
I need to be able to tell if the page is valid or not, so that if it is not, i can un-freeze the screen.
How can I do this??
javascript code that freezes the screen... (originally from 4guysfromrolla)
function FreezeScreen(msg) {
var outerPane = document.getElementById('FreezePane');
var innerPane = document.getElementById('InnerFreezePane');
if (outerPane) outerPane.className = 'FreezePaneOn';
}
code that runs the javascript...
<asp:Button ID="btnSubmit" runat="server" Text="<%$ Resources:LocalizedText, button_SubmitOrder %>" onclick="btnSubmit_Click" ValidationGroup="validateHeader" OnClientClick="FreezeScreen();" />
It will probably be something like this.
function ValidatePage() {
FreezeScreen();
if (typeof (Page_ClientValidate) == 'function') {
Page_ClientValidate();
}
if (Page_IsValid) {
UnFreezeScreen();
return true;
}
else {
UnFreezeScreen();
return false;
}
}
And on the button
<asp:Button ID="btnSubmit" runat="server" Text="<%$ Resources:LocalizedText, button_SubmitOrder %>" onclick="btnSubmit_Click" ValidationGroup="validateHeader" OnClientClick="return ValidatePage();" />

Javascript validation overwrites ASP.NET validators

I have a problem that is making me crazy. On my page I have one Javascript validation and two ASP.NET validators. The validation outcome depends just on the result of the Javascript. That means if the Javascript returns true the ASP.NET validators are not checked.
The Javascript code is:
<script type="text/javascript">
function Validate() {
var ddlObj = document.getElementById('<%=ddStatus.ClientID%>');
var txtObj = document.getElementById('<%=txtComment.ClientID%>');
if (ddlObj.selectedIndex != 0) {
if (txtObj.value == "") {
alert("Any change of Status requires a comment!");
txtObj.focus();
return false;
}
}
}
</script>
Instead the two ASP.NET validators are:
<td><asp:TextBox runat="server" ID="txtSerialNr" ></asp:TextBox>
<asp:RequiredFieldValidator runat="server" ID="RequiredFieldValidator1" ControlToValidate="txtSerialNr" ErrorMessage="***" />
</td>
<td><asp:TextBox runat="server" ID="txtProdName" ></asp:TextBox>
<asp:RequiredFieldValidator runat="server" ID="rfv1" ControlToValidate="txtProdName" ErrorMessage="***"></asp:RequiredFieldValidator></td>
Anybody might help? Thanks
UPDATE:
I call the Javascript from a button:
<asp:Button runat="server" ID="btnSubmit" Text="Save New Product"
style="cursor:hand" OnClick="btnSubmit_Click" />
But I register the attribute from the code-behind:
protected void Page_Load(object sender, EventArgs e)
{
btnSubmit.Attributes.Add("OnClientClick", "return Validate()");
}
You can fire the client side validation from within the Validate() function:
validate = function(){
bool isValid = Page_ClientValidate(""); //triggers validation
if (isValid){
var ddlObj = document.getElementById("<%=ddStatus.ClientID%>");
var txtObj = document.getElementById("<%=txtComment.ClientID%>");
if (ddlObj.selectedIndex != 0) {
if (txtObj.value == "") {
alert("Any change of Status requires a comment!");
txtObj.focus();
isValid = false;
}
}
}
return isValid;
}
Markup:
<asp:Button runat="server" OnClientClick="return validate();" ... />
OK, there's a couple of things wrong here.
If you are concerned enough to do validation, you must ALWAYS do server-side validation in addition to client-side. Client-side validation is very user-friendly and fast to respond, but it can be bypassed simply by setting JavaScript to 'off'!
I don't see where you've told your controls which JavaScript function to call when they validate? You use RequiredFieldValidators which don't require an external function - but then attempt custom validation using your Validate() function.
If you do end up using a CustomValidator, then you'll need to change the 'signature' of your function. It needs to be of the form
function validateIt(sender, args){
var testResult = //your validation test here
args.IsValid = testResult;
}

Validation summary message pops up twice

I have validation controls in my page and I am using Validation summary message box to display the validation messages,the javascript function shown below worked for me but the problem is I am using this javascript function on OnClientClick event of the button and when I click the button with form controls not been filled its displaying the validation summary message box as expected but when i close the summary box it's getting displayed again and i need to close the message box to disappear, means i have to do two clicks everytime. Can somebody correct me what am I doing wrong.
Here is what I am doing:-
<asp:Button ID="SubmitButtonOne" runat="server" Text="Submit" OnClick="SubmitButtonOne_Click"
ValidationGroup="Cases" ClientIDMode="Static" OnClientClick="PleaseWaitShow()" />
Here is the javascript function:
function PleaseWaitShow() {
var isPageValid = true;
// Do nothing if client validation is not active
if (typeof (Page_Validators) != "undefined") {
if (typeof (Page_ClientValidate) == 'function') {
isPageValid = Page_ClientValidate();
}
}
if (isPageValid) {
document.getElementById('SubmitButtonOne').value = "Processing...";
}
}
code behind:
protected void SubmitButtonOne_Click(object sender, EventArgs e)
{
try
{
// some functionality
}
catch (Exception)
{
//show errror message
}
}
It is expected behavior.
Once Page_ClientValidate is fired due to your explicit call inside PleaseWaitShow method and second is an implicit call made by the PostBack button click.
And so you are seeing two times the ValidationSummary message box.
I don't have a solution to circumvent this but will update if something strikes.
Note: One thing I would like to point out is since you have ValidationGroup="Cases" on your submit button you should pass that to your Page_ClientValidate method.
Update 1: One way I can think of is trying something like this:
1: OnClientClick="return PleaseWaitShow();"
2: return isPageValid from PleaseWaitShow():
function PleaseWaitShow() {
var isPageValid = true;
....
....
....
return isPageValid;
}
No, it is not the expected behavior. Rather, it's a bug in ASP.NET validation JS code.
The ValidationSummaryOnSubmit function loops over all summaries, and for each summary, loops over all validators. If not group is specified, then each validator's message is appended, resulting in 2 (3, 4, 5?) repetitions of the same messages.
I solved the problem by fixing the function (staring at line 53 or so):
....
for (i = 0; i < Page_Validators.length; i++)
{
var validator = Page_Validators[i];
if (validator.validationGroup != null && summary.validationGroup != null)
{
if (validator.validationGroup != summary.validationGroup) continue;
}
if (!validator.isvalid && typeof (validator.errormessage) == "string")
{
s += pre + validator.errormessage + post;
}
}
....
if you use Page_ClientValidate method, you should set causevalidation to false. CausesValidation="false"
because Page_ClientValidate is already doing this for button or control you validate
Please remove ValidationGroup of Button. Only user for ValidationSummary
Like:
<asp:TextBox ID="txtName" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="rqvName" runat="server" ControlToValidate="txtName" ErrorMessage="Please enter Name" ValidationGroup="SaveName"> </asp:RequiredFieldValidator>
<asp:Button ID="btnSave" runat="server" OnClientClick="DisableButton();" Text="Save this Name" ></asp:Button>
<asp:ValidationSummary ID="valSaveName" runat="server" ValidationGroup="SaveName" ShowMessageBox="true" ShowSummary="false" />
Thanks

Categories

Resources