I have a selectlist with that is built using jquery inside a grid. When a user enters a key the select list is built, I then call click() and focus() so that I can use the key commands again.
The problem that I have is that .focus() is changing the selection of the select list when fired when it is fired. Has anyone experienced this behaviour before or found a workaround? Thanks in advance
function INTEREST_createPaymentTypeDropDown() {
//Interest specific:
//build a dropdown for the enum
//if the PaymentType input exists
if ($("#PaymentType").length > 0) {
var cellPaymentTypeValue = $("#PaymentType").val();
var selectedOption;
$("#PaymentType").replaceWith("<select id='PaymentType' style='width:95px; height: 20px;' name='PaymentType'></select>");
$.each(INTEREST_PAYMENT_TYPES, function(key, val) {
var newoption = $("<option value=\"" + val + "\">" + key + "</option>");
if (val == cellPaymentTypeValue || key == cellPaymentTypeValue) {
//append select to the current value
selectedOption = val;
}
$("#PaymentType").append(newoption);
$("#PaymentType").addClass("t-input");
});
if (selectedOption != null) {
$("#PaymentType").val(selectedOption.toString());
}
}
function INTEREST_setEditField(field) {
if ($("#PaymentType").length > 0) {
// this is where the problem is
$("#PaymentType").click();
}
else {
$(".t-grid-content").find('.t-input').click();
$(".t-grid-content").find('.t-input').select();
}
INTEREST_persistPaymentTypeOnCellChange(field);
}
function INTEREST_persistPaymentTypeOnCellChange(field) {
//keep the value of the enum not the enum index
//in the payment type field
var paymentTypeCell = $(field).parent().children().eq(1);
if ($(paymentTypeCell).html().length == 1) {
$.each(INTEREST_PAYMENT_TYPES, function(key, val) {
if ($(paymentTypeCell).html() == val) {
$(paymentTypeCell).html(key);
}
});
}
}
$('td.t-grid-edit-cell', 'div#AccountPayments').live('keydown', function(event) {
if (event.which == 39 || event.which == 9) //Tab or right arrow
{
if ($(this).hasClass('t-last')) {
INTEREST_goToNextRow(this, event);
}
else {
INTEREST_goToRight(this, event);
}
}
else if (event.which == 37 || event.which == 9 && event.shiftKey) //left arrow. Todo: add shift tab
{
if ($(this).hasClass('t-first')) {
INTEREST_goToPreviousRow(this, event);
}
else {
INTEREST_goToLeft(this, event);
}
}
else if (event.which == 40) //down arrow
{
INTEREST_goDown(this, event);
}
else if (event.which == 38) //up arrow
{
INTEREST_goUp(this, event);
}
});
$("#PaymentType").live('click', function(event) {
$(this).focus();
});
Could it be that there's no empty option at the top of the list so that when the click() is called it's causing PaymentType to auto-select the 0th option?
Related
I'm making a custom dropdown and want to make good keyboard support. How do I get focus on my first LI when the UL visible. Didn't find answer by my self.
I take code from there https://codepen.io/beforesemicolon/pen/abNpjKo
On CodePen focus on first element works. But on my page - no... please, tell me if you know :)
Here is the code:
function DropDown(dropDown) {
const [toggler, menu] = dropDown.children;
const handleClickOut = e => {
if(!dropDown) {
return document.removeEventListener('click', handleClickOut);
}
if(!dropDown.contains(e.target)) {
this.toggle(false);
}
};
const setValue = (item) => {
const val = item.textContent;
toggler.textContent = val;
this.value = val;
this.toggle(false);
dropDown.dispatchEvent(new Event('change'));
toggler.focus();
}
const handleItemKeyDown = (e) => {
e.preventDefault();
if(e.keyCode === 38 && e.target.previousElementSibling) { // up
e.target.setAttribute("aria-selected", "false");
e.target.previousElementSibling.setAttribute("aria-selected", "true");
e.target.previousElementSibling.focus();
} else if(e.keyCode === 40 && e.target.nextElementSibling) { // down
e.target.setAttribute("aria-selected", "false");
e.target.nextElementSibling.setAttribute("aria-selected", "true");
e.target.nextElementSibling.focus();
} else if(e.keyCode === 27) { // escape key
this.toggle(false);
} else if(e.keyCode === 13 || e.keyCode === 32) { // enter or spacebar key
setValue(e.target);
}
}
const handleToggleKeyPress = (e) => {
e.preventDefault();
if(e.keyCode === 27) { // escape key
this.toggle(false);
} else if (e.keyCode === 13 || e.keyCode === 32) { // enter or spacebar key
this.toggle(true);
} else if (e.shiftKey && e.keyCode === 9) { // tab + shift key
this.toggle(false);
document.getElementById("message_email").focus();
} else if (e.keyCode === 9 ) { // tab key
this.toggle(false);
document.getElementById("message_text").focus();
}
}
toggler.addEventListener('keydown', handleToggleKeyPress);
toggler.addEventListener('click', () => this.toggle());
[...menu.children].forEach(item => {
item.addEventListener('keydown', handleItemKeyDown);
item.addEventListener('click', () => setValue(item));
});
this.element = dropDown;
this.value = toggler.textContent;
this.toggle = (expand = null) => {
expand = expand === null ? menu.getAttribute("aria-expanded") !== "true" : expand;
menu.setAttribute("aria-expanded", expand);
if(expand) {
menu.children[0].focus();
toggler.classList.add('active');
menu.children[0].focus();
document.addEventListener('click', handleClickOut);
dropDown.dispatchEvent(new Event('opened'));
//toggler.blur();
} else {
toggler.classList.remove('active');
toggler.focus();
dropDown.dispatchEvent(new Event('closed'));
document.removeEventListener('click', handleClickOut);
}
}
}
const dropDown = new DropDown(document.querySelector('.message__dropdown'));
Heh... problem was in CSS. Property {transition-duration} was written by me for UL (I mean for changing background color, but I didn't choose {transition-property}).
After I remove {transition-duration} focusing is working well. Oh my God... it tooks fore hours
I have joined a script called jquery.mycart with datatable.
document.onkeydown = function(evt) {
evt = evt || window.event;
var isEscape = false;
if ("key" in evt) {
isEscape = (evt.key == "Enter" || evt.key == "Enter");
} else {
isEscape = (evt.keyCode == 13);
}
if (isEscape) {
table.rows( { search:'applied' } ).data().each(function(value, index) {
console.log(value, index);
});
}
};
I have a problem that when we suppose we search for "Antalgina" when we press enter this search is added to the shopping cart. (look at the console).
Full code
https://codepen.io/anon/pen/oaQJNg
Please how could I do it or give me some hint
I hope you can help me.
Working codePen.
You could a simple jQuery event like :
$("document").on('onkeydown', function (e) {
if (e.keyCode !== 13) {
table.rows( { search:'applied' } ).data().each(function(value, index) {
console.log(value, index);
});
});
});
I have text area controls in my page and I had code it such way that when user click on text area or hit 'ENTER' key that time it will create bullet-list in text area. But problem is that if user click on text area and it will create bullet-list but if user does not type anything in text area then it should get empty and bullet should be removed. In simple way text area bullet-list should get removed if it has no data in it.
And one more thing is to prevent user deleting bullet from text area.
here is my code :
<textarea name="MondayAcomp" id="MondayAcomp" cols="45" rows="5" onKeyDown="if(event.keyCode == 13) return false;" onKeyUp="bulletOnEnter(this.id)" onFocus="onfoc(this.id)" onBlur="onFocOff(this.id)" style="margin: 0px; width: 200px; height: 219px;"></textarea>
Javascript functions:
function onfoc(id) {
if (document.getElementById(id).value == "") {
document.getElementById(id).value += '• ';
}
}
function onFocOff(id) {
if (document.getElementById(id).value == '• ') {
document.getElementById(id).empty;
}
}
function bulletOnEnter(id) {
var keycode = (event.keyCode ? event.keyCode : event.which);
if (keycode == '13') {
event.preventDefault();
document.getElementById(id).value += '\n• ';
}
var txtval = document.getElementById(id).value;
if (txtval.substr(txtval.length - 1) == '\n') {
document.getElementById(id).value = txtval.substring(0, txtval.length - 1);
}
}
jsfiddle here
It is not .empty, it is .value = "";.
For the keyCode you need to pass event parameter to your callback function too.
You can prevent adding empty lines, by checking the last line in your return key callback too.
Only way I can imageine, to prevent deleting the bullets, is a loop at the end and check each line start.
function onfoc(id) {
if( document.getElementById(id).value == '' ) {
document.getElementById(id).value +='• ';
}
}
function onFocOff(id) {
if( document.getElementById(id).value == '• ' ) {
document.getElementById(id).value = '';
}
}
function bulletOnEnter(event, id) {
event = event || window.event;
// handle 'return' key
var keycode = event.keyCode || event.charCode || event.which;
var txtval = document.getElementById(id).value;
if( keycode == 13 && txtval.substr(txtval.length - 2) != '• ' ) {
event.preventDefault();
document.getElementById(id).value += '\n• ';
}
// remove possible last empty line
txtval = document.getElementById(id).value;
if( txtval.substr(txtval.length - 1) == '\n' ) {
document.getElementById(id).value = txtval.substring(0, txtval.length - 1);
}
// check if each line starts with a bullet
var lines = document.getElementById(id).value.split('\n')
for( var i = 0, l = lines.length; i < l; i++ ) {
if( lines[i].substr(0, 1) !== '•' ) {
lines[i] = '•' + lines[i];
}
}
document.getElementById(id).value = lines.join('\n');
}
<textarea id="MondayAcomp" onKeyDown="if(event.keyCode == 13) return false;" onKeyUp="bulletOnEnter(event, this.id)" onFocus="onfoc(this.id)" onBlur="onFocOff(this.id)"></textarea>
As additional answer, I converted the code to use jQuery instead of plain JS, because you tagged your question with jQuery.
$('#MondayAcomp').on({
focus: function() {
if( $(this).val() == '' ) {
$(this).val($(this).val() + '• ');
}
},
blur: function() {
if( $(this).val() == '• ' ) {
$(this).val('');
}
},
keydown: function(e) {
if( e.keyCode == 13 ) {
e.preventDefault();
}
},
keyup: function(e) {
var element = $(this),
value = element.val();
// handle 'return' key
if( e.keyCode == 13 && value.substr(-2) != '• ' ) {
e.preventDefault();
element.val((value += '\n• '));
}
// remove possible last empty line
if( value.substr(-1) == '\n' ) {
element.val((value = value.substring(0, value.length - 1)));
}
// check if each line starts with a bullet
var lines = element.val().split('\n')
for( var i = 0, l = lines.length; i < l; i++ ) {
if( lines[i].substr(0, 1) !== '•' ) {
lines[i] = '•' + lines[i];
}
}
element.val(lines.join('\n'));
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="MondayAcomp"></textarea>
I am trying to format the phone number field based on the country .The logic works fine when the user fill in the details but does not work when the country is changed and filled in again.
Ex:
Filled in the form for Germany and then without reloading the page if try change county to US and fill in phone "+" is being added even though format for it is different.
$(document).ready(function($){
$('#country').on('change', function() {
if ( this.value == 'US' || this.value == 'CA')
{
$('#C_BusPhone')
.keydown(function (e) {
var key = e.charCode || e.keyCode || 0;
$phone = $(this);
if (key !== 8 && key !== 9) {
if ($phone.val().length === 4) {
$phone.val($phone.val() + ')');
}
if ($phone.val().length === 5) {
$phone.val($phone.val() + ' ');
}
if ($phone.val().length === 9) {
$phone.val($phone.val() + '-');
}
}
return (key == 8 ||
key == 9 ||
key == 46 ||
(key >= 48 && key <= 57) ||
(key >= 96 && key <= 105));
})
.bind('focus click', function () {
$phone = $(this);
if ($phone.val().length === 0) {
$phone.val('(');
}
else {
var val = $phone.val();
$phone.val('').val(val);
}
})
.blur(function () {
$phone = $(this);
if ($phone.val() === '(') {
$phone.val('');
}
});
}
else
{
$('#C_BusPhone')
.keydown(function (e) {
if ($(this).val().indexOf("+") === -1) {
$(this).val("+" + $this.val());
}
})
}
});
});
Not sure if this was the cause for your error, but this line needs to get corrected from
$(this).val("+" + $this.val());
to this
$(this).val("+" + $(this).val());
It was a fast catch, just use your browser javascript console for debugging.
See the updated fiddle here. You might want to add the starting parenthesis to your international prefix as well.
I am trying to create a drop down like functionality where a div is shown once somebody starts typing in the input box. I am able to attach mouse click event on the individual elements to select them. But I am not able to select them via pressing enter.
HTML
<input type="text" class="input" name="example" id="example" placeholder="example..." autocomplete="off" list="examplelist" />
<div class="autofill">
<ul class="autocomplete">
<li class="autocomplete-list">John Doe (San Jose, CA)</li>
<li class="autocomplete-list">Jane Doe (San Francisco, CA)</li>
<li class="autocomplete-list">John Jane (San Carlos, CA)</li>
</ul>
</div>
JQuery
$(document).ready(function () {
var $listItems = $('li.autocomplete-list'),
$div = $('div.autofill'),
$input = $('#example');
$div.hide();
$('input#example').on('keydown', function (e) {
var key = e.keyCode,
$selected = $listItems.filter('.selected'),
$current;
$div.show();
if (key != 40 && key != 38) return;
$listItems.removeClass('selected');
if (key == 40) { // Down key
if (!$selected.length || $selected.is(':last-child')) {
$current = $listItems.eq(0);
} else {
$current = $selected.next();
}
} else if (key == 38) { // Up key
if (!$selected.length || $selected.is(':first-child')) {
$current = $listItems.last();
} else {
$current = $selected.prev();
}
}
$current.addClass('selected');
// When I press enter after selecting the li element
// Does not work :(
$current.on('keypress keydown keyup', 'li', function (event) {
if (event.keyCode == 13) {
var value = $(this).text().split('(')[0].trim();
$input.val(value) ;
$div.hide();
}
});
});
// If somebody clicks on the li item
$('li.autocomplete-list').on('click', function (e) {
var value = $(this).text().split('(')[0].trim();
$input.val(value);
$div.hide();
});
// change color on hover
$('li.autocomplete-list').hover(
function(){ $(this).addClass('hover') },
function(){ $(this).removeClass('hover') }
);
// When I press enter after selecting the li element
// Does not work :(
$('li.autocomplete-list').on('keypress keydown keyup', 'li', function (event) {
if (event.keyCode == 13) {
var value = $(this).text().split('(')[0].trim();
$input.val(value) ;
$div.hide();
}
});
});
How can I select a particular li element and then take its value when press enter? Here is the JSFiddle
The <li> element doesn't have focus, even though it's selected visually. The text input still has focus.
You need to check for the enter key on the text <input>. Not on the <li>
$('input#example').on('keydown', function (e) {
//...
var key = e.keyCode
if (key == 40) { // Down key
//...
} else if (key == 38) { // Up key
//...
} else if (key == 13) { // Enter key
//... make sure $current is not null
}
//...
}
Also be careful of this statement
if (key != 40 && key != 38) return;
Which will return from the event handler when the enter key is pressed.
Here's a fiddle: http://jsfiddle.net/q1vtwtdp/4/
Jordan P is correct, the handling of the list should all happen within the keydown handler function of the input.
$('input#example').on('keydown', function (e) {
var key = e.keyCode,
$selected = $listItems.filter('.selected'),
$current;
$div.show();
$listItems.removeClass('selected');
if (key == 40) { // Down key
if (!$selected.length || $selected.is(':last-child')) {
$current = $listItems.eq(0);
} else {
$current = $selected.next();
}
}
if (key == 38) { // Up key
if (!$selected.length || $selected.is(':first-child')) {
$current = $listItems.last();
} else {
$current = $selected.prev();
}
}
if (key == 13) {
var value = $('.autocomplete-list').html().split('(')[0].trim();
$input.val(value);
$div.hide();
$current = $selected
}
$current.addClass('selected');
});
So you don't need:
$('li.autocomplete-list').on('keypress keydown keyup', 'li', function (event) {
if (event.keyCode == 13) {
var value = $(this).text().split('(')[0].trim();
$input.val(value) ;
$div.hide();
}
});
Working JSFiddle