I have a text box and an options list where options can be added to the current text that is in that box. The problem I'm having is that when I click on an option, and that option is added to the text, I want the cursor to be put back into the text box so the user can continue typing. Any help is much appreciated.
Text field:
input type='text' ng-model='comment.text' ng-change='userList(comment.text)'
JS:
$scope.addUserToComment = function(user) {
$scope.comment.text += user + " ";
$scope.usersShow = false;
};
Avoid modifying the DOM in the controllers.
edit: but to answer your question, ng-focus was me being lazy.
I would create a directive
angular.module('focus-me', []).
.directive('focusMe', function(){
return {
scope: { watch_this: '=' },
link: function(scope, element, attrs){
scope.$watch('watch_this', function(){
$(element).focus();
}
}
}
});
this gives you two options
input type='text' focus-me='comment.text' ng-model='comment.text' ng-change='userList(comment.text)'
or
input type='text' focus-me='some_obj_attr_you_toggle' ng-model='comment.text' ng-change='userList(comment.text)'
1st will call the watcher function more times than necessary, when you are typing as well (not really a big deal).
2nd will only call the watcher function when you toggle the attr in your addUserTo function.
A simpler way (although you are modifying the dom in the controller) would be:
$scope.addUserToComment = function(user, $event) {
$($event.target).find('css selector to navigate to textbox').focus();
$scope.comment.text += user + " ";
$scope.usersShow = false;
};
in your ng-click add another parameter
ng-click='addUserToComment(user, $event)'
PS. Code might not be 100% correct but you get the idea.
$('a').on('click', '#options', function(){
$('input').focus();
});
Related
My JHipster generator version is: generator-jhipster 2.27.1
I am using show-validation for my Form validation. Everything seems to be working alright except the following scenario.
Assume I have a text field which is required.
Enter one character, Field becomes valid.
Delete the text, Field becomes Invalid, error message appears and the form-group for input turns red.
Now Re-enter text. Field becomes valid and error message disappears, but the
has-error class on form-group is not yet removed. Form group still remains red.
When you proceed to enter the
second character, the has-error is now removed.
This is the relevant code from form.directive.js
$inputs.each(function() {
var $input = $(this);
scope.$watch(function() {
return $input.hasClass('ng-invalid') && $input.hasClass('ng-dirty');
}, function(isInvalid) {
$formGroup.toggleClass('has-error', isInvalid);
});
}
The form-validation directive is not updating immediately but is behind by one input change. I am not able to figure out which part of the code needs modifying.
Added console logs, but to no avail. I assume it has got something to do with text value vis-a-vis model value, but don't know how to fix it.
How about this?
(added: attrs, formCtrl attr to link function and changed $watch.function - uncomment dirty check if needed)
link: function (scope, element, attrs, formCtrl) {
element.find('.form-group').each(function() {
var $formGroup = $(this);
var $inputs = $formGroup.find('input[ng-model],textarea[ng-model],select[ng-model]');
if ($inputs.length > 0) {
$inputs.each(function() {
var $input = $(this);
scope.$watch(function() {
//inputs need to have 'name' attribute for this to work
return formCtrl[$input[0].name].$invalid;
//&& formCtrl[$input[0].name].$dirty;
}, function(isInvalid) {
$formGroup.toggleClass('has-error', isInvalid);
});
});
}
});
}
I have the option to delete an entity by clicking DELETE ENTITY. When this is clicked the words DELETE ENTITY are changed to CLICK AGAIN TO CONFIRM. I want the words to change back to DELETE ENTITY if the focus is lost on the button. I tried using ng-blur="resetConfirmDelete", but that didn't work. Any ideas?
HTML
<!--Delete entity-->
<p class="action-link no-outline" ng-click="setConfirmDelete()" ng-show="!confirmDelete" ng-if="permissions.entities.collaborator">DELETE ENTITY</p>
<p id="delete-confirm" class="action-link no-outline" ng-click="delete()" ng-show="confirmDelete" ng-if="permissions.entities.collaborator">CLICK AGAIN TO CONFIRM</p>
</div>
CONTROLLER
$scope.setConfirmDelete = function () {
$scope.confirmDelete = true;
};
$scope.resetConfirmDelete = function () {
$scope.confirmDelete = false;
}
Try using ngBlur for this: https://docs.angularjs.org/api/ng/directive/ngBlur
<p id="delete-confirm" class="action-link no-outline" ng-blur=resetConfirmDelete()">..</p>
UPD
Then you may make use of some directive that detects click anywhere outside of the specific DOM element, for example like this one:
.directive('clickElsewhere', function($parse, $rootScope) {
return {
restrict: 'A',
compile: function($element, attr) {
var fn;
fn = $parse(attr['clickElsewhere']);
return function(scope, element) {
var offEvent;
offEvent = $rootScope.$on('click', function(event, target) {
if (element.find($(target)).length || element.is($(target))) {
return;
}
return scope.$apply(function() {
return fn(scope);
});
});
return scope.$on('$destroy', offEvent);
};
}
};
});
then in the template you can do:
<p id="delete-confirm" class="action-link no-outline"
click-else-where="resetConfirmDelete()" >
You might be running into a problem using ng-blur because the statements appear to be in a div, which is not a :focus-able element by default. Try using a button instead.
Weird that ng-blur="resetConfirmDelete" didnt work, it is the right solution as much as i know.
Maybe the second <p> is not being focused when it appears there for the focuse is never lost and ng-blur is never activated.
Also try adding the ng-blur to the first <p> instead of the second one, assuming it will be focused when the second one appears.
Editted for better answer..
You need to swap the hide/show between elements and focus one at same time.
<!--Delete entity-->
<div
<p class="action-link
no-outline"
ng-click="setConfirmDelete()"
ng-show="!confirmDelete"
ng-if="permissions.facilities.collaborator">DELETE FACILITY</p>
<p id="delete-confirm"
class="action-link no-outline"
ng-click="delete()"
ng-show="confirmDelete"
ng-focus="confirmDelete"
ng-blur="blurDelete()"
ng-if="permissions.facilities.collaborator">CLICK AGAIN TO CONFIRM</p>
</div>
u'll need this lines:
ng-focus="confirmDelete"
ng-blur="blurDelete()"
With Angular, I'm trying to implement a way to change a value with an 'Edit' button click in such a way that when this button is clicked, an input is displayed over the text, and when the 'Save' button is clicked, the input's opacity becomes 0, and the model's value is applied.
I've created a jsfiddle to make my issue a bit more visual. JSFIDDLE DEMO
The issue is the following: I want to select the text to make it obvious for the user that it can be changed now, after the 'Edit' button is clicked. I do it this way:
var input = angular.element(document.querySelector('input'))[0];
input.focus();
input.select();
The only problem is that the input.select() only works on second attempt. You can see it in the demo. I have no rational explanation to this whatsoever. I need to mention that this app that I'm writing is for Electron, it means that it will only launch in Chromium, so I don't need cross-browser support for this.
When the 'Edit' button is clicked for the first time, no selection happens:
But when I click 'Save' and then 'Edit' again, everything works as expected:
Any thought would be much appreciated!
Use $timeout , it will trigger digest cycle
var app = angular.module('app', []);
app.controller('mainController', function($timeout,$scope) {
var vm = this;
vm.address = '127.0.0.1';
vm.name = 'anabelbreakfasts';
vm.editing = {
address: false
};
vm.temp = {
address: null
};
vm.changeClick = function(element) {
vm.editing[element] = !vm.editing[element];
if (vm.editing[element]) {
vm.temp[element] = vm[element];
var input = angular.element(document.querySelector('div.row.' + element + ' input'))[0];
$timeout(function(){
input.focus();
input.select();
});
} else {
vm[element] = vm.temp[element];
}
};
});
Fiddle
Use setTimeout:
setTimeout(function(){
input.select();
}, 0)
Also, input.focus() is kind of redundant
I have a textarea like so,
<textarea id="txtaFilter" cols="45" rows="5"></textarea>
and the following script,
$(document).ready(function () {
$(".selector").bind('change', function () {
var value = $(this).val();
$("#txtaFilter").val($("#txtaFilter").val() + value);
$(this).children('option:eq(0)').prop('selected', true);
});
});
where ".selector" is a class applied to two dropdownlists.
When I chose a value on the dropdown, it appears to do nothing, but after looking at the debugger in chrome it is changing the value just not displaying it.
Does anyone know why this is? Is there something special I'm missing about the .val() property?
Problem/Solution:
I forgot that there are multiple "#txtaFilter"'s on the page when I removed the $(this).siblings("#txtaFilter"), So it was accessing the hidden one instead of the visible one. Sorry about that, guess I was wrong on the question too :/
You can use val method:
$("#txtaFilter").val(function(i, oldVal){
return oldVal + value
});
Use .val() to get the text of a textarea.
$(document).ready(function () {
$(".selector").bind('change', function () {
var value = $(this).val();
var txtaFilter = $("#txtaFilter");
txtaFilter.val(txtaFilter.val()+value);
$(this).children('option:eq(0)').attr('selected', true);
});
});
I'm having a slight issue getting a jquery action to function ideally. Currently everything is working properly on a blur from a particular field, which is called "person_email". The issue is that if the end user does this, and decides to click a hyperlink for example on the rest of the page that jquery from the blur triggers, the user see's this briefly, and then continues to the corresponding link.
Ideally this would work that the blur would only trigger if a hyperlink was not clicked.
var $email = $("#person_email");
var $hint = $("#hint_edit");
$email.on('blur',function() {
$hint.hide; // Hide the hint
$(this).mailcheck({
suggested: function(element, suggestion) {
// First error - Fill in/show entire hint element
var suggestion = "Did you mean: <span class='suggestion'>" +
"<span class='address'>" + "</span>" +
"<a href='#' class='domain'>" + suggestion.address +
"#" + suggestion.domain + "</a></span>?";
$hint.html(suggestion).fadeIn(150);
}
});
});
$hint.on('click', '.domain', function() {
// On click, fill in the field with the suggestion and remove the hint
$email.val($(".suggestion").text());
$hint.fadeOut(200, function() {
$(this).empty();
});
return false;
});
})
I assume you want off
$("a").on("click",function() {
$email.off();
});