open NgbTypeahead dropdown when click event on button - focus

I need to simulate focus event on input to open NgbTypeahead dropdown , is it possible? Because i cant do it like:
.ts:
#ViewChild('inputExecutor') inputExecutor: ElementRef
focus$ = new Subject<string>();
click$ = new Subject<string>();
focused(){
this.executorForm.controls['executor'].setValue('');
this.focus$.next(this.executorForm.value.executor);
}
inputFocus(){
this.inputExecutor.nativeElement.focus();
}
html:
<input
class="choose-executor-input"
type="text"
name="executor"
formControlName="executor"
[ngbTypeahead]="searchExecutors"
(focus)="focus$.next($event.target.value); focused()"
(click)="click$.next($event.target.value);"
(selectItem)="itemSelected($event)"
[resultFormatter]="formatExecutors"
[inputFormatter]="formatExecutors"
#instance="ngbTypeahead"
#inputExecutor/>
<button
click)="inputFocus()"
class="btn btn-executor-open"></button>
</button>
So how i can focus on input to open dropdown? Any issues?

To accomplish this, you can fire an input event on the input element the NgbTypeahead is bound to, then call the focus method so that the input has focus and you can start typing immediately.
I started with the Open on focus demo from the ng-bootstrap website, and made the following changes:
Declare a new template variable elem so the DOM element is accessible inside the component TS file (note you can't use the existing instance as that is an NgbTypeahead not an HTML element):
Component HTML:
<input
id="typeahead-focus"
...
#instance="ngbTypeahead"
#elem
/>
Component TS:
#ViewChild('elem') elem: ElementRef;
Add a button to the template which will call a focus function - this is the button that when clicked will open the typeahead and focus on it:
<button (click)="openTypeahead()">Open Typeahead</button>
Add an openTypeahead function in the component TS file as follows:
public openTypeahead(): void {
// Dispatch event on input element that NgbTypeahead is bound to
this.elem.nativeElement.dispatchEvent(new Event('input'));
// Ensure input has focus so the user can start typing
this.elem.nativeElement.focus();
}
Please see this Stackblitz for a demo

I use
HTML:
<input #instance="ngbTypeahead" .../>
<button (click)="openTypeahead(instance)">Open Typeahead</button>
TS:
openTypeahead(inp) {
inp._elementRef.nativeElement.value = '';
inp._elementRef.nativeElement.dispatchEvent(new Event('input'));
inp._elementRef.nativeElement.focus();
}

Related

how to pass value using modal.show

Im trying to use pass my car value to another function, which i have no idea how. i tried to place the whole function btn-info-add into .span8. But this it will execute twice on the 2nd time.
$(".span8").on("click", "table #trID", function() {
var car = ($(this).closest("tr").children("td").eq(1).html());
$('#myModal1').modal('show');
});
$("#btn-info-add").click(function() //button inside the modal
selectCourse(car); //execute ajax
});
var car; //car must be declared out of your function to be available for both functions
$(".span8").on("click", "table #trID", function() {
car = ($(this).closest("tr").children("td").eq(1).html());
$('#myModal1').modal('show');
});
$("#btn-info-add").click(function() //button inside the modal
selectCourse(car); //execute ajax
});
You can create a hidden element inside your dialog (input would be great) and assign it your desire value.
<div id="dialog" title="Basic dialog">
<p>This is the default dialog which is useful for displaying information. The dialog window can be moved, resized and closed with the 'x' icon.</p>
<input id="carvalue" type="hidden" value=""/>
</div>
Note that I created an input element (hidden, of course) which is going to store the value that I want to access later. After that, you can modify your code like this:
$(".span8").on("click", "table #trID", function() {
var car = ($(this).closest("tr").children("td").eq(1).html());
$("#carvalue").val(car); // Store value into hidden input
$('#myModal1').modal('show');
});
$("#btn-info-add").click(function() //button inside the modal
var car = $("#carvalue").val(); // retrieve value from input hidden
if(car != ""){
selectCourse(car);
}
});
This technique is commonly used in forms to pass additional information on AJAX calls. Your user will not notice its presence and you can keep working. Happy coding!
EDIT:
JQuery has a method called jQuery.data to store information into JQuery elements. So your values are going to be stored on the element itself. Your code will look like this:
$(".span8").on("click", "table #trID", function() {
var car = ($(this).closest("tr").children("td").eq(1).html());
jQuery.data("#btn-info-add", "car", car); // store data inside jQuery element
$('#myModal1').modal('show');
});
$("#btn-info-add").click(function() //button inside the modal
selectCourse(jQuery.data("#btn-info-add", "car")); //execute ajax
});
I hope it helps you. Happy coding!

How do I process styles after a knockout computed method refreshes my view?

I have a problem in my KnockoutJS application that I can't seem to figure out. Basically, I've bound a list to a 'ko.computed' method which allows me to filter items from the main list. I use this list for my main display to the user. On each item in my template, I have one ore more buttons that I need to render as JqueryUI buttons. I can't seem to find the way to redraw the buttons correctly in my model once the computed triggers a change.
Here is a very (very) simple example of a mock view model:
function List(items) {
var self = this;
self.allItems = ko.observableArray(items || []);
self.search = ko.observable('');
self.filtered = ko.computed(function(){
var search = self.search();
return ko.utils.arrayFilter(self.allItems(), function(item){
return item == search;
});
});
}
My view might look like this:
Search: <input type='text' data-bind='value: search' />
<ul data-bind='foreach: filtered'>
<li>
<span data-bind='text: $data'> </span>
<button>NOTICE</button>
</li>
</ul>
And here is how I initialize the display:
$(function(){
var vm = new List(['a', 'b', 'c', 'd', 'e', 'f', 'g']);
ko.applyBindings(vm);
$('button').button(); // <-- notice!
});
Note that everything works fine initially! I get the nice looking JqueryUI button when the page first displays... However, as soon as I enter a into the search box, the button loses it's style completely. I need to find a way to call $('button').button() again.
Is there an event or callback inside of Knockout.js that I could call to setup my ui buttons after the computed method is triggered?
Thanks in advance!
The reason the style is getting reset is because the dom element that the button was previously bound to has been destroyed.
You can solve this by creating a simple custom binding (not-tested)
ko.bindingHandlers.uibutton = {
init: function(element, valueAccessor) {
var $element = $(element), config = valueAccessor();
$element.button();
}
}
This can be added to your template with this addition
<button data-bind="uibutton: {}">NOTICE</button>
You can remove the call to $('button').button();
When using KO we can almost do without standard Jquery expressions altogether, often custom bindings allow us to do the same but with the possibility of more advanced things like reacting to observables etc.
Hope this helps

jQuery UI autocomplete select event not working with mouse click

I have a list of links, and I have this search box #reportname. When the user types in the search box, autocomplete will show the text of the links in a list.
<div class="inline">
<div class="span-10">
<label for="reportname">Report Name</label>
<input type="text" name="reportname" id="reportname" />
</div>
<div class="span-10 last">
<button type="button" id="reportfind">Select</button>
</div>
</div>
The user can then use the keyboard arrow to select one of the text, and when he press ENTER, browser will go to the address of the link. So far so good.
<script type="text/javascript">
$(document).ready(function () {
$("#reportname").autocomplete({
source: $.map($("a.large"), function (a) { return a.text }),
select: function () { $("#reportfind").click() }
})
$("#reportfind").click(function () {
var reportname = $("#reportname")[0].value
var thelinks = $('a.large:contains("' + reportname + '")').filter(
function (i) { return (this.text === reportname) })
window.location = thelinks[0].href
})
});
</script>
The issue is when the user types, autocomplete shows a list, and then the user use the mouse to click one of the result. With keyboard navigation, the content of the search box is changed, but if the user clicks one of the options, the search box is not modified and the select event is immediately triggered.
How can I make the script work with keyboard selection and mouse selection? How can I differentiate between select events that are triggered by keyboard with the ones triggered by mouse?
To your 2nd question: "How can I differentiate between select events that are triggered by keyboard with the ones triggered by mouse?"
The event object in the jQuery UI events would include a .originalEvent, the original event it wrapped. It could have been wrapped multiple times though, such as in the case of Autocomplete widget. So, you need to trace up the tree to get the original event object, then you can check for the event type:
$("#reportname").autocomplete({
select: function(event, ui) {
var origEvent = event;
while (origEvent.originalEvent !== undefined)
origEvent = origEvent.originalEvent;
if (origEvent.type == 'keydown')
$("#reportfind").click();
},
...
});
Thanks to #William Niu and firebug, I found that the select event parameter 'ui' contains the complete selected value: ui.item.value. So instead of depending on jquery UI to change the text of the textbox, which didn't happen if the user clicks with mouse, I just pick up the selected value from 'ui':
$("#reportname").autocomplete({
select: function (event, ui) {
var reportname = ui.item.value
var thelinks = $('a.large:contains("' + reportname + '")').filter(
function (i) { return (this.text === reportname) })
window.location = thelinks[0].href
};
})
I tested it in all version of IE (inlcuding 9) and always ended up with an empty input-control after I selected the item using the mouse. This caused some headaches. I even went down to the source code of jQuery UI to see what happens there but didn’t find any hints either.
We can do this by setting a timeout, which internally queues an event in the javascript-engine of IE. Because it is guaranteed, that this timeout-event will be queued after the focus event (this has already been triggered before by IE itself).
select: function (event, ui) {
var label = ui.item.label;
var value = ui.item.value;
$this = $(this);
setTimeout(function () {
$('#txtBoxRole').val(value);
}, 1);
},
Had the same issue / problem.
Jquery: 1.11.1
UI: 1.11.0
Question: Do you use bassistance jquery validte plugin simultanously?
If positive: update this to a newest version or just disable it for tests.
I updated from 1.5.5 to 1.13.0
Helped for me. Good luck!
I recently encountered the exact same problem (autocomplete items not clickable, keyboard events working).
Turned out that in my case the answer was not at all JS related. The autocomplete UI was not clickable simply because it was lacking an appropriate value for the z-index CSS property.
.ui-autocomplete {
z-index: 99999; /* adjust this value */
}
That did the trick.
This may be a bit farshot, but I had a similar situation where selecting an autocomplete value left the input field empty. The answer was to ignore the "change" events (as those were handled by default) and replace them with binds to "autocompletechange" events.
The "change" event gets triggered before the value from autocomplete is in the field => the field had "empty" value when handling the normal "change" event.
// ignore the "change" event for the field
var item = $("#"+id); // JQuery for getting the element
item.bind("autocompletechange", function(event, ui) { [call your handler function here] }
I was facing a similar problem. I wanted to submit the form when the user clicked on an option. But the form got submitted even before the value of the input could be set. Hence on the server side the controller got a null value.
I solved it using a modified version of William Niu's answer.
Check this post - https://stackoverflow.com/a/19781850/1565521
I had the same issue, mouse click was not selecting the item which was clicked.My code was supposed to make an ajax call to fetch the data as per the selection item from autocomplete source.
Previous code: mouse click not working.
select: function(event, ui) {
event.preventDefault();
for(i= 0; i< customer.length; i++)
if(document.getElementById('inputBox').value == customer[i].name)
{
$.ajax({
call
})
Changed code :mouse click working
select: function(event, ui) {
// event.preventDefault();
for(i= 0; i< customer.length; i++)
// if(document.getElementById('inputBox').value == customer[i].fields.name)
if(ui.item.value == customer[i].name)
{
$.ajax({
call
})
After inspecting the code in the developer tools console, I noticed there were two list items added. I removed the pairing <li></li> from my response code and oh yeah, the links worked
I also added this function as the click event:
$("#main-search").result(function ()
{
$("#main-search").val("redirecting...."), window.location.href = $("#main-search").attr("href").match(/page=([0-9]+)/)[1];
})
This works and you can test it here: Search for the term dress -->

How to close the popup window in Telerik MVC

I am using telerik MVC control and I am having a popup window and I want to close the pop up window by firing click event from my cancel button on the popup window .
Can someone tell me how should I do it ?
This is what I did
<input type="button" value="Cancel" onclick="onClose()" />
and my java script is like this
<script type="text/javascript">
function onClose() {
window.close();
}
</script>
but when I do that I get a confirmation box asking me whether I want to close the window and If I select yes my browser window is closed.
I just did a similar thing with the asp.net-ajax window from telerik.
They have demos out that helped me.
Try http://demos.telerik.com/aspnet-mvc/window/clientsideapi for the mvc controls
You need to get a handle of the object
function GetRadWindow() {
var oWindow = null;
if (window.radWindow) oWindow = window.radWindow;
else if (window.frameElement.radWindow) oWindow = window.frameElement.radWindow;
return oWindow;
}
Then you can call close on the rad window object
function windowClose(reload) {
var oWindow = GetRadWindow();
oWindow.close();
}

GLOBAL loading inside each single button with Jquery in ajax calls of asp.net mvc

I have the following scenario:
I have a button\link with a image inside like this:
<button type="submit" id="myButton" class="button"><img src="../../Content/images/check.png" id="defaultImage" />
SaveData!!!</button>
We are OK here! Now what I need to do is:
I want on the click that the image change for a loading element that is previously loaded in the page like this:
<img id="loadingImage" src="../../Content/images/loader.gif" style="display: none;" alt="loading"/>
And then when the load complete turn back the old button image, I ended with this code:
function loader() {
var $button = $('#myButton');
if (btnState == '1') {
$button.find('img').hide();
$button.prepend($('#loadingImage'));
$('#loadingImage').css({ 'display': 'inherit' });
btnState = '0';
}
else {
$button.find('img').hide();
$button.prepend($('#defaultImage'));
$('#defaultImage').show();
btnState = '1';
}
}
This does the trick for ONE SINGLE button(since I pass its ID in the function) but, when I have for example a grid with a button on each line, I found inviable when managing a screen with many buttons do this for each of then. The main question is: How can I make this method general for all buttons/links on one specific class in the page?
The goal is: Click a button, get the image and change it and stop(can be manual). I just don't wanna have to Hook ALL buttons.
You should do something like this, it will prevent the user from double submitting:
$('.button').click(function(evt) {
evt.preventDefault();
var button = this;
hideButton(button);
$('ID or CLASS').load('AJAX FILE URL', function() {
//On success, show button remove image
showButton(button);
});
});
function hideButton(button) {
$(button).hide().after('<img src="../../Content/images/loader.gif" alt="loading"/>');
}
function showButton(button) {
$(button).next('img').hide();
$(button).show();
}
All of the code above should be in the $(document).load
Your HTML should look like:
<button type="submit" class="button"><img src="../../Content/images/check.png" />SaveData!!!</button>
There is no need for Id's now on anything.

Resources