Kendo Combo box always selecting first item on Tab - javascript

I have the following code in my Kendo Combo Box:
.Events(events =>
{
events.Select("carUpdate");
events.DataBound("dropDownBind");
})
My carUpdate js method is then as below:
function carUpdate(e) {
debugger;
var rowData = getRowData(e, this);
//If enough data is given to identify unique technology autocomplete the row
var grid = $grid.data('kendoGrid');
if (isUniqueManufacturerDataProvided(rowData)) {
rowData.CarName = this.dataItem(e.selectedIndex).Name;
rowData.CarId = this.dataItem(e.selectedIndex).Id;
return;
}
if (this.selectedIndex === null || this.selectedIndex === -1
|| e.sender._last === kendo.keys.TAB) {
rowData.CarName = pleaseSelect;
rowData.CarId = null;
//$("#Car").data("kendoComboBox").value(pleaseSelect);
//$("#Car").data("kendoComboBox").trigger("close");
return;
} else {
rowData.CarName = this.dataItem(e.selectedIndex).Name;
rowData.CarId = this.dataItem(e.selectedIndex).Id;
}
}
If my ComboBox Contains AB, ABC, ABCD, ABCDE
If I enter A and press the Tab Key I want the combo box to revert to my Please Select Option and move to the next Field in the grid. However what I am finding is the if I just Enter A and press Tab the AB option is getting selected in the box. The other behaviour I want is that ABCDE is entered (i.e - enough data so the combox is filtered to only 1 option) and the Tab key is pressed this option is selected and the cursor moves to the next field in the grid. Is there something I have missed in my js to make this work

Related

Angular: Tabkey Press not Populating fields

I'm new to Angular, I have a component which contains some basic fields and dropdown menu.When I select anything from dropdown using tab key the other related field are not getting populated,But it works with mouse click.
receipt-creation.component.ts
populateItems(event: any, obj) {
this.receiptForm.valueChanges.subscribe(() => {
const dirty = this.isFormDirty(this.receiptForm);
if (dirty) {
this.unsavedChanges = true;
}
});
this.receiptLineItems = obj.itemList; // obj.itemList contain the values related to selected item
this.changeDetectorRef.detectChanges();
this.updateSubtotal(); // this function caluclate the total based on the item selected from the dropdown
}
receipt-creation.component.html
<add-new-row
[addNewText]="INVOICE_CONSTS.ADD_LINE_ITEM"
[canAutoAddNewRow]="false"
[checkPristine]="true"
[type]="'receipt'"
[data]="lineItemsMetaData"
[form]="receiptCreationForm"
[triggerExtraAddNewKey]="true"
[itemList]="receiptLineItems"
(changeItemEvent)="populateItems($event, receiptCreationForm)"
(keydown.enter)="preventFormSubmission($event)"
></add-new-row>
With event.preventDefault() the fields gets populated, but I want the default behaviour of tab key to be working.

Different behaviors on jQuery row deselect, and I don't understand why

I have two variations of code, each variation has a desired behavior, and an undesired behavior... But I don't understand why this is happening, or how to combine them to get both desired behaviors. (I've tried different variations of if/else statements trying to get both of the desired behaviors in one code, but I'm unsuccessful so far.
Variation 1: http://jsfiddle.net/crashvector/q81m7sab/15/
Correct behavior: You can select a row, change the drop down that appears, (the drop down value writes to the table) and you can deselect the row. (The check-uncheck column updates from a 1 to a 0.)
Undesired behavior: You can select a row, and then immediately deselect it. The check-uncheck column updates from 1 to 0, BUT the drop down doesn't write it's current value to the table and disappear.
}).on('deselect', function (e, dt, type) {
var dt_indexes = dt[0]
if (type === 'row') {
$.each( dt_indexes, function ( index ) {
var row = dataTable.row( dt_indexes[index] );
if(!Category && !Category.length) {
writeCell($(row.node()).find('select'));
};
toggleDataAndDraw(row, type, 0);
} );
}
dataTable.draw();
});
var writeCell = dropdown => {
var currentRow = dataTable.row(dropdown.closest('tr'));
var rowData = currentRow.data();
rowData.Category = dropdown.val();
$(currentRow.node()).find('td:eq(6)').html(
currentRow.data().Category
);
currentRow.draw();
};
Variation 2: http://jsfiddle.net/crashvector/q81m7sab/16/
Correct behavior: You can select a row, and then immediately deselect it. The check-uncheck column updates from 1 to 0, the drop down value writes to the table and disappears.
Undesired behavior: You can select a row, change the drop down that appears, (the drop down value writes to the table) and you can deselect the row. BUT the check-uncheck column DOESN'T update from a 1 to a 0.
}).on('deselect', function (e, dt, type) {
var dt_indexes = dt[0]
if (type === 'row') {
$.each( dt_indexes, function ( index ) {
var row = dataTable.row( dt_indexes[index] );
//if(!Category && !Category.length) {
writeCell($(row.node()).find('select'));
//};
toggleDataAndDraw(row, type, 0);
} );
}
dataTable.draw();
});
var writeCell = dropdown => {
var currentRow = dataTable.row(dropdown.closest('tr'));
var rowData = currentRow.data();
rowData.Category = dropdown.val();
$(currentRow.node()).find('td:eq(6)').html(
currentRow.data().Category
);
currentRow.draw();
};
END GOAL One function that has both correct behaviors and neither undesired behavior.
From your jsFiddle "Variation 1"... Simply change the condition (on line #222):
if(!Category && !Category.length) {
to:
if($(row.node()).find('select').length){
So it will execute writeCell() if the <select> is still present when the user is unchecking the row.

How can I hide an element when a user selects an option, navigates away, or selects the same option?

I'm practicing some JQuery and am working on a simple app that asks the user what their favorite food and drink are.
I'm trying to create the app so that the resulting text... "Your favorite food is x, and drink is y", only shows when the user has actually selected their favorite food/drink and when they aren't actively selecting.
My problem is, I can't figure out how to hide the resulting text while the user is selecting the options, in a manner that also has the ability to show the text once the selects are made. I used a change() method which allows me to show the text when they select something new. But what about if the user clicks away, or selects the same option?
Thoughts?
Here's the code...
http://codepen.io/zharriott/pen/oZxvBO?editors=1011
$(document).ready(() => {
/******************
REFERENCES
******************/
const $foodSelector = $('.questions__q1'),
$drinkSelector = $('.questions__q2'),
$dropdownInputs = $('.questions select'),
$foodResultTxt = $('.result__fav-food'),
$drinkResultTxt = $('.result__fav-drink'),
$result = $('.result'),
$resultTxt = $result.text();
/******************/
$dropdownInputs.change(() => {
//IF food/drink has not been selected, leave result hidden
if ( $foodSelector.find(':selected').text() === 'Select an option...' || $drinkSelector.find(':selected').text() === 'Select an option...' ) {}
else {
//Update and show result to display user's current answers
$foodResultTxt.text($foodSelector.find(':selected').text());
$drinkResultTxt.text($drinkSelector.find(':selected').text());
console.log($resultTxt);
$result.show(1400);
}
});
});
Thoughts?
You can consider saving the current value of the input with the focus event and then comparing the selected value after change with both the previous one and the placeholder.
$dropdownInputs.focus(function(){
var oldFoodValue = $foodSelector.find(':selected').text();
var oldDrinkValue = $drinkSelector.find(':selected').text();
}).change(() => {
//IF food/drink has not been selected or is equal to the previous value, leave result hidden
if ( $foodSelector.find(':selected').text() === 'Select an option...' ||
$drinkSelector.find(':selected').text() === 'Select an option...' ||
$foodSelector.find(':selected').text() === oldFoodValue ||
$drinkSelector.find(':selected').text() === oldDrinkValue) {}
else {
//Update and show result to display user's current answers
$foodResultTxt.text($foodSelector.find(':selected').text());
$drinkResultTxt.text($drinkSelector.find(':selected').text());
console.log($resultTxt);
$result.show(1400);
}
});
$foodResultTxt.hide();
and when need to show:
$foodResultTxt.show();

How do I clear / reset a Kendo DropDownList with only javascript?

I have a Kendo DropDownList (name=Function) that contains 3 options. When one option is selected, it triggers an ajax call to get data to populate a different DropDownList (name=Parents). This works as-expected. However, if the user then changes the original DropDownList "Function" back to a different selection, I need to clear/reset (remove all options) and disable the "Parents" DropDownList.
function LoadKendoDropdownContents(dropdownBoxId, data) {
var dropdownBox = $("#" + dropdownBoxId).data("kendoDropDownList");
if (data === "" || data === null || $.isEmptyObject(data)) {
var dataSource = [];
}
else {
var dataSource = data;
}
dropdownBox.setDataSource(dataSource);
}
It's really the "var dataSource = []" that is giving me problems. It's like the "Parents" DropDownList isn't refreshing/rebinding when that is applied. All of the options except the one that was selected get removed, but how do I remove the one that was previously selected? I want it to be "empty" again.
Thank you.
---- Solution I used ----
function LoadKendoDropdownContents(dropdownBoxId, data) {
var dropdownBox = $("#" + dropdownBoxId).data("kendoDropDownList");
if (data === "" || data === null || $.isEmptyObject(data)) {
var dataSource = new kendo.data.DataSource({
data: []
});
dropdownBox.text(" --- ");
dropdownBox.value(-1);
}
else {
var dataSource = new kendo.data.DataSource({
data: data
});
dropdownBox.text("[Select]");
dropdownBox.value(-1);
}
dropdownBox.setDataSource(dataSource);
}
It might be easier to use the cascading dropdown feature.
When you change the dataSource, it removes the dropdown items, but you also need to clear the selected text and disable the box, by calling:
dropdownBox.setDataSource(dataSource);
dropdownBox.text('');
dropdownBox.enable(false);
If you have defined a data source for both the parent and child drop down then you could use the cascadeFrom('parent') method in the child and set a value that you can identify as null or clear.

label inside combobox and conditional multiselect

I am building a pretty combobox with checkboxes and conditional entries. Everything works out alright, except for two features that I cannot figure out how to implement.
1) I would like to move the label inside the combobox, make it shift the values to the right, and appear in a slightly gray color.
2) I would like the value to ignore certain entries (group headers) selected. Those entries are there for functionality only - to select/unselect groups of other entries.
The entire project is in the zip file. You don't need a server, it's a client base app. Just download the archive, unpack, and launch app.html in your browser.
http://filesave.me/file/30586/project-zip.html
And here's a snapshot of what I would like to achieve.
Regarding your second issue, the best way I see is to override combobox onListSelectionChange to filter the values you don't want:
onListSelectionChange: function(list, selectedRecords) {
//Add the following line
selectedRecords = Ext.Array.filter(selectedRecords, function(rec){
return rec.data.parent!=0;
});
//Original code unchanged from here
var me = this,
isMulti = me.multiSelect,
hasRecords = selectedRecords.length > 0;
// Only react to selection if it is not called from setValue, and if our list is
// expanded (ignores changes to the selection model triggered elsewhere)
if (!me.ignoreSelection && me.isExpanded) {
if (!isMulti) {
Ext.defer(me.collapse, 1, me);
}
/*
* Only set the value here if we're in multi selection mode or we have
* a selection. Otherwise setValue will be called with an empty value
* which will cause the change event to fire twice.
*/
if (isMulti || hasRecords) {
me.setValue(selectedRecords, false);
}
if (hasRecords) {
me.fireEvent('select', me, selectedRecords);
}
me.inputEl.focus();
}
},
And change your onBoundlistItemClick to only select and deselect items in the boundlist not to setValue of the combo:
onBoundlistItemClick: function(dataview, record, item, index, e, eOpts) {
var chk = item.className.toString().indexOf('x-boundlist-selected') == -1;
if ( ! record.data.parent) {
var d = dataview.dataSource.data.items;
for (var i in d) {
var s = d[i].data;
if (s.parent == record.data.id) {
if (chk) { // select
dataview.getSelectionModel().select(d[i],true);
} else { // deselect
dataview.getSelectionModel().deselect(d[i]);
}
}
}
}
},
Regarding your first issue, it is easy to add the label using the displayTpl config option. But this will only add the text you need, without any style (grey color, etc). The combo is using a text input, which does not accept html tags. If you don't need the user to type text, than you may want to change the combo basic behavior and use another element instead of the text input.

Categories