Javascript variable can't be overwritten after the first declaration - javascript

I have a function that will refresh the page based on the number chosen:
prodName="doesn't matter, not directly $.ajax related"
function searchProduct() {
var prodName = $("#admin-search-product").val().trim();
var pagenumb = 1;
$(".page-item").click(function() {
pagenumb = $(this).children('.page-link').attr('value');
});
alert(pagenumb);
if (prodName == "") {
$.ajax({
type: "POST",
url: "admin_search_product.php",
data: {
search_prod: 0,
},
success: function(respond) {
$("#admin_content").html(respond).show();
$("#admin-search-product").focus().val('').val(prodName);
}
});
} else {
$.ajax({
type: "POST",
url: "admin_search_product.php",
data: {
search_prod: 1,
searchName: prodName,
pagenumb: pagenumb
},
success: function(respond) {
$("#admin_content").html(respond).show();
$("#admin-search-product").focus().val('').val(prodName);
}
});
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="admin-search-product">
<div class="page-item">
<input class="page-link">
</div>
<button onclick="searchProduct()">clickme</button>
Everything works well, except the problem is that the pagenumb variable stays on "1" even though the code "pagenumb = $(this).children('.page-link').attr('value');" can retrieve the value of the page clicked, tested with alert() function and it can return the value of "2" if put within the click function.
However if I test the alert() function outside the click function, it shows that the pagenumb variable stayed the same. I don't know why it doesnt want to change the received value even though I'm able to receive it.

You should bind the event handler once when the page is ready, not every time you searchProducts().
You want the change event, not click. pagenumb should be updated when the input's value changes. Click will only try to update the value when you focus the input box, which is not what you want.
prodName = "doesn't matter, not directly $.ajax related"
var pagenumb = 1;
// you should bind this event handler _once_ when the _page is ready_
// you want the change event, not click. update pagenumb whenever value _changes_
$(".page-item").change(function() {
// coerce to number using + operator
pagenumb = +$(this).children('.page-link').val();
});
function searchProduct() {
var prodName = $("#admin-search-product").val().trim();
alert(pagenumb);
if (prodName == "") {
$.ajax({
type: "POST",
url: "admin_search_product.php",
data: {
search_prod: 0,
},
success: function(respond) {
$("#admin_content").html(respond).show();
$("#admin-search-product").focus().val('').val(prodName);
}
});
} else {
$.ajax({
type: "POST",
url: "admin_search_product.php",
data: {
search_prod: 1,
searchName: prodName,
pagenumb: pagenumb
},
success: function(respond) {
$("#admin_content").html(respond).show();
$("#admin-search-product").focus().val('').val(prodName);
}
});
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="admin-search-product">
<div class="page-item">
<input class="page-link">
</div>
<button onclick="searchProduct()">clickme</button>

Related

How to delay ajax call on keypress?

I have an input box where I'm doing an AJAX GET to check if the email is within my database. I'm simply checking for an email address and if it's within the database, we retrieve true/else false. So depending on the return I display either a tick or cross image.
$.ajax({
url: '/api/user/emailaddress/' + emailAddress,
type: 'GET',
dataType: 'json',
success: function(data) {
if (data===true) {
$(".email-address-validator").removeClass("success");
$(".email-address-validator").addClass("error");
}
}
});
Each time a key is pressed within the input box field, this gets called. The problem that I thought might prop up is if someone looks at this file and see's that I'm doing an AJAX GET request on the field that they might just keep pressing keys on that particular input box.
Q: How can I set a timeout on this, for around 5 seconds so a user doesn't just keep spamming the box?
You could set a flag to handle this scenario. Something like this is much better than a timer.
var waitingForResponse= false;
function isValidEmail () {
if (!waitingForResponse) {
waitingForResponse = true;
$.ajax({
url: '/api/user/emailaddress/' + emailAddress,
type: 'GET',
dataType: 'json',
success: function(data) {
waitingForResponse= false;
if (data===true) {
$(".email-address-validator").removeClass("success");
$(".email-address-validator").addClass("error");
}
}
});
}
}
This design pattern will prevent subsequent requests until the first response is received. If you need a further interval between requests than this suggestion, then you can wrap the waitingForResponse flag in a setTimeout function inside the success callback. Like so:
var waitingForResponse= false;
function isValidEmail () {
if (!waitingForResponse) {
waitingForResponse = true;
$.ajax({
url: '/api/user/emailaddress/' + emailAddress,
type: 'GET',
dataType: 'json',
success: function(data) {
setTimeout(function () {
waitingForResponse= false;
}, 5000);
if (data===true) {
$(".email-address-validator").removeClass("success");
$(".email-address-validator").addClass("error");
}
}
});
}
}

JS: using ajax to check existing data in db on input typing

So I want to detect if the value a user is typing in an input exists in the database, if so, display an error message. I've gotten pretty close except when the input is empty, the empty value is being submitted instead of what is GOING to be typed.
$("#email").on("blur", function(){
var val = $(this).val(), id = $("#id").val();
$.ajax({
method: 'GET',
url: '/msg',
data: {
action: "check_title",
email: val,
id: id
},
success: function(data) {
$(".error-msg").text(data);
}
})
});
I've also tried one with a keyup function and it's still doing the same, evaluating the empty field. How can I have it so it's constantly evaluating what is being typed?
Along the same lines as Jeff Puckett's answer, I would perform the empty test and return an instructional message if empty:
$("#email").on("blur", function(){
var val = $(this).val(), id = $("#id").val();
if (val.length < 1 || val==""){
alert('Please complete all fields');
$('#email').css('background','yellow').focus();
return false;
}
$.ajax({
method: 'GET',
url: '/msg',
data: {
action: "check_title",
email: val,
id: id
},
success: function(data) {
$(".error-msg").text(data);
}
});
});
This snippet creates an input with the id of "in" and checks if there is something in in's value. I guess that is answering your question a bit more specifically. And thanks "Jeff Puckett II" for pointing this out.
$('#in').on('input focusout', function(){
var val = $('#in').val();
if (val != ""){
console.log('someones typing');
} else {
console.log('empty');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<input id="in" type="text">
</body>
try .on('input') instead of .on('blur')
$("#email").on("input", function(){//do something});
//in your function just add
if(!val) {
$(".error-msg").text("Empty!");
}
//or
if(val) {
//your ajax code
}
simply check if input is empty first
$("#email").on("blur", function(){
var val = $(this).val(), id = $("#id").val();
// check if val is empty
if (val != "")
$.ajax({
method: 'GET',
url: '/msg',
data: {
action: "check_title",
email: val,
id: id
},
success: function(data) {
$(".error-msg").text(data);
}
})
});
use this:
$('input').keyup(function(){
console.log($(this).val());
});
keyup or keydown to get data every time when a user type in the focused input.

Having issues on if-else statement on the text changed event

I have a little bit issue here on my html text changed event in regards with my if-else statement. Here's the scenario, I have the html layout below which has a dropdown list of all locations. Now, if type in your location on the input text box which has id of "#searchloc" it will query as you typed in and rebind the record list on the "#dropdownlist" div element. So my problem is, I want to rebind the "#dropdownlist" div element back to its default which shows all locations once I clear back or empty the "#searchloc" input textbox but the "#dropdownlist" div element remained clear or empty. Below I tried to use if-else statement to do this but I notice that under the else{...} statement it won't fire the function or even the alert method. How do I handle this type of issue in jquery?
HTML Layout:
<input type="text" id="searchloc" class="searchloc" onchange = "QueryLocation();" onkeydown="this.onchange();" onkeyup="this.onchange();" onkeypress = "this.onchange();" oninput = "this.onchange();" placeholder="Search Location" />
<div id="dropdownlist" data-bind="foreach: PopulateAllLocation" >
<div id="alllocationdiv" > <label id="listlocation" class="listlocation" data-bind="text: CityTown"></label></div>
</div>
jQuery:
// Change the dropdownlist result as text input change
function QueryLocation() {
if ($("#searchloc").val() != null) {
var dataObject = {
CityTown: $("#searchloc").val()
};
$.ajax({
url: '/OnlineStore/SearchLocation',
type: 'GET',
contentType: 'application/json; charset=utf-8',
data: dataObject,
dataType: 'json',
success: function (data) {
self.PopulateAllLocation(data);
},
error: function () {
console.log('err')
}
});
}
else {
// Under this else statement won't fire any of this function...???
DisplayLocations();
alert("Textbox is empty...");
}
}
When you check for a value of an empty textbox in Javascript its not null its "" i.e empty string instead. So in your if condition the value is never equal to null, that is the reason the else part is never executed.
function QueryLocation() {
if ($("#searchloc").val() != "") {
var dataObject = {
CityTown: $("#searchloc").val()
};
$.ajax({
url: '/OnlineStore/SearchLocation',
type: 'GET',
contentType: 'application/json; charset=utf-8',
data: dataObject,
dataType: 'json',
success: function (data) {
self.PopulateAllLocation(data);
},
error: function () {
console.log('err')
}
});
}
else {
DisplayLocations();
alert("Textbox is empty...");
}
}

Waiting for Ajax called DOM manipulation to finish

Sorry for the title but I had no idea how to call it.
I got some ajax call function that on success adds some HTML elements to the page:
function ajax_submit_append(form_data, url, result, complete) {
$.ajax({
url: url,
type: 'POST',
data: form_data,
success: function(msg) {
var res = $(msg).filter('span.redirect');
if($(res).html() != null){
window.location.replace($(res).html());
return false;
}
$(result).append(msg);
},
complete: complete()
});
};
Function does something on success where the most important is the .append and then this ajax function is called in some button .click function like this:
$(function() {
$("#product_list_add_btn").click(function(e){
ajax_submit_append(
form_data = {
product_name: $('.selectpicker option:selected').val(),
amount: $('#amount').val()},
"<?php echo site_url('admin_panel/new_order/add_product'); ?>",
'#add_product_result',
calculateSum
);
return false;
});
});
What I want to achieve is that calculateSum function (sums table columns) is called after .append is done via ajax.
For now, when I add calculateSum to ajax complete event it is still called before new row is added to the table with .append
Edit: I present You calculateSum, but I believe there is nothing faulty there.
function calculateSum() {
var sum = 0;
// iterate through each td based on class and add the values
$(".countit").each(function() {
var value = $(this).text();
// add only if the value is number
if(!isNaN(value) && value.length != 0) {
sum += parseFloat(value);
}
});
$('#total_price').text(sum);
alert("test");
};
If I had to guess, I would say its something with click event?
How to fix this?
Try using jqXHR's done() method:
function ajax_submit_append(form_data, url, result, complete) {
$.ajax({
url: url,
type: 'POST',
data: form_data,
success: function(msg) {
var res = $(msg).filter('span.redirect');
if($(res).html() != null){
window.location.replace($(res).html());
return false;
}
$(result).append(msg);
}
}).done(complete);
};

Targeting specific element jquery

I have searched this on the net however couldn't find a solution, simply I would like to replace the content inside button element with ajax response. The only problem I am facing is that, the whole divs are being changed not the one I click on. If I change the class to id only the first one changes not the specific button I want. So how do I replace the content of specific button?
PHP Code:
while($row = $result->fetch_assoc()){// there are four rows so I have 4 buttons.
echo "<button class=btn btn-primary test' value='."$row['id']".'>."$row['voteup']".</button>";
}
javascript code:
$(function() {
$('.test').on('click', function() { // attach the click to the button
var test_val = $(this).val(); // Grab the value from the button
$.ajax({
type: "GET",
url: "test.php", // Move ?tar=vrate to the data array.
data: {tar: 'vrate', test: test_val},
cache: false,
success: function(response)
{
$(".test").fadeIn('slow').html(response);//this is replacing all 4 buttons not just one, if I change the class to id, only the first one is being replaced with the response. I also tried $( .test", this) but no luck.
}
});
});
});
$(function () {
$('.test').on('click', function () {
var test_val = $(this).val();
$.ajax({
// -------v Set the context of the callback
context: this,
type: "GET",
url: "test.php",
data: {
tar: 'vrate',
test: test_val
},
cache: false,
success: function (response) {
// v--and use `this` here
$(this).fadeIn('slow').html(response);
}
});
});
});
Try to use the $(this) reference here to achieve what you want,
$('.test').on('click', function() { // attach the click to the button
var test_val = $(this).val(); // Grab the value from the button
var $this = $(this);
$.ajax({
type: "GET",
url: "test.php", // Move ?tar=vrate to the data array.
data: {tar: 'vrate', test: test_val},
cache: false,
success: function(response)
{
$this.fadeIn('slow').html(response);
}
});
});

Categories