Clear input and start chat scroll from bottom - javascript

I'm trying to clear the input on a message submit. And also on chat window load keep the scroll at the bottom.
I've tried many scripts, I've also tried different approaches, outsourcing. But I think due to my structure something just isn't right. I will admit I'm no expert when it comes to anything JavaScript related. I'm just dying to get this done out the way, its been bugging me for months now that I cannot get it to work.
Here is my code
var scrolled = false;
function updateScroll() {
if (!scrolled) {
var element = document.getElementById("ChatPopScroll");
element.scrollTop = element.scrollHeight;
}
}
$("#ChatPopScroll").on('scroll', function() {
scrolled = true;
});
$(function() {
$('form#SendForm').on('submit', function(e) {
$.post('elements/sendmessagefriend.php', $(this).serialize(), function(data) {
// This is executed when the call to mail.php was succesful.
// 'data' contains the response from the request
$('#message').val('');
var form = document.getElementById("SendForm");
form.reset();
$('#SendForm').trigger("reset");
})
.error(function() {
$('#message').val('');
});
e.preventDefault();
$('#message').val('');
});
});
$(document).ready(function() {
$('div.message-window').each(function(index, messageWindow) {
messageWindow = $(messageWindow);
// Run fetchMessages() once, when the page is loaded.
fetchMessages(messageWindow);
// Set an interval timer for checking messages.
// Not ideal, but it works for now.
setInterval(fetchMessages, 500, messageWindow);
// in milliseconds!!!!!! (1000ms = 1s)
});
});
function fetchMessages(messageWindow) {
// For each message window, check for new chats
// Get the friend_id from the window
var friend_id = messageWindow.attr("friend_id");
// Get the last chat message_id from the last chat message in this window.
var last_message_id = messageWindow.find("ul > li:last").attr("message_id");
// Ask the server for the latest messages.
// Send over the friend_id and last_message_id, so it can send back new messages from this friend.
$.get("elements/chat-load.php", {
last_message_id: last_message_id,
friend_id: friend_id
}, function(messages) {
// This function is run when the AJAX request succeeds.
// Append the new messages to the end of the chat
messageWindow.find("ul").append(messages);
});
}
function openPopup(ID) {
$('.popup');
$("#" + ID).fadeIn(200);
}
function closePopup(ID) {
$('.popup');
$("#" + ID).fadeOut(200);
}
function MinPopup(ID) {
$('.popup');
$("#" + ID).addClass('ChatMinPop').removeClass('ChatActivePop');
}
function UpPopup(ID) {
$('.popup');
$("#" + ID).addClass('ChatActivePop').removeClass('ChatMinPop');
}
<div id="ChatPopScroll" class="ChatPopMsg">
<div id="messages" class="messages message-window" friend_id="<?=$FriendName->id ?>">
<ul id="ScrollAuto" class="message">
</ul>
</div>
</div>
<div class="ChatPopFoot">
<form autocomplete="off" id="SendForm" class="SendMsg" role="form" method="post">
<input autocomplete="off" id="message" class="ChatPopFootTxt" type="text" name="message">
<input style="" id="submit" class="submit MsgInputHidden" type="submit" name="submit" value="Submit" />
</form>
</div>

Related

Submitting 2 forms separately via AJAX - Python Flask

I'm trying to submit 2 separate forms via AJAX, but on submitting form2 I get a 500 bad request error.
My HTML code is below, but basically my page is a flask template that works as follows:
*User makes selections
*These selections are then posted via the submit button named "button" Value "Calculate Available Overall Heights".
*This runs some SQL query to determine a list of entries that are placed into a newly generated <select id="mySelect" class="form-control" onchange="myFunction()"></select>
This is done by JS which is also listed below as MyJS.js
OAH.html
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<p class="h2">XXX</p>
<form method="post" id="form1">
<fieldset>
</div>
<div class="col-sm-3">
<span style="float:left"><label>Overall Height</label></span>
///my inputs, various selects etc ///
<div id="response">
<!-- Empty element until form submitted-->
</div>
<p id="ApertureHeight"></p>
<p id="ApertureHeightBelowPelmet"></p>
<p id="ApertureHeightUnderRoofSticks"></p><br>
<p id="OverallWidth"></p>
<p id="RearAppWidth"></p>
<p id="RearPillarNS"></p>
<p id="OAH"></p>
</div>
</fieldset>
<script src="/static/js/MyJS.js"></script>
</form>
<form method="post" id="form2">
<div class="col-sm-3">
<label>
<span style="float:left"><input type="text" id="myText" value=""></span>
</label>
<br>
<input type="button" value="Click Me!" onclick="submitForms()" />
</div>
</form>
</body>
</html>
form2 has a button called "Click Me!" which calls a function that submits form 2.
submitForms = function(){
document.getElementById("form2").submit();
};
MyJS.js
$("#form1").on("submit", function(event) {
$targetElement = $('#response');
event.preventDefault();
// Perform ajax call
//
console.log("Sending data: " + $(this).serialize());
$.ajax({
url: '/OAH',
data: $('form').serialize(),
datatype: 'json',
type: 'POST',
success: function(response) {
// Success handler
var TableTing = response["table"];
$("#TableThing").empty();
$("#TableThing").append(TableTing);
for (key in response) {
if (key == 'myList') {
// Add the new elements from 'myList' to the form
$targetElement.empty();
select = $('<select id="mySelect" class="form-control" onchange="myFunction()"></select>');
response[key].forEach(function(item) {
select.append($('<option>').text(item));
});
$targetElement.html(select);
} else {
// Update existing controls to those of the response.
$(':input[name="' + key + '"]').val(response[key]);
}
}
return myFunction()
// End handler
}
// Proceed with normal submission or new ajax call
})
});
submitForms = function(){
document.getElementById("form2").submit();
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
$("#form2").on("submit", function(event) {
event.preventDefault();
console.log("Sending data: " + $(this).serialize());
$.ajax({
url: '/OAH',
data: $('#form2').serialize(),
datatype: 'json',
type: 'POST',
success: function(response) {
return myFunction()
// End handler
}
// Proceed with normal submission or new ajax call
})
});
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function myFunction() {
var FifthWheel = document.getElementById("FifthWheelHeight").value;
var NeckDepth = document.getElementById("NeckDepth").value;
var CantRailDepth = document.getElementById("CantRailDepth").value;
var RearTensioner = document.getElementById("RearTensioner").value;
var OAH = document.getElementById("mySelect").value;
if (CantRailDepth = 115) {
var PelmetDim = 100;
} else {
PelmetDim = 75;
}
var ApertureHeight = Number(OAH) - Number(FifthWheel) - Number(NeckDepth) - Number(CantRailDepth);
var ApertureHeightBelowPelment = Number(ApertureHeight) - Number(PelmetDim);
var ApertureHeightUnderRoofSticks = Number(OAH) - Number(FifthWheel) - Number(NeckDepth) - 35;
document.getElementById("ApertureHeight").innerHTML = "Aperture below Cantrail = " + ApertureHeight + "mm";
document.getElementById("ApertureHeightBelowPelmet").innerHTML = "Aperture below pelmet = " +
ApertureHeightBelowPelment + "mm";
document.getElementById("ApertureHeightUnderRoofSticks").innerHTML = "Aperture below roof sticks = " +
ApertureHeightUnderRoofSticks + "mm";
document.getElementById("OverallWidth").innerHTML = "Overall Width = 2548mm (2550mm on spec)";
document.getElementById("OAH").innerHTML = OAH;
document.getElementById("myText").value = document.getElementById("OAH").innerHTML;
}
I need this form to submit separately, via AJAX without refreshing the page, as I need the JSON array to be able to calculate further stuff that will be passed into Python Flask. My issue is I am getting a bad request when submitting form2.
Anyone got any ideas on what I have done wrong?
I think you are using the same endpoint URL to try handle 2 different requests. The 2nd form does not send the correct data and you're then getting Server errors. Try creating another endpoint on your python flask server for handling form2 and the myText field value.

Adding multiple forms and inputs with onclick events using javascript

I am currently working on an website project that my friends and I would like to publish in the future. I´m currently building the html and css side of the page and need to implement dynamic events (if that's how its called) in the page for customer input.
I have a very little understanding when it comes to javascript/jquery (I am able to get a general idea of what is happening, yet my syntax comprehension is poop) and have only a basic knowledge of html and css. Now, I am aware that my inquiry is extensive and I would really appreciate any help, or pointers in the right direction!
So far the different blocks of code that I have found and tried by googling have worked for me, but only in executing individual functions (e.g.: the toggle function works but the create.element function doesn't).
This is my current html code that I am trying to modify with Javascript:
<div class="bttiendas">
<button class="btndag">Agregar</button>
<button class="btndgu">Guardar</button>
</div>
<div class="rdatos">
<form class="thf">
<input class="morehf" type="button" value="+/-" />
<input class="chf" type="text" placeholder="Lorem ipsum" readonly />
<input class="chf" type="text" placeholder="Lorem ipsum" readonly />
<input class="chf" type="text" placeholder="Lorem ipsum" readonly />
<input class="edithf" type="button" value="Edit" />
<input class="erasehf" type="reset" value="Erase" />
</form>
<form class="trf">
<input class="crf" type="text" placeholder="POS" readonly />
<input class="crf" type="text" disabled />
<input class="crf" type="text" disabled />
<input class="crf" type="text" disabled />
</form>
</div>
What I am trying to accomplish with Javascript is as follows:
-To be able to create with javascript both .thf and .trf forms dynamically along with every other input/button that is inside each form with clicking the .btndag button (this is an onclick event followed by create.element if I'm not mistaken).
-For the .morehf <input button> have a hide/show toggle function for .trf and anything else inside that form.
-Toggle disabled in the .crf input text boxes with the .edithf <input button>.
-To be able to erase/remove both .thf and .trf forms (their input textboxes AND the buttons .morehf .edithf .erasehf) with the .erasehf <input button>.
-And to be able to save/submit (I am not sure which is the correct term here) any added and completely filled out forms fields (for when we want to send the changes to our database).
Again I would greatly appreciate any help you could give me, and thank you in advance for your time.
You can import jquery into your solution.
For step 1: you do not make sense. Do you mean you want to load data into your form from somewhere to edit data or something? how is this dynamic? It looks like static forms on a page.
For step 2:
<input class="morehf" onclick="toggleTrf()" type="button" value="+/-" />
<script>
function toggleTrf() {
$(".trf").toggle()
}
</script>
step 3:
<input class="edithf" onclick="disableInputs()" type="button" value="Edit" />
<script>
function disableInputs() {
if($(".crf").is(":disabled");){
//jquery 1.6+
$(".crf").prop('disabled', false);
//jquery 1.5 -
$(".crf").removeAttr('disabled');
}
else {
//jquery 1.6+
$(".crf").prop('disabled', true);
//jquery 1.5 -
$(".crf").attr('disabled','disabled');
}
}
</script>
step 4: it is not clear what you mean by erase the form but you can clear the text in the inputs
<input class="erasehf" thpe="reset" onclick="clearInputs()" value="Erase" />
<script>
function clearInputs() {
$("input").val("")
}
</script>
step 5:
<form action="some/path">
<input name="someName" type="text" text="random field" value="1" />
<button type="submit">submit</button>
</form>
That submit button will submit the form to whatever path you specify in your form action. As for saving to the database etc it is impossible to guess what technology you will use to do that.sorry about code formattin im typing on a phone.
I believe I have included everything the OP wanted. The non-jQuery approach (ES6). JSFiddle
First lets add a few helper variables:
let formSets = 0;
let createForm = function(id) {
return `<form data-id='${id}' class="thf">
<input class="morehf" type="button" value="+/-" />
<input class="chf" type="text" placeholder="Lorem ipsum" readonly />
<input class="chf" type="text" placeholder="Lorem ipsum" readonly />
<input class="chf" type="text" placeholder="Lorem ipsum" readonly />
<input class="edithf" type="button" value="Edit" />
<input class="erasehf" type="reset" value="Erase" />
</form>
<form data-id='${id}' class="trf">
<input class="crf" type="text" placeholder="POS" readonly />
<input class="crf" type="text" disabled />
<input class="crf" type="text" disabled />
<input class="crf" type="text" disabled />
</form>`;
};
Add the onclick event for the "add" function. We have to reassign the click events to the dynamically added elements or we could have done event delegation like I did for the remove button:
document.getElementsByClassName('btndag')[0].onclick = () => {
document.getElementById('a').innerHTML += createForm(++formSets);
for (let ii = 0; ii < formSets; ii++) {
document.getElementsByClassName("morehf")[ii].onclick = () => {
document.getElementsByClassName("trf")[ii].classList.toggle('hide');
}
document.getElementsByClassName("edithf")[ii].onclick = () => {
let form = document.getElementsByClassName("trf")[ii].children;
for (let i = 0; i < form.length; i++) {
let input = form[i];
if (input.disabled == true) {
input.disabled = false;
} else {
input.disabled = true;
}
}
}
}
};
Add the remove button a little differently using event delegation which allows us to target another element based on the parents target:
document.getElementById('a').onclick = function(e) {
let t = e.target;
if (t.className == 'erasehf') {
let me = t.parentNode;
let sib = me.nextElementSibling;
me.parentNode.removeChild(me);
sib.parentNode.removeChild(sib);
}
}
Finally, submit the data. This part is a little more vague simply because I am not exactly sure how you want the data formatted. But here is how you would submit the form using AJAX:
document.getElementsByClassName('btndgu')[0].onclick = function() {
Request("/linkto/save.asp").post({
//datahere
}).then(function () {
//on success
}, function () {
//on failure
});
}
Note that this uses a helper AJAX function that I made:
let Request = function(url, opt) {
// start loader
var AJAX = function(type, url, data, success, failure, cache) {
var InitRequest = new Promise(function(accept, reject) {
var request = new XMLHttpRequest(); // initiate new XMLHttpRequest
var done = false;
var compile = function(data) { //turn the data object into a usable source for the send function
var send = [];
for (var item in data) { // compile all data in "item=data" strings
send.push(item + "=" + encodeURIComponent(data[item]));
}
send = send.join("&"); // combine data to form "item1=data1&item2=dat2&item3=data3"
return send;
};
// if we choose not send any data, then the data variable will take the place of the success variable
// because of this, we have to also shift the failure function
if (typeof data === "function") {
success = data || accept;
failure = success || reject;
data = "";
} else {
success = success || accept;
failure = failure || reject;
data = compile(data);
}
if (type.toUpperCase() == 'POST') {
request.open(type.toUpperCase(), url, true);
// this header allows POST requests to work
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
} else if (type.toUpperCase() == 'GET') {
// for GET requests, we need to put all data in the url
// we would end up with test.php?item1=data1&item2=dat2&item3=data3
request.open(type.toUpperCase(), url + "?" + data, true);
} else {
console.error('Incorrect request type submitted: "' + type + '" is not supported.');
return false;
}
// in order for laravel to properly send ajax requests
request.setRequestHeader('X-CSRF-TOKEN', $('meta[name="csrf-token"]').attr('content'));
request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
request.onreadystatechange = function() {
if (!done) {
if (request.readyState === 4) { // when the readyState == 4, we have completed the request
if (request.status === 200 || request.status === 0 /*for ff bug*/ ) {
success(request.responseText, request);
} else { //if failed
try {
request.responseJSON = JSON.parse(request.responseText);
} catch (e) {
return false;
}
failure(request);
}
// hide the loader because the request has finished
done = true;
}
}
};
// send off the request
request.send(data);
});
return InitRequest;
};
// The "opt" variable also goes into place as the
// Cache reset
if (opt && typeof opt !== "string" && typeof opt !== "boolean") {
var DEFAULTS = {
type: "GET",
data: {},
cache: false,
success: function() {},
failure: function() {}
};
var o = $.extend(DEFAULTS, opt);
return AJAX(o.type, url, o.data, o.success, o.failure, o.cache);
} else {
return {
post: function(data, success, failure, cache) {
return AJAX("POST", url, data, success, failure, cache);
},
get: function(data, success, failure, cache) {
return AJAX("GET", url, data, success, failure, cache);
}
}
}
}
A little more information about sending data via AJAX
Data in your case should correspond with the ids:
{
0: {
trf: {
input1: "..",
input2: "..",
input3: ".."
}
},
1: {
trf: {
input1: "..",
input2: "..",
input3: ".."
}
}
}

User input does not get captured/stored

I am trying to figure out why this onclick function in my JavaScript and Jquery code are not working.
I am referring my "userInput" in the JavaScript code and storing it in a variable called "userDate". For some reason, the user input does not get captured/stored.
This is my HTML:
<form role="form">
<p> Enter the date:
<input id="userInput" type="text" placeholder="yyyy-mm-dd" autofocus required></p>
<button id="convert" type="submit" class="btn btn-primary btn-lg" padding="center">
<span class="glyphicon glyphicon-euro"></span>
</button>
</form>
This is my JS code:
$(function () {
// cache the DOM element
var $currencies = $("#currencies");
var $userInput = $("#userInput");
// We are listening on the 'document',
// for a click on an element with an ID of #convert in the HTML
$("#convert").on("click", function() {
var userDate = $userInput;
// testing
console.log(userDate);
alert ("Handler for .click() is called.");
// AJAX call for GET request
$.ajax({
type: 'GET',
url: 'http://xxx.xx',
success: function(currencies) {
console.log("success func is called");
console.log(userDate);
$.each(currencies, function(i, currency){
$currencies.append("<div> EUR: " + currencies.rates["EUR"] + ", date: " + currencies.date + "</div>");
});
},
// error handling for my request
error: function() {
alert("error loading currencies");
}
});
});
});
change
var userDate = $userInput;
to
var userDate = $userInput.val();
$userInput is a reference to the jquery object holding the input element. Using .val() returns the text value of that input element.

setInterval on IE10

The setInterval function does not work on I.E. 10. I have a web page that when a form is submitted, it will trigger a long process on the server for downloading a file. I use setInterval to repeatly poll the server for progress so that the user gets some kind of update on the progress.
The ProgressServlet will only get called once only. I did not test this on another web browser because it is "illegal" to use another browser in my company.
<script>
var myVar;
function validateForm()
{
//validation logic omitted
myVar = setInterval(getProgress(), 1000);
return true;
}
function getProgress() {
//ProgressServelt will return progress of the long process on the server
$.get("ProgressServlet", $.now(), function(res) {
if (res != "9999" || res == "No value avaliable") {
$("#progress").html(res);
} else {
$("#progress").html("Stopped: " + res);
clearInterval(myVar);
}
});
}
</script>
<form method="post" action="CreateServlet" name = "create">
Change Number(s):<br>
<input type="text" name="change" id="change">
<p></p>
<input type="submit" value="Download" onClick="return validateForm()">
</form>
<p></p>
<button id="send" name="send">Display</button>
Change
myVar = setInterval(getProgress(), 1000);
to
myVar = setInterval(getProgress, 1000);
That is: pass the function, not what it returns.

Use one jQuery function multiple times for several form inputs

I got a question in which I hope someone can help me
I have this script:
File test.php:
<script>
$(document).ready(function() {
var min_chars = 1;
var characters_error = 'Write at least '+ min_chars +' character';
var checking_html = 'Getting information...';
$('#get_information').click(function(){
if($('#idprice').val().length < min_chars){
$('#results_gotten').html(characters_error);
}else{
$('#results_gotten').html(checking_html);
check_availability();
}
});
});
function check_availability(){
var idprice = $('#idprice').val();
$.get("check_idprice.php?id="+$("#idprice").val(), function(data){
$("#results_gotten").html(data);
$("#results_gotten").show();
});
}
</script>
<input name="idprice" type="text" id="idprice" />
<input type="button" id="get_information" value="Checar"><br>
<div id="results_gotten"></div>
And a second file check_idprice.php
if (isset($_GET['id'])) { $id = $_GET['id']; } else { die ('No information'); }
$result = mysql_query("SELECT * FROM `sm_prices` WHERE `productid` = '". $id ."'");
$noresults = mysql_num_rows($result);
if($noresults > 0){
echo $noresults." found";
}else{
echo "No results found";
}
And it works perfectly, you can see it in action here:
http://www.enteratenorte.org/starmexico/test.php (You can search of 15-1 to get a result)
or here:
http://jsfiddle.net/EnterateNorte/hpT66/ (wont get you any result since it need a DB)
How ever, I would like to have multiple filds in the same test.php file, something like this:
<input name="idprice1" type="text" id="idprice1" />
<input type="button" id="get_information1" value="Check"><br>
<div id="results_gotten1"></div>
<input name="idprice2" type="text" id="idprice2" />
<input type="button" id="get_information2" value="Check"><br>
<div id="results_gotten2"></div>
<input name="idprice3" type="text" id="idprice3" />
<input type="button" id="get_information3" value="Check"><br>
<div id="results_gotten3"></div>
It could be 3 or more fields
How can this be achived using one single code?
You could wrap each block in a parent DIV:
<div class="retrieveInfo">
<input name="idprice1" type="text" id="idprice1" class="retrieveInfoText" />
<input type="button" id="get_information1" class="retrieveInfoSubmit" value="Check"><br>
<div id="results_gotten1" class="retrieveInfoResults"></div>
</div>
Then your JS might look something like this:
<script>
$(document).ready(function() {
var min_chars = 1
, characters_error = 'Write at least '+ min_chars +' character'
, checking_html = 'Getting information...'
, infoContainer = $('.retrieveInfo'); // this selects all the containers with this css class
/// now you can loop through each of the containers found...
infoContainer.each(function(){
var self = $(this) // $(this) refers to the current "container"
, infoSubmit = self.find('.retrieveInfoSubmit') // find button
, infoText = self.find('.retrieveInfoText') // find text box
, infoResults = self.find('.retrieveInfoResults'); // find result div
// since this is a loop, this click handler will be attached to all buttons found
infoSubmit.click(function(e){
// stop the browser from submitting the form (default action)
e.preventDefault();
// check if the info validates
if( infoText.val().length < min_chars){
infoResults.html(characters_error);
// returning here will stop execution of the function, no need for else
return false;
}
infoResults.html(checking_html);
// modified the funciton to accept some arguments
check_availability(infoText.val(), infoResults);
});
});
});
/**
* checkVal is the user input
* resultDiv is the jQuery object that points to the results for this container
*/
function check_availability(checkVal, resultDiv){
$.get("check_idprice.php?id=" + checkVal, function(data){
resultDiv.html(data).show();
});
}
</script>
Try something similar to the following
for(var i=0;i<3;i++) {
$('#get_information'+i).click(function(){
if($('#idprice'+i).val().length < min_chars){
$('#results_gotten'+i).html(characters_error);
}else{
$('#results_gotten'+i).html(checking_html);
check_availability(i);
}
});
}
function check_availability(i){
var idprice = $('#idprice'+i).val();
$.get("check_idprice.php?id="+$("#idprice"+i).val(), function(data){
$("#results_gotten"+i).html(data);
$("#results_gotten"+i).show();
});
}

Categories