jQuery Mobile: Injected content appears then disappears immediately - jquery-mobile

I have a login page using jQuery Mobile which contains the following code:
<div id="loginPage" data-role="page" data-theme="a">
<div data-role="content">
<div id="alerts"></div>
<form id="login-form">
<input type="text" id="username" name="username" value="" placeholder="username or email" />
<input type="password" id="password" name="password" value="" placeholder="password" />
<button id="login-button" onClick="userLogin()">Login</button>
</form>
</div><!-- /content -->
</div><!-- /page -->
Here is a part of my javascript that is called when the user clicks the 'Login' button. If one of the fields is left blank, I see the following text injected into the #alerts div, but then within a fraction of a second the content has disappeared again.
if (username.length == 0 || password.length == 0) {
//alert('Please enter your username or email and your password');
$('#alerts').html('Please enter your username or email and your password.').trigger('create');
}
I also tried this using .append() instead of .html(). Same result with both. I've commented out my test alert(), which works when one of the fields is left blank.
What can I do to make sure the content remains on the page once it is injected?
Thank you for any help or insight you can offer! -Mark
Per Jasper's request, here is all of the javascript that is executed when the 'Login' button is clicked:
function userLogin() {
var username = $("#username").val();
var password = $("#password").val();
if (username.length == 0 || password.length == 0) {
$('#alerts').append('Please enter your username or email and your password.').trigger('create');
}
else {
$.post("services/user-status.php", { type: 'login', username: username, password: password },
function(data) {
var response = data.item;
console.log(response);
if (response.loggedIn == false) {
$('#alerts').html('The username/email and password you used did not work. Please try again.').trigger('create');
}
else {
localStorage.userID = response.userID;
localStorage.username = response.username;
localStorage.userStatus = 'loggedIn';
$.mobile.changePage('profile.html');
}
},'json');
}
}

It looks like you need to stop the propagation of the click event from firing for your button. You can do that by returning false in the click event handler:
HTML --
<button id="login-button" onClick="return userLogin()">Login</button>
JS --
function userLogin() {
...
return false;
}​
Here is a demo: http://jsfiddle.net/BkMEB/3/
Also, since you are using jQuery, you can bind to the <button> element like this:
$('#login-button').bind('click', userLogin);
This is the same as putting onClick="return userLogin()" as an attribute of the button but allows you to remove your inline JS.
Here is a demo: http://jsfiddle.net/BkMEB/4/

Related

DirtyForms does not work properly with $.blockUI

I'm using DirtyForms and $.blockUI plugin, the latter to change pages when clicking on links (in my app, some pages take a couple of seconds more to load and a visual feedback is fine).
When I change field content and then click any link, DirtyForms is triggered: but when I cancel the process to stay on the page, $.blockUI starts its game, resulting in a stuck page
$('form[method="post"]').dirtyForms();
$('a').on('click', function(){
$.blockUI();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.dirtyforms/2.0.0/jquery.dirtyforms.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.blockUI/2.70/jquery.blockUI.min.js"></script>
<p>Change the field content to activate DirtyForms, then click on the link.<br>
When the popup appears, click on "cancel" to stay on the page.<br>
Watch blockUI getting fired as the link is going to be followed</p>
<form action="#" method="post">
<input type="text" name="username" required>
<button type="submit">send</button>
</form>
click me after changing field content
Please, any solution?
EDIT: I also tried with stay.dirtyforms and afterstay.dirtyforms events, but they have no effect. defer.dirtyforms seems to work but the event is triggered twice (I put a console.log() to check) and I am not sure this is the way to go...
I've edit my answer: I've added some line of code to disable first the onbeforeunload dialog alert, taken from here. And at the end a link to an answer with another idea you can try.
My idea: you have to prevent the default link action and use the $.blockUI Modal Dialogs methods to open a custom dialog, then catch the link attribute href from the link put it inside a variable and use the variable value for the #yes button of the dialog.
See if this solution can meet your needs
/* beforeunload bind and unbind taken from https://gist.github.com/woss/3c2296d9e67e9b91292d */
// call this to restore 'onbeforeunload'
var windowReloadBind = function(message) {
window.onbeforeunload = function(event) {
if (message.length === 0) {
message = '';
};
if (typeof event == 'undefined') {
event = window.event;
};
if (event) {
event.returnValue = message;
};
return message;
}
};
// call this to prevent 'onbeforeunload' dialog
var windowReloadUnBind = function() {
window.onbeforeunload = function() {
return null;
};
};
var linkToFollow; // href to follow
$('form[method="post"]').dirtyForms();
$('a').on('click', function(e){
e.preventDefault();
windowReloadUnBind(); // prevent dialog
$.blockUI({ message: $('#question'), css: { width: '275px' } });
linkToFollow = $(this).attr('href');
});
$('#no').click(function() {
$.unblockUI();
return false;
});
$('#yes').click(function() {
$(window.location).attr('href', linkToFollow);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.dirtyforms/2.0.0/jquery.dirtyforms.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.blockUI/2.70/jquery.blockUI.min.js"></script>
<p>Change the field content to activate DirtyForms, then click on the link.<br>
When the popup appears, click on "cancel" to stay on the page.<br>
Watch blockUI getting fired as the link is going to be followed</p>
<form action="#" method="post">
<input type="text" name="username" required>
<button type="submit">send</button>
</form>
click me after changing field content
<div id="question" style="display:none; cursor: default">
<h6>Would you like to contine?.</h6>
<input type="button" id="yes" value="Yes" />
<input type="button" id="no" value="No" />
</div>
Other idea taken from another answer: Other idea would be to make a simple jQuery.ajax({}) call before return value in beforeunload as seen in this answer

How to go to next input by tapping return key on an iPhone/iPad with Ionic2?

I am using Ionic Cordova to build an iPhone app. I have a login screen username input and password input plus a submit button. I cannot make to focus on password input after typing the username and tap "return".
My login.html looks like this:
<ion-list >
<ion-item>
<div id="loginlogo"></div>
</ion-item>
<ion-item>
<ion-label stacked>Username</ion-label>
<ion-input type="text" name="usernameInput" (keyup.enter)="focusAndGo()" [(ngModel)]="usernameInput"></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>Password</ion-label>
<ion-input type="password" id="passwordInput" name="passwordInput" [(ngModel)]="passwordInput"></ion-input>
</ion-item>
<ion-item><button (click)="logincontrol()" ion-button color="light" block>Login</button></ion-item>
</ion-list>
and my login.ts look like this:
#ViewChild('passwordInput') nameInput;
focusAndGo()
{
var input = document.getElementById('passwordInput');
input.focus();
this.nameInput.setFocus();
//this.nameInput.nativeElement.focus();
//this.nameInput.nativeElement.setFocus();
//this.passwordInput.focus();
//alert(event.keyCode );
//if( event.keyCode ==13)
//{
//this.passwordInput.focus;
//}
}
I tried everything that is commented above. I cannot get cursor to move to next input.
I think you should prevent default behaviour before setting focus,
send $event to your function
<ion-input type="text" name="usernameInput" (keyup)="focusAndGo($event)" [(ngModel)]="usernameInput"></ion-input>
and use preventDefault() before setting focus
focusAndGo(e)
{
e.preventDefault();
var input = document.getElementById('passwordInput');
input.focus();
}
Update for a better aproach: this SO answer
(I updated the post after received an upvote, but I think the correct answer is the indicate in the link)
it's a old post but a posibility is make a directive like
#Directive({
selector: '[next-tab]',
})
export class NextTabDirective{
#Input('next-tab') nextControl: any;
#HostListener("keydown.enter", ["$event"])
onEnter(event: KeyboardEvent) {
if (this.nextControl.focus)
{
this.nextControl.focus();
event.preventDefault();
return false;
}
}
}
then you can use a form like
<form [formGroup]="dataForm" (submit)="submit(dataForm)">
<input formControlName="data1" [next-tab]="data2">
<input #data2 formControlName="data2" [next-tab]="data3">
<input #data3 formControlName="data3">
<button type="submit">Click</button>
</form>

jQuery Mobile: number input and plus/minus buttons inline

Is there a possibility to have a number input with minus-button on the left and plus-button on the right? Or maybe also -- ++ to change value in bigger steps.
I know that I'm not the first one asking this but:
This solution is not displaying correctly in the first turn and jQuery-Mobile-Stepper-Widget from Github (can't post another link because I'm new) does not work with current version of jQuery Mobile.
The result should look like the screenshot in this question: Has anyone implemented jQuery Mobile Add (+/-) Button Number Incrementers? respectively horizontal grouped buttons in jQuery Mobile
Any ideas or new snippets, working with current version of jQuery mobile?
Here is a hint, the rest is purely CSS job and extra JS codes to control the value, e.g. maximum, minimum...etc.
HTML
<div data-role="controlgroup" data-type="horizontal" data-mini="true">
<button id="plus" data-inline="true">+</button>
<input type="text" id="number" value="0" disabled="disabled" />
<button id="minus" data-inline="true">-</button>
</div>
Code
$('#plus').unbind('click').bind('click', function () {
var value = $('#number').val();
value++;
$('#number').val(value);
});
$('#minus').unbind('click').bind('click', function () {
var value = $('#number').val();
value--;
$('#number').val(value);
});
JSFiddle
In jQM the input type number does the most of the magic you want
<input type="number" name="number" value="0"/>
If you require more fancy styling you have to follow Omar's code
<i onclick="qty('plus');" class="fa fa-plus c_pointer"></i>
<input type="text" id="prdqty" name="qty" value="1" placeholder="1">
<i onclick="qty('minus');" class="fa fa-minus c_pointer"></i>
function qty(val){
pqty = $('#prdqty').val();
if (val == "plus") {
var newVal = parseFloat(pqty) + 1;
} else {
if (pqty > 1) {
var newVal = parseFloat(pqty) - 1;
} else {
newVal = 1;
}
}
$('#prdqty').val(newVal);
}

Enabling disabled submit button doesn't work during filling the field which is required to enable the submit

sorry if the title isn't clear, i was trying to explain in the best possible way. The situation I have is the following: I have a newsletter with a submit button. I have used jquery to unlock the SUBMIT button after the correct email is typed in. It is working fine apart of one thing - I have to click anywhere outside the field (not on the submit button) to enable the submit, then on submit. There was something I have to add somewhere around this line i think, but I dont know what:
document.getElementById("submit").disabled = false;
the full code is here:
HTML:
<div class="element">
<input type="text" id="email" name="email" value="Enter your email" />
</div>
<div id="bsubmit">
<input name="submit" id="submit" src="_images/generic/send_button.png?submit+button=" type="image" disabled="disabled" />
</div>
and jq:
$.fn.swapText = function(){
return this.each(function(){
var tmpDefVal = $(this).val();
$(this).css('color', '#999');
$(this).focus(function(){
if($(this).val() == tmpDefVal){
$(this)
.css('color', '#000')
.val('');
}
});
$(this).blur(function(){
if($(this).val() == ''){
$(this)
.css('color', '#999')
.val(tmpDefVal);
}
});
});
}
$(document).ready(function(){
$('#email').swapText();
$('#email').change(function(){
var regexp = /^\w+[#]\w+\.\w{2}$/;
if(regexp.test($(this).val())){
$(this).removeClass('err');
$(this).addClass('ok');
document.getElementById("submit").disabled = false;
}else{
$(this).removeClass('ok');
$(this).addClass('err');
}
});
});
Thanks for any help.
One problem is that you have two elements with an id of submit.

How to submit form with multi buttons with same value asp.netMvc

I need to build voting web site so, I have couple candidates and below them a vote button,
how I can find which of the buttons was submitted
thanks
Give each of your buttons a name, like so (notice they are both "submit" buttons)::
<input type="submit" name="buttonYes" value="Yes" />
<input type="submit" name="buttonNo" value="No" />
Then, in your controller, capture a parameter for each of the two button names like this:
public ActionResult Index(string buttonYes, string buttonNo) { ... }
You can then tell which button was pressed by checking to see which of these two parameters is not null; the one which is pressed with a have a value equal to the "value" attribute of the button, the other one will be null:
if (buttonYes != null)
{
// Then the yes button was preseed
}
else if (buttonNo != null)
{
// Then the no button was pressed
}
else
{
// Neither button was used to submit the form
// and we got here some other way
}
The reason this works is because the web browser sends the information for the submit button that was pressed as part of the HTTP post to the web server. The button that was not pressed will not be sent with the post, and therefore the parameter will be null.
There are lots of ways to rewrite and optimzie this, but this is the essence of it and shows the fundamentals that are at work--you can play with it from there.
I wouldn't use the button value, I would set it up so that the url used to do the post encodes the vote itself. You could do this a couple of ways.
Use links
<div class="left">
<img src="/images/candidate/#Model.Candidates[0].ID" alt="#Model.Candidates[0].Name" />
#Html.ActionLink( "Vote for " + Model.Candidates[0].Name, "count", "vote" )
</div>
<div class="right">
<img src="/images/candidate/#Model.Candidates[1].ID" alt="#Model.Candidates[1].Name" />
#Html.ActionLink( "Vote for " + Model.Candidates[1].Name, "count", "vote" )
</div>
Use separate forms
<div class="left">
#using (Html.BeginForm( "count", "vote", new { id = Model.Candidates[0].ID } ))
{
<img src="/images/candidate/#Model.Candidates[0].ID" alt="#Model.Candidates[0].Name" />
<input type="submit" value="Vote" />
}
</div>
<div class="right">
#using (Html.BeginForm( "count", "vote", new { id = Model.Candidates[1].ID } ))
{
<img src="/images/candidate/#Model.Candidates[1].ID" alt="#Model.Candidates[1].Name" />
<input type="submit" value="Vote" />
}
</div>
Either of the above can be adapted to work with AJAX as well. Note, if you care, you'll need to build in some mechanism to detect vote fraud, e.g., add a one-time nonce to the url to verify that it isn't used more than once; track the number of times a user has voted if they are authenticated, etc.

Resources