How to simulate an autofocus - javascript

I created a webview (Android) for our site.
I put the input in autofocus:
<input name="barcode"
type="search"
placeholder="Scan Barcode"
class="form-control"
autocomplete="off"
autofocus
required>
When the page is loaded the input is selected but the keyboard of Android does not open => Perfect
But when I focus on this input the android keyboard opens and I do not want it to open because this input is only used to scan barcodes
So I would like to "simulate" an autofocus when closing a modal (for example) rather than a simple focus, how to do?
$('.modal').on('hidden.bs.modal', function (e) {
$("input[name='barcode']").focus();
});
EDIT : More details :
We use these scannettes to access our intranet site :
https://www.jmprime.co.uk/product_info.php/android-barcode-scanner-with-gun-grip-rugged-handheld-ip67-device-with-1d-barcode-reader-p-238
On the page in question there is only one input, the goal is to enter the input without opening the android keyboard in order to scan a bar code (they are then sent to the database)

As of This answer, readonly seems to work.
I found it difficult to work directly on the input, so I would still use the trick of the fake input.
With timeout set at 1ms it works like charm. (updated fiddle below)
<input id="barcode" name="barcode" type="hidden" placeholder="Scan Barcode" required>
<label for="barcode" class="your-cool-class-to-make-this-look-like-an-input" />
With the for attribute, when clicked, it will focus the related input.
https://jsfiddle.net/ubdnvsk0/26/

Try this:
I used Bootstrap 4 for modaland jQuery.
I forgot to why .focus() sometimes doesn't execute but I remember by putting it into setTimeout() with a time of 0, it does the trick.
Just in case you get confused with the code: () => {} is similar to
function() {}, it's an anonymous function / callback
Arrow functions are a more concise way to write function, introduced
in ES6.
Arrow functions are anonymous functions, which means you
cannot name it. Arrow functions do not bind to this, they don't create
their own this, thus the enclosing this is being used.
Reading Material: 'Arrow Functions - developer.mozilla.org'
$(document).ready(() => {
$('#myModal').on('hidden.bs.modal', () => {
setTimeout(() => {
$("#barcode").focus();
}, 0);
})
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
<div class="container">
<input id="barcode" name="barcode" type="search" placeholder="Scan Barcode" class="form-control" autocomplete="off" autofocus required readonly><br>
<!-- Button to Open the Modal -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal">
Open modal
</button>
<!-- The Modal -->
<div class="modal" id="myModal">
<div class="modal-dialog">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title">Modal Heading</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<!-- Modal body -->
<div class="modal-body">
Modal body..
</div>
<!-- Modal footer -->
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>

Related

Modal window comment editing module (editable text)

I want to make, that during the ediditing comment action, I have modal window with comment text written inside textarea, and it is editable without deleting all text with clicking. I tried just to put value inside textarea or placing it in placeholder. But both options are wrong and doesnt work.
Can someone take a look on this code and give me an advice, how should I take for it.
editComment.html
<div class="modal-header">
<h3 class="modal-title" id="modal-title">Edytuj komentarz</h3>
</div>
<div class="modal-body" id="modal-body">
<div class="row">
<div class="col-sm-12">
<div class="row">
<div class="col-sm-12 form-group">
<label>Treść</label>
<textarea class="form-control input-sm"
name="description"
ng-maxlength="512"
ng-model="$ctrl.selected"
rows="6">{{comment.value()}}</textarea>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-raised btn-primary"
type="button"
ng-disabled="!$ctrl.selected"
ng-click="$ctrl.ok()">Zapisz
</button>
<button class="btn btn-raised btn-warning"
type="button"
ng-click="$ctrl.cancel()">Anuluj
</button>
</div>
editComment.js
(function() {
'use strict';
angular.module('settlerApplication').controller('EditCommentCtrl', function($uibModalInstance) {
var $ctrl = this;
$ctrl.ok = function() {
$uibModalInstance.close($ctrl.selected);
};
$ctrl.cancel = function() {
$uibModalInstance.dismiss('cancel');
};
});
})();
I'm not sure to understand what you are trying to achieve. But anyway : if you want to init your textarea's ng-model with $ctrl.foo (comment.value() in your case, from what I understood), you should either :
In the controller, init your $ctrl.selected variable with this value :
$ctrl.selected = $ctrl.foo;
Or, in your template, use ng-init :
<textarea class="form-control input-sm"
ng-init="$ctrl.selected = $ctrl.foo"
name="description"
ng-maxlength="512"
ng-model="$ctrl.selected"
rows="6"></textarea>
Ok, so I am going to explain that a little.
I have modal window like that:
I want to edit existing comments in this window. And so I want my comment appears instead of text: "Komentarz" (under: "Treść" after clicking in there). And I want that comment text to be editable, so I dont have to write it down again (put the whole text to that area). Is it make it a little better explained about my goal?

Weird behaviour of my scope variables

I am new in this field and want to write a app, now I meet some problems. Here is a simple version of my code, what I want is the API only show signUp first. After I press signUp and press submit the button shown should be only signout
Now, my scope variable doesn't work, two button show here. Could you modify it and tell me the reason? Please use the rootscope and scope and sc.logIn() if possible so that I can know how to write in this way. Thanks!
https://plnkr.co/edit/ewhLZsKKTWTzlECsj4xO?p=preview
angular.module('myApp',['myApp.dashboard','myApp.signUp']);
angular.module('myApp.dashboard').controller('mainControl',mainControl);
mainControl.$inject = ['$rootScope','$scope'];
function mainControl($rootScope,$scope){
$rootScope.logged=false;
$scope.logged=$rootScope.logged;
}
angular.module('myApp.signUp').controller('signUpControl',signUpControl);
signUpControl.$inject = ['$rootScope','$scope'];
function signUpControl($rootScope){
alert("haha");
this.logIn=function(){
$rootScope.logged=true;
};
}
There are couple of issues with your code.
Whenever you declare a module without a second argument, it just tries to fetch the module that is already declared / defined. In order to create a new module, you need to pass in the dependencies or an empty array, if there are no dependencies.
Also, you need to watch on the changes being done to the scope to ensure your changes are notified to the controllers to make them visible on the view.
Here is the working solution:
angular.module('myApp', ['myApp.dashboard', 'myApp.signUp']);
angular.module('myApp.dashboard', []).controller('mainControl', mainControl);
function mainControl($rootScope, $scope) {
$rootScope.logged = false;
$rootScope.$watch(() => $rootScope.logged, function() {
$scope.logged = $rootScope.logged;
});
}
mainControl.$inject = ['$rootScope', '$scope'];
angular.module('myApp.signUp', []).controller('signUpControl', signUpControl);
signUpControl.$inject = ['$rootScope', '$scope'];
function signUpControl($rootScope) {
this.logIn = function() {
var a = 1;
$rootScope.logged = true;
};
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="mainControl as mc">
<div>{{mc.logged}}
<div ng-hide="logged">
<button type="button" class="btn" data-toggle="modal" data-target=".signUp">Sign Up</button>
</div>
<div ng-show="logged">
<button>Sign Out</button>
</div>
</div>
<div class="signUp modal fade" id="signUp" ng-controller='signUpControl as sc'>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">sigh up</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
</div>
<div class="modal-body">
<form id="signUpForm" name="signUpForm" ng-submit="sc.logIn()">
<label for="email">
<span>email:</span>
<input type="email" name="email">
</label>
<button class="submit" id="signUpSubmit" type="submit" value="signUp">submit</button>
</form>
</div>
<div class="modal-footer">
</div>
</div>
</div>
</div>
</div>
</div>
For some reason the code snippet doesnt let me submit the form.
You can find a working solution here : Codepen
It is not weird at all.
Open your console, it shows errors.
Your main problem is angular bootstrap error.
angular.module('myApp.dashboard', [])
------------------------------- ^^ ------- must be an array even empty

using modal as submit confirmation

I currently have a form. As per below.
<form action="/process" id="formTest" name="formTest" enctype="multipart/form-data" method="POST">
<input type="text">
</form>
I added a modal to confirm on the submit.
<div class="modal fade" id="bondModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title"></h4>
</div>
<div class="modal-body">
<p>Test;</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" id="accept" class="btn btn-primary">Accept</button>
</div>
</div><!-- /.modal-content -->
Now if the user submit, the modal of confirmation will be showed, and if the user subsequently choose accept, it will proceed the submit.
The problem is , the subsequent submit never works.
$('#formTest').submit(function(e) {
e.preventDefault();
$('#bondModal').modal('show');
$("#accept").click(function(e) {
$("#formTest").submit();
e.preventDefault();
$('#bondModal').modal('hide');
}
);
} });
The thing is if I change the code to reset instead of submit..it works for reset ..
$('#formTest').trigger('reset');
You've got yourself stuck in a loop.
When you fire the action:
$("#formTest").submit();
You are not submitting the form because you are calling your own function which prevents the default action:
$('#formTest').submit(function(e) {
e.preventDefault();
//do stuff
});
If you want to use the code you have currently you can do 1 of 2 things:
use one() on the submit function so it only fires once. This would require you to rebind on a reset or cancel
$('#formTest').one('submit', function(e) {
e.preventDefault();
//do stuff
});
Or unbind the submit function just before your forced submission.
$('#formTest').on('submit', function(e) {
e.preventDefault();
$("#accept").click(function(e) {
$('#formTest').unbind('submit');
$('#formTest').submit();
});
});
However, I would go a different way, and take the submit button out of the visible markup on the page. Just put an a tag in the form that you fire the open-modal function from upon click. Then you don't need to do any submission in your code, you just have the standard submit and reset buttons in the modal and they carry out their default behavior:
The markup:
<form>
<input type="text">
<a class="open-modal">Submit</a>
<div class="modal">
<h4 class="modal-title">Confirm?</h4>
<p>Test</p>
<input type="reset" class="btn btn-default">Cancel</button>
<input type="submit" class="btn btn-primary">Accept</button>
</div>
</form>
And the code:
$('a.open-modal').on('click', function(e) {
e.preventDefault();
$('.modal').fadeIn();
});
Much simpler. Hope this helps.
The issue is this line:
document.getElementbyname("formTest").submit();
There is no function called "getElementbyname()". It seems you are looking for document.getElementsByName() which returns a NodeList. In that case:
document.getElementsByName("formTest")[0].submit();
However, you can also use the document.forms array:
document.forms["formTest"].submit();
Finally, since your form has an ID, you could also use that:
document.getElementById("formTest").submit();

How to properly open and close Bootstrap modal from AngularJS

On my html page, I got just a simple Bootstrap modal and button to call it:
<button class="btn btn-primary" data-toggle="modal" data-target="#addUpdateGroup">Add group</button>
<div class="modal fade" id="addUpdateGroup" tabindex="-1" role="dialog" aria-labelledby="addUpdateGrouplLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
</div>
<form name="addUpdateGroupForm" ng-submit="addUpdateGroupForm.$valid && groupCtrl.addUpdateGroup()" novalidate>
<div class="modal-body">
<input type="hidden" ng-model="groupCtrl.group.id" name="groupid" />
<label for="groupname">Group name:</label>
<br>
<input ng-model="groupCtrl.group.name" type="text" name="groupname" id="groupname" required />
<br><br>
<label for="groupcolor">Boja grupe:</label>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Add</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
</form>
</div>
</div>
</div>
It's a just simple form. The validation is done by AngularJS.
Now...when user submits the form, I'd like for the modal to close, but ONLY if it was valid input.
So I've put the code for closing the modal into the controller:
this.addUpdateGroup = function() {
// Adding a new group
if (typeof this.group.id === 'undefined') {
this.id += 1;
this.group.id = this.id;
this.groups.push(this.group);
// Updating an existing group
} else {
this.groups[this.group.id].name = this.group.name;
this.groups[this.group.id].color = this.group.color;
}
// Clean the form and remove the modal
this.group = {};
$scope.addUpdateGroupForm.$setPristine(true);
$('.modal').modal('hide');
};
But this doesn't follow the best practice of not manipulating the DOM from the controller.
QUESTION: Is there a better way? How would you implement a modal which needs to be shown or hidden when certain function in controller is called?
You are not following Angular best practices. If you havent done so already, review this legendary answer: https://stackoverflow.com/a/15012542/202913 Specifically points 1 - 3 of that post.
That out of the way, you should be using either of the following two libraries. Both of them implement Bootstrap's functionality, but with a native Angular implementation, i.e. it does not rely on the Javascript library of Bootstrap (but does use the Bootstrap's CSS):
angular-ui/bootstrap
angular-strap
Both are excellent, so use whichever library feels more comfortable to your coding style.

Modal Form Submission without refresh

I have a modal window that pops up when I want to add a new project to my dashboard. I have gotten it to work with jquery post however, I cannot prevent it from refreshing. What I want to do is after the project is added to the database, show a success message and close the modal window after few seconds and not refresh the page (parent page of modal).
Here is my modal
<div class="modal fade" id="add-project-dialog" tabindex="-1" role="dialog" aria-labelledby="basicModal" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title" id="myModalLabel">Add a new Project</h4>
</div>
<div class="modal-body">
<h3>New Project:</h3>
<form class="form-horizontal" id="add-project-form" action="/projects/add" method="POST">
<fieldset>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label" for="name">Project Name</label>
<div class="col-md-4">
<input id="name" name="name" type="text" placeholder="" class="form-control input-md">
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label" for="description">Project Description</label>
<div class="col-md-4">
<input id="description" name="description" type="text" placeholder="" class="form-control input-md">
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label" for="project_state">Project State</label>
<div class="col-md-4">
<input id="project_state" name="project_state" type="text" placeholder="" class="form-control input-md">
</div>
</div>
</fieldset>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button id="add-btn" class="btn" type="submit">Add</button>
</div>
</form>
</div>
</div>
Here is my project-dashboard.js
AddProject = function(){
$(document).ready(function() {
$("#submit").submit(function(event){
event.preventDefault();
$.ajax({
url: "/projects/add",
type:"POST",
data:
{
'name': $('#name').val(),
'description': $('#description').val(),
'project_state': $('#project_state').val()
}
});
});
});
}
My views.py
class AddProject(webapp2.RedirectHandler):
def get(self):
template_values = {
#'greetings': greetings,
#'url_linktext': url_linktext,
}
path = os.path.join(os.path.dirname(__file__), '../templates/project-add.html')
self.response.write(template.render(path, template_values))
def post(self):
project = Project()
project.name = self.request.get('name')
project.description = self.request.get('description')
project.project_state = self.request.get('project_state')
time.sleep(2)
project.put()
self.redirect('/projects')
I have tried removing the self.redirect('/projects') however that only takes me to a blank page that is /projects/add (that is the action in the form).
The issue is that you added .ready(foo) handler inside of the AddProject function. I suppose that document is loaded when AddProject is called.
Another issue is that in your HTML, the form has id add-project-form, so you should do $("#add-project-form") instead of $("#submit").
$(document).ready(function () {
$("#add-project-form").submit(function(event){
event.preventDefault();
$.ajax({
url: "/projects/add",
type:"POST",
data:
{
'name': $('#name').val(),
'description': $('#description').val(),
'project_state': $('#project_state').val()
}
});
});
});
});
Take ready handler outside of the AddProject function and it should work (the submit handler is added).
Edit: After some debugging, the answer was to use the right id and proper placing of the javascript code, as noted by the comments.
For starters, a refresh is easy to avoid, just make sure to prevent the default event from running; since you're using jQuery, I would recommend doing return false to end the function, since it both 'prevents default' and 'stops propagation'.
So the first thing you should do is check if your javascript code is actually running and not erring in the middle of execution. If everything is fine there, the worst case is that the project is not actually added (server side error) but the page should not refresh.
Your server side code has nothing to do with the refresh (if it's being properly hijacked), so the response doesn't really matter, I would actually return the id of the new project (so you could provide a link for the newly created item or something like that), but i digress...
Here is a snippet for not only closing modals without page refresh but when pressing enter it submits modal and closes without refresh
I have it set up on my site where I can have multiple modals and some modals process data on submit and some don't. What I do is create a unique ID for each modal that does processing. For example in my webpage:
HTML (modal footer):
<div class="modal-footer form-footer"><br>
<span class="caption">
<button id="PreLoadOrders" class="btn btn-md green btn-right" type="button" disabled>Add to Cart <i class="fa fa-shopping-cart"></i></button>
<button id="ClrHist" class="btn btn-md red btn-right" data-dismiss="modal" data-original-title="" title="Return to Scan Order Entry" type="cancel">Cancel <i class="fa fa-close"></i></a>
</span>
</div>
jQUERY:
$(document).ready(function(){
// Allow enter key to trigger preloadorders form
$(document).keypress(function(e) {
if(e.which == 13) {
e.preventDefault();
if($(".trigger").is(".ok")) //custom validation dont copy
$("#PreLoadOrders").trigger("click");
else
return;
}
});
});
As you can see this submit performs processing which is why I have this jQuery for this modal. Now let's say I have another modal within this webpage but no processing is performed and since one modal is open at a time I put another $(document).ready() in a global php/js script that all pages get and I give the modal's close button a class called: ".modal-close":
HTML:
<div class="modal-footer caption">
<button type="submit" class="modal-close btn default" data-dismiss="modal" aria-hidden="true">Close</button>
</div>
jQuery (include global.inc):
$(document).ready(function(){
// Allow enter key to trigger a particular class button
$(document).keypress(function(e) {
if(e.which == 13) {
if($(".modal").is(":visible")){
$(".modal:visible").find(".modal-close").trigger('click');
}
}
});
});
Now you should get no page refreshes on any of your modals if u follow these steps.

Categories

Resources