Search typehead trigger time in jquery - javascript

Is there any way how to trigger the event in every 3 seconds in laravel vuejs, but I've been using Jquery in my script.The problem is when I search and input any string, since I've been using keyup on input type it will trigger the event every characters I've type. All I want, It will trigger when you stop typing for at least 3 seconds, else if you continued typing it will not trigger the event, is there any way to achieve this? it will very helpful for me.
Currently I've been tried settimeout but every time I've type will get multiple results after setting the time.
<input type="text" class="form-control required-field" name="driver_fullname" placeholder="Enter fullname" v-model="formFields.fullname" v-on:keyup="typehead"/>
script
typehead(){
let vm = this;
let driveInfo = vm.formFields.fullname;
setTimeout(() => {
axios.put(BASE_URL + '/transportation/driver/autoComplete/' + driveInfo).then(response => {
console.log(response.data);
});
}, 500);
},

Sounds like what you really want is to debounce the user input to prevent an API call on every keystroke.
Check out https://www.npmjs.com/package/debounce
If you really want to delay by three seconds after the user stops typing, one way would be to use clearTimeout().
Add typeaheadTimeout: null to your component data.
Then:
typehead() {
let driveInfo = this.formFields.fullname;
if (this.typeaheadTimeout) {
clearTimeout(this.typeaheadTimeout);
}
this.typeaheadTimeout = setTimeout(() => {
axios.put(BASE_URL + '/transportation/driver/autoComplete/' + driveInfo).then(response => {
console.log(response.data);
});
}, 3000);
},

Related

file input ref triggering file-picker twice

File input ref is triggering twice when I click button multiple times very quickly -
<input
type="file"
ref={uploadRef}
...
/>
<DefaultButton
onClick={onClick}
...
/>
and,
const onClick = React.useCallback(
(e) => {
uploadRef.current?.click();
// e.stopPropagation();
}
},
[]
Related info - I tried e.stopPropagation() mentioned here - https://github.com/reactjs/react-modal/issues/494. This doesn't work.
The Button onclick multiple times "quickly" loads two file pickers in sequence. If I close first, immediately I see next one and the last selection persists.
You can try to have timeout for that click event
let timer //initialise timer somewhere
const onClick = React.useCallback(
() => {
//remove the previous timer, once an user clicks again
timer && clearTimeout(timer)
timer = setTimeout(() => {
uploadRef.current?.click();
}, 200) // this is an idle time before opening file picker, it works for me, you can modify it as you wish
},
[timer])

How to simulate text input onchange when testing

I have the following code where I am only enabling a button if relevant data exists.
I am trying to test this by faking a change in the input field so that the relevant data is available.
But my simulation does not seem to work thus the data remains empty which in turn means my button remains disabled. Can I please get some help on what I am doing wrong please? Thank you.
Note that following code works where events fires as expected and updates. Just issue in writing test.
const [code1, setCode1] = useState('');
const cannotPress = () => !(code1);
const handleFieldChange = (event, updater) => {
updater(event.target.value);
};
// in test, trying to simulate a value entered in this input so that the event fires and
// updates code1's value thus making cannotPress=false. This would enable the button and pass test.
<input id="code1" value={code1} onChange={event => handleFieldChange(event, setCode1)} />
<button id='btn type="submit" disabled={cannotPress()} onClick={() => doSomething()}>Submit</button>
Test
describe('tests', () => {
const wrapper = shallow(<MyApp info={info} />);
it('simple test', () => {
const btn = wrapper.find('button#btn'); // able to find button
const input = wrapper.find('input#code1'); // able to find input (tested by placing in default values)
console.log(input.props().value); // prints nothing as expected
input.instance().props.onChange(({ target: { value: 'some fake data' } })); // expecting the event to trigger and change value for code1.
console.log(input.props().value); // ISSUE: expected to print 'some fake data' but still empty.
expect(btn.prop('disabled')).toBe(false); // fails cos input has no value thus disabled is still true
});
});
I think you will need to simulate the event (using enzyme) rather then trying to manipulate the onChange() property directly.
Seems like a similar issue to:
https://stackoverflow.com/a/37452043/10610784
Try the suggested solution
input.simulate('change', { target: { value: 'Hello' } })

How to call a function when input is cleared in AngularJS?

I know Angular has simple syntax to display messages or update css, but what I'm trying to do is actually call a function.
<input ng-model="somefield">
<span ng-show="!somefield.length">Please enter something!</span>
<span ng-show="somefield.length">Good boy!</span>
This is my model vm.tagSearching = '' I can detect when I start typing in the input and see the value update. However once I get to the last letter, and I delete that I don't get an update.
I tried using $scope.watch
$scope.$watch('vm.tagSearching', function() {
alert('hey, var has changed!');
});
However this only fires once as the app initializes, but never again, even while typing.
Markup
<input class="tag-search-input"
type="text"
placeholder="Search Tags"
ng-model="tgs.tagSearching"
typeahead="t for t in tgs.fuzzyTagSearch($viewValue)">
Controller
function fuzzyTagSearch(word) {
console.log('fuzzyTagSearch',word);
if (word.length > 2) {
ApiFactory.getSearchResults(word).then(function(data) {
console.log('data',data.data.ticker_tags);
vm.terms = data.data.ticker_tags;
});
}
}
How would you accomplish this? I need to detect when the input is clear when the user backspaces / deletes all the letters so that I can reset the table.
You can simply set up an ng-change directive.
<input ng-model="tgs.tagSearching" ng-change="tgs.detectEmpty()">
vm.detectEmpty = function() {
if (vm.tagSearching.trim().length === 0) {
// it's empty
}
}

Javascript oninput(setTimeout 2s) / onchange - fire that comes as first

Hi I have a function Save that's triggered onchange event or oninput after 2s timeout.
Problem is that function Save is triggered twice in this scenario:
type something
wait 2s
oninput fires save event
click out of input
onchange fires save event
I need save only once depending on what happens first. If user types something and immediately leaves input, then save via onchange and oninput timeout should be cancelled. But if types something and waits 2s then save via oninput and onchange shouldn't be triggered.
I need some simple and clean solution. Does it exist? Thanks :)
edit:
here is my code http://jsfiddle.net/TQ9KR/
jQuery('#text').on('change', function() {
save();
});
jQuery('#text').on('input', function(){
clearTimeout(this.delayer);
var context = this;
this.delayer = setTimeout(function () {
jQuery(context).trigger('change');
}, 2000);
});
function save(){
jQuery('#a').text('saved on ' + new Date().getTime());
}
You could set a flag to indicate whether save is needed:
jQuery('#text').on('change', function() {
save();
});
jQuery('#text').on('input', function(){
jQuery(this).data('unsaved', true);
clearTimeout(this.delayer);
var context = this;
this.delayer = setTimeout(function () {
jQuery(context).trigger('change');
}, 2000);
});
function save(){
if (jQuery('#text').data('unsaved')) {
jQuery('#a').text('saved on ' + new Date().getTime());
jQuery('#text').data('unsaved', false);
}
}
Demo: http://jsfiddle.net/TQ9KR/1/
Update: for your requirement of dealing also with changes to the field value from other JavaScript functions you could do the following instead (keeping your original 'change' and 'input' handlers:
function save(){
var $text = jQuery('#text');
if ($text.data('prevVal') != $text.val()) {
jQuery('#a').text('saved on ' + new Date().getTime());
$text.data('prevVal', $text.val());
}
}
That is, only save if the current value of the field is different to whatever was saved last time (where the first time around it will automatically be different since there will be no previously saved value).
Demo: http://jsfiddle.net/TQ9KR/2/
Could you not add a data attribute, something like data-hasChanged and check that?
well honestly only cleen solution that i can think of is to initialize global boolean variable that indicates has save hapen
var hasSaveHapen = false;
and now when any of those functions try to save use this:
if(!hasSaveHapen){
do your save action
hasSaveHapen = false;
}

Detect Textbox Field Change jQuery

I have a text box that accepts integers, and I need it to run a function that will use the text box's input, as soon as a user inputs numbers into the field.
The problem here is that keyUp() will detect each and every input. So if I type 23, it will fire once for 2 and once for 3. I only need it to run when the input is complete.
Is there a way to do this, without losing focus and without using a timer that will keep checking the text box input every while using setInterval?
Look like you want to be notified when the user stops typing. The following code can be used as a starting point, it calls bufferedKeyUp 300 ms after the user stops typing. http://jsfiddle.net/mendesjuan/VTMEe/
$(function() {
// Creates a handler that will wait until the event hasn't fired for a period
// before it fires the actual event handler
function createBuffered(fun, delay) {
var timer;
return function() {
clearTimeout(timer);
var args = arguments;
var me = this;
timer = setTimeout(function() {
fun.apply(me, args);
}, delay);
}
}
$('#in').keyup( createBuffered(function(){
console.log('change');
}, 300));
});​
Ext-JS has a nice simple way to do this http://jsfiddle.net/mendesjuan/DYkmU/1/
Ext.get('myid').on('keyup', function() {
console.log('change');
}, null, {buffer: 300});
Why not test the textbox contents after they're changed, after all that's when input is complete isn't it?
If the result is not okay, you can always clear and focus the textbox so the user has to enter valid data.
Something like:
$("textbox").change( function () {
if (someTestForGoodData) {
handleTheGoodData();
} else {
$(this).focus();
alert($(this) + " has bad data!");
}
})
$('input').on('input propertychange', function() {
$('#output').html($(this).val().length + ' characters');
});
From this answer.

Categories

Resources