Change tabindex dynamically in jquery - javascript

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();
});

Related

How to use Javascript to click on an html item (A spreadsheet text box?) that has a different ID each time you click?

I am a teacher with the worst possible slow gradebook, so much so that I would like to use some code to automate it. Basically to submit a grade I need to:
Find the cell box and click on it once to show the submit button
Then click on the button
HOWEVER: Every time you click on the box or button it gives it a new html ID. Therefore I need some code that looks for all the boxes and buttons and hits them. I am not sure how to do this without a static ID.
My code is most definitely formatted improperly, I am a total beginner.
var selectorBox = ['name_of_cell']
var selectorCollection = ['name_of_button']
selectorBox.forEach((s) =>{
let element = document.querySelector(s);
if(element) element.click();
else console.warn('No element found for the supplied selector:', s);
});
selectorCollection.forEach((s) =>{
let element = document.querySelector(s);
if(element) element.click();
else console.warn('no element found for the supplied selector:', s);
});
I need help:
Reformatting to the proper syntax / spacing etc.
Writing a function that finds and clicks on the box THEN the button (the above works).
Making my code look for the boxes then buttons, however as mentioned above the ID for each box and button switches every time you click on one, and for each different class i have (I have about 400 students.)
If you can select cells/buttons by class, you can loop through all cells, "click" them, and then "click" the button once it appears.
var cells = document.querySelectorAll('.x-grid-cell');
cells.foreach((cell) => {
cell.click();
var button = document.querySelector('.class_of_your_button')
button.click()
})

Deselect after focus

I am switching between different projects by on change event on select element. I am getting them from DB. But before loading different project i have to store name of previous one.For that i am using on focus event.
How can i then deselect my select element?
document.getElementById("selectProject").selected = false;
is not working.
var whichProjectToSave;
function onFocusSelectProject(){
//for saveJsonF();
whichProjectToSave=document.getElementById("selectProject").value;
}
function callSettingswindow(){
saveJsonF();
canvas.clear();
getJsonF();////////////////////////////////////
document.getElementById("selectProject").selected = false;
}
document.getElementById("selectProject").onchange= callSettingswindow;
To make it clear: How to deselect "select" element after change is performed?
I am not aware of any methods that will let you "de-focus" from an element. But you could focus on any other element - as a result the select element will lose focus.
You could make use of jQuery if you wanted to programmatically focus on the element with next tab index. See this answer for more details.

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

Focus on first input after row is cloned

so I'm pretty sure that I'm doing everything right, but I'm probably missing an event somewhere or something.
Here's what I've got. I have a table and it is filled with a row of inputs, just one row to start. There are four columns and on the fourth column of each row I have attached the focusout event. On focusout clone the last row and add a new row, with the first input of the new row being the focus so that they can just tab and continue.
What is not happening is that the first input is not getting the focus. So I'm trying to figure out why this is occurring.
I have a link to the fiddle and my code is below. Thank you for any help ahead of time!
jQuery
$(function(){
var $lastRow = $('#testTable').find('tr:last');
var $tbody = $('#textTabl').find('tbody');
var $lastCell = $('#testTable').find('tr:last').find('td:last').prev().find('input');
$($lastRow).find("td:first > input").focus();
$('body').on('focusout',$lastCell,function(){
var $newRow = $($lastRow).clone(true, true);
$($lastRow).addClass('last');
$($newRow).insertAfter($lastRow);
$lastRow = $('#testTable').find('tr:last');
$($lastRow).find("td:first > input").focus();
});
});
fiddle
http://jsfiddle.net/dh0kxtLv/1/
EDITS & UPDATES
Currently using the new code above to experiment in my fiddle, but it's creating an odd behavior where the only cell that gets the focus is the first one, and if I try to focus out it duplicates the row and focuses on the next first cell. So it's kind of working but still failing
I believe the problem you are experiencing is that the last cell is the last focusable element within the document. So by the time the focusout event is fired, focus has left the document which would remove your ability to focus any element.
Using your original code, simply adding an invisible focusable element below your table would avoid the issue:
http://jsfiddle.net/dh0kxtLv/6/
Note the inclusion of <div tabindex='0'></div> after the table.
To much code, just use:
$(function(){
$('body').on('focusout','#testTable input:last',function(){
var el=$(this);
el.closest('tr').clone().insertAfter(el.closest('tr'))
el.closest('table').find('tr:last input:first').focus();
})
});

HTML: Get value from input with no ID

Been looking around and I cant seem to find an answer to this so maybe im wording it wrong but here it goes.
So I have a table displaying data from a database. In jQuery I have made it so a row can be added with empty inputs and then submitted to the database, this works fine.
I am now attempting to be able to edit it. So each row will have a button to edit that row, the button will put the row values into inputs so you can change the value and update the database. How can I do this? I was looking into using this here but Im not sure how I can get the value of the input boxes without them having some sort of ID.
jQuery I was trying to use:
$('#tbl').on('click','.xx',function() {
$(this).siblings().each(
function(){
if ($(this).find('input').length){
$(this).text($(this).find('input').val());
}
else {
var t = $(this).text();
$(this).text('').append($('<input />',{'value' : t}).val(t));
}
});
});
Am I over thinking this? Should I just be grabbing the values and then putting them in pre-made input boxes?
Update:
HTML:
sb.AppendLine("<table style='width: 80%;'>")
sb.AppendLine("<tr class='inputRowbelow'>")
sb.AppendLine("<td style='width: 20%;' class='ui-widget-header ui-corner-all'>Area</td>")
sb.AppendLine("<td class='ui-widget-header ui-corner-all'>Details</td>")
sb.AppendLine("<td class='ui-widget-header ui-corner-all'>Options</td>")
sb.AppendLine("</tr>")
For Each w In workItems
sb.AppendLine("<tr>")
sb.AppendLine("<td>" & w.area & "</td>")
sb.AppendLine("<td>" & w.details & "</td>")
sb.AppendLine("<td><a href='#' class='fg-button ui-state-default ui-corner-all edit'><img src='/images/spacer.gif' class='ui-icon ui-icon-pencil' /></a></td>")
sb.AppendLine("</tr>")
Next
sb.AppendLine("</table>")
There are a couple of ways to do this, including changing your VB code to add extra data to the html, but I will answer this from a pure javascript/JQuery solution.
First of all you need to handle the click event for each edit button, after that you find the matching row, and then you can get the first to td elements of that row...
$(".edit").click(function(e){
e.preventDefault();//prevent the link from navigating the page
var button = $(this);//get the button element
var row = button.closest("tr");//get the row that the button belongs to
var cellArea = row.find("td:eq(0)");//get the first cell (area)
var cellDetails = row.find("td:eq(1)");//get the second cell (details)
//now you can change these to your inputs and process who you want
//something like this...
ConvertToInput(cellArea, "area");
ConvertToInput(cellDetails, "details");
});
function ConvertToInput(element, newId){
var input = $("<input/>");//create a new input element
input.attr("id", newId);//set an id so we can find it
var val = element.html();//get the current value of the cell
input.val(val);//set the input value to match the existing cell
element.html(input);//change the cell content to the new input element
}
Here is a working example
From that you can then do the saving that you say you have already implemented, using the ID values of each field to get the values to save.
Instead of using a For Each ... in ... Next loop, use a a For loop with a counter. give each button and each row an ID with the current counter value at the end. You can then use Jquery to make each row editable separately, because each row has a row number now.

Categories