$watch on form element - javascript

I'm trying to implement real time search so i have a search for including many input fields
so each and every time when user update input fields search function should be triggered.
i have came up with $watch to track model changes on form field
$scope.$watch('filters.site', function () {
$scope.$broadcast('updateDataTable');
});
$scope.$watch('filters.fname', function () {
$scope.$broadcast('updateDataTable');
});
$scope.$watch('filters.lname', function () {
$scope.$broadcast('updateDataTable');
});
but i'm just wondered is there anyway to get whole form value changes
my form look like
<form name="searchForm">
<label for="">FIRST NAME</label>
<input type="text"
class="form-control"
data-ng-model="filters.fname">
<span></span>
<label for="">LAST NAME</label>
<input type="text"
class="form-control"
data-ng-model="filters.lname">
<span></span>
<label for="">SITE</label>
<input type="text"
class="form-control"
data-ng-model="filters.site">
<span></span>
</form>
thanks

If you pass true as the last argument to $watch, Angular will watch for deep equality instead, and you can watch the entire object at once:
$scope.$watch("filters", function() { ... }, true);
That will incur creating a copy of the object on every digest cycle, but if all your filters object contains is those filters, it's probably not going to be any more inefficient than watching everything separately. If your filters object is expensive to copy for some reason you could also use a $watchGroup for equivalent functionality to your current code except neater:
$scope.$watchGroup(["filters.site", "filters.fname", ...], function() { ... });

$scope.$watch('filters', function () {
$scope.$broadcast('updateDataTable');
});

You can use the ng-change directive that could call your search function just add it on all your input so when one of the input change the search function will be called.
<input type="text" class="form-control" data-ng-change="search()" data-ng-model="filters.fname">

Related

JavaScript watch form fields and set session cookie

I'm a little rusty as it's been a long time since I've used much JavaScript. I'm wanting to watch all input fields within a form for the mouseout event and set a session cookie to store that value. Is there a neat way I can do this so I can watch all form fields within a form and avoid needing to watch one field at a time — I'm anticipating there could be a large number of fields so I want an efficient way to target them.
Say my form is:
<form action="#">
<input id="form1_name" name="name" class="s_input" required="required" type="text">
<input id="form1_email" name="email" class="s_input" required="required" type="text">
<textarea id="form1_message" name="message" class="s_input" cols="30" rows="4" required="required"></textarea>
<input id="form1_submit" name="submit" class="s_input" value="Send" type="submit">
</form>
This is as far as I got with my JS, it currently fails with:
//get all the fields in question
var inputFields = document.getElementsByClassName('s_input');
//can see the inputs collected in an array
console.log(inputFields);
//fails
inputFields.addEventListener("mouseleave", function( event ) {
});
I get an error of:
TypeError: inputFields.addEventListener is not a function [Learn More]
document.getElementsByClassName('s_input'); Creates an array so to add anything to each element of the class s_input you need to loop over the collection.
Something like this should work:
for (i = 0; i < inputFields.length; i++) {
inputFields[i].addEventListener("mouseleave", function( event ) {
//event code here
});
}
Edit: Probably better to use "blur" event as mouseleave wont work if user is on a touch device or using keyboard only to tab through inputs.
Instead of attaching an event listener for blur you can do this:
<input onblur="callYourFunction()" id="form1_name" name="name" class="s_input" required="required" type="text">

focus on input trigger twice instead of only one trigger

Hi I am creating jquery plugin. I stuck on when i focus on input box then it triggered twice.
$(document).ready(function(){
$('#searchText').typefast();
$('#searchText1').typefast();
})
$.fn.typefast=function(){
$('input').focus(function(){
console.log($(this).attr('id'));
})
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" class="form-control" name="" value="" id="searchText">
<input type="text" class="form-control" name="" value="" id="searchText1">
`
It's running twice because you are explicitly calling typefast() twice in your document.ready function. Even though your selectors were both missing the # in them, typefast() still gets called on the empty jQuery wrappers. And, since typefast() doesn't actually do anything with the contents of the wrapped set it gets called on, it goes ahead and processes on all input elements. So, the end result is that all input elements get typefast registered into their focus event twice.
If (and this is a big if) you were going to use a plug-in for this, you should just call it once because the plug-in finds all input elements and sets their event handler. Also, plug-ins have a certain pattern that is recommended to be followed to ensure that the $ will, in fact, point to the jQuery object and to ensure that method chaining will work. That would look like this:
$(function(){
// You would want this to be a jQuery utility method (not a wrapped set method)
// so you would set it up directly on jQuery, not jQuery.fn. This way, you can
// just call it whenever you want without a wrapped set.
$.typefast();
});
// By wrapping the plugin in an Immediately Invoked Function Expression
// that passes itself the jQuery object, we guarantee the $ will work
(function($){
$.typefast = function(){
$('input').focus(function(){
console.log($(this).attr('id'));
});
}
}(jQuery));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" class="form-control" name="" value="" id="searchText">
<input type="text" class="form-control" name="" value="" id="searchText1">
But, there is no need for a jQuery plug-in here. This is not what plug-ins are for and you are not even writing it according to best practices. This is not the way to set up event handlers. All you need to do is set up an event handler for the focus event of the textboxes:
// Just passing a function directly to the jQuery object is the same
// thing as explicitly setting a callback for document.ready
$(function(){
// This is the function that will be called when any input gets the focus
function typeFast(){
console.log($(this).attr('id'));
}
// Set all input elements to call typeFast when they receive the focus
$('input').on("focus", typeFast);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" class="form-control" name="" value="" id="searchText">
<input type="text" class="form-control" name="" value="" id="searchText1">

Bind variable to field on focus in angular

I'm using Angular 1.6.2 for a personal project for learning the framework, and I couldn't figure out a way to solve this problem:
I have a variable that gets updated often(like once a second or less) and I have two input text fields in the view. I want the variable to update the input(and another variable) only when it is focused.
For sake of better UX I now updated the view a little bit, so now every Text-Input has a Radio-Button alongside(since sometimes the user might want the value to be updated but he'll need to click outside the field).
Inside the controller:
$interval(function () {
// This gets the updated value from an external source/code.
$scope.updatingValue = updatingValueFunc();
}, 1000);
$scope.fields = [
{ first: 12323, second: 1430,}
];
Html:
<div class="field-wrap">
<input type="radio" name="current-bind" value="answer.end">
<input type="number" ng-model="answer.second">
</div>
<div class="field-wrap">
<input type="radio" name="current-bind" value="answer.start">
<input type="number" ng-model="fields.first">
</div>
Angular has a ng-focus hook you can use to call your update function.
<input type="radio" name="current-bind" value="answer.end" ng-focus="updateValue()"/>
and in your js you can create a function to match it
$scope.updateValue = function(){
$scope.updatingValue = updatingValueFunc();
}
You can also use ng-click if you want the function to run on click instead of on focus.

Angular ng-Model not showing up second time

I have this code inside a modal popup that is shown under certain circumstances, the first time the modal is shown everything is working normal.
I have this code:
<div class="form-group">
<p>First Name:</p>
{{vm.user.name_first}}
<input type="text" class="form-control" ng-model="vm.user.name_first" name="firstName" required />
</div>
After closing the modal and opening again, the text below the p is shown correctly, however, the ng-model (which has the same content after the p), is showing the input empty instead of the content of vm.user.name_first.
What can be happening that only affects the second time?
Try this:
<div class="form-group">
<p>First Name:</p>
{{vm.user.name_first}}
<input type="text" class="form-control" ng-model="vm.user.name_first" name="firstName" ng-model-options="{ getterSetter: true }" required />
Explanation:
Sometimes it's helpful to bind ngModel to a getter/setter function. A getter/setter is a function that returns a representation of the model when called with zero arguments, and sets the internal state of a model when called with an argument. It's sometimes useful to use this for models that have an internal representation that's different from what the model exposes to the view.
https://docs.angularjs.org/api/ng/directive/ngModel -> last paragraph

JavaScript did not receive value in this.form

I am using a three part code below:
First part of the code: Basically a javascript function changeSearchEngine will be triggered when user select Google.
<p id="searchbox">This paragraph will change once javascript is triggered</p>
<form align=right>
<select name="searchengine" onchange="changeSearchEngine(this.form)">
<option value="google">Google</option>
</select>
</form>
This is my changeSearchEngine function in javascript.
function changeSearchEngine(form)
{
var searchEngine=form.searchengine.value;
if (searchEngine=="google")
{
var url_google='<form method="get" action="http://www.google.com/search" onsubmit="submitGoogle(this.form)" target="_blank"><input type="text" name="q" size="31" maxlength="255" value="" /><input type="submit" value="Google Search"/></form>';
document.getElementById("searchbox").innerHTML=url_google;
}
}
At this point of time, all is working well. When I select Google, the searchbox for google appears. I can search and everything.
Notice there is a onsubmit="submitGoogle(this.form)" right? I need to save what the user search terms into SQL table. So I have this javascript function below to capture what user have type:
function submitGoogle(form)
{
alert("Inside submitGoogle function");
var searchterm=form.q.value;
alert(searchterm); //to test. this part didnt capture the value.
}
I managed to invoke the submitGoogle function BUT however I can't retrieve the value of q despite using searchterm=form.q.value. What did I do wrong here?
In your onsubmit handler, you are passing this.form. But, this already refers to the form since it is the form itself that triggers the submit event. Form fields have a form property, but the form itself does not have a form property. So, just change your handler to pass this instead of this.form.
http://jsfiddle.net/fmqNj/
onsubmit="submitGoogle(this)"
Okay I found one possible solution. Let me answer my own question.
In changeSearchEngine(form) function, i change to this:
var url_google='<form method="get" name="googleform" action="http://www.google.com/search" onsubmit="submitGoogle(this.form)" target="_blank"><input type="text" name="q" size="31" maxlength="255" value="hello" /><input type="submit" value="Google Search"/></form>';
In submitGoogle(form) function, i change to this:
var searchterm=document.googleform.q.value;
But I still like others to comment on my solution whether it is not elegant or not within the practice. :D

Categories

Resources