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

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
}
}

Related

Angularjs click clear button inside input but no effect to binded json object

As title. I have a page with several inputs with type="text", and set them with clear buttons generated by the js code:
function SetClearButtonInTextBox(Callback) {
if (!window.document.documentMode) {
$("input").each(function () {
var im = $(this);
if (!$(this).parent().hasClass("text-input-wrapper") && !$(this).hasClass("btn")) {
$(this).wrap("<div class='text-input-wrapper'></div>");
$(this).after("<button class=\"Covered\" type=\"button\">×</button>");
}
$(this).closest("div.text-input-wrapper").find("button").mousedown(function () {
im.val("");
im.change();
//return false;
});
});
}
}
And my inputs like this:
<input name="ModelA" ng-model="dl.ModelA" ng-change="ClearText(this,dl.ModelA);" value=""/>
<input name="ModelB" ng-model="dl.ModelB" ng-change="ClearText(this,dl.ModelB);" value=""/>
And I made the "ClearText" function as:
$scope.ClearText=function(target, ngModelTo){
if (target.target.value == "") {
ngModelTo = "";
}
}
I want when I click the clear button inside input, the binded value and the textbox will also be cleared, but I found that only my textbox is cleared but the binded value isn't.
Could someone guide me to make it?

Jquery - check if control is NOT currently being edited

I have some code that updates controls on my page using Javascript/Ajax/Json calls.
My only problem is that sometimes the control is updated while the user is actively attempting to change the control.
For example - I will be typing in something, and the Ajax call will execute, replacing what I have typed.
Is this a way in javascript/jquery to say:
If $(this).NotBeingCurrentlyEdited ?
I know about the focus option, but how can I say "Not in focus, not being edited currently?"
You can use document.activeElement to check which element has the focus. If the element you want to change has the focus then skip the update. See example snippet below.
var val = 0;
setInterval(() => {
$('input').each((i, el) => {
if (document.activeElement !== el) {
$(el).val(val);
}
});
val++;
}, 2000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="1">
<input id="2">
The way I would approach it is using a timer to determine if the textbox has recently been changed by the user. You could combine this with checking the control's focus as well once an Ajax request is received. You can either disregard updates to that field entirely when TextBoxIsBeingEdited = true or store the updates somewhere to push once the timer ticks.
var TextBoxIsBeingEdited = false;
function TextBoxEdited(){
if(TextBoxIsBeingEdited === false){
document.getElementById("TextBoxStatus").innerText = "Editing";
TextBoxIsBeingEdited = true;
setTimeout(ResetTextBoxEdited, 2000);
}
}
function ResetTextBoxEdited(){
document.getElementById("TextBoxStatus").innerText = "Not Being Edited";
TextBoxIsBeingEdited = false;
}
<input type="text" id="TextBox" oninput="TextBoxEdited()">
<br><br>
<div id="TextBoxStatus">
Not Being Edited
</div>

trying to remove item from localstorage using the key name

I am trying to remove item from localstorage or rather clear it on button click. I have written the code but on clicking on the button, it does not clear the localstorage data. this is the variable with the localstorage data
window.onbeforeunload = function() {
localStorage.setItem("first_name", $('#inputName').val());
};
EDITTED
window.onload = function() {
var name = localStorage.getItem("first_name");
if (name !== null) {
$('#inputName').val(name);
alert(name);
}
};
this is the function to clear storage
function clearStorage(){
alert('localstorage cleared!');
localStorage.removeItem('first_name');
}
the snippet of the button click code block to clear localstorage data using the key-name
<input type="text" id="inputName" placeholder="Name" required>
<button onclick="clearStorage()">clear</button>
on clicking the button in attempt to wipe out the data from the localstorage and refreshing the page, the localstorage data is still in the input value.
how to clear localstorage content is my challenge
You're successfully removing the item — and then when you refresh, you're setting it again as you leave the page, because you still have:
window.onbeforeunload = function() {
localStorage.setItem("first_name", $('#inputName').val());
};
You'll have to decide when you want to set the item. The above will always do it, even if you've cleared it previously.
Perhaps you'd be better off only setting the item when the input changes, and not in onbeforeunload. That is, getting rid of the above, and instead:
$("#inputName").on("input", function() {
localStorage.setItem("first_name", $(this).val());
});
That way, if you clear the item (remove it from local storage), it won't get added back unless you edit the field again.
The code for setting/clearing the local storage looks good. However, the input field is not real-time synched with your local storage so, if you want your input to be always up to date with your local storage value, you should update it inside the clearStorage function in this way. Also you don't need to refresh the page if you use this approach:
window.onload = function() {
var name = fetchLocalStorage();
if (name !== null) {
$('#inputName').val(name);
alert(name);
}
};
function fetchLocalStorage() {
return localStorage.getItem("first_name");
}
function clearStorage() {
// clear local storage
localStorage.removeItem('first_name');
alert('localstorage cleared!');
// update input value
var name = fetchLocalStorage();
$('#inputName').val(name);
}
function saveStorage() {
localStorage.setItem("first_name", $('#inputName').val());
}
And the HTML should be updated to:
<input type="text" id="inputName" placeholder="Name" required>
<button type="button" onclick="saveStorage()">save</button>
<button type="button" onclick="clearStorage()">clear</button>
uhm, try adding type="button" to your button...
this prevents the form submit + page reload + onbeforeunload -> where your storage item gets set every time...
https://developer.mozilla.org/en/docs/Web/HTML/Element/button#attr-type

autoscroll to first blank required field using angular js

I have created a form using angular js with around 7 input elements. When I click on submit, I want the form to get scrolled up to the first blank field which is required. But now it is not correctly pointing to the field left blank. Any solution to resolve this ?
Check the error here.
before submitting the form, you can check whether the form is valid or not and use .focus() to focus on that element.
$scope.onSubmit = function(yourForm) {
if (!yourForm.$valid) {
angular.element("[name='" + yourForm.$name + "']").find('.ng-invalid:visible:first').focus();
return false;
}
};
method #2 - You can also use $anchorScroll service
see the documentation here
$scope.onSubmit = function(yourForm) {
if (!yourForm.$valid) {
var id = angular.element("[name='" + yourForm.$name + "']").find('.ng-invalid:visible:first').data('id');
$location.hash(id);
$anchorScroll();
return false;
}
};

Proper handling of input change event

It may be a correct behavior of change event, but the below behavior is bit annoying. When the value is updated from the field history (see explanation below), the event is not triggered.
Please see example code below. the result input field is updated with the change in input field 'input1'. The form and submit button is not fully relevant, but needed to submit a form to make the browser keep the history of field values.
To test:
enter any input in the field (say ABC)
Submit the form
enter first character of input from 1 (A)
use the down arrow to select the previous value + Enter
or use the mouse to select the previous value from the history
No input change is detected.
Which event/ how should this code should modify so that an event is generated whenever the input value is changed.
thanks.
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
</head>
<body>
Result:<input type="text" id="result" readonly></input>
<form method="post" action="">
<input type="text" id="input1" />
<button type=submit>Submit</button>
</form>
<script >
$(document).ready(function() {
$('#input1').change(
function(){
$('#result').val($('#input1').val());
});
});
</script>
</body>
</html>
I think this has nothing to do with jQuery.
A change event should be dispatched when the content of a control has changed and the control loses focus. In practice, the implementation of the change event is inconsistent in browsers, e.g. Firefox dispatches a change event when radio buttons are clicked on rather then when they lose focus. Also in IE, selecting a value from a list of previous values then causing a blur event doesn't fire a change event.
Note that for form controls to be successful, they must have a name attribute with a value. A simple test case is:
<form action="#">
<input type="text" name="input1" onchange="alert('changed');">
<input type="submit">
</form>
One solution is to use the blur event instead and compare the control's current value to its defaultValue - if they're different, perform whatever it is you were going to do for the change event. If the value may be changed a number of times, after the first time you need to compare with the last value onblur rather than the defaultValue.
Anyhow, here's a function that can be called onblur to see if a text input has changed. It needs a bit of work if you want to use it with other types of form control, but I don't think that's necessary.
<form action="#">
<input type="text" name="input1" onblur="
var changed = checkChanged(this);
if (changed[0]) {
alert('changed to: ' + changed[1]);
}
">
<input type="submit">
</form>
<script type="text/javascript">
// For text inputs only
var checkChanged = (function() {
var dataStore = [];
return function (el) {
var value = el.value,
oValue;
for (var i=0, iLen=dataStore.length; i<iLen; i+=2) {
// If element is in dataStore, compare current value to
// previous value
if (dataStore[i] == el) {
oValue = dataStore[++i];
// If value has changed...
if (value !== oValue) {
dataStore[i] = value;
return [true, value];
// Otherwise, return false
} else {
return [false, value];
}
}
}
// Otherwise, compare value to defaultValue and
// add it to dataStore
dataStore.push(el, value);
return [(el.defaultValue != value), value];
}
}());
</script>
Try the keyup event:
$(document).ready(function() {
$('#input1').keyup(
function(){
$('#result').val($('#input1').val());
});
});
http://jsfiddle.net/kaptZ/7/
It seems like it's definitely a browser bug. Not much you can do besides implement your own change handler with focus and blur. This example is not very reusable, but it solved the problem and can be used as inspiration for something reusable.
http://jsfiddle.net/kaptZ/9/
var startValue;
var input1 = $('#input1');
input1.focus(function(){
startValue = this.value;
});
input1.blur(function(){
if (this.value != startValue) {
$('#result').val(this.value);
}
});
A dirty alternative is to use autocomplete="off"
It looks like this bug which was supposed to be fixed in November 2009.
In modern browsers you can use the input event and update as you type. It can be bound either to the text input:
$('#input1').bind('input', function(){
$('#result').val($('#input1').val());
});
Or to the form:
$('#input1').closest('form').bind('input', function(){
$('#result').val($('#input1').val());
});

Categories

Resources