Controller stops updating value after the value is changed - javascript

I'm trying to use angular to change the css class of an element when a user inputs data, both after a button click and in real time as the user is typing in data.
HTML:
<input type="text" class="defaultClass" ng-class="{true: 'errorClass',
false:'defaultClass'}[updateInput()]" ng-model="inputOne">
CSS:
.defaultClass {border: 1px solid #ccc;}
.errorClass {border: 1px solid #FF0000;}
After a button is pressed, the controller checks if the model of the element is blank and if so, makes the function return true and therefore changes the css class in the ng-class to show an error.
$scope.calcButton = function (){
if ($scope.inputOne === "" || $scope.inputOne === undefined) {
$scope.updateInput = function() {
return true;
};
} else {
$scope.updateInput = function() {
return false;
};
}
};
Outside of the button click function, I have the following code in the same controller that should be watching the status of $scope.inputOne and returning true or false based upon the status of the input:
$scope.updateInput = function() {
if ($scope.inputOne === "") {
return true;
} else {
return false;
}
};
And it works fine as long as I don't click the button, but once the value is changed by the button press the controller stops checking if the input field is empty or filled.
This is a problem because I want to have the error messages fade away as the user types in data after a button press that threw errors, but I can't change the css by user input at this point.
Why does it do this? How can I ensure that the controller still keeps track of what's going on in the input field after the button click?

Try like this
ng-class="{'errorClass' : !inputOne,'defaultClass': inputOne }"
or like this
ng-class="!inputOne ? 'errorClass' : 'defaultClass'"
'',null,NaN,undefined,0 etc considered false in JavaScript.
just check model has value or not.
It'll work through two way binding . don't need method for this to check

Related

Check checkbox input manually in click handler

So I have this code snippet that handles click events on input[type=checkbox]. What I want to achieve is to set checked property manually, depending on the if condition scope.vm.checkedRows.indexOf(orderId) === -1 (here the false/true assignment is inverted to make the point), however it does not work.
link: function(scope, element) {
element.on('click', '.csv-ignore input', function(event) {
scope.$apply(function() {
var orderId = angular.element(event.target).closest('tr').data('order-id')
if (scope.vm.checkedRows.indexOf(orderId) === -1) {
scope.vm.checkedRows.push(orderId);
event.target.checked = false;
} else {
scope.vm.checkedRows.splice(scope.vm.checkedRows.indexOf(orderId), 1);
event.target.checked = true;
}
});
return false;
})
}
Checkbox does not get checked/unchecked. What I found interesting is that then I comment out return false it works fine. However I initially added return false to prevent default behavior and check/uncheck checkbox manually. Do you know what is wrong with this code?
Maybe you can directly put an expression in ng-checked and do rest of the operation in the controller's on click. It will set checked value dynamically
<input type="checkbox" ng-model="item" ng-checked="(vm.checkedRows.indexOf(orderId) !== -1)">

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 onChange computation - show only one alert

I didnt know how to properly name my question, but here goes.
In my html i have a "form" but not
<form></form>
.It is just a couple of selects, radio buttons and text inputs.
I enter, check and select values and according to these values, some computation is done. This "form" is computing on every keydown, blur, change. So when I change one value it will immediately recalculate the results with new value.
I would like to alert the user, when he didnt fill any of the necessary inputs. Here is how it works now (this is in a separate .js file)
function calculator() {
// Here is code that gathers the data from html
// and here are also some computations (many if-s)
// The code is too long to be putted here
}
$(function () {
$('select, input').on('keydown blur change', calculator);
});
I tried to put a if statement inside of my calculator function:
function calculator() {
// Here is code that gathers the data from html
// and here are also some computations (many if-s)
// The code is too long to be putted here
if (val1 == '' && sadzba == '' && viem == '' && ...) {
alert('You have to fill all necessary fields!')
}
}
This obviously caused, that the alert was popped every time I enter / choose new value, because at the beginning all variables are empty / with no value.
So how can I achieve, this situation: User fills in the "form" except of (for example)one value and only then will the alert pop up.
Than you.
I suggest to do the check on submit and return false if one of the fields is empty, preventing the form to be submitted.
$('form').on('submit', function () {
if (val1 == '' || sadzba == '' || viem == '') {
alert('You have to fill all necessary fields!');
return false;
} else { return true; }
});
Use a different event handler for the onblur event since that's when the cursor has left the input box. (It also prevents the event handler from firing all the time. That's a pretty expensive process and it can slow your page down)
$('select, input').on('blur', didTheyLeaveTheFieldEmpty);
Hope I understood you right, you can try this:
function calculator(event) {
if ( $(event.target).val().length == 0 ) {
alert('fill the field');
}
}
$('select, input').on('keyup', calculator);
even if you don't want a form with a submit buton you can create a button
and trigger your code on it's click
<input type="button" class="calculate">
$(function () {
$('.calculate').on('click', calculator);
});

jQuery validation with submit button disabled

I made some sort of form validation. User can input name of group and group description. With jQuery I'm validating if group name is empty or not, if empty submit button should be disabled. Now I have problems with disabling submit button. If I click on input tag where group name is, then validation is ok, and submit button is disabled, but if I just click on submit button, without touching anything else, then jQuery skip validation and fires submit button although name of group is empty.
I tried setting input tag in focus with jQuery but it only works if I actually click on that input tag.
Submit button is 'saveGroup' button.
Can someone tell me how to invoke click event on this input tag, or maybe I can use some other validation tehnique.
<div class="newGroupDiv">
<label>Title: </label><input type="text" id="groupTitle" onblur="checkTitle();"><br>
<label>Description:</label><br>
<textarea id="groupDescription"></textarea><br><br>
<button id="saveGroup">Save</button>
<button id="cancelGroup">Cancel</button>
<label id="groupError"></label>
</div>
---------------------------------------------------------------------------------
$("#saveGroup").click(function(){
var variable = checkTitle();
if(variable == true){
if($("#groupError").html() == ""){
$(".columns").append('<ul class="'+ $("#groupTitle").val() +'"><li class="naslov">'+ $("#groupTitle").val() +'</li></ul>');
$("ul").sortable({containment : 'document',
tolerance: 'pointer',
cursor: 'pointer',
revert: 'true',
opacity : 0.6,
connectWith : "ul",
placeholder: 'border',
items : 'li:not(.naslov)',
start : function(){
check = false;
$(".readContent").fadeOut(300);
}, stop : function(){
check = true;
}}).disableSelection();
$.post("addGroup.php", {'title' : $("#groupTitle").val(), 'description' : $("#groupDescription").val(),
'color' : $("#colorHex").html(), 'color2' : $("#colorHex2").html()}, function(){
window.location.reload();
});
}
}
});
--------------------------------------------------------------------------------
var checkTitle = function(){
$.post("checkTitle.php", {'title' : $("#groupTitle").val()}, function(data){
if(data == 'exist') $("#groupError").html("Group already exists");
if(data == 'no title') $("#groupError").html("Group title can't be empty");
else if(data == 'ok') $("#groupError").html("");
});
return true;
}
With this 'variable' I tried to accomplish some sort of callback wait, so when this variable gets result from function it should continue with rest of code, but I'm not sure if it works.
You would be better of switching the way you do things here. First of, as I said, make sure you do the "isEmpty" check without performing any ajax calls. Javascript is perfectly capable of doing so itself.
Secondly, instead of checking the HTML inside your element, you'd be better of checking the result of your checkTitle() function. Because there might be a slight possibility the if($("#groupError").html() == ""){ fails because there is still some HTML detected.
The above comments result in this javascript:
function checkTitle() {
$groupTitle = $('#groupTitle').val();
if($groupTitle == "") {
$("#groupError").html("Group title can't be empty");
return false;
} else {
$.post("checkTitle.php", {'title' : $groupTitle }, function(data){
if(data == 'exist') {
$("#groupError").html("Group already exists");
return false;
} else if(data == 'ok') {
$("#groupError").html("");
return true;
}
});
}
}
Now the result of the checkTitle() function can be used in your final check that you perform onBlur and onClick. Let's continue with your HTML:
<div class="newGroupDiv">
<label>Title: </label>
<input type="text" id="groupTitle" onblur="checkTitle();"><br>
<label>Description:</label><br>
<textarea id="groupDescription"></textarea><br><br>
<button id="saveGroup">Save</button>
<button id="cancelGroup">Cancel</button>
<label id="groupError"></label>
</div>
Just a little suggestion is to use a div instead of a label to show your groupError in, I understand right now this is for demo purposes only so it's just a little sidenote.
I'm not 100% possitive this solution will work, however, what I think is causing the issue is the default behaviour of the button you're using. Since the script is completely relying on the ajax call, my guess is that you have to prevent the default from happening as such:
$('#saveGroup').click(function(e) {
e.preventDefault();
});
You could give the script below a shot, hopefully it works. I can't test it because of the ajax calls. But I'll make a jsFiddle with some test data in a minute:
$("#saveGroup").click(function(e){
e.preventDefault();
var formValidation = checkTitle();
// formValidation is only true in case no errors occured
// Therefor making your #groupError check useless
if(formValidation == true) {
// Reset the #groupError html content
$('#groupError').html('');
// insert your other jQuery code here
}
});
a jsFiddle: http://jsfiddle.net/8bJAc/
As you can see onBlur the data is checked (please not there's a random factor that simulates true/false for your ajax call) and after submitting you can see either a success or error message.

Why am I getting "DOM Exception 8" ,when using Jquery's unwrap()?

I have this simple small peace of code which generate an exception : (only in chrome)
Uncaught Error: NotFoundError: DOM Exception 8
Scenario : If a user visited a textbox and didn't put a value , he will be notify when bluring.
And the textbox will be wrapped with a red div. And if he clicks - (in order to put a value) - the red div is removed ( by unwrap the textbox).
So
I have a textbox.
This textbox has a blur handler attched.
When a blur occurs , I'm checking if a value has been entered.
if a value has been entered : everything is ok. nothing is done.
if not :
I alert the user
I wrap the textbox , with a red border
I attach a click event handler so that if the user clicks on the text box (in order to put a value )
the border disappears .
The problem :
When the user was alerted and a red-div wraps the textbox , every time I click on the textbox (in order to put a value) - Im getting the exception ( and obviously things are messed up)
Question :
Why is it happenning , and how can I fix it ?
The code : ( JSBIN )
$("body").on("blur", ".myTb", function () {
if (!$(this).val()) {
alert('you must enter something!');
doWork($(this))
}
});
function doWork(obj) {
var t = $("<div class='divError'/>");
obj.wrap(t);
obj.on('click', function () {
obj.unwrap();
});
}
p.s.:
1) I want to keep the idea of wrapping an element with a red div and to remove it when - user clicks (in order to put a value). (because this is a small part of my plugin which already works like this)
2) There is no problem in FF
3) chrome version : 25.0.1364.97 m
4) jquery: 1.8
I think the problem is, that you wrap the input field multiple times. As soon as you test if the error wrapper already exists, the error is gone:
$("body").on("blur", ".myTb", function () {
if (!$(this).val()) {
doWork($(this));
}
});
function doWork(obj) {
var t = $("<div class='divError'/>"),
hasError = obj.closest('.divError').length;
if(!hasError) {
alert('you must enter something!');
obj.wrap(t);
}
//console.log(obj);
obj.on('click', function () {
console.log(obj);
obj.unwrap();
obj.focus(); // be sure to set focus to the input element
});
}
Updated test is here.
The problem is that the blur event fires when you unwrap the input element. It's safer to use .one() in this case:
function blurOn()
{
$("body").one("blur", ".myTb", function () {
if (!$(this).val()) {
alert('you must enter something!');
doWork($(this));
}
});
}
function doWork(obj)
{
var t = $("<div class='divError'/>");
obj.wrap(t);
obj.one('focus', function () {
obj.unwrap().focus();
blurOn(); // enable blur event handler again
});
}
blurOn();
Demo

Categories

Resources