SAPUI5 TreeTable: User Interaction set to "true" when event fired by code - javascript

When selecting a row in my SAPUI5 tree table I have to make sure that
all existing selections are removed
check if selected row has children and if so, select the item and all its children
To do that I use a function that gets called on the rowSelectionChange-Event of my table:
onRowSelectionChange: function(oEvent) {
if (oEvent.getParameters().userInteraction)
var oTable = oEvent.getSource();
var oObject = oEvent.getParameters().rowContext.getObject();
var iIndex = oEvent.getParameters().rowIndex;
// Check if row was selected or deselected
if (oTable.isIndexSelected(iIndex)) {
// Deselect other items
oTable.clearSelection();
// Select row again
oTable.addSelectionInterval(iIndex, iIndex);
// Check if object has children
if (oObject.content) {
//Select child rows here
} else {
// Do stuff
}
} else {
// Do stuff
}
}
}
As you can see the first thing I do is to check if the selection change's origin was an explicit user interaction, because, of course, clearing the selection and then adding the selection for the child rows will call the function again.
My problem is now, that when clearSelection() calls my function, the userInteraction-parameter is again set to true, despite not being an explicit user interaction. Am I missing something here?
Thank you!

Related

Angular SyncFusion's EJS-GRID Child Grid (Hierarchical Binding)

I'm working on ejs-grid and I want to toggle(Expand/Collapse) a child grid when I click on a row in the grid.
I was able to get the row click functionality working using (rowSelected) attribute but I don't really know how to get the current state of a child grid(collapsed or expanded).
My Current Code
toggleChildGrid(event){
const rowIndex = event.rowIndex;
const isCollapsed = true;
if(isCollapsed){
this.grid.detailRowModule.expand(rowIndex);
}
else{
this.grid.detailRowModule.collapse(rowIndex)
}
}
I just made the isCollapsed variable true but I will like that to be derived dynamically based on the state of the child grid.
You could use a set containing row indices that are expanded, and add/remove from that list to represent if the row is expanded/collapsed
private expandedRowIndices = new Set<number>();
toggleChildGrid(event: {rowIndex: number}): void {
const rowIndex = { event };
const isExpanded = this.expandedRowIndices.has(rowIndex);
// If it is currently expanded, now collapse
if (isExpanded) {
this.grid.detailRowModule.collapse(rowIndex);
this.this.expandedRowIndices.remove(rowIndex);
} else {
this.grid.detailRowModule.expand(rowIndex);
this.this.expandedRowIndices.add(rowIndex);
}
}
Based on your shared information we suspect that you want to expand/collapse the child grid based on the current state while clicking on the row of grid. To achieve your requirement we suggest you to use our default recordClick event.
Using this event we find the current state of child grid and based on that we have collapsed and expanded using expand and collapse method.
Please refer to the below code and sample link.
recordClick(args){
const isCollapsed = (args.target.closest('tr').nextElementSibling.classList.contains('e- detailrow') && (args.target.closest('tr').nextElementSibling.style.display != 'none')) == true ? true : false;
if (!isCollapsed) {
this.grid.detailRowModule.expand(args.rowIndex);
}
else {
this.grid.detailRowModule.collapse(args.rowIndex);
}
}
Sample link: https://stackblitz.com/edit/angular-pm1ziu-9kpxum?file=app.component.ts
API Link: https://ej2.syncfusion.com/documentation/api/grid#recordclick

Doing mutual exclusive checkbox of two buttons with siblings()

I am trying to get two buttons groups with checkboxes mutually exclusive.
Here's my current result on this JS Fiddle
As you can see, there are four divs (with id="UserVsComputer", id="User1VsUser2", id="PlayableHits" and id="button-new-game").
I want the two first <div> ( UserVsComputer and User1VsUser2 ) to be mutually exclusive when we click on the checkbox of concerning <input> (i.e corresponding to the right <div>).
In JavaScript part, I did:
// Select the clicked checkbox for game type
$('input.game').on('click',function(){
setGameType();
});
function setGameType() {
// Get state of the first clicked element
var element = $('#UserVsComputer input.game');
var checkBoxState = element.prop('checked');
// Set !checkBoxState for the sibling checkbox, i.e the other
element.siblings().find('input.game').prop('checked',!checkBoxState);
updateGameType();
}
function updateGameType() {
// Set type of game
if ($('#UserVsComputer input').prop('checked'))
gameType = 'UserVsComputer';
else
gameType = 'User1VsUser2';
}
I don't want the <div id="PlayableHits" class="checkbox"> to be concerned by this mutual exclusion on two first checkboxes.
For example, below a capture showing that I can set the two first checkbox to true without making them exclusive:
What might be wrong here?
Try the following - it uses the target of the click event to ascertain which checkbox was checked:
// Select the clicked checkbox for game type
$('input.game').on('click',function(e){
setGameType(e.target);
});
function setGameType(cb) {
var container = $(cb).parent().parent();
var checkBox = $(cb);
var checkBoxState = checkBox.prop('checked');
// Set !checkBoxState for the sibling checkbox, i.e the other
container.siblings().find('input.game').prop('checked', !checkBoxState);
updateGameType();
}
function updateGameType() {
// Set type of game
if ($('#UserVsComputer input').prop('checked')) {
gameType = 'UserVsComputer';
} else {
gameType = 'User1VsUser2';
}
}
There are other bits which could use some attention (the hardcoded .parent().parent() isn't pretty but works in this case..

Updating based on checkbox selection

I placing some xml data in grid using extjs. Now I'm trying to build an update function,
that worked fine, however I'm trying first to extract the data to be updated, so that the user won't have to insert the whole data again.
I managed to extract the data depending on the position in the grid, but not on the selection of checkbox next to each entry in the grid.
Code:
if (btn.id == "btn_update") {
var selection = grid.getSelectionModel().getSelection();
if(selection.length == 0){
alert("Please select an item to update");
}
else if(selection.length > 1){
alert("Please only select one item to update");
}
else{
Ext.getCmp('update_name').setValue(gridStore.getAt(0).get("FirstName"));
Ext.getCmp('update_lastname').setValue(gridStore.getAt(0).get("LastName"));
Ext.getCmp('update_email').setValue(gridStore.getAt(0).get("Email"));
winupdate.show();
}
}
How can I achieve that?
Hope this will help you.
You can use checkboxSelectionModel in grid and when you click on checkbox select event will be fired and that will give you current record, index and many other.
xtype:'grid',
selModel: Ext.create('Ext.selection.CheckboxModel',{
listeners: {
select: function (el, record, index, eOpts) {
//Get current record from record variable
}
}

jQuery: focusout triggering before onclick for Ajax suggestion

I have a webpage I'm building where I need to be able to select 1-9 members via a dropdown, which then provides that many input fields to enter their name. Each name field has a "suggestion" div below it where an ajax-fed member list is populated. Each item in that list has an "onclick='setMember(a, b, c)'" field associated with it. Once the input field loses focus we then validate (using ajax) that the input username returns exactly 1 database entry and set the field to that entry's text and an associated hidden memberId field to that one entry's id.
The problem is: when I click on the member name in the suggestion box the lose focus triggers and it attempts to validate a name which has multiple matches, thereby clearing it out. I do want it to clear on invalid, but I don't want it to clear before the onclick of the suggestion box name.
Example:
In the example above Paul Smith would populate fine if there was only one name in the suggestion list when it lost focus, but if I tried clicking on Raphael's name in the suggestion area (that is: clicking the grey div) it would wipe out the input field first.
Here is the javascript, trimmed for brevity:
function memberList() {
var count = document.getElementById('numMembers').value;
var current = document.getElementById('listMembers').childNodes.length;
if(count >= current) {
for(var i=current; i<=count; i++) {
var memberForm = document.createElement('div');
memberForm.setAttribute('id', 'member'+i);
var memberInput = document.createElement('input');
memberInput.setAttribute('name', 'memberName'+i);
memberInput.setAttribute('id', 'memberName'+i);
memberInput.setAttribute('type', 'text');
memberInput.setAttribute('class', 'ajax-member-load');
memberInput.setAttribute('value', '');
memberForm.appendChild(memberInput);
// two other fields (the ones next to the member name) removed for brevity
document.getElementById('listMembers').appendChild(memberForm);
}
}
else if(count < current) {
for(var i=(current-1); i>count; i--) {
document.getElementById('listMembers').removeChild(document.getElementById('listMembers').lastChild);
}
}
jQuery('.ajax-member-load').each(function() {
var num = this.id.replace( /^\D+/g, '');
// Update suggestion list on key release
jQuery(this).keyup(function(event) {
update(num);
});
// Check for only one suggestion and either populate it or clear it
jQuery(this).focusout(function(event) {
var number = this.id.replace( /^\D+/g, '');
memberCheck(number);
jQuery('#member'+number+'suggestions').html("");
});
});
}
// Looks up suggestions according to the partially input member name
function update(memberNumber) {
// AJAX code here, removed for brevity
self.xmlHttpReq.onreadystatechange = function() {
if (self.xmlHttpReq.readyState == 4) {
document.getElementById('member'+memberNumber+'suggestions').innerHTML = self.xmlHttpReq.responseText;
}
}
}
// Looks up the member by name, via ajax
// if exactly 1 match, it fills in the name and id
// otherwise the name comes back blank and the id is 0
function memberCheck(number) {
// AJAX code here, removed for brevity
if (self.xmlHttpReq.readyState == 4) {
var jsonResponse = JSON.parse(self.xmlHttpReq.responseText);
jQuery("#member"+number+"id").val(jsonResponse.id);
jQuery('#memberName'+number).val(jsonResponse.name);
}
}
}
function setMember(memberId, name, listNumber) {
jQuery("#memberName"+listNumber).val(name);
jQuery("#member"+listNumber+"id").val(memberId);
jQuery("#member"+listNumber+"suggestions").html("");
}
// Generate members form
memberList();
The suggestion divs (which are now being deleted before their onclicks and trigger) simply look like this:
<div onclick='setMember(123, "Raphael Jordan", 2)'>Raphael Jordan</div>
<div onclick='setMember(450, "Chris Raptson", 2)'>Chris Raptson</div>
Does anyone have any clue how I can solve this priority problem? I'm sure I can't be the first one with this issue, but I can't figure out what to search for to find similar questions.
Thank you!
If you use mousedown instead of click on the suggestions binding, it will occur before the blur of the input. JSFiddle.
<input type="text" />
Click
$('input').on('blur', function(e) {
console.log(e);
});
$('a').on('mousedown', function(e) {
console.log(e);
});
Or more specifically to your case:
<div onmousedown='setMember(123, "Raphael Jordan", 2)'>Raphael Jordan</div>
using onmousedown instead of onclick will call focusout event but in onmousedown event handler you can use event.preventDefault() to avoid loosing focus. This will be useful for password fields where you dont want to loose focus on input field on click of Eye icon to show/hide password

Disable drop on empty cells using redips drag

I am using redips drag class to be able to drag/drop table cells of my table.
I would like to add a condition to forbid the drop if the destination cell was empty. Which means I only need to "switch" if the target cell is not empty.
Any help ?
if (target_elements_length) {
// call myhandler_switched because clone_limit could call myhandler_clonedend1 or myhandler_clonedend2
REDIPS.drag.myhandler_switched();
// and myhandler_dropped
REDIPS.drag.myhandler_dropped(target_cell);
// if object is cloned, update climit1_X or climit2_X classname
if (cloned_flag === 1) {
clone_limit();
}
}
// otherwise element is dropped to the empty cells
else {
//TODO cancel the event.
}
Nevermind ...
this is the solution.
Modify drag.js accordingly:
if (target_elements_length) {
obj.parentNode.removeChild(obj);
target_cell.appendChild(obj);
// call myhandler_switched because clone_limit could call myhandler_clonedend1 or myhandler_clonedend2
REDIPS.drag.myhandler_switched();
// and myhandler_dropped
REDIPS.drag.myhandler_dropped(target_cell);
// if object is cloned, update climit1_X or climit2_X classname
if (cloned_flag === 1) {
clone_limit();
}
}

Categories

Resources