jQuery Confirm Replacement In A Simple Situation [duplicate] - c#

Following up from this question, I'm trying to implement an unobtrusive confirm dialog.
$(document).ready(function () {
$("[data-confirmPrompt]").click(function (event) {
var confirmPrompt = event.currentTarget.attributes['data-confirmPrompt'].value;
event.preventDefault();
$.prompt(confirmPrompt, {
buttons: { Yes: true, No: false },
callback: function (v, m, f) {
if (v) {
// User clicked Yes. Unbind handler to avoid
// recursion, then click the target element again
$(event.currentTarget).unbind('click');
event.currentTarget.click();
}
}
});
});
});
When the user has clicked on "Yes", I want the default action associated with the event to execute. I've done it above by unbinding the jQuery handler, and clicking the element again. This works fine when submitting a form or navigating to a different page - but of course does not work in AJAX-enabled pages, where I want to keep the jQuery event handler.
Is there an alternative generic way to execute the default action? Logically something like event.executeDefault().

Using the suggestion Alexey Lebedev made in his second comment, my current implementation now looks like the sample below, except that I've also added my own implementation of localization for the button labels.
Notes:
I'm now using a jqueryUI dialog widget
Note the use of .delegate so that the handler is "ajax-aware", i.e. works on elements added to the DOM after the page is loaded, e.g. as a result of an AJAX call
Uses a flag to prevent recursion when the user clicks Yes on the confirm dialog.
Uses jquery 1.6.4 and jquery-ui-1.8.16
If anyone can suggest improvements, please chime in.
<!-- Examples of usage -->
<input type='submit' data-confirm="OK to delete customer 123?" ... />
<a href="..." data-confirm="OK to navigate?" ... />
<!-- Implementation -->
<script type="text/javascript">
var confirmClickHandler = function (event) {
if ($(event.currentTarget).data('isConfirming')) return;
var message = event.currentTarget.attributes['data-confirm'].value;
event.preventDefault();
$('<div></div>')
.html(message)
.dialog({
title: "Confirm",
buttons: {
"Yes": function () {
$(this).dialog("close");
$(event.currentTarget).data('isConfirming', true);
event.currentTarget.click();
$(event.currentTarget).data('isConfirming', null);
},
"No": function () {
$(this).dialog("close");
}
},
modal: true,
resizable: false,
closeOnEscape: true
});
};
$(document).ready(function () {
$("body").delegate("[data-confirm]", "click", confirmClickHandler);
});
</script>

I'm doing something similar and this works fine for me:
$('#link').click(function(e){
if(!confirm('Are you sure you want to asdf?')){
e.preventDefault();
}
});

I honestly don't know if this answers your question, but it might help a bit.
Consider the following HTML:
<button onclick="alert('Hello world!');" class="btn">Test 1</button>
<button onclick="alert(this.className);" class="btn">Test 2</button>
I've added the following to my $(document).ready:
$('button').each(function() {
var btn = $(this);
var onClick = btn.attr('onclick');
//replace this with _this
onClick = onClick.replace(/this/g, "_this");
btn.attr('onclick', '');
btn.click(function() {
if (confirm('Do it?')) {
//set _this first!
var _this = btn[0];
eval(onClick);
}
});
});
It seems to get the job done. Check this jsFiddle example: http://jsfiddle.net/KeesCBakker/4jThg/.
EDIT
I've created something that looks more like your question: http://jsfiddle.net/KeesCBakker/hqLH5/. Just couldn't figure out which $.prompt plugin your were using, so I grabbed the first one I've found from github (this one only works in Chrome :S).

I was able to achieve this by calling event.stopPropagation() from a more specific context, and ensuring that I don't call event.preventDefault(). While you can't call the default action explicitly, you can set up the conditions so that the default action happens — and do as little or as much else as you wish.
// Normal event handler
$("[data-toggle]").click(ev => {
switchToTab(ev.currentTarget)
ev.preventDefault()
})
// Allow default handler in a specific case.
$("[data-toggle] ul a").click(ev => {
// Don't bubble the event to the less specific handler, above
ev.stopPropagation()
// An incorrect return value will also cancel the default action.
return true
})

Related

How can I elegantly get two HTML checkboxes to tick each other off?

I have two mutually exclusive checkboxes; that being so, I'd like each one to automatically reflect the opposite state of the other when a change is made: if checkboxA is checked, checkboxB should be, if checked, unchecked (etc., I'm sure you know what I mean).
I'm creating the checkboxes in my code-behind like so:
ckbxPaymentForSelf = new CheckBox();
ckbxPaymentForSelf.Text = "myself";
ckbxPaymentForSelf.ID = "ckbxPaymentForSelf";
this.Controls.Add(ckbxPaymentForSelf);
ckbxPaymentForSomeoneElse = new CheckBox();
ckbxPaymentForSomeoneElse.Text = "someone else";
ckbxPaymentForSomeoneElse.ID = "ckbxPaymentForSomeoneElse";
this.Controls.Add(ckbxPaymentForSomeoneElse);
Based on this, I thought maybe I could use the checkbox's Name property and set them both to the same value, something like "ckbxsSelfOrSomeoneElse" but there is no "Name" property on Checkbox available to me.
I could write some jQuery like so (pseudoscript):
$(document).on("change", '[id$=ckbxPaymentForSelf]', function () {
var ckd = this.checked;
if (ckd) // check ckbxPaymentForSomeoneElse and uncheck if it it's checked
else // check ckbxPaymentForSomeoneElse and check if it it's unchecked
});
$(document).on("change", '[id$=ckbxPaymentForSomeoneElse]', function () {
var ckd = this.checked;
if (ckd) // check ckbxPaymentForSelf and uncheck if it it's checked
else // check ckbxPaymentForSelf and check if it it's unchecked
});
...but am wondering if there is a more obvious or elegant solution to this, as this is indubitably a common requirement.
UPDATE
I tried 's answer:
$(document).on("click", '[id$=ckbxPaymentForSelf]', function () {
alert('reached onclick for ckbxpaymentforself');
$('#ckbxPaymentForSomeoneElse').prop('checked', !this.checked);
});
$(document).on("click", '[id$=ckbxPaymentForSomeoneElse]', function () {
alert('reached onclick for ckbxpaymentforsomeoneelse');
$('#ckbxPaymentForSelf').prop('checked', !this.checked);
});
...but, illogically (it seems to me and, obviously, him), it doesn't work. The strange/suspicious thing is that the alert messages are showing twice! I have to click them twice to dismiss them. Why would that be, and could that be the/a problem? I did notice that the jQuery appears twice in the "View Source" although, of course, it is in only one place in the actual source code (at the bottom of the .asxc file).
UPDATE 2
As wilusdaman suggested (make it an answer, Wilus, and I'll accept it as such), the elegantest way is to use radiobuttons instead. All that is needed is this:
rbPaymentForSelf = new RadioButton();
rbPaymentForSelf.Text = "myself";
rbPaymentForSelf.ID = "rbPaymentForSelf";
rbPaymentForSelf.GroupName = "SelfOfSomeoneElse";
this.Controls.Add(rbPaymentForSelf);
String checkboxPaymentForSomeoneElseText = "someone else";
rbPaymentForSomeoneElse = new RadioButton();
rbPaymentForSomeoneElse.Text = checkboxPaymentForSomeoneElseText;
rbPaymentForSomeoneElse.ID = "rbPaymentForSomeoneElse";
rbPaymentForSomeoneElse.GroupName = "SelfOfSomeoneElse";
this.Controls.Add(rbPaymentForSomeoneElse);
...and this jQuery, relatedly, then acts:
/* If user selects "payment for self" (they are seeking payment for themselves, as opposed to someone else), omit (invisibilize) sections 2 and 3 on the form */
$(document).on("change", '[id$=rbPaymentForSelf]', function () {
if (this.checked) {
$('[id$=panelSection2]').slideUp();
$('[id$=panelSection3]').slideUp();
$('[id$=_MailStopRow]').slideDown();
$('[id$=_AddressRows]').slideUp();
}
});
/* If user selects "payment for someone else" (they are seeking payment for someone else, as opposed to themselves), make sections 2 and 3 on the form visible */
$(document).on("change", '[id$=rbPaymentForSomeoneElse]', function () {
if (this.checked) {
$('[id$=panelSection2]').slideDown();
$('[id$=panelSection3]').slideDown();
$('[id$=_MailStopRow]').slideUp();
$('[id$=_AddressRows]').slideDown();
}
});
However, the sections that should show if the user selects "someone else" do not display the first time the user (me for now) selects the "someone else" radio button - subsequently, it does work, though...
i am able to achieve using javascript as below:
<body>
<input type="checkbox" id="one" name="one" onchange="check1()"/>
<input type="checkbox" id="two" name="two" onchange="check2()"/>
<script>
function check1()
{
if(one.checked)
{
document.getElementById("two").checked = false;
}
else
{
document.getElementById("two").checked = true;
}
}
function check2()
{
if(two.checked)
{
document.getElementById("one").checked = false;
}
else
{
document.getElementById("one").checked = true;
}
}
</script>
</body>
This can be used for each instance you have in your project, you never need to worry about mixing the logic in for each selector you wish to target. Super reusable!
Since the click event happens on the client side, heres some jQuery to fit your requirements:
$.fn.dependantCheckbox = function() {
"use strict";
var $targ = $(this);
function syncSelection(group, action) {
$targ.each(function() {
if ($(this).data('checkbox-group') === group) {
$(this).prop('checked', action);
}
});
};
$('input[type="checkbox"][data-checkbox-group]').on('change', function() {
var groupSelection = $(this).data('checkbox-group');
var isChecked = $(this).prop('checked');
syncSelection(groupSelection, isChecked);
});
}
$('input[type="checkbox"][data-checkbox-group]').dependantCheckbox();
http://codepen.io/nicholasabrams/pen/mJqyqG
I believe using a client side MVC framework is a much better elegant solution.
Eg, in AngularJs, you can bind your view (two checkboxes) to your model, and every time when you change your model, your view will be updated by framework.
In addition, I believe you can also use observationCollection to do the same on the server side (https://msdn.microsoft.com/en-us/library/ms668604(v=vs.110).aspx).
While this is elegent you will face an issue because the change event will fire for both. This would be a cartesian product as the two will start a war. the code would change the state of the other going forever, or at least causing unwanted results. Using click would be a better solution.
$(document).on("change", '#ckbxPaymentForSelf', function () {
$('#ckbxPaymentForSomeoneElse').prop('checked', !this.checked);
});
$(document).on("change", '#ckbxPaymentForSomeoneElse', function () {
$('#ckbxPaymentForSelf').prop('checked', !this.checked);
});
I suggest the following. Note the labels and use of the class vs the id to assign the event handler:
$(document).on("click", '.ckbxPaymentForSelf', function () {
$('#ckbxPaymentForSomeoneElse').prop('checked', !this.checked);
});
$(document).on("click", '.ckbxPaymentForSomeoneElse', function () {
$('#ckbxPaymentForSelf').prop('checked', !this.checked);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input id="ckbxPaymentForSelf" class="ckbxPaymentForSelf" type="checkbox" checked/>
<label class="ckbxPaymentForSelf" for="ckbxPaymentForSelf">Payment For Self</label></br>
<input id="ckbxPaymentForSomeoneElse" class="ckbxPaymentForSomeoneElse" type="checkbox" />
<label class="ckbxPaymentForSomeoneElse" for="ckbxPaymentForSomeoneElse">Payment For Someone Else</label></br>
Note: When creating the controls server side you may want to set the
ClientIdMode="Static"
or script this way:
$('#<%= ckbxPaymentForSomeoneElse.ClientID %>').prop('checked', !this.checked);
in the script to be sure your control is referenced

Display panel over another panel for web app

I was looking for an answer, but could not find anything helpfull yet.
I have a gridview with some data (from SQL database) and an option to delete a row. Before deleting the row I want the user to confirm the delete (pupup window). I know how to create a popup with javascript, but I don't like the apperance of that popup. I would like to make ky own "popup".
I was thinking of overlaying one panel (where I put text (Label) and some buttons (OK, Cancel)) over the panel where I have the gridview. Something like in the picture. How would I accomplish something like that?
How about using the Ajax control toolkit popup?
http://www.asp.net/ajaxlibrary/act_Popup.ashx
This seems to do exactly what you are looking for for you.
What about JQueryUI dialog with custom styling?
Use the jQuery UI dialog
Example:
<script type="text/javascript">
$(function () {
var $dialog = $("#dialog");
var $foo = $("input:submit[id$=foo]");
var confirmed = false;
$dialog.hide();
$dialog.dialog({
width: "300px",
modal: true,
autoOpen: false,
buttons: {
OK: function (e) {
$dialog.dialog("close");
confirmed = true;
$foo.click();
},
Cancel: function (e) {
$dialog.dialog("close");
confirmed = false;
}
}
});
$foo.click(function (e) {
if (!confirmed) {
$dialog.dialog("open");
}
return confirmed;
});
});
</script>
Full working example can be downloaded from here

Using fb-login-button div class and JQuery

I have a FB login button and want to bind it to a function but I can't seem to get it work:
<div class="fb-login-button" id="auth-loginlink"></div>
This is the line that I am trying to bind it to my fb-login-button
$("#auth-loginlink").click(function () { grantPermission(); });
<script type="text/javascript">
function grantPermission() {
window.FB.login(function (response) {
// ... login stuffs
}
</script>
It will work if I use a normal hyper link like:
Login
Please kindly advice what am I doing wrong. Thanks.
If it's really a button might as well use the button tag:
<button class="fb-login-button" id="auth-loginlink">Login</button>
Put your javascript inside the script tag, and return false in the handler:
<script type="text/javascript">
$("#auth-loginlink").click(function () { grantPermission(); return false; });
function grantPermission() {
window.FB.login(function (response) {
// ... login stuffs
}
</script>
... also might be a good idea to do $("#auth-loginlink").button() but not totally necessary.
Note: If your html is actually below your javascript code the above will not always work.

how to call a Ajax control event from jQuery

I am working with some controls that are written using microsoft ajax tool kit. I want to trigger an event in these controls using jQuery. I was hoping that it should be as simple as triggering any event from jQuery but it does not seem to be working. Here is sample code..
Ajax Control
/// <reference name="MicrosoftAjax.js"/>
Type.registerNamespace("MyNameSpace");
MyNameSpace.AjaxUserControl = function(element) {
MyNameSpace.AjaxUserControl.initializeBase(this, [element]);
}
MyNameSpace.AjaxUserControl.prototype = {
initialize: function() {
MyNameSpace.AjaxUserControl.callBaseMethod(this, 'initialize');
}
},
dispose: function() {
MyNameSpace.AjaxUserControl.callBaseMethod(this, 'dispose');
},
_onChange: function(evt) {
alert('On Change event.');
},
}
if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
Jquery Code:
var myJqueryControl = (function ($, AjaxControl) {
$(document).ready(function(){
var ajaxEventProxy = Function.createDelegate(AjaxControl, AjaxControl._onChange);
$("#JqueryCommandButton").click(ajaxEventProxy);
} (jQuery,MyNameSpace.AjaxUserControl));
Its not working, when the button is clicked i cannot see alert message inside onchange. Would appreciate any guidance on how to make it work.
Thanks
CSC
It would work much easier if you followed the JQuery widget pattern. Because an AJAX control wraps around an element, much like the widget does, you can more easily integrate the two, by writing some setup with the init method:
_init: function() {
//store a control reference within the widget
this._control = $find(this.element.attr("id"));
}
Then, in your widget, you can refer to the control via the this._control.
If you can't switch models, the way to resolve this is not refer to the type directly, but the instance... instead of passing in the reference MyNameSpace.AjaxUserControl to the constructor, pass in an instance, then you can do:
instance._onchange();
To invoke the event.

JQuery custom event in ASP.Net User Control

I have an ASP.Net user control that contains some checkboxes, and I want to use JQuery to raise an event from the user control when one of the checkboxes is clicked. Here is the JQuery code in the user control where I'm trying to raise the event:
$(document).ready(function() {
$(':checkbox').click(function(){
$('#hfRemainingInstalls').trigger('CheckBoxClicked');
});
});
and here is the JQuery code in the containing aspx page where I'm trying to subscribe to the event:
$(document).ready(function() {
$("p").bind('CheckBoxClicked', function(e) {
alert("checkbox clicked");
});
});
I'm never seeing my alert when I click on one of the checkboxes. Anyone know what might be the problem here?
I am sure you have an ID problem. ASP.NET controls that reside inside of container elements such as UserControls and MasterPages, when rendered, have some junk prefixed to the id attribute to ensure uniqueness. It is usually something like "ctl01_01_YourID" That said, you should probably be using the jQuery endsWith selector...
$('input[id$=hfRemainingInstalls]').trigger('CheckBoxClicked');
The following will alert "true" if the element is found...
alert($('#hfRemainingInstalls').length > 0);
so is there a relationship between the Id tags P and Id hfRemainingInstalls
1: Solution
$(':checkbox').click(function(){
$("p").trigger('CheckBoxClicked');
});
$(document).ready(function() {
$("p").bind('CheckBoxClicked', function(e) {
alert("checkbox clicked");
});
});
2: Solution
$(':checkbox').click(function(){
$("#hfRemainingInstalls").trigger('CheckBoxClicked');
});
$(document).ready(function() {
$("#hfRemainingInstalls").bind('CheckBoxClicked', function(e) {
alert("checkbox clicked");
});
});

Categories

Resources