ExtJS: How to pass keystrokes from text field to Grid? - javascript

I have following grid declaration:
quickSearchGrid = Ext.create('Ext.grid.Panel', {
height: 500,
collapsible: true,
.....
Then, I have input element above it:
<input type="text" id="quickSearch" value="Search" style="height: 25px; width: 100%;" />
I want to pass specific keystrokes - Up, Down, PgUp, PgDown etc from input to grid. So that when user has focus in text field, he'll be able to navigate in the grid with keyboard.
What I'm trying is creating my own KeyNav:
var nav = Ext.create('Ext.util.KeyNav', Ext.get('quickSearch'), {
scope: Ext.get('quickSearch'),
down: function (e) {
console.log(e)
quickSearchGrid.fireEvent('keydown', quickSearchGrid, e)
}
});
Function is being called (it writes to console) but grid does not react.

Found a workaround you could use. Create the text input in extJs instead of declaring it in html:
var quickSearch = Ext.create('Ext.form.field.Text', {
id: 'quickSearch',
name: 'quickSearch',
fieldLabel: 'QuickSearch',
allowBlank: true
});
You can then use it for navigation in the grid with arrows by selecting a record with index 1 higher/lower than the one currently selected:
var grid = quickSearchGrid;
var view = quickSearchGrid.getView();
var nav = Ext.create('Ext.util.KeyNav', Ext.getDoc(), {
down: function(e) {
var selectionModel = grid.getSelectionModel();
var select = 0; // select first if no record is selected
if ( selectionModel.hasSelection() ) {
select = grid.getSelectionModel().getSelection()[0].index + 1;
}
view.select(select);
quickSearch.focus(); // to get focus back to the input
},
up: function(e) {
var selectionModel = grid.getSelectionModel();
var select = grid.store.totalCount - 1; // select last element if no record is selected
if ( selectionModel.hasSelection() ) {
select = grid.getSelectionModel().getSelection()[0].index - 1;
}
view.select(select);
quickSearch.focus(); // to get focus back to the input
},
});

With ExtJS 6, it was really easy to simulate navigation with bufferedRenderer.scrollTo() method:
Here, I'm creating KeyNav but you can rewrite it to pure Javascript/jQuery:
quickSearchKeyNav = Ext.create('Ext.util.KeyNav', Ext.get('quickSearch'), {
scope: Ext.get('quickSearch'),
up: function (e) {
quickSearchGrid.view.bufferedRenderer.scrollTo(
quickSearchGrid.getStore().indexOf(quickSearchGrid.getSelection()[0]) - 1,
true);
},
pageUp: function (e) {
var rowsOnScreen = quickSearchGrid.getNavigationModel().getRowsVisible();
quickSearchGrid.view.bufferedRenderer.scrollTo(
quickSearchGrid.getStore().indexOf(quickSearchGrid.getSelection()[0]) - rowsOnScreen,
true);
},
pageDown: function (e) {
var rowsOnScreen = quickSearchGrid.getNavigationModel().getRowsVisible();
quickSearchGrid.view.bufferedRenderer.scrollTo(
quickSearchGrid.getStore().indexOf(quickSearchGrid.getSelection()[0]) + rowsOnScreen,
true);
},
down: function (e) {
quickSearchGrid.view.bufferedRenderer.scrollTo(
quickSearchGrid.getStore().indexOf(quickSearchGrid.getSelection()[0]) + 1,
true);
}
});

Related

Get Selected Items of listview syncfusion

i want to show the selected items of listview in a grid. all selected items should show on the home page. but i cant find a way to do so. i have attached the js file code and screenshot of the popup
var subItemsLoaded = false,
SubItemSelectionModalId = '#subItemSelectionModal';
listViewHeight = 400,
subItemClicked = 0;
$(SubItemSelectionModalId).on('shown.bs.modal', function () {
if (
(window.selections.assetTemplate.id != null &&
window.selections.assetTemplate.id != 0)) {
$(SubItemSelectionModalId + ' .modal-body').ejWaitingPopup({
showOnInit: true
});
$(SubItemSelectionModalId + ' .listViewItems').ejListView({
"height": 400,
"loadComplete": function () {
repositionSearchBoxFor(SubItemSelectionModalId);
var obj = $(SubItemSelectionModalId + ' .modal-body').data("ejWaitingPopup");
console.log("12345.5");
obj.hide();
console.log("123456");
},
"mouseUp": function (e) {
},
"enableAjax": true,
"enableCheckMark": true,
"enableFiltering": true,
"dataSource": ej.DataManager({
"url": "/Shared",
"cachingPageSize": 0,
"timeTillExpiration": 0
}),
"query": ej.Query().from("GetSubItems").addParams("assetTemplateId", window.selections.assetTemplate.id).addParams("assetTemplateVariantId", window.selections.assetTemplateVariant.id),
"fieldSettings": {
"text": "SubItemName",
"id": "SubItemId"
}
});
}
});
$(SubItemSelectionModalId).on('hidden.bs.modal', function () {
var listViewItems = $(SubItemSelectionModalId + ' .listViewItems');
if (listViewItems.find('ul').length > 0) {
var selections = $(SubItemSelectionModalId + ' .listViewItems').ejListView("getCheckedItems");
if (selections.length > 0) {
$('#selectedSubItems').html(selections.join(' , ')).removeClass('hidden');
}
}
});
enter image description here
Yes, it is possible to show the selected items of the Listview in a Grid. For this, you have to use the mouseUp event of the Listview to take the selected items of the list and then give these selected items as the dataSource for the Grid control.
Also in order to get the ID of the selected list, you have to get the ID attribute and take its ID and bind the ID field as one of the columns of the Grid control. This way, you can get the ID of a particular list in a Listview and then bind it to the Grid.
We have also prepared a sample for your reference: http://jsplayground.syncfusion.com/prahqy2i
Regards,
Arun P.

Kendo grid - how to make whole row selection navigetable by UP/DOWN keyboard keys?

I have the following grid with coloured row after the mouse click on the selected row.
I would like to add the same functionality if user will using UP and DOWN rows on the keyboard with event where actual selected row by keyboard will be passed like in the change function below.
How can i do it please using the Kendo?
change: function (e) {
var selectedRows = this.select();
var selectedDataItems = [];
for (var i = 0; i < selectedRows.length; i++) {
var dataItem = this.dataItem(selectedRows[i]);
selectedDataItems.push(dataItem);
}
console.log(selectedDataItems);
$scope.setDetailToScope(selectedDataItems, "row_select");
},
Edit:
I tried this function too:
$(function () {
var arrows = [38, 40];
var grid = $("#grid").data("kendoGrid");
grid.table.on("keydown", function (e) {
if (arrows.indexOf(e.keyCode) >= 0) {
setTimeout(function () {
grid.select($("#rowSelection_active_cell").closest("tr"));
});
}
})
});
Up/Down button is recognized but i cannot get the next selected row and colorize it.
You can simply enable Kendo navigatable feature:
$("#grid").kendoGrid({
...
selectable: "row",
navigatable: true,
...
});
Similarly to: http://demos.telerik.com/kendo-ui/grid/keyboard-navigation
EDIT:
To navigate without ghost highlighting you should manually handle this:
var data = $("#grid").data('kendoGrid');
var arrows = [38, 40];
data.table.on("keydown", function (e) {
if (arrows.indexOf(e.keyCode) >= 0) {
setTimeout(function () {
data.select($("#grid_active_cell").closest("tr"));
},1);
}
}
https://jsfiddle.net/bzm5dwvo/
you must set grid Selectable and GridSelectionMode set Single
like :
.Selectable(s=> s.Mode(GridSelectionMode.Single))
and you can use Navigate envent in grid events :
.Events(evt=> evt.Navigate("navigate"));
and in js function :
function navigate(e) {
var grid = e.sender;
grid.select(grid.tbody.find(e.element.parent()));
}

how to validate data on drop event of itemselecter in extjs?

we not like to add three word again in selected item.
we like to validate on drag and drop event and need to show message that u already added this record.
i try with below code but not able to fine relevant event for validate
listeners: {
added:function(obj,event){
console.log("added");
},change:function(obj,event){
console.log("change");
},removed:function(obj,event){
console.log("removed");
}, blur:function(obj,event){
console.log("blur");
}, click: function( obj) {
console.log('click');
}, select: function( obj) {
console.log('select');
}
}
please see attached image bellow.
I am Using Extjs 3.4
The change event fires when an item is selected or deselected... But at this stage, you won't be able to prevent it anymore. So, apparently, your best move is to override the onAddBtnClick method:
{
xtype: 'itemselector'
// ... config
,onAddBtnClick: function() {
var me = this,
selected = me.getSelections(me.fromField.boundList),
i, l, record;
var toStore = this.toField.boundList.getStore(),
idField = 'value', // or 'id', or whatever you want
selectedIds = Ext.pluck(Ext.pluck(toStore.getRange(), 'data'), idField),
accepted = [], rejected = [];
for (i=0, l=selected.length; i<l; i++) {
record = selected[i];
if (selectedIds.indexOf(record.get(idField)) === -1) {
accepted.push(record);
} else {
rejected.push(record);
}
}
if (rejected.length) {
// warning msg
}
me.moveRec(true, accepted);
me.toField.boundList.getSelectionModel().select(accepted);
}
}

Is it possible to reinitialize a CKEditor Combobox/Drop Down Menu?

How do I dynamically update the items in a drop down?
I have a custom plugin for CKEditor that populates a drop down menu with a list of items which I can inject into my textarea.
This list of items comes from a Javascript array called maptags, which is updated dynamically for each page.
var maptags = []
This list of tags gets added to the drop down when you first click on it by the init: function. My problem is what if the items in that array change as the client changes things on the page, how can I reload that list to the updated array?
Here is my CKEditor Plugin code:
CKEDITOR.plugins.add('mapitems', {
requires: ['richcombo'], //, 'styles' ],
init: function (editor) {
var config = editor.config,
lang = editor.lang.format;
editor.ui.addRichCombo('mapitems',
{
label: "Map Items",
title: "Map Items",
voiceLabel: "Map Items",
className: 'cke_format',
multiSelect: false,
panel:
{
css: [config.contentsCss, CKEDITOR.getUrl(editor.skinPath + 'editor.css')],
voiceLabel: lang.panelVoiceLabel
},
init: function () {
this.startGroup("Map Items");
//this.add('value', 'drop_text', 'drop_label');
for (var this_tag in maptags) {
this.add(maptags[this_tag][0], maptags[this_tag][1], maptags[this_tag][2]);
}
},
onClick: function (value) {
editor.focus();
editor.fire('saveSnapshot');
editor.insertHtml(value);
editor.fire('saveSnapshot');
}
});
}
});
I think I just solved this actually.
Change your init like this:
init: function () {
var rebuildList = CKEDITOR.tools.bind(buildList, this);
rebuildList();
$(editor).bind('rebuildList', rebuildList);
},
And define the buildList function outside that scope.
var buildListHasRunOnce = 0;
var buildList = function () {
if (buildListHasRunOnce) {
// Remove the old unordered list from the dom.
// This is just to cleanup the old list within the iframe
$(this._.panel._.iframe.$).contents().find("ul").remove();
// reset list
this._.items = {};
this._.list._.items = {};
}
for (var i in yourListOfItems) {
var item = yourListOfItems[i];
// do your add calls
this.add(item.id, 'something here as html', item.text);
}
if (buildListHasRunOnce) {
// Force CKEditor to commit the html it generates through this.add
this._.committed = 0; // We have to set to false in order to trigger a complete commit()
this.commit();
}
buildListHasRunOnce = 1;
};
The clever thing about the CKEDITOR.tools.bind function is that we supply "this" when we bind it, so whenever the rebuildList is triggered, this refer to the richcombo object itself which I was not able to get any other way.
Hope this helps, it works fine for me!
ElChe
I could not find any helpful documenatation around richcombo, i took a look to the source code and got an idea of the events i needed.
#El Che solution helped me to get through this issue but i had another approach to the problem because i had a more complex combobox structure (search,groups)
var _this = this;
populateCombo.call(_this, data);
function populateCombo(data) {
/* I have a search workaround added here */
this.startGroup('Default'); /* create default group */
/* add items with your logic */
for (var i = 0; i < data.length; i++) {
var dataitem = data[i];
this.add(dataitem.name, dataitem.description, dataitem.name);
}
/* other groups .... */
}
var buildListHasRunOnce = 0;
/* triggered when combo is shown */
editor.on("panelShow", function(){
if (buildListHasRunOnce) {
// reset list
populateCombo.call(_this, data);
}
buildListHasRunOnce = 1;
});
/* triggered when combo is hidden */
editor.on("panelHide", function(){
$(_this._.list.element.$).empty();
_this._.items = {};
_this._.list._.items = {};
});
NOTE
All above code is inside addRichCombo init callback
I remove combobox content on "panelHide" event
I repopulate combobox on "panelShow" event
Hope this helps

Javascript / jQuery Hide fields based on Selected Drop Down item

I have some code that I have created for an OnChange event which works perfectly.
<script type="text/javascript">
function UpdEventChanged(selectEl) {
var text = selectEl.options[selectEl.selectedIndex].text;
if (text == "Sickness" || text == "Holiday") {
$("input[id$=eventPostCode").hide();
$("#ContentPlaceHolder1_LBLUpdPCReq").hide();
$("#ContentPlaceHolder1_lblUpdPC").hide();
}
else {
$("input[id$=eventPostCode").show();
$("#ContentPlaceHolder1_LBLUpdPCReq").show();
$("#ContentPlaceHolder1_lblUpdPC").show();
}
}
</script>
I need to integrate the above code to make it work on the Page Load event. Here is my code:
// update Dialog
$('#updatedialog').dialog({
autoOpen: false,
width: 500,
buttons: {
"update": function() {
//alert(currentUpdateEvent.title);
var eventToUpdate = {
id: currentUpdateEvent.id,
//title: $("#eventName").val(),
title: $("#EventSalesPerson option:selected").text(),
description: $("#eventDesc").val(),
salesperson: $("#EventSalesPerson option:selected").text(),
eventPostCode: $("input[id$=eventPostCode]").val(),
eventname: $("#EventEventName option:selected").text()
};
{
PageMethods.UpdateEvent(eventToUpdate, updateSuccess);
$(this).dialog("close");
currentUpdateEvent.title = $("#eventName").val();
currentUpdateEvent.description = $("#eventDesc").val();
currentUpdateEvent.salesperson = $("#EventSalesPerson option:selected").text();
currentUpdateEvent.eventname = $("#EventEventName option:selected").text();
currentUpdateEvent.eventPostCode = $("input[id$=eventPostCode]").val();
$('#calendar').fullCalendar('updateEvent', currentUpdateEvent);
location.reload(true);
}
},
"delete": function() {
if (confirm("do you really want to delete this event?")) {
PageMethods.deleteEvent($("#eventId").val(), deleteSuccess);
$(this).dialog("close");
$('#calendar').fullCalendar('removeEvents', $("#eventId").val());
}
}
}
});
If #EventEventName selected text = Holiday or Sickness then I need the following items to be hidden:
"input[id$=eventPostCode"
"#ContentPlaceHolder1_LBLUpdPCReq"
"#ContentPlaceHolder1_lblUpdPC"
And obviously if they are not selected then the above should be displayed.
Thanks
It looks like you need something about like this:
var EventEventNameText = $('#EventEventName').val();
if (EventEventNameText=='Holiday' || EventEventNameText=='Sickness') {
$('#eventPostCode').hide();
$('#ContentPlaceHolder1_LBLUpdPCReq').hide();
$('#ContentPlaceHolder1_lblUpdPC').hide();
}
Let me know how that works for you.

Categories

Resources