How can I detect if text is paste using right-click - javascript

If I paste text using ctrl c and ctrl v on table1(For example on "Apple"), duplicate text on input on table2 still change, but If i paste using right click and paste,duplicate input on table 2 does NOT change. :( Ive created two different event(keyup and change) but nothing seems to work when text is paste using right click. Please see below :
Keypress fiddle demo
$(document).off('keydown').on('keydown', $('#table1 tbody tr td input:eq(0)'), function (e) {
var oldValue =$(e.target).val();//get the input value before keypress or edit
$(document).on('keyup', $('#table1 tbody tr td input'),function(e){
$('#table2').find('td input').each(function(){
if($(this).val() === oldValue){
$(this).val($(e.target).val());
}
$(document).off('keyup');
});
});
});
on change fiddle demo
var oldValue;
$(document).on('keydown', '.main', function (e) {
oldValue = $(this).val();
foo(oldValue);
});
var newValue;
$(document).on('keyup', '.main', function (e) {
newValue = $(this).val();
foo(oldValue);
});
function foo(oldValue) {
$('#table1').find('tbody tr').find('td input').change(function (i) {
var orig = $(this).val();
$('#table2 tbody tr').find('td input').each(function (i) {
if (oldValue == $(this).val()) {
$(this).val(orig);
}
});
});
}

You can count the characters onChange (since you can only enter one character at a time.
Edit:
Why it wasn't working:
on your jsfiddle remember to set onDomReady in the frameworks & extension for the equivalent of $(document).ready(handlerFn)
When you use on('change', handlerFn) or .change(handlerFn) on an input it will fire only after the textbox loses focus ( blur ). The response is not instantaneous like when you use select on your forms. Use bind("input", handlerFn) instead of on(change) for inputs.
The code below will update the matching word on #table2 from the one being edited on #table1. Updating will work for copy-paste CTRL C/V or on mouse copy/paste events. It will also alert if the user copy/paste by comparing the length of the old and new value.
$("#table1 >* input").each(function() {
var elem = $(this),
oldValue;
elem.on('focus', function () {
elem.data('oldVal', elem.val());
elem.data('oldLen', elem.data('oldVal').length);
});
// Look for changes in the value,
// bind 'input' event to the textbox to fire the function
// every time the input changes (paste, delete, type etc.)
elem.bind("input", function(event){
oldValue = elem.data('oldVal');
// update oldVal
elem.data('oldVal', elem.val());
// check if pasted
if (elem.val().length - elem.data('oldLen') > 1 ) {
alert('Most certainly pasted');
}
// update input value length
elem.data('oldLen', elem.data('oldVal').length);
// update #table2
foo(oldValue, elem.val()) ;
});
});
And the function to update #table2
function foo(oldValue, newValue) {
$('#table2')
.find('input')
.each(function (i) {
if (oldValue === $(this).val()) {
$(this).val(newValue);
}
});
}
here's a jsfiddle for you to play with

Check this code, Hope this will help you:
jQuery('#some_text_box').on('input propertychange paste', function() {
var text1 = $('#some_text_box').val();
//alert(text1);
$('#tab2').val(text1);
});
This is your first text box #some_text_box.
<input type='text' value = "Apple" id='some_text_box' />
And this is table 2 text box #tab2
<input type='text' value="Apple" id='tab2'/>
JSFiddle

Ok well this will detect for you if the user uses Ctrl + V etc but thats it. If they right click and paste then you will need another expression to capture that. I left this open by using keydownand keyupso you can capture more variations if needed.
This is jQuery so you will need the library to cover this.
$(document).ready(function()
{
var ctrlDown = false;
var ctrlKey = 17, vKey = 86, cKey = 67;
$(document).keydown(function(e)
{
if (e.keyCode == ctrlKey) ctrlDown = true;
}).keyup(function(e)
{
if (e.keyCode == ctrlKey) ctrlDown = false;
});
$("#no-copy-paste").keydown(function(e)
{
if (ctrlDown && (e.keyCode == vKey || e.keyCode == cKey)) return false;
});
});
Here is an article on handlers that may be some help to you as well.
http://unixpapa.com/js/key.html
-Epik

Related

How to trigger the select function when the value is selected after the tab is pressed

I have a combo box that enables the autocomplete function.
The project that I am working on currently uses the same code that is mentioned in the answer.
I have modified the code to select the value on the tab pressed if it matched the exact text in the select.
In the source, I called this function.
this._addTabAndReturnListener(matchedOptions);
and I have implemented _addTabAndReturnListener as:
_addTabAndReturnListener: function(options) {
var self = this;
var element = this.element;
var input = this.input[0];
this.input.off('keydown.first'); // Disable listener from previous call
this.input.on('keydown.first', function(e) {
var keycode = e.which;
if (keycode == 9 || keycode == 13) // If tab key pressed
if (options.length == 1) {
var result = null;
element.children("option").each(function() {
if ($(this).text() == options[0].value)
result = this;
})
if (result != null)
input.value = $(result).text();
$(this).attr("title", input.value + " matched").tooltip("open");
input.dispatchEvent(new Event("select"));
}
});
},
I wanted to trigger the select function when the value is selected after the tab is pressed, but not able to do so.
Normally when a value is selected from the dropdown the following functions have been triggered, and the alert is displayed. But it is not working on the tab pressed.
$('#myselect').combobox({
select: function(event, ui) {
alert(event.target);
}
});
What could be the solution for this?
Jsfiddle
I was able to solve this issue by adding a trigger.
$(this).trigger("tabOnChange", result);
and define a new event, called tabOnChange
tabOnChange: function(event, opt) {
opt.selected = true;
this._trigger("select", event, {
item: opt
});
},
Fiddle:

Tab through elements using Enter key including select2

I am using following code to tab through form elements using enter key. Problem is that this code skip select2 elements.
$('body').on('keydown', 'input, select', function(e) {
if (e.key === "Enter") {
var self = $(this), form = self.parents('form:eq(0)'), focusable, next;
focusable = form.find('input,a,select,button,textarea').filter(':not([disabled]):not([tabindex="-1"]):visible');
next = focusable.eq(focusable.index(this)+1);
if (next.length) {
next.focus();
} else {
//form.submit();
}
return false;
}
});
Change your keydown to keyup
$('body').on('keyup', 'input, select', function(e)
Reason is keydown is already handled in select2 library for choosing an item

jquery rename content insite a tag and confirming it

How can I target only one container?
The User should be able to change the Name and then confirm the change.
My function works fine but when I have more containers repeated and I confirm Its changing all the tags!
Please check the demo where you can also see the changeElementTypefunction
Demo:
http://jsfiddle.net/26qNq/1/
JS:
$('.replace').on('click', function (){
$("h2").changeElementType("textarea");
$(this).hide();
$(this).next('a').show();
$('.confirm').on('click', function(){
var $textarea = $('textarea');
$(this).hide();
$(this).prev('a').show();
$textarea.html($textarea.val()).changeElementType("h2");
});
if ($('textarea:visible')){
$(document).keypress(function(e) {
if(e.which == 13) {
alert('You pressed enter!');
$("textarea").changeElementType("h2");
$('.replace').css('opacity','1');
}
});
}
});
You need to identify the relevant h2/textarea
var container = $(this).closest('.rename')
container.find('h2').changeElementType("textarea");
and
var container = $(this).closest('.rename')
var $textarea = container.find('textarea');
You also should nest your handler binding because each time your try to edit, you add a new handler
Full changes
$(document).keypress(function (e) {
if ($('textarea:visible')) {
if (e.which == 13) {
alert('You pressed enter!');
$("textarea").changeElementType("h2");
$('.replace').css('opacity', '1');
}
}
});
$('.replace').on('click', function () {
var container = $(this).closest('.rename')
container.find('h2').changeElementType("textarea");
$(this).hide();
$(this).next('a').show();
});
$('.confirm').on('click', function () {
var container = $(this).closest('.rename')
var $textarea = container.find('textarea');
$(this).hide();
$(this).prev('a').show();
$textarea.html($textarea.val()).changeElementType("h2");
});
Demo at http://jsfiddle.net/26qNq/6/
Adding an ID to each of them seems to work.
All I needed to do was add a numeric ID to each element we were using and add this to your replace code:
var id = $(this).attr('id');
$("h2#" + id).changeElementType("textarea");
demo: http://jsfiddle.net/26qNq/12/

clearing radio input using jQuery

I have a bunch of radio buttons that are below. These radio buttons are part of a larger form and are optional, so If a user clicks on one, then decides he/she doesn't want the option selected, there is no way to undo this.
I was wondering if there was any jQuery etc, that, when clicking a link for example, clear any radio selection, based on the group name in the HTML?
Thanks
var group_name = "the_group_name";
// if jquery 1.6++
$(":radio[name='" + group_name + "']").prop('checked', false);
// prev than 1.6
// $(":radio[name='" + group_name + "']").attr('checked', false);
Working demo: http://jsfiddle.net/roberkules/66FYL/
var Custom = {
init: function() {
checkAllPrettyCheckboxes = function(caller, container){
// Find the label corresponding to each checkbox and click it
$(container).find('input[type=checkbox]:not(:checked)').each(function(){
if($.browser.msie){
$(this).attr('checked','checked');
}else{
$(this).trigger('click');
};
});
};
uncheckAllPrettyCheckboxes = function(caller, container){
// Find the label corresponding to each checkbox and unselect them
$(container).find('input[type=checkbox]:checked').each(function(){
$('label[for="'+$(this).attr('id')+'"]').trigger('click');
if($.browser.msie){
$(this).attr('checked','');
}else{
$(this).trigger('click');
};
});
};
I have created it in an init function, and adter then i called the init.
}
window.onload = Custom.init;
I have created a solution like roberkules' solution, except mine clears the radiobutton if you click the radiobutton itself while it's checked. Use this if you don't want to add an extra "Clear" button to your layout.
http://jsfiddle.net/P9zZQ/6/
// Requires JQuery 1.4+ (possibly earlier)
$(function () {
// Turn off a radiobutton if clicked again while on
var checkOff = function (event) {
var target = $(event.target);
if (target.is('label')) {
// deal with clicked label
if (target.attr('for')) {
// label has 'for' attribute
target = $('#' + target.attr('for'));
} else {
// label contains a radiobutton as a child
target = target.find('input[type=radio]');
}
}
if (target.is('input:checked[type=radio]')) {
event.preventDefault();
window.setTimeout(function () {
target.attr('checked', false);
}, 200);
}
}
// Find all radiobuttons and labels inside .radio-clearable containers
$(
'.radio-clearable input[type=radio], ' +
'.radio-clearable label').mousedown(function (event) {
// When clicked -- clear if it was checked
checkOff(event);
}).keydown(function (event) {
// When receiving space, escape, enter, del, or bksp -- clear if it was checked
if (event.which == 32 || event.which == 27 || event.which == 13 || which == 46 || which == 8) {
checkOff(event);
}
});
});
Usage: For any radiobutton you want to be clearable in this manner, wrap it in a container with class "radio-clearable".
The code is triggered by clicking or sending a key (Space, Escape, Enter, Del, BkSp) to the radiobutton element or to its label.

Detecting data changes in forms using jQuery

I'm using ASP.NET 2.0 with a Master Page, and I was wondering if anyone knew of a way to detect when the fields within a certain <div> or fieldset have been changed (e.g., marked 'IsDirty')?
You could bind the Change event for all inputs and flag a variable as true. Like this.
var somethingChanged = false;
$(document).ready(function() {
$('input').change(function() {
somethingChanged = true;
});
});
But, keep in mind that if the user changes something, then changes back to the original values, it will still be flagged as changed.
UPDATE: For a specific div or fieldset. Just use the id for the given fieldset or div. Example:
var somethingChanged = false;
$(document).ready(function() {
$('#myDiv input').change(function() {
somethingChanged = true;
});
});
Quick (but very dirty) solution
This is quick, but it won't take care of ctrl+z or cmd+z and it will give you a false positive when pressing shift, ctrl or the tab key:
$('#my-form').on('change keyup paste', ':input', function(e) {
// The form has been changed. Your code here.
});
Test it with this fiddle.
Quick (less dirty) solution
This will prevent false positives for shift, ctrl or the tab key, but it won't handle ctrl+z or cmd+z:
$('#my-form').on('change keyup paste', ':input', function(e) {
var keycode = e.which;
if (e.type === 'paste' || e.type === 'change' || (
(keycode === 46 || keycode === 8) || // delete & backspace
(keycode > 47 && keycode < 58) || // number keys
keycode == 32 || keycode == 13 || // spacebar & return key(s) (if you want to allow carriage returns)
(keycode > 64 && keycode < 91) || // letter keys
(keycode > 95 && keycode < 112) || // numpad keys
(keycode > 185 && keycode < 193) || // ;=,-./` (in order)
(keycode > 218 && keycode < 223))) { // [\]' (in order))
// The form has been changed. Your code here.
}
});
Test it with this fiddle.
A complete solution
If you want to handle all the cases, you should use:
// init the form when the document is ready or when the form is populated after an ajax call
$(document).ready(function() {
$('#my-form').find(':input').each(function(index, value) {
$(this).data('val', $(this).val());
});
})
$('#my-form').on('change paste', ':input', function(e) {
$(this).data('val', $(this).val());
// The form has been changed. Your code here.
});
$('#my-form').on('keyup', ':input', function(e) {
if ($(this).val() != $(this).data('val')) {
$(this).data('val', $(this).val());
// The form has been changed. Your code here.
}
});
Test it with this fiddle.
A simple and elegant solution (it detects form elements changes in real time):
var formChanged = false;
$('#my-div form').on('keyup change paste', 'input, select, textarea', function(){
formChanged = true;
});
For a form you could serialize the contents on load then compare serialization at a later time, e.g.:
$(function(){
var initdata=$('form').serialize();
$('form').submit(function(e){
e.preventDefault();
var nowdata=$('form').serialize();
if(initdata==nowdata) console.log('nothing changed'); else console.log('something changed');
// save
initdata=nowdata;
$.post('settings.php',nowdata).done(function(){
console.log('saved');
});
});
});
Note this requires form elements to have a name attribute.
Just to clarify because the question is "within a certain fieldset/div":
var somethingChanged = false;
$(document).ready(function() {
$('fieldset > input').change(function() {
somethingChanged = true;
});
});
or
var somethingChanged = false;
$(document).ready(function() {
$('div > input').change(function() {
somethingChanged = true;
});
});
You can give the fieldset or div an ID and bind the change event to it ... the event should propagate from the inner children.
var somethingChanged = false;
$('#fieldset_id').change(function(e)
{
// e.target is the element which triggered the event
// console.log(e.target);
somethingChanged = true;
});
Additionally if you wanted to have a single event listening function you could put the change event on the form and then check which fieldset changed:
$('#form_id').change(function(e)
{
var changedFieldset = $(e.target).parents('fieldset');
// do stuff
});
I came up with this piece of code in CoffeeScript (not really field tested, yet):
Add class 'change_warning' to forms that should be watched for changes.
Add class 'change_allowed' to the save button.
change_warning.coffee:
window.ChangeWarning = {
save: ->
$(".change_warning").each (index,element) ->
$(element).data('serialized', $(element).serialize())
changed: (element) ->
$(element).serialize() != $(element).data('serialized')
changed_any: ->
$.makeArray($(".change_warning").map (index,element) -> ChangeWarning.changed(element)).some (f)->f
# AKA $(".change_warning").any (element) -> ChangeWarning.changed(element)
# But jQuery collections do not know the any/some method, yet (nor are they arrays)
change_allowed: ->
ChangeWarning.change_allowed_flag = true
beforeunload: ->
unless ChangeWarning.change_allowed_flag or not ChangeWarning.changed_any()
"You have unsaved changes"
}
$ ->
ChangeWarning.save()
$(".change_allowed").bind 'click', -> ChangeWarning.change_allowed()
$(window).bind 'beforeunload', -> ChangeWarning.beforeunload()
An alternative to Dw7's answer if you only want the fields inside a fieldset then you can call serialize() on its input values. Note: serialize() will not pickup any elements that do not have a "name" attribute. This will work for select tags as well.
var initialValues = $('#your-fieldset :input').serialize();
$('form').submit(function(e) {
e.preventDefault();
var currentValues = $('#your-fieldset :input').serialize();
if (currentValues == initialValues) {
// Nothing has changed
alert('Nothing was changed');
}
else {
this.submit();
}
});
.live is now deprecated and replaced by .on:
var confirmerSortie = false;
$(document).on('change', 'select', function() {
confirmerSortie = true;
});
$(document).on('change keypress', 'input', function() {
confirmerSortie = true;
});
$(document).on('change keypress', 'textarea', function() {
confirmerSortie = true;
});
The following solution worked for me:
$("#myDiv :input").change(function() { $("#myDiv").data("changed",true);});
}
if($("#myDiv").data("changed")) {
console.log('Form data changed hence proceed to submit');
}
else {
console.log('No change detected!');
}
Thanks

Categories