i have a mainbox inside which some more boxes are dynamically generated.
// first time retrive
$.post("dataretrive.php", {
}, function(data, status) {
document.getElementById('mainbox').innerHTML = data;
timer();
});
then on click on these subboxes some i am implementing some functionality
$('.boxes-main').unbind('click').on('click', '.subbox', function(e){
var value1 = $(this).attr('data');
var value2 = $(this).attr('data2');
var value3 = $(this).attr('data3');
var value11 = $(this).attr('data4');
var value12 = $(this).attr('data5');
var value13 = $(this).attr('data6');
...... // some more functionality with these data which i think doesn't matter for this question for this question
});
As i want to implement shortcuts to these subbox like when user press 1 it trigger a click event on that box. I also have ID's associated with that. like box1 , box2, box3 and so on. and i am trying to put a click event of that box when key 1 is pressed.
$(document).keypress(function(e) {
if(e.charCode == 49) {
$('#box1').click();
}
});
I had also tried trigger function , $("boxes-main #box1').click(); but nothing works because contents are dynamically generated. someone tell me please how to implement manual click event on dynamically generated element.
and don't get confused between boxes-main and mainbox both are class and id of same div element.
Based on your comment:
and don't get confused between boxes-main and mainbox both are class
and id of same div element.
It is not the click generation that is broken, but you are targeting the wrong ancestor in your delegated click event handler. Go higher up the ancestors to a non-changing element. document is the best default if nothing else is closer.
$(document).on('click', '.subbox', function(e){
Notes:
Don't mix bind with on. Use off instead
You don't need off/unbind at all in this example
Related
I have an existing system built using jQuery, Backbone.js and a REST-ish back-end written in C#. The application is an SPA with forms to fill and navigation. My job is to build a "Navigation Interceptor" to connect on the application so the system detects whether a field was modified in the current view so that when the user navigates, he will be warned that fields were modified and be requested to save or cancel the changes.
The way I designed it is using jQuery. To make it short, I use a selector on input, select, etc.. and bind a change event to it. Then I use a selector on links and buttons, unbind all click events, bind my "interceptor" (if a field has changed, ask before navigating) and then rebind all click events after my interceptor. I use stopImmediatePropagation() to cancel the regular navigation events, resulting in a kind of wrapper around the events.
By doing so, I have 2 problems:
Calling .val() on a field does not trigger the change event which is fine since I populate the fields dynamically. The problem is that the bootstrap date pickers does not seem to be setting the value using .val() resulting in all date fields having the "changed" state when initialized.
Elements dynamically created (e.g.: field in accordion panel created after the page has loaded) don't accept the events resulting in forms not firing the change event of my navigation interceptor.
My question is regarding the 2 above elements:
Is there a way to determine if a specific field is a date picker and bind the change event on that field so that when I populate it, the change event does not fire, but when the users do, it does (I tried binding on the changeDate event but the setDate method seems to be firing the changeDate event also)?
Is there a way to determine if the element was dynamically created (e.g.: $(''))? The problem is that I do not have a specific selector for a single field, so I think I cannot use delegation ($(document).on('change', 'someFieldSelectorICannotKnow', function () {});). All I have is a handle on the jQuery element ($(this) in a .each(fn) iteration).
#2 Solved using event delegation on all fields and skipping the handler if the field is not a form field
Solution of #2:
NavigationInterceptor.prototype.bindChangeEventOnAllEditableFields = function () {
var self = this;
var fieldsSelector = $(this.configuration.selectors.formFields.join(', '));
$(fieldsSelector).each(function () {
var isFormField = !self.searchClassFromArrayInElement(self.configuration.classes.nonFormFieldClasses, $(this));
if (isFormField && self.configuration.debug.highlight.fields.unchanged && $(this).attr('type') === 'radio') {
$(this).parent().css('background-color', self.configuration.debug.highlight.fields.unchanged);
} else if (isFormField && self.configuration.debug.highlight.fields.unchanged) {
$(this).css('background-color', self.configuration.debug.highlight.fields.unchanged);
}
});
$(document).on('change', fieldsSelector, function (event) {
var field = $(event.target);
var isFormField = !self.searchClassFromArrayInElement(self.configuration.classes.nonFormFieldClasses, field);
if (isFormField) {
self.hasFieldChanged = true;
if (self.configuration.debug.highlight.fields.changed) {
if (field.attr('type') === 'radio') {
field.parent().css('background-color', self.configuration.debug.highlight.fields.changed);
} else {
field.css('background-color', self.configuration.debug.highlight.fields.changed);
}
}
}
});
return this;
}
var unchangeable_classes = ['decorative', 'constant'];
$(document).on('change', 'input,select,textarea', function () {
var $this=$(this);
for(var i =0;i<unchangeable_classes.length;++i){
if($this.hasClass(unchangeable_classes[i]))
return;
}
global_changed = true;
});
Why doesn't this work, it should? (Edited in response to comment.)
My thoughts>>
1)A way to stop calling changeDate() after calling setDate(), you could just call event.stopPropogation(), it will prevent the event from bubbling up
2)while creating a dynamic element, you could add any property of your wish. For eg
var iDiv = document.createElement('div');
iDiv.isDynamic = true;
then while iterating through the element, check for isDynamic property
Why not add a benign class tag to the element
$('#foo').addClass('bar');
then you can check for the class to see if it was created
if ($('#foo').hasClass('bar'))
alert('was created');
Note that when you add elements you have to re-attach the events. So if you have a global document event and then add an element, that element won't be included unless you explicitly attach the new element.
I'm posting the answer for my question #1.
What I did is modify bootstrap's source. When calling setDate like so:
$('#myDateInput').datepicker('setDate', new Date());
The code goes through the function setDates which calls update and setValue, the first one resulting in the date being set in the datepicker itself, the second one setting only the value in the input text field. What I did is remove the call to 'change' which triggers the change event on the field and left the custom event 'dateChange'. This results in my code not firing the change event when I call setDate, but calls it when the user sets a date using the picker itself.
Is there any way in Javascript or jquery using which we can internally click the "Delete" button to delete some text in HTML web pages?
I don't want my users to click the "Delete" button physically but I want to give them interface where when they click I will apply the "Delete" button functionality there.
You can trigger it using the keydown function:
$(function(){
var press = jQuery.Event("keyup");
press.ctrlKey = false;
press.which = 46;
$('#check').keyup(function(e){
alert(e.which);
}).trigger(press);
});
But this solution does NOT simulate a natural keypress event on the HTML element. This method only triggers the keyup event, it does not replicate the user going into the element and pressing that key. For doing that you can refer HERE.
But this dispatch event is also not globally supported.
I think applying the functionality of delete button on click of button can fullfill your requirement
Just write $("input").val("") on click of button or follow the answer of #haxxton given above, OR SEE DEMO HERE
Further to my comment on the OP.
Assuming your HTML looks something like
<p id="deleteMe">This text should be deleted</p>
<button id="deleteButton">DELETE</button
Option 1
if your intention is to remove the entire text of an element you could use
var deleteButton = document.getElementById('deleteButton');
deleteButton.onclick = function(){
var deleteItem = document.getElementById('deleteMe');
deleteItem.innerHTML = '';
}
Option 2
However, if it is your intention to only remove one character per click you could use something like
var deleteButton = document.getElementById('deleteButton');
deleteButton.onclick = function(){
var deleteItem = document.getElementById('deleteMe');
deleteItem.innerHTML = deleteItem.innerHTML.substring(0, deleteItem.innerHTML.length - 1);
}
Please visit : Is it possible to simulate key press events programmatically?
you can use the keycode as 46 insetead of
character.charCodeAt(0)
Call internally to a event is simple with jQuery:
$('#delete').click(); // call internally to 'Delete' button
It launchs the click event which contains your delete functionality.
See a demo more complete: http://jsfiddle.net/581env0c/2/
In Enterprise Portal (essentially sharepoint) we're attempting to automatically fire the "click" of a button whenever a td loses focus, and then return focus to the cell of the table we left. The idea is that we want the user to be able to continuously enter data without having to click that button every time.
The problem is, I don't know how to specify a specific cell within the table to return to, so it just returns to the first cell. I've read in several places that this is either very difficult or impossible without things like SlickGrid. Can anyone help me do this in straight up Javascript/Jquery?
The code I have so far looks like this:
<script>
$jQ(window).load(function refreshSummary() {
var activeElement;
$jQ("td").focus(function () {
activeElement = document.activeElement;
});
$jQ("td").focusout(function () {
var refreshLink = "ctl00_ctl00_m_g_78a9aecd_0fef_4b43_a2ff_45942fe92ea0_ctl01_ctl04_RefreshLink";
document.getElementById(refreshLink).click();
document.getelementbyid(activeelement).focus();
});
});
</script>
Don't you want to just focus back on the element after click on focusout?
$jQ(window).load(function refreshSummary() {
var activeElement;
$jQ("td").focus(function () {
activeElement = document.activeElement;
});
$jQ("td").focusout(function () {
var refreshLink = "ctl00_ctl00_m_g_78a9aecd_0fef_4b43_a2ff_45942fe92ea0_ctl01_ctl04_RefreshLink";
document.getElementById(refreshLink).click();
$(this).focus();
});
});
I want to use the arrow keys to navigate between the input text fields in my form (next, previous). I found this simple method to implement it: link to it but for me it doesn't work... I tried it in the HEAD and in the BODY after the FORM as well, but no luck...
I think the problem could be, that my form is send back to the page via AJAX...
I'm not that familiar with jQuery, can someone please help me out here?
This is the jQuery code:
<script>
$(document).ready(function(){
$('input').keyup(function(e){
if(e.which==39)
$(this).closest('td').next().find('input').focus();
else if(e.which==37)
$(this).closest('td').prev().find('input').focus();
else if(e.which==40)
$(this).closest('tr').next().find('td:eq('+$(this).closest('td').index()+')').find('input').focus();
else if(e.which==38)
$(this).closest('tr').prev().find('td:eq('+$(this).closest('td').index()+')').find('input').focus();
});
});
</script>
if your inputs are dynamically created after domready event you should change
$('input').keyup(function(e){
...
into
$('body').on('keyup', 'input', function(e) {
...
doing so the keyup event will be captured on body element using event delegation
For further info see the documentation here: http://api.jquery.com/on/
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on(). To ensure the elements are present and can be selected, perform event binding inside a document ready handler for elements that are in the HTML markup on the page. If new HTML is being injected into the page, select the elements and attach event handlers after the new HTML is placed into the page. Or, use delegated events to attach an event handler...
If your script is loaded before the form is on the page then the keyup binding would not be able to bind on load. Try using:
$('input').live('keyup', function(e) { code here });
Just in case you want to bind more than one event, this is how you do it:
$('body').on({
'keyup' : function(e) {
...
},
'keydown' : function(e) {
...
}
}, 'input');
Also 'body' can be swapped with any parent element of 'input' that will not be dynamically added to the page (i.e. it exists on page load). So if you have some div containing each input, you might want to bind that instead.
I've got a slight improvement to the code above. The problem with the code is that you cannot navigate inside an input field. E.g. you have a value of '100.00|' with the cursor currently at the end (indicated with |). If you press the left key it will jump to the prev input field instead of moving the caret by one position to '100.0|0'.
In order to do that you need to check the current caret position with e.target.selectionStart. But you also need the prev caret position as otherwise you can't identify whether the caret went from 1 to 0 (no jump) or the caret was already on 0 and the user pressed left again (jump).
Another change I've added is that only input fields with the class tableInput are considered. In case you want to exclude some fields.
function(e){
var charPos = e.target.selectionStart;
var strLength = e.target.value.length;
var prevPos = $(this).data('prevPos');
if(e.which==39){
//only go right if we really reached the end, that means the prev pos is the same then the current pos
if(charPos==strLength && (prevPos ==null || prevPos == charPos)){
$(this).closest('td').next().find('input.tableInput').focus();
$(this).data('prevPos',null);
}else{
$(this).data('prevPos',charPos);
}
}else if(e.which==37){
//only go left if we really reached the beginning, that means the prev pos is the same then the current pos
if(charPos == 0 && (prevPos ==null || prevPos == charPos)){
$(this).closest('td').prev().find('input.tableInput').focus();
$(this).data('prevPos',null);
}else{
$(this).data('prevPos',charPos);
}
}else if(e.which==40){
$(this).closest('tr').next().find('td:eq('+$(this).closest('td').index()+')').find('input.tableInput').focus();
$(this).data('prevPos',null);
}else if(e.which==38){
$(this).closest('tr').prev().find('td:eq('+$(this).closest('td').index()+')').find('input.tableInput').focus();
$(this).data('prevPos',null);
}
});
I have a simple in-line edit in my grid, and I want to commit the change when the user tabs off the textbox. The default behavior of jqGrid forces the user to press 'Enter' to commit the change, but this is non-intuitive for our users.
onSelectRow: function(id) {
$(gridCoreGroups).editRow(id, true, undefined, function(response)
{
alert("hello world");
}
}
I've worked my way through the events provided, but they all happen as a result of the user pressing 'Enter', which I want to avoid. Is there something I can wire up that would trigger an action when the user tabs off this cell?
For in line editing you can accomplished this several ways. To bind an onblur event to the input field using the onSelectRow trigger, eliminating the need for edit and save buttons, do something like this:
$('#gridId').setGridParam({onSelectRow: function(id){
//Edit row on select
$('#gridid').editRow(id, true);
//Modify event handler to save on blur.
var fieldName = "Name of the field which will trigger save on blur.";
//Note, this solution only makes sense when applied to the last field in a row.
$("input[id^='"+id+"_"+fieldName+"']","#gridId").bind('blur',function(){
$('#gridId').saveRow(id);
});
}});
To apply a jQuery live event handler to all inputs that may appear within a row (jqGrid labels all inputs as rowId_fieldName ), loop throw the number of rows in your grid and do something like this:
var ids = $("#gridId").jqGrid('getDataIDs');
for(var i=0; i < ids.length; i++){
fieldName = "field_which_will_trigger_on_blur";
$("input[id^='"+ids[i]+"_"+fieldName+"']","#gridId").live('blur',function(){
$('#gridId').jqGrid('saveRow',ids[i]);
});
}
Note: To use blur with .live() like above, you'll need jQuery 1.4 or the patch located at:
Simulating "focus" and "blur" in jQuery .live() method
Be careful with rowIds. When you get into sorting, adding and removing of rows, you may find yourself writing some tricky jQuery to convert row ids to iRows or row numbers.
If you're like me and you went with individual cell edit, you'll want to modify the afterEditCell trigger with something like:
$('#gridId').setGridParam({afterEditCell: function(id,name,val,iRow,iCol){
//Modify event handler to save on blur.
$("#"+iRow+"_"+name,"#gridId").bind('blur',function(){
$('#gridId').saveCell(iRow,iCol);
});
}});
Hope that helps..
This is pretty horrible, but its my take on this problem, and is prob a bit easier and more generic - it presses enter programmatically when the item loses focus :)
afterEditCell: function() {
//This code saves the state of the box when focus is lost in a pretty horrible
//way, may be they will add support for this in the future
//set up horrible hack for pressing enter when leaving cell
e = jQuery.Event("keydown");
e.keyCode = $.ui.keyCode.ENTER;
//get the edited thing
edit = $(".edit-cell > *");
edit.blur(function() {
edit.trigger(e);
});
},
Add that code to your jqgrid setup code.
It assumes that the last edited item is the only thing with .edit-cell as a parent td.
My solution was to use basic jQuery selectors and events independently of the grid to detect this event. I use the live and blur events on the textboxes in the grid to capture the event. The two events are not supported in combination with each other, so this hack ended up being the solution:
Simulating "focus" and "blur" in jQuery .live() method
I know this question is old however the answer is outdated.
A global variable called lastsel must be created and the following added to the jqGrid code
onSelectRow: function (id) {
if (!status)//deselected
{
if ($("tr#" + lastsel).attr("editable") == 1) //editable=1 means row in edit mode
jQuery('#list1').jqGrid('saveRow', lastsel);
}
if (id && id !== lastsel) {
jQuery('#list1').jqGrid('restoreRow', lastsel);
jQuery('#list1').jqGrid('editRow', id, true);
lastsel = id;
}
},
I had the same issue and tried the answers above. In the end I went with a solution that inserts an "Enter" key press when the user is leaving the tab.
// Call this function to save and unfinished edit
// - If an input exists with the "edit-call" class then the edit has
// not been finished. Complete the edit by injecting an "Enter" key press
function saveEdits() {
var $input = $("#grid").find(".edit-cell input");
if ($input.length == 1) {
var e = $.Event("keydown");
e.which = 13;
e.keyCode = 13;
$input.trigger(e);
}
}
Instead of using selectRow use CellSelect.
onCellSelect: function (row, col, content, event) {
if (row != lastsel) {
grid.jqGrid('saveRow', lastsel);
lastsel = row;
}
var cm = grid.jqGrid("getGridParam", "colModel");
//keep it false bcoz i am calling an event on the enter keypress
grid.jqGrid('editRow', row, false);
var fieldName = cm[col].name;
//If input tag becomes blur then function called.
$("input[id^='"+row+"_"+fieldName+"']","#gridId").bind('blur',function(e){
grid.jqGrid('saveRow', row);
saveDataFromTable();
});
//Enter key press event.
$("input[id^='"+row+"_"+fieldName+"']","#gridId").bind('keypress',function(e){
var code = (e.keyCode ? e.keyCode : e.which);
//If enter key pressed then save particular row and validate.
if( code == 13 ){
grid.jqGrid('saveRow', row);
saveDataFromTable();
}
});
}
//saveDataFromTable() is the function which validates my data.