JavaScript event button onclick works only one time - javascript

I want to fire an onclick event from a button. The event is declared in a separate JavaScript file.
The code must reproduce a chat. If I send first text it works fine, but if I try to send something again (second text) it does not fire.
The html file contains:
var chatOutputDiv = document.getElementById("chatOutput");
chatSubmit.onclick = function () {
// Create a Json object with "displayname" being the display name and "messageText" the message.
// "displayname" is taken from URL, message from element chatInput.
//var chatMessage = { "displayname": getURLParameter("displayName"), "messageText": chatInput.value };
// We send data on the "chat", channel which is currently hard-coded
// in later versions we allow custom naming of channels.
//conference.sendData("chat", chatMessage);
// Send text in current chat
chatOutputDiv.innerHTML += "<br> user : message";
// Clear chat input
chatInput.value = "";
};
<div class="row">
<div class="col-xs-12 col-lg-12 col-sm-12 col-md-12" align="center">
<div id="chatOutput" style="height: 200px; width: 220px; overflow-y: scroll;">
<input type="text" id="chatInput"/>
<input id="chatSubmit" type="button" value="Send"/>
</div>
</div>
</div>
If you try this code, it works one time, but after that it doesn't work anymore. It seems that it doesn't fire the event.

It's because you are recreating the html inside .chatOutput when you click the button, so the HTML (which includes the button) is rewritten and the event is lost.
There are various ways around this. One would be to make the function a named function that you call, and adding chatSubmit = document.getElementById("chatSubmit"); chatSubmit.onclick = myFunctionName; to the end of your function.
However, I think a nicer way of doing it is to just use an extra div to store the response, like so:
<div class="row">
<div class="col-xs-12 col-lg-12 col-sm-12 col-md-12" align="center">
<div id="chatOutput" style="height: 200px; width: 220px; overflow-y: scroll;">
<input type="text" id="chatInput"/>
<input id="chatSubmit" type="button" value="Send"/>
<div id="chatResponse"></div>
</div>
</div>
</div>
var chatOutputDiv = document.getElementById("chatOutput")
var chatSubmit = document.getElementById("chatSubmit")
var chatResponse = document.getElementById("chatResponse");
var chatInput = document.getElementById("chatInput");
function foobar() {
chatResponse.innerHTML += "<br> user : " + chatInput.value;
chatInput.value = "";
}
chatSubmit.onclick = foobar;
Fiddle: https://jsfiddle.net/r0gm30mr/

Related

How to retrieve shopping cart items, implementing LocalStorage

How do I retrieve information stored in a js file? I assume I am labelling my node elements in HTML incorrectly
I'm hoping to gain a better understanding of how to retrieve a function node from localStorage
Below are the key factors I am trying to get using getElementById into local storage from post HTML.
This is not everything in my listing.html document, I have excluded everything but what I think are essential elements
<div class="listing">
<div class="container-form">
<div class="mySlides fade">
<div class="numbertext">1 / 3</div>
<img class="img" value(src)="1" id="img" src="images/4.JPG" alt="img1">
</div>
<div class="infoBox">
<h5 post="weight" id="weight" value="7.00">7.00 : Under - 16 oz</h5>
</div>
<div class="column-bottom">
<div class="add-button">
<div class="add-button" method="post">
<p><input type="submit" onclick="addListing()" class="btn"></input></p>
<div class="buy-button">
<span class="price" post="price" id="price" value="60">$60</span>
<button type="button" class="btn" onclick="window.location.href='cart.html'" onclick="addListing()"
;>BuyMe</button>
</div>
</div>
</div>
</div>
</div>
</div>
I am trying to use the function below to store each element from the post HTML
function addlisting() {
let listing = ['listings'];
if (localStorage.getItem('listings')) {
listing = JSON.stringify(localStorage.getItem('listings'));
alert("added!");
}
listing.push({ 'listingId': listingId + 1, image: '<imageLink>' });
listingsId = listingsId + 1;
var listingsName = document.getElementById('name').innerHTML;
var listingsPrice = document.getElementById('price').getAttribute('data- value');
var listingsImage = document.getElementById("img").src;
var listingsWeight = document.getElementById('weight').getAttribute('data- value');
value = parseFloat(listingsPrice, listingsWeight).toFixed(2);
localStorage.getItem('name', 'price', 'img', 'weight', JSON.stringify(listingsName, listingPrice, listingsImage, listingsWeight));
}
here is the $(document).ready(function(){ function I'm hoping to implement into my code, I got this from another Stack Overflow page as it was the most fitting however I am yet to understand each component.
$(document).ready(function () {
$('#Btn').load(function () {
let listings = [];
if (localStorage.getItem('listings')) {
listings = JSON.parse(localStorage.setItem('listings'));
}
listings.push({ 'listingId': 1, image: '<imageLink>' });
});
});
my question again is how do I then execute this function using onload Onto a separate HTML, called cart.html. I did not display my cart.html file because there is nothing pertaining to this question on it. And furthermore how to go about styling Onload events that retrieve information from localStorage.
P.S.
There is an alert function within my first .js excerpt addListing(), that does not fire when clicked. probably a sign of bad programming. I've just never found a straightforward answer

document.createElement flashes up with what I want. Then it disappears

I'm having a small issue with my code. I want the user's input to appear on the screen, like a chatbot. However, it is not doing this. What it's doing instead is flashing up with what I want. Then it is disappearing. Just the message, not the entire thing, but that sometimes happens as well. What has happened and how can I fix it?
function executeNewMessage() {
var messagecontainer = document.getElementById("message");
var message = messagecontainer.value;
var newmessagediv = document.createElement("DIV");
newmessagediv.innerHTML = message;
document.getElementById("bodymessages").appendChild(newmessagediv);
}
<div id="site">
<div id="head">
Chatbot
</div>
<div id="body">
<div id="bodymessages"></div>
<span id="bottom"></span>
</div>
<div id="foot">
<form>
<label for="message">Type your message here</label>
<input id="message" type="text" />
<a href="#bottom">
<button id="submit" onclick="executeNewMessage()">→</button>
</a>
</form>
</div>
</div>
The reason that this is happening is because you are using HTML form. The default behavior for form is that they try to submit to the server. That's why you only see the change for a short duration and the page reloads again. Hence, you need to use preventDefault() method.
So, your function should look like this:
function executeNewMessage(e) { //Here e is the event object
var messagecontainer = document.getElementById("message");
var message = messagecontainer.value;
var newmessagediv = document.createElement("DIV");
newmessagediv.innerHTML = message;
document.getElementById("bodymessages").appendChild(newmessagediv);
e.preventDefault();
}
So, what the preventDefault() does is that it prevents the default action of an event.
https://www.w3schools.com/jsref/event_preventdefault.asp

Why button will not append text from textarea to a panel (Bootstrap)?

I am trying to trigger an event with a button that takes text from a textarea and sends it to a panel using the Bootstrap Framework (v.3.3.7). Currently trying to do this using an event listener in Javascript rather than assigning an ‘onclick’ value for the button.
HTML:
<div class="container-fluid">
<div class="row">
<!-- Panel where text will be appended to -->
<div id="mainChatBox" class="panel-body" style="height:435px; overflow-y:scroll"></div>
<!-- Textarea and button -->
<div class="panel panel-footer" style="height:40px">
<div class="form-group col-md-10 col-lg-10">
<input type="text" placeholder="Type your message here" class="form-control" id="messageBar" />
</div>
<div class="input-group-btn col-md-2 col-lg-2">
<button id="sendMessageButton" class="btn btn-default">Send</button>
</div>
</div>
</div>
</div>
Javascript
var sendMessageButton = document.querySelector('#sendMessageButton');
var messageBar = document.querySelector('#messageBar');
var mainChatBox = document.querySelector('#mainChatBox');
sendMessageButton.addEventListener("click", function (event) {
var message = messageBar.value;
mainChatBox.innerHTML += message + "<br />";
});
I tried debugging by using this code and another version where I instead assign the button an ‘onclick’ value and then keep the function for it.
Here is a link to a reddit post with that version of code where I tried to find a solution with assigning an ‘onclick’ value to the button instead of using an EventListener.
Reddit post link
I need to know why when the event is triggered by the button that the text will not be appended to the mainChatBox when using either the method with the 'onclick' value assignation to the "button" tag for sendMessageButton, or the EventListener in the Javascript.

Using datepicker with jquery, dialog box associated with div onselect

Not sure if this is possible, I'm just starting to learn javascript and jQuery. If the way that I would like is not possible, I am very open to hearing of different ways I may be able to achieve this.
I want to display a datepicker, the user will click on dates and when they do a dialog box appears which has specific predefined data in it. They can select a different date, and it will open another dialog box with different predefined data in it, and I want to keep track of the dates that they click on.
<div id="tabs">
<ul>
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
<div id="tabs-1">
<p>I'm going to have different data applying to only this day</p>
</div>
<div id="tabs-2">
<p>I'm going to have different data applying to only this day</p>
</div>
<div id="tabs-3">
<p>I'm going to have different data applying to only this day</p>
</div>
</div>
Open jQuery dialog box upon selecting a date from jQuery datepicker inline
That link was useful because a user has a jsfiddle posted: http://jsfiddle.net/qqabC/ which is a start to what I am trying to do, I am just not sure of how or if it is even possible to incorporate divs into the dialog boxes like so. I keep messing around with it but I have been getting nowhere. Each date that is selected will have different dialog box content in it.
If this is not possible, what would be the best way to achieve this? Thank you.
--Edit:
I still need to implement the divs that I have defined above with div id "tabs". Tabs = workout days. So tabs-1 to tabs-5 would be 5 total days. tabs-1 is going to be their first click which is day 1 form content, tabs-2 will be their second click which is day 2 form content, and so on. I believe I should use a for loop, because which each click the div is being incremented onto the next one. I was trying to do something like:
var divs = $('#tabs > div[id]');
var links = $('#tabs li');
divs.hide();
for (i=0;i<=max_workouts;i++) {
$('#tabs li').on('click', function(e){
var clickedID = $(this).attr('href').clone().appendTo(#workout-modal);
}
Something like that, to iterate through the div's with each click, but it's not working, I have been trying to find examples of placing existing div content in modals but there is nothing on iterating through divs in this way, do you have any suggestions?
Here is an example of how you could achieve this functionality using Bootstrap. Of course you'll need to change the functionality and design as needed but this should be a fair start
The workflow is as follows:
User clicks a date
Modal is displayed with various inputs
Inputs are cleared when modal opens
User enters info in the inputs
User clicks add workout
A span label is added to the display showing the workout number and the date selected
This span has data attributes set to store the date, title, and each of the values from the modal inputs
If user clicks the "X" on the right end of the span, it is removed
If user clicks the span label anywhere else it reopens the modal and populates the inputs with the data stored as attributes on the span
If the user clicks add workout after loading an existing one, the new span replaces the old one instead of adding to the end of the div
Here is a jsFiddle also
$(function(){
var max_workouts = 5;
$('#workout-datepicker').datepicker({
startDate: "today"
}).on('changeDate', function(e) {
var cur = $('.workout-label').length;
if (cur < max_workouts) {
var workoutDate = e.format('mm/dd/yyyy');
var title = 'Workout ' + (cur + 1) + ' - ' + workoutDate;
openModal(title, workoutDate);
}
else{
var $tooMany=$('#too-many');
$tooMany.show();
setTimeout(function(){ $tooMany.hide() }, 2000);
}
});
var $workoutLabelsContainer = $('#workout-labels-container');
$('#add-workout').click(function() {
var $workoutModal = $('#workout-modal');
var workoutDate = $workoutModal.data('workout-date');
var title = $workoutModal.data('workout-title');
var vaule1 = $('#modal-workout-value-1').val();
var vaule2 = $('#modal-workout-value-2').val();
var $workout = $('<span class="label label-primary workout-label col-sm-12">' + title + '<span class="glyphicon glyphicon-remove pull-right remove-workout" aria-hidden="true"></span></span>');
var clickedLabelIndex = $workoutModal.data('crurent-label-index');
$workout.data('workout-title', title).data('workout-date', workoutDate).data('value-1', vaule1).data('value-2', vaule2);
if (clickedLabelIndex == -1) $workoutLabelsContainer.append($workout);
else($('.workout-label').eq(clickedLabelIndex).replaceWith($workout))
$workoutModal.modal('hide');
});
$workoutLabelsContainer.on('click', '.remove-workout', function(e) {
e.stopPropagation();
$(this).closest('.workout-label').remove();
})
$workoutLabelsContainer.on('click', '.workout-label', function() {
var $workoutLabel = $(this);
var workoutDate = $workoutLabel.data('workout-date');
var title = $workoutLabel.data('workout-title');
var value1 = $workoutLabel.data('value-1');
var value2 = $workoutLabel.data('value-2');
var labelIndex = $('.workout-label').index($workoutLabel);
openModal(title, workoutDate, value1, value2, labelIndex);
});
function openModal(title, workoutDate, value1, value2, labelIndex) {
var $workoutModal = $('#workout-modal');
var $value1 = $('#modal-workout-value-1').val('');
var $value2 = $('#modal-workout-value-2').val('');
$workoutModal.data('workout-title', title).data('workout-date', workoutDate);
$('#workout-modal-title').html(title);
if (value1) $value1.val(value1);
if (value2) $value2.val(value2);
if (labelIndex !== 'undefined' && labelIndex > -1) $workoutModal.data('crurent-label-index', labelIndex);
else $workoutModal.data('crurent-label-index', -1);
$workoutModal.modal({
show: true
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.5.1/js/bootstrap-datepicker.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.5.1/css/bootstrap-datepicker.min.css" rel="stylesheet"/>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<style>
.workout-label {
padding: 6px;
font-size: 16px;
width: 100%;
display: block;
margin-bottom: 5px;
cursor: pointer;
}
.remove-workout {
cursor: pointer;
}
#too-many{
display:none;
}
</style>
<br>
<br>
<div class="container well" id="workout-container">
<div class="row">
<div class="col-xs-6">
<div id="workout-datepicker"></div>
</div>
<div class="col-xs-6" id="workout-labels-container">
</div>
</div>
<div class="alert alert-danger" id="too-many" role="alert">Maximun reached</div>
</div>
<div id="workout-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" 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">×</button>
<h3 id="workout-modal-title"></h3>
</div>
<div class="modal-body">
<form class="form-horizontal" role="form">
<div class="form-group">
<label for="firstname" class="col-sm-4 control-label">Some short text:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="modal-workout-value-1" placeholder="">
</div>
</div>
<div class="form-group">
<label for="lastname" class="col-sm-4 control-label">Some longer text:</label>
<div class="col-sm-8">
<textarea class="form-control" id="modal-workout-value-2" name="textarea"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
<button type="button" class="btn btn-primary" id="add-workout">Add workout</button>
</div>
</form>
</div>
</div>
</div>

Changing HTML Form Text Using Javascript and/or Razor

I'm working in a view that deals with creating account information and resetting passwords. Where I'm stuck: depending if the password request was sent, approved, or denied, this will in turn change how the log in screen/password request appears. I want it to change the present text in the form and update it with a message and the user can submit OK, etc. so the browser will close automatically (or have the current form be hidden so I can create a new one with the information, whichever is easier).
Before I had an alert to send the message, but now I need it as HTML to style it.
//All of this is in a Javascript script tag
var reset = getParameterByName('reset');
if (reset == "sent") {
//alert("Done! Please check your email to confirm.")
//How can I change the current text on the form?
document.getElementsByClassName('panel-login').innerHTML = "<div class='panel-login' style='color: white; background-color: blue;'><p>Done! Please check your email to confirm.</p></div>";
//Here so I know something is updating on the site...
var message = "<div style='color: white; background-color: blue;'><p>Done! Please check your email to confirm.</p></div>";
document.write(message);
}
if (reset == "fail") {
alert("Password reset request failed.")
}
if (reset == "approved") {
alert("Confirmed! A password reset email has been issued.")
#*var url = '#Url.Action("Login", "Account")';
window.location = url;*#
}
(Whatever works with the first if (sent) will be copied and pasted into the last two once I get this working.)
This is the HTML for the above:
<div class="panel_login" style="opacity: 0.9;">
<div class="">
#using (Html.BeginForm("ResetPassword2", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { #class = "form-signin mg-btm" }))
{
<div class="" style="padding-left: 20px; padding-right: 20px; padding-bottom: 20px; padding-top: 10px; ">
<div class="">
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "Password reset was unsuccessful. Please check email and try again.")
<label>Email</label>
<div class="input-group">
<span id="emailinput" ng-model="user.EMAIL" class="input-group-addon"><span class="glyphicon glyphicon-user"></span></span>
#Html.TextBoxFor(m => m.Email, new { #class = "form-control", placeholder = "" })
#Html.ValidationMessageFor(m => m.Email)
</div>
</div>
</div><div class="panel-footer">
<div class="row centered">
<div class="col-xs-12">
<button id="singlebutton" name="singlebutton" class="btn btn-primary" onclick="Back(); return false;">Cancel</button>
<button class="btn btn-large btn-danger" type="submit" ng-click="resetpassword(user)">Request Password Reset</button>
</div>
</div>
</div>
}
</div>
I've tried hiding the panel-login so I can create a new div/element to display the message/form. It didn't work (doing something wrong):
document.getElementsbyClassName('panel-login').style.display = 'none';
Learned that since it was an array, I will need something else since the above produces a null and error. Tried using a variable to get the class and then a for statement to target it to style. Again, no avail.
I'm not familiar with Razor (still learning) and copying what I need in JavaScript seems to just replicate things instead of changing what's already there. Thanks in advance.
If I follow you, getElementsByClassName is the culprit. Try:
var loginPanel = document.getElementsbyClassName('panel-login')[0];
This will find the first match in the array.
I ended up figuring this out.
Essentially, I created other divs which is styled similarly to the log in screen and in the same position, but kept them hidden until they're called by their function to appear depending on user input and URL. Log in screen originally is visible but later hidden when another div is made visible to display the tailored message.
I first created this through Javascript (using functions to create HTML), but later changed it to HTML and CSS but still used JS to call the functions. The main reason I had to switch is because some messages after being confirmed either submitted something or was supposed to close the tab or go back and I had trouble doing so since apparently a script can't close the current page that didn't initially open it. Still having that problem in Chrome TBH.

Categories