jQuery does not change element text after ajax - javascript

I have the following html:
<div class="form-outline mb-4">
<input type="text" id="PlanID" asp-for="PlanID" name="PlanID" class="form-control form-control-lg" value="#Model.PlanID" />
<label id="errorLabel" name="errorLabel" class="form-label text-danger" for="PlanID"></label>
</div>
<button class="btn btn-primary btn-lg btn-block" type="button" disabled id="nextButton" name="nextButton" onclick="DisplayProgressMessage(this, 'Next');">Next</button>
And I have the following jquery:
$.ajax({
type: "POST",
url: "#Url.Action("CheckPlanID")",
data: {PlanID: planID},
dataType: "text",
success: function (msg) {
if (msg.length > 4) {
console.log(msg.length);
$("#nextButton").prop("disabled", true);
$("#errorLabel").text = msg;
}
},
error: function (req, status, error) {
console.log(msg);
}
});
I have additional jquery that keeps the button disabled until the length of the data in the input is 4. When the length is 4, I enable the button.
When running the code, as soon as the length of the data in the input box is 4, the button is enabled and I click on it. the ajax executes and sends the data to my controller. The controller processes the data and will send back a string. If the length of the returned string is greater than 4, then the string being returned is an error string and that error string should get displayed to the user.
When I run the code and force an error, I can see the length of the error string being displayed in the console so I know this section of code is being executed. The button gets disabled, but the text of the errorLabel is not changing.
The text of the errorLabel should change to the error message. Is there something else that needs to be done? Am I missing something?
Thank you!

In jQuery, text is a method not an attribute so to fix your issue you'd simply change this
$("#errorLabel").text = msg
into this
$("#errorLabel").text(msg)
Also it seems, based on your code if (msg.length > 4), you only change the text if msg length is greater than 4. That means, unless msg has 5 characters or more the text won't change.
Learn more about text() method on jQuery docs.

Related

how can without refreshing pull data with ajax in django

I can post with ajax, but when I want to pull data without refreshing the page, I can only do it 2 times, then the button loses its function.
<div>
<input type="hidden" name="producecode" class="pcode" value="{{per.produceCode}}" />
<input type="hidden" name="useremail" class="uponequantity" value="{{user.username}}" />
<button class="btn btn-sm btn-primary upoq"><i class="fa fa-plus"></i></button></div>
and jquery
$.ajax({
type: "POST",
url: "/uponequantity/",
headers: { "X-CSRFToken": '{{csrf_token}}' },
data: {
"producecode":$(this).parent().find(".pcode").val(),
"useremail":$(".uponequantity").val(),
},
success: function() {
window.location.assign('/basket/'+"?b="+$(".uponequantity").val());
}
});
/*$.ajax({
url:'/baskett/'+"?b="+$(".uponequantity").val(),
headers: { "X-CSRFToken": '{{csrf_token}}' },
type:'POST',
success:function(result){
$('.basket').html(result);
}
});
*/
})
Just add another line to reference your second input same as the first.
$(".up").click(function(){
$(".prdtd").find("input:first- child").attr("value");
$(".pcode").val()
$(".uponequantity").val()//<-- new line for the second hidden value
}
-----------------------------------------
Update:
-----------------------------------------
OP has multiple buttons with the same class each in it's own div and wants to access the values within each div.
So, first off you need to change "pcode" from an id to class in order to get all instances. (id is for unique instances)
After that you need to be able to get the "pcode" & "uponequantity" that are associated with that button and one way of doing that is:
$(".up").click(function(){
$(this).parent().find(".pcode").val()
$(this).parent().find(".uponequantity").val()
}
Simply put, the this keyword references the clicked button.
You then get the direct parent element which would have the button and the hidden values as children.
Finally you get each specific child through the find command and do whatever you want with them.
If I understand your question correctly, you would like to get the value of both inputs in your callback.
It seems like you misspelt pdcode in your JavaScript.
Does the below code snippet help?
$(".up").click(function() {
const value1 = $(".pdcode").val();
const value2 = $(".uponequantity").val();
}

Set max value of an input box based on another input box

How can I set the max value of amount input box based on balance input box? For example, if the value of balance input box is 500 so the max value of amount input box is 500. So when the user enters a number in amount input box greater than the value of balance input box, it will show an error message. How can I do that? I'm using angularjs to validate but it seems it's not working on my code.
This what I did: https://jsfiddle.net/mbnxdvpw/
This is how I retrieve the balance data. When the user clicks the payment icon it will show a modal and when it is success the balance data from the database will be retrieved in balance input.
function view_payment(payment_sales_id) {
var modal = $('#payment-sales-modal');
$.ajax({
type: 'POST',
url: url + 'GetPaymentDetailsById',
data: { payment_sales_id : payment_sales_id },
dataType: 'json',
success: function (data) {
modal.modal({ backdrop: 'static', keyboard: false});
modal.find($('#payment_sales_id')).val(payment_sales_id);
modal.find($('#payment_net_amount')).val(data.sales_net_amount);
modal.find($('#payment_balance')).val(data.sales_balance);
}
});
}
HTML
<div class="form-group">
<label for="">Balance <small>*</small></label>
<input type="text" id="payment_balance" name="payment_balance" placeholder="Balance" class="form-control" ng-model="payment_balance" readonly>
</div>
<div class="form-group">
<label for="">Amount <small>*</small></label>
<input type="text" id="payment_amount" name="payment_amount" placeholder="Amount" class="form-control" ng-model="payment_amount" ng-pattern="/^[0-9]+\.?[0-9]*$/" max="payment_balance.value">
<span ng-messages="formPayment.payment_amount.$error" ng-if="formPayment.payment_amount.$dirty">
<strong ng-message="pattern" class="text-danger">Please type numbers only.</strong>
<strong ng-message="max" class="text-danger">Please enter a value less than or equal according to balance.</strong>
</span>
</div>
First of all, you are injecting the value directly on the input payment_balance, that's not the most cleanest angular way to do it. You should use $scope (check my js example below) so you could change it on the fly without need to find the input over and over again (probably not a problem on this particullary code, but one thing to have in mind).
Second, you should use a <form> to check for properties like $error or $dirty. That being said, I did an small example (not focusing the retrieved data).
Happy coding =}

Contact form does not send (undefined) [duplicate]

This question already has answers here:
Javascript POST not working - Sending Javascript array to PHP
(4 answers)
Closed 4 years ago.
I have a form and I want it to be send to my email. This is my HTML script with the form:
<form id="contact-form" class="contact-form style-2">
<div class="form-row">
<div class="form-col-2">
<input type="text" name="cf-name" placeholder="Naam*">
</div>
<div class="form-col-2">
<input type="text" name="cf-email" placeholder="Email*">
</div>
</div>
<div class="form-row">
<div class="form-col-2">
<input type="tel" name="cf-phone" placeholder="Telefoonnummer">
</div>
<div class="form-row">
<div class="form-col">
<textarea name="cf-message" rows="2" placeholder="Vragen/verzoeken"></textarea>
</div>
</div>
<button type="submit" class="btn style-3" data-type="submit">Verzend</button>
<p class="text-size-small2">Velden met een * zijn vereist.</p>
</form>
I want to make use of AJAX and this is my script.
if ($('#contact-form').length) {
var cf = $('#contact-form');
cf.append('<div class="message-container"></div>');
cf.on("submit", function (event) {
var self = $(this),
text;
var request = $.ajax({
url: "bat/mail.php",
type: "post",
data: self.serialize()
});
request.then(function (data) {
if (data == "1") {
text = "Your message has been sent successfully!";
cf.find('input:not([type="submit"]),textarea').val('');
$('.message-container').html('<div class="alert-box success"><i class="icon-smile"></i><p>' + text + '</p></div>')
.delay(150)
.slideDown(300)
.delay(4000)
.slideUp(300, function () {
$(this).html("");
});
} else {
if (cf.find('textarea').val().length < 10) {
text = "Message must contain at least 10 characters!"
}
if (cf.find('input').val() == "") {
text = "All required fields must be filled!";
}
$('.message-container').html('<div class="alert-box error"><i class="icon-warning"></i><p>' + text + '</p></div>')
.delay(150)
.slideDown(300)
.delay(4000)
.slideUp(300, function () {
$(this).html("");
});
}
}, function () {
$('.message-container').html('<div class="alert-box error"><i class="icon-warning"></i><p>Connection to server failed!</p></div>')
.delay(150)
.slideDown(300)
.delay(4000)
.slideUp(300, function () {
$(this).html("");
});
});
event.preventDefault();
});
}
And this is my PHP file:
<?php
$user_email = "fr.sven.fr#hotmail.com";
$mail = array(
"name" => htmlspecialchars($_POST['cf-name']),
"email" => htmlspecialchars($_POST['cf-email']),
"subject" => htmlspecialchars($_POST['cf-subject']),
"message" => htmlspecialchars($_POST['cf-message'])
);
function validate($arr){
return !empty($arr['name']) && strlen($arr['message']) > 20 && filter_var($arr['email'],FILTER_VALIDATE_EMAIL);
}
if(validate($mail)){
echo mail($user_email, $mail['subject'],
"Name : {$mail['name']}\n"
."E-mail : {$mail['email']}\n"
."Message : {$mail['message']}"
);
}
?>
When I submit the file without typing filling in the form I get the correct error. When I fill in the message with less than 10 characters, I get the correct error, but when I fill in everything correctly I get the error:
Notice: Undefined index: cf-name in /Applications/MAMP/htdocs/Klus spanje/php/mail.php on line 7
Notice: Undefined index: cf-email in /Applications/MAMP/htdocs/Klus spanje/php/mail.php on line 8
Notice: Undefined index: cf-subject in /Applications/MAMP/htdocs/Klus spanje/php/bat/mail.php on line 9
Notice: Undefined index: cf-message in /Applications/MAMP/htdocs/Klus spanje/php/bat/mail.php on line 10
I have no idea what I do wrong, can someone help?
EDIT:
Ah, you added the php errors now, great!
So it is not seeing the right post variables. As you didn't provide the html of your form (which would be helpful next time!) I can only provide you a way to figure this out yourself :)
To figure out the right names that are posted, you can use
print_r($_POST);
in your php code. This will show you the key-value pairs that are sent from the client. Most likely the keys are just a bit different than you thought, but changing them to the ones printed by the above code should solve this error!
ORIGINAL: (because I am proud of making the screenshot ;))
My guess is, that the data returned by php is not exactly "1". You can confirm in the chrome console, under network the network tab:
The green circle is just to find the requests made by javascript.
You can also use console.log(data); but then what did I make this screenshot for? ;)
Now the problem with your code is that, when your javascript doesn't get "1", it will get to this code (with comments by me)
// These two conditions are both not met (as you fill in the form correctly)
if(cf.find('textarea').val().length < 10){
// So text doesn't get set here
text = "Message must contain at least 10 characters!"
}
if(cf.find('input').val() == ""){
// Neither does this one
text = "All required fields must be filled!";
}
// So at this point, the variable `text` has not gotten any value assigned,
// making it `undefined`. Which wouldn't be a problem,
// if it weren't for the fact you try to use it as is in the html here
$('.message-container').html('<div class="alert-box error"><i class="icon-warning"></i><p>'+text+'</p></div>')
.delay(150)
.slideDown(300)
.delay(4000)
.slideUp(300,function(){
$(this).html("");
});
Something you could do for now is, at least, provide a default error message:
$('.message-container').html('<div class="alert-box error"><i class="icon-warning"></i><p>'+(text || 'Default error message')+'</p></div>')
But the thing is to either
Make the php return the right value and run without an error, and if that is already working
Make sure the javascript does match the correct data, without any spaces in the data. Maybe even using data.trim() (which removes whitespaces at the start and end of the string) could help here.
Hope this gives you a good point to start debugging the issue :)

Display text in textarea using javascript

I have used the following code in index.jsp to set the value of textarea INPUT_TEXT and INPUT_TEXT2 in a form after extensive processing, wherein the text goes through a servlet, a java class and the preprocessed data then gets returned to the 2nd textarea.
CODE I:
<td>
<%
String txtvalue="";
if(request.getAttribute("x")!=null){
txtvalue=request.getAttribute("x").toString();
System.out.println("txtvalue= "+txtvalue);
}%>
<textarea id="INPUT_TEXT" name="INPUT_TEXT" style="font-size: 13pt;" rows="15" cols="50"><%=txtvalue%></textarea>
</td>
<td>
<%
String txt="";
if(request.getAttribute("y")!=null){
txt=request.getAttribute("y").toString();
System.out.println("txt= "+txt);
}%>
<textarea id="INPUT_TEXT2" name="INPUT_TEXT2" style="font-size: 13pt;" rows="15" cols="50"><%=txt%></textarea>
</td>
I have tried using
1)innerHTML,
2)setting the value using document.getElementById("INPUT_TEXT") and
3)the present method which I have given in the code I.
Unfortunately, nothing works!
Method 3 (code I) used to work, but then I had to make some changes in the function that is called after onclick, to make a POST request, which now looks like this:
CODE II
function submitPreprocessForm() {
var postData=$("#maryWebClient").serializeArray();
$.ajax({
url: "preprocess",
context:this,
type:"POST",
dataType:"JSON",
data:postData,
contentType: "application/x-www-form-urlencoded;charset=utf-8",
success: function(response){
}
});
}
Now, the txt and txtvalue (Code I) are being printed only to the NetBeans output console (correctly, I might add) but not to the webpage, which gets reset when I click the submit button. Thus, although the entire internal functioning works perfectly, the only problem is text not being displayed in the respective textareas.
Kindly help.
The following approach solved my problem and text is displayed in the textrea.
success: function(response){
$("#INPUT_TEXT").val(response["x"]);
$("#INPUT_TEXT2").val(response["y"]);
},
I had to remove the <%=txtvalue%> as it caused the textarea to be initialized to null.
<div>
<textarea id="text" ></textarea>
<button type="submit" onclick="show()"> submit</button>
</div>
function show(){
let a = document.getElementById("text");
console.log(a.value);
}
The above JS function show() , shows the content in textarea after clicking the submit button .

Javascript asynchronous calls to a function that updates DOM elements are overlapping and causing issues

The context:
I have a form that asks for a zipcode, state, and city. Next to each input field I have two spans, one that shows a green checkmark if the input is good, and one that shows a red x if the input is bad. Naturally only one is visible at any given time.
<input type="text" id="Zip" class="form-control">
<span id="ZipOK" style="display:none;" class="glyphicon glyphicon-ok"></span>
<span id="ZipBad" style="display:none;" class="glyphicon glyphicon-remove"></span>
<input type="text" id="State">
<span id="StateOK" style="display:none;" class="glyphicon glyphicon-ok"></span>
<span id="StateBad" style="display:none;" class="glyphicon glyphicon-remove"></span>
<input type="text" id="City">
<span id="CityOK" style="display:none;" class="glyphicon glyphicon-ok"></span>
<span id="CityBad" style="display:none;" class="glyphicon glyphicon-remove"></span>
I have a function that detects input to the zip field and then does a database call to get the state and city from the zip code and auto fill the form.
jQuery('.form-control').keyup(function(){
validateZipcode();
});
This is the function that does the ajax, autofills the state/city and hides/shows the appropriate feedback spans.
function validateZip() {
zip = $('#Zip').val();
if (zip.length === 5 && $.isNumeric(zip)) {
$.ajax({
type:"POST",
url: '?report=ajax&request=getStateAndCityFromZip',
data:"Zip="+encodeURIComponent(zip),
success: function(output) {
output = $.parseJSON(output);
if (output['State'].length > 0 && output['City'].length > 0) {
$('#State').val(output['State']);
$('#City').val(output['City']);
$('#StateOK').fadeIn();
$('#StateBad').hide();
$('#CityOK').fadeIn();
$('#CityBad').hide();
$('#ZipOK').fadeIn();
$('#ZipBad').hide();
} else {
$('#ZipOK').hide();
$('#ZipBad').fadeIn();
}
},
error: function (xhr, ajaxOptions, thrownError) {
}});
} else {
$('#ZipOK').hide();
$('#ZipBad').fadeIn();
}
}
The problem:
This code works as is, however there are some instances where if I put in the zip code extremely fast, both the #ZipBad and #ZipGood spans will end up visible. Typing at relatively normal or slow pace results in expected behavior.
I assume this has something to do with asynchronous calls to validateZip(), but I don't really know enough about javascript to know how to fix this. Does anyone have any ideas?
If the user types fast, then you can end up with multiple animations in process at the same time and the .hide() which is not an animation will go in the wrong sequence, potentially ending up with the wrong display. The animations queue in order, the .hide() does not so things can get out of sequence.
There are also some edge cases where you could end up with multiple ajax calls in flight at the same time, but this would require typing 5 characters in the zip field, then quickly backspacing and typing a fifth character again and this could end up confusing things too.
You can defend against the animations by using .stop(true) before every animation or visibility change to stop any currently running animations and you can defend against the multiple ajax calls by canceling any previous call like this:
Here's one way you could implement this:
var lastValidateAjax;
function validateZip() {
var zip = $('#Zip').val();
if (zip.length === 5 && $.isNumeric(zip)) {
if (lastValidateAjax) {
lastValidateAjax.abort();
}
lastValidateAjax = $.ajax({
type:"POST",
url: '?report=ajax&request=getStateAndCityFromZip',
data: {Zip: zip},
success: function(output) {
lastValidateAjax = null;
output = $.parseJSON(output);
if (output.State.length > 0 && output.City.length > 0) {
$('#State').val(output.State);
$('#City').val(output.City);
$('#StateOK, #CityOK, #ZipOK').stop(true).fadeIn();
$('#StateBad, #CityBad, #ZipBad').stop(true).hide();
} else {
$('#ZipOK').stop(true).hide();
$('#ZipBad').stop(true).fadeIn();
}
},
error: function (xhr, ajaxOptions, thrownError) {
lastValidateAjax = null;
}
});
} else {
$('#ZipOK').stop(true).hide();
$('#ZipBad').stop(true).fadeIn();
}
}
FYI, I also took the opportunity to use multiple items in the same select and to use jQuery chaining to simplify the code.
See this other answer for a discussion of jQuery's .abort() for ajax calls:
Abort Ajax requests using jQuery

Categories