Action on clicking out of a form, inside a table - javascript

To start here is the fiddle with all the relevant code: http://jsfiddle.net/baruck/43787/
I'm building a webapp that at some point the user needs to register a number of items.
It is a big form, and this section of the form is inside a table.
Each input tag is inside a td followed by a span. When the user clicks to edit a certain row a script hides the span (that holds the value of the input) and shows up the input. When the user click on another row (or creates a new one) the script picks the value of the input add it/change the span text and hides the input and shows up the span.
When user clicks on some row, it first selects the row adding the 'editing' class to it, and the second click put the focus on the input.
While I'm clicking inside the table all goes well; the problem is when I click outside of the table that contains the inputs or hit tab after the last input on the active row. The focus go somewhere else...
When one of those two action happens I want to 'deactivate the row', meaning pick up the values from the inputs on that row, add/change them in the span, hide the input and show the span.
Summary: need to fire this function when clicking outside of the table with a class of 'editable' or when 'tab away' on the last input of row...
function deactivateRows() {
//Deactivate editing on the rows
$('table.editable tr.editing').removeClass('editing');
$('table.editable').find('td').not('.delete').each(function () {
$(this).find('input').each(function () {
var inputContent = $(this).val();
$(this).prop('disabled', true).addClass('hide').attr('value', inputContent);
$(this).parent().find('span').html(inputContent).removeClass('hide');
});
});
}

I think the trick will be to traverse up the DOM from a clicked element, or the related element of a blur event, and see if you hit table.editable. Something like this:
var isInsideEditable = function (el) {
return !!el && $(el).closest('table.editable').length > 0;
};
$('select, input, textarea', '.editable').on('blur', function (e) {
if (!isInsideEditable(e.relatedTarget))
deactivateRows();
});
$(window).on('click', function (e) {
if (!isInsideEditable(e.target))
deactivateRows();
return false;
});

Related

create reset value button on select2

im using select2 and try to create a reset button for each select. i have 6 select.
my script is like this
$('.deggre').on('change', function() {
var deggre = $( this ).val();
var span = $("#dropdownMenu1").find('span').clone(); // Copy 'X' span.
$("#dropdownMenu1").text(deggre); // Insert text first.
$("#dropdownMenu1").append(span); // Then, append the 'X' span.
if($(this).val() == "")
$('#dropdownMenu1').css({"display": "none"});//value is none then hide
else
$('#dropdownMenu1').css({"display": "inline-block"});//have value then show
});
$("#dropdownMenu1").click(function(){
$(".deggre").val("");
});
my script didnt work for this case. how to solve this problem?
i need to show the button when we choose option on select2, and give innerHtml to the button. and then when the button click, its will reset his own select then the button is gone cause it didnt get the value.
heres my jsfiddle
https://jsfiddle.net/acvxeq8x/2/
You need to trigger the change
$("#dropdownMenu2").click(function(){
$(".position").val("").trigger('change');
});
I have updated your fiddle: https://jsfiddle.net/acvxeq8x/3/
Here is the simplified and minimal version of your code which is pretty straight forward. The code below seems long because of comments added within for explanation. Hope you will ignore them once you understand.
HTML Changes
<div class="wrap">
<!--Remove everything within wrap div and keep one copy of button in js to dynamically
construct the button tag-->
</div>
New CSS added
button.btnspl{
margin:10px;
/*Bit styling for dynamically created buttons*/
}
JS Changes
//Bind single change event to all your select element
$('.deggre,.position,.year').on('change', function() {
var ctrl=$(this); //reference for current element
var ctrlClass=ctrl[0].classList[0]; //get the first class which will be the class given
//to your original select element like deggre, position, year etc.,
$('button.btnspl[data-control="'+ctrlClass+'"]').remove();
//Since your select element is single select type, I hope you want to keep only one tag
//for each select. So, you remove other tags with above line
if(ctrl.val() == "")return; //return if value is empty, you aren't creating anything
var btn=$('<button class="btn btn-grey btnspl" type="button"><span class="glyphicon glyphicon-remove"></span></button>');
//Button copy from your wrap div
var option = $('<span>'+ctrl.val()+'</span>');
//get the selected option and place it in span
var span = $(deggre).insertBefore(btn.find('span'));
//insert the above created span before the glyphicon-remove in button
btn.attr('data-control',ctrlClass);
//the created button should have information about the control which created it
//so wrapping the ctrlClass [deggre, year, position] into data-* attribute of created button
//this will be used to remove particular button and clear its respective select,
//on different scenarios
$('.wrap').append(btn);
//append the button to .wrap div
});
//attaching close click event to glyphicon-remove.
//Read about event-delegation for dynamically created elements
//button is dynamically created here
$('.wrap').on('click','.glyphicon-remove',function(){
var ctrl=$(this).closest('.btn');
//get the parent of the clicked remove icon using closest
var ctrlClass=ctrl.attr('data-control');
//get its data-control attribute added during creation
$('.'+ctrlClass).val("").trigger('change');
//empty its value and trigger change
ctrl.remove();
//remove the control
})
JSFiddle DEMO

Using $.contains to find if an element contains another with focus

I have the following JQuery, which is part of the handling for double-clicking a table row. If the row contains an input box with active focus I want to exit the function, otherwise I want to proceed:
$("#foo tbody tr").dblclick(function() {
if ($.contains( $(this)[0], document.activeElement)) {
return;
}
// otherwise, do something with the row
});
However, it's not working: the conditional apparently always returns false (the activeElement not in the double-clicked row), even when the row does contain an input box with focus.
What's wrong?
EDIT: what I'm doing here is moving the row from one table to another when it is double-clicked. But each row contains a cell which contains text that can be clicked on to edit it (when the user clicks once on the cell text, it becomes an input box). What I find is that if the user is editing this cell but double clicks on the row, the move happens, which I want to avoid.
You can add a class to the element with focus and check for that in your doubleclick event. You can then remove the class whenever it's needed.http://jsfiddle.net/uq0ga86v/5/
$('input').focus(function(){
$('input').removeClass('focus');
$(this).addClass('focus');
})
$("#foo tbody tr").dblclick(function() {
if ($(this).find('input.focus').length != 0) {
alert('g');
}
// otherwise, do something with the row
$(this).find('input.focus').removeClass("focus");
});
Better handle the double click directly on the expected input, doing on a row will raise the blur event on any active element inside the row.
FYI, you can delegate that event to the row (see: Direct and delegated events)
$("#foo tbody tr")
.off(".nsActive")
.on("dblclick.nsActive", ".expected-input", function (e) {
//code here
});
Keep in mind that in this case we employed the event delegation to "#foo tbody tr" meaning that element must exist before delegating the dblclick event on ".expected-input" to it.
See jQuery.on: Event names and namespaces and Direct and delegated events.

Editable table (remove text and add text field on click) fires too many times

So I have this table that I want to make editable. In order to do so, I have a simple event listener that removes the text from the td element and appends a input field with that text as the value. The value of that text field is then appended to the td once the text field loses focus.
The problem is it fires when the user, for example, tries to highlight and delete the text (click).
I changed the selector to exclude the specific input field's class, but to no avail.
Javascript:
$(function() {
$('.text_field:not(.remove_text)').click(function() {
var text = $(this).text().trim(),
length = text.length;
$(this).empty()
.append("<input type='text' class='remove_text' size='"+length+"' value='"+text+"' />")
.find('.remove_text')
.focusout(function() {
$(this).closest('td').empty().append($(this).val());
})
.focus();
});
});
Here is a fiddle to show what I mean.
Is there something wrong with the selector or something?
An easy solution would be to add some logic to prevent emptying the table cell if it already contains an input element.
$('.text_field:not(.remove_text)').click(function() {
if( $(this).find('input').length > 0 ) {
return;
}
// your existing code
}
Here is a working example JS Fiddle
The selector is only used once for attaching the event listener. If you want to check the condition every time, it might be better to put it inside the handler:
$('.text_field').click(function(e) {
if ($(e.target).is(".remove_text") || $(e.target).closest(".remove_text").length > 0) return;
//Otherwise, execute code
});
Fiddle Here: http://jsfiddle.net/5uxf6yy7/3/

Change tabindex dynamically in jquery

Imagine this simple layout ( http://jsfiddle.net/4F9cL/ ).
We have a table, for each row i have a label a textbox and a checkbox.
The first textbox has tabindex = 1 , the first checkbox has tabindex = 2, the next textbox on the second row has tabindex = 3 and so on.
What i would like to do is change the tabindex on the checkbox on the same row for the textbox that im in if the content of the textbox has changed.
For example at the moment im checking the checkbox on the row that the thebox content has been changed, i do that with the following code:
$("input:text").change(function () {
$(this).parents('tr:first').find('input:checkbox').prop('checked', 'checked');
So the scenario is the following: If the content of the textbox hasnt changed, when i tab i want the focus to change to the checkbox on the same row. If the content of the textbox HAS changed, i would like the focus to be on the next textbox on the row below INSTEAD of the checkbox on the same row.
I hope i explained it good enough for you to understand what im trying to do.
I've tried using .removeprop() and .removeattr() but that doesnt work and when next tab hits it just goes to the bottom of the page.
$("input:text").change(...);
The change event of a textbox will only be executed once the textbox loses focus. This means that when you press Tab, that function has not yet run, and you'll end up with your old tabindex target.
$("input:text").keyup(...);
$("input:text").keydown(...);
These events will fire when you either press down on (keydown), or release (keyup) a button while the textbox is focused.
Something like this should do the trick:
$("input:text").keyup(function() {
var textBox = $(this);
var textBoxIsEmpty = textBox.val().length == 0; //I assume you use this to determine which element should be the next to get focused when pressing tab.
var currentTabIndex = parseInt( textBox.attr("tabindex") );
var nextTarget = GetNextTarget(textBoxIsEmpty); //not sure how you define this. This is the item you want to be your next target when you press tab.
var nextTabIndex = currentTabIndex + 1;
nextTarget.attr("tabindex", nextTabIndex);
});
Although I am not 100% sure if changing the tabindex dynamically works in every browser.
I have tried like that and it's working fine for me.
before applying this you should clear on this you have declare you tabindex in the input properly.
jQuery("input:text").keyup(function() {
currentTabIndex = parseInt(jQuery(this).attr("tabindex") );
nextTabIndex = currentTabIndex + 1;
jQuery('input[tabindex='+nextTabIndex+']').select();
});

row selection on row click but not on hyperlink click in one of the column in jquery datatable?

i have my customer dataTable which has five columns. one column contains hyperlink. One of the column is checkbox.
i want when user clicks on the row, that row should be selected(which means row color should change and checkbox
should be selected). i can do it with below code snippet
$("#customer").on('click', $.fn.getDataTablesClickHandler("#selectAll"));
//where customer is the html div associated with dataTable and call the same function which gets triggered
//on call of selectAll html element. Inside that function i toggle the class of row
It works great. But my problem is i dont want this to happen(i.e row seection) on click of link inside one of the column.
how i can do this?So basically how can i restrict firing getDataTablesClickHandler on click of certain link in a cell or
on click on cell?
Try this out, you want to check out which target is being clicked, and ignore it if it's an anchor tag.
$("#customer").on('click', function(event) {
if(event.target.tagName == 'A')
return;
$.fn.getDataTablesClickHandler("#selectAll").apply(this);
});
You could do something like this:
if customer is your table;
$("#customer").on('click', 'tr', function(){
if( !$(this).is('tr') )
return;
$.fn.getDataTablesClickHandler("#selectAll");
});

Categories