Material Angular md-autocomplete clear and blur after selection (multi select) - blur

I am trying to use md-autocomplete in Angular Material as a multi selector. The idea is, that the selected element from the autocomplete will be added to an object array after selection and then the selection will be removed from the md-autocomplete. I was able to clear the md-autocomplete, but the focus stays on the md-autocomplete input and so the autocomplete suggestions are still visible.
Example:
http://cdpn.io/QjQGVQ
Code:
function selectedItemChange(item) {
$log.info('Item changed to ' + JSON.stringify(item));
if(item)
{
//check if item is already selected
if($filter('filter')(vm.contactsSelected, function (d) {return d.id === item.id;})[0])
{
$log.info('Item already selected. Will not add it again.');
}
else
{
//add id to object
vm.contactsSelected.push(item);
}
// clear search field
vm.searchText = '';
vm.selectedItem = undefined;
//somehow blur the autocomplete focus
//$mdAutocompleteCtrl.blur();
}
}
PS: I am aware I could use the contact chips of Angular Material instead, but I was still wondering how the blur could be achieved.

If you set md-no-cache="true" property inside your the list will dissapear, but input field will not be cleared. I think is better solution than clearing input field but leaving the list visible, but is up to you.

Related

Date and Time picker as custom editor in Tabulator

How do I create a custom date and time picker editor instead of just a date picker editor?
I have made a date and time picker from jquery-ui library with a jquery-ui-timepicker add-on independently, but i cannot get this to work with tabulator custom editor.
Any help would be great. thank you!
Tabulator's documentation includes a guide to making custom editors
Essentially the important bits are that it needs to return a DOM Node, that is should call the 'success' function when a value has been set and 'cancel' if the value hasn't changed.
In the case of a jquery UI widget then you also need to make sure you instantiate the widget inside the onRendered callback which is triggered when the element is added to the DOM otherwise jQuery will error.
As a basic example based on the built in input editor:
var dateFormatter = function(cell, onRendered, success, cancel, editorParams){
var cellValue = cell.getValue(),
var input = document.createElement("input"); // define input element
//assign current cell value to input element
input.value = typeof cellValue !== "undefined" ? cellValue : "";
//handle loss of focus to the input element and changes in value
function onChange(e){
if(((cellValue === null || typeof cellValue === "undefined") && input.value !== "") || input.value !== cellValue){
success(input.value); //if value has changed save value
}else{
cancel(); //otherwise cancel edit
}
}
//submit new value on blur or change
input.addEventListener("change", onChange);
input.addEventListener("blur", onChange);
//instantiate the jQuery widget
onRendered(function(){
$(input).datepicker({
//date picker setup options
});
});
//return input element
return input;
}
(Using the blur event may cause issues if you have to click in controls for the jQuery widget so you may want to comment out the blur event listener)
(Also the change event may not be what you need depending on the usage case but i believe the jquery datepicker widget has an onSelect callback that you could use to trigger the success function)
You would then need to attach the formatter to the column in its column definition:
{title:"Date", field:"date", formatter:dateFormatter}

Cypress: How to know if element is visible or not in using If condition?

I want to know if an element is visible or not. I am not sure how to do that.
I know that we can run this:
cy.get('selector').should('be.visible')
But if element is invisible then test is failed. So I just want a boolean value if element is not visible so I can decide through if condition.
Use case:
I want to open a side menu by clicking on the button only if sidebar is invisible.
if(sidebarIsInvisible){
cy.get('#sideMenuToggleButton').click();
}
Is this possible?
I really appreciate for any contribution.
Thanks in advance
Cypress allows jQuery to work with DOM elements so this will work for you:
cy.get("selector_for_your_button").then($button => {
if ($button.is(':visible')){
//you get here only if button is visible
}
})
UPDATE: You need to differentiate between button existing and button being visible. The code below differentiates between 3 various scenarios (exists & visible, exists & not visible, not exists). If you want to pass the test if the button doesn't exist, you can just do assert.isOk('everything','everything is OK')
cy.get("body").then($body => {
if ($body.find("selector_for_your_button").length > 0) {
//evaluates as true if button exists at all
cy.get("selector_for_your_button']").then($header => {
if ($header.is(':visible')){
//you get here only if button EXISTS and is VISIBLE
} else {
//you get here only if button EXISTS but is INVISIBLE
}
});
} else {
//you get here if the button DOESN'T EXIST
assert.isOk('everything','everything is OK');
}
});
You can also use my plugin cypress-if to write conditional command chains
cy.get('...').if('visible').click()
Read https://glebbahmutov.com/blog/cypress-if/
try this code:
isElementVisible(xpathLocater) {
this.xpath(xpathLocater).should('be.visible');
};
isElementNotVisible(xpathLocater) {
this.xpath(xpathLocater).should('not.exist');
};
then use these two methods with if statement like shown below:
if(isElementNotVisible) {
}
or
if(isElementVisible) {
}

How to prevent full refresh using onChange event SSJS

(You may be able to figure out an answer by ONLY reading the last question by itself, but I included everything for reference if necessary)
The onChange of one field is causing displayErrors to show validation results prior to when I need it to do that.
On an xpage, I have these two comboboxes:
1.) locationType
2.) locationEtc
Choices for locationEtc are dependent on what was selected in locationType field.
In the locationEtc field, the choices are using one computed value with this code:
try
{
var locType = getComponent("locationType").getValue();
var key = '';
switch(locType) {
case 'Commuity Service Center':
key = 'loc_cso';
break;
case 'RYDC':
key = 'loc_rydc';
break;
case 'YDC':
key = 'loc_ydc';
break;
case 'HQ':
key = 'loc_hq';
break;
default:
key = 'facilities';
}
var luChoices = #DbLookup('','keywords', key, 'choices');
luChoices.unshift("Select one|''");
return luChoices;
}
catch(e)
{
print("Error:::::"+e);
}
The choices were NOT changing for locationEtc whenever I pick a locationType, but then they do when I add code to clear the location field whenever locationType changes, using a simple action for onChange event of locationType field:
This is great, but when it all refreshes, my displayErrors control appears (yellow background area) showing required field validation results, and a lot of the fields are not filled in yet by design.
How can I make the displayErrors to show ONLY when tying to submit?
Thanks everyone who can help.
Matt
Set disableValidators="true" on the simple action that you created

Setting scroll position on Kendo Angular Grid

When a grid is in a component at one route and the user navigates away and then comes back, the current kendo grid loses its scroll position and starts at the top.
Anyone know a way to "remember" the scroll position so it can be set on the grid manually?
Not a great solution, but it works for the time being. Here it is.
Inside the component with the grid:
private _scrollPos: number;
#ViewChild("grid", { read: ElementRef }) gridEl: ElementRef;
constructor(private router: Router) { }
ngOnInit(): void {
this.router.events.subscribe(e => {
if (e instanceof NavigationStart) {
let gridContent = this.getGridContentElement();
if (gridContent.scrollTop > 0) {
this._scrollPos = gridContent.scrollTop;
}
}
else if (e instanceof NavigationEnd) {
if (this._scrollPos > 0) {
let gridContent = this.getGridContentElement();
gridContent.scrollTo({ top: this._scrollPos });
}
}
}
}
private getGridContentElement(): Element {
let el = this.gridEl.nativeElement as HTMLElement;
let gridContent = el.getElementsByClassName("k-grid-content").item(0);
return gridContent;
}
This is can done by remembering which row was selected, saving the id of the row, and then setting the grid property [selectedKeys]="id" when the user navigates back.
For example if the data for the grid was based on product data then save last viewed row id (ProductID). When the user navigates back to grid, you can push the ProductID you saved to an array that is bound on the grid. This will make the row selected, to scroll to the row you can use the class k-state-selected and scrollIntoView to scroll the row into view.
This is a basic implementation, but should give you a enough to go on. I created a Stackblitz example so you can see how to implement this. Make sure to configure the grid with kendoGridSelectBy and selectedKeys. The kendoGridSelectBy should match the id that you push to the array. In the example I created it was ProductID.
You can set the Grid skip to the same value it last was. You can check out the persist state examples. The Grids use regular paging, but the same principles apply.

click to replace value, shift + click to append value using jquery

I have a list with items.
When I click any of these items, I copy its id-value into a form text-field.
Everytime I click, it replaces the value, which is correct by default. But what I would like to add, is a way for the user to hold down a key on their keyboard, and when they then click, they just .append whatever they just clicked into the same form field.
Here's my jQuery-code I'm using for the first/default scenario:
$(function(){
$('ul#filter-results li').click(function(){
var from = $(this).attr('id'); // get the list ID and
$('input#search').val(from+' ').keyup(); // insert into text-field then trigger the search and
$('input#search').focus(); // make sure the field is focused so the user can start typing immediately
});
});
Is there a way to implement some sort of keyboard key-listener?
Something like:
if (e.shiftKey){
.append('this text instead')
}
haven't tried out to see if shiftKey is even any valid name here
shiftKey is of one of the properties of the event object and is valid to be used. try this:
$(document).on('keyup click', function(e){
if (e.shiftKey) {
$('input#search').focus()
$('input#search').val(e.target.id)
}
})
DEMO
$('ul#filter-results').on('click', 'li', function(e) {
if(e.shiftKey) {
do something;
} else {
do something else;
}
});
There is a jQuery plugin for extended click.
You could try that or see how they have done it and implement it yourself.
ExtendedClick plugin
Hope this helps.
This is what I ended up with:
I switched over to altKey because shiftKey marked a lot of text when I clicked.
Didn't do anything besides it doesn't look good...
$(function(){
$('ul#filter-results li').click(function(e){
var text = $(this).attr('id'); // get the ID
var input = $('#search'); // form field to insert text into
if (e.altKey){ input.val(input.val()+', '+text+' ').keyup(); } // fetch whatever is already there, and add some more
else { input.val(text+' ').keyup(); } // just replace whatever is already there
$('#search').focus();
});
});
Thanks for good suggestions...

Resources