I am trying to incorporate this code
var timeoutId;
$('textarea').keypress(function () {
if (timeoutId) clearTimeout(timeoutId);
timeoutId = setTimeout(function () {
$.ajax({
url: '/savecomment',
data: { comment: $(this).val() }
});
}, 750);
});
from the tutorial here to implement auto-save in my web app. However, I am confused about two things.
Where exactly is the code being saved in this example? When I reload the page, the text I wrote is no longer there.
I tried to incorporate their example of this implementation into my code, but it did not work. The text box and the gray "no change" text above it appears fine, but this text does not change when I type. How could this be if I copied the HTML, CSS, and JS exactly as they are in the example?
Sorry for the elementary questions and thanks in advance.
The short answer is: Because you probably did not implement the server-side, e.g. the /savecomment endpoint for the $.ajax() call.
I would argue that this is quite an over-engineered example and could easily be solved with localStorage, could be as simple as this:
// check if we have something to restore on page-load
$(window).on('load', function() {
if ( localStorage.getItem('text') ) {
$('textarea').val(localStorage.getItem('text'));
}
});
$('textarea').on('input', function () {
localStorage.setItem('text', $(this).val());
// in a real browser you could verify it by
// uncommenting the following line, does not work
// in the sandbox this snippet runs in...
console.log('Saved text: ', localStorage.getItem('text'));
});
$('form').on('submit', function() {
alert('Actually save the text to the server via AJAX call');
// you should then clear the saved text after you successfully saved
// the content on the server
localStorage.removeItem('text');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="/savecomment">
<textarea name="sometext"></textarea>
<button type="submit">Save To Server</button>
</form>
then, when the user is actually done, have a "Save" button that can be clicked, that actually sends the finished text to the server.
Where is it saved?
It is saved in the app which runs in the /savecomment path. You need to implement this endpoint.
Is it sufficient to produce html, css and js?
Not sufficient. You need to implement the server app which saves the comment too.
Related
For a web based project, I am using jQuery. In one part of the code, there is data that gets dynamically added to the screen on the client side based on the activity of other users connected to the server. I want to write a code that will allow me to execute a function when a client clicks on the data.
To elaborate a little bit, there is a list which shows which members are online. When a new client connects, his name is added to the list and all other users can see on their screen that he is online. When another user clicks on his name, he sends a message request.
This is the relevant jQuery code:
$('#inc').append("<br><i onclick='accept()'>"+data.plr+"<i><br>")
And the accept function is defined under this block which is within another function, so like
function a(){
$('#inc')....
}
function accept(){
//...
}
However, when the code runs I get an error which says accept() is not defined
How do I solve this problem?
Maybe you can do it in that way...
$('#inc').append("<br><i>"+data.plr+"<i><br>")
$('#inc i:last-child').click(accept);
I did a small CodePen to let you see the code in action
https://codesandbox.io/embed/frosty-jang-fvk3j
I've always done it this way. I find this easier.
$('#inc').append("<br><i class="child">"+data.plr+"<i><br>")
$('.child').on("click",function(){
//your code here
});
You can do it with this way as well :
jQuery(function(){
click_link = $('<a class="" href="#">Click here</a>');
click_link .bind("click", function(){
alert('DO something');
});
$('.your_dom').append(click_link );
});
Write it using jQuery methods:
var $i = $('<i>').text(data.plr).click(function(event) {
//handle here onClick event
}); //or if you have the function already declared just write .click(accept);
$('#inc').append('<br />', $i, '<br />');
https://api.jquery.com/click/
I've spent the last 4 years trying to solve this problem (on and off) and quite frankly my brain hurts.
I'm a voluntary designer for a local community project (a radio station). We have an "On Air" module that displays what track is currently playing and coming up.
Until recently I was using auto refreshing iframes that contained HTML files with the track information (these HTML files are automatically uploaded via FTP every 15 seconds by our playout system). These iframes refreshed every 15 seconds, however, this often lead to 404's in the iframe and ugly flickering as they reloaded.
I've spent some time looking in to an AJAX solution. I currently have an XML file with the track information (which the playout system automatically uploads via FTP every 15 seconds) and a HTML document that uses AJAX to refresh every 10 seconds. However, while I've helped fix the 404 issue, I'm still left with the ugly flicker as the text refreshes.
I have read that there is a way to have ajax refresh only if values in a database have changed, but I haven't had much luck in researching ways to do this if an XML document is updated.
If anyone can help point me in the right direction, many cookies and love will be bestowed upon you. Thanks!
Here's the code I currently have:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
(function($)
{
$(document).ready(function()
{
$.ajaxSetup(
{
cache: false,
beforeSend: function() {
$('#content').hide();
$('#loading').show();
},
complete: function() {
$('#loading').hide();
$('#content').show();
},
success: function() {
$('#loading').hide();
$('#content').show();
}
});
var $container = $("#content");
$container.load("test.xml");
var refreshId = setInterval(function()
{
$container.load('test.xml');
}, 10000);
});
})(jQuery);
</script>
</head>
<body>
<div id="wrapper">
<div id="content"></div>
<img src="loading.gif" id="loading" alt="loading" style="display:none;" />
</div>
</body>
</html>
And here is the test.xml:
<OnAirInfo>
<CurrentTrack><OCP_NOW_ITEMNAME></CurrentTrack>
<CurrentArtist><OCP_NOW_ARTIST1NAME></CurrentArtist>
<NextTrack><OCP_NEXT_ITEMNAME></NextTrack>
<NextArtist><OCP_NEXT_ARTIST1NAME></NextArtist>
</OnAirInfo>
You can use HTML5's Server-Sent Events
A server-sent event is when a web page automatically gets updates from a server.
All you have to do is create an EventSource object and pass it the URL of your server file(Here I am assuming .php file).
var source = new EventSource('your_file.php'); //This file will fetch the updates from `database`.
Then you can listen to the events for the updates.
source.addEventListener('message', function(e) {
console.log(e.data);
}, false);
There is a very nice explanation on HTML5rocks- EventSource about this concept. You should definitely take a look into it.
Hope this helps.
By default, any AJAX call is cached by the browser itself and won't transfert the whole file if the server say it hasn't changed.
For you case, I would suggest the folowing :
<div id="content">
<p id="CurrentTrack"></p><br/>
<p id="CurrentArtist"></p><br/>
<p id="NextTrack"></p><br/>
<p id="NextArtist"></p>
</div>
<script>
setInterval(function()
{
$.get("/url/to/your/xml/",
function(data){
// In case your server don't serve the file with the right mime type
var response = $($.parseXML(data)).find("OnAirInfo");
// Data extraction from xml
var CurrentTrack = response.children("CurrentTrack").text();
var CurrentArtist = response.children("CurrentArtist").text();
var NextTrack = response.children("NextTrack").text();
var NextArtist = response.children("NextArtist").text();
// Smooth text transition to prevent the "flickering"
$("#CurrentTrack").fadeOut(function() {
$(this).text(CurrentTrack).fadeIn();
});
$("#CurrentArtist").fadeOut(function() {
$(this).text(CurrentArtist).fadeIn();
});
$("#NextTrack").fadeOut(function() {
$(this).text(NextTrack).fadeIn();
});
$("#NextArtist").fadeOut(function() {
$(this).text(NextArtist).fadeIn();
});
});
}, 10000);
</script>
The smooth transition with the fadeout/fadein should look better than the text changing directly.
off course you have to adapt it to your system but this loading way will :
Prevent any 404 to interfear (the ajax success will just not be called so the text will stay the same until the next update
Allow for a wide range of data to be transmited (you could add the album cover thumbnail as a base64 string in your xml, or the url to the picture)
Allow you to keep the formating on the page and not on a separate one
Edit : Updated to your code specification
some info
I'm working on a webpage that can load data on multiple layouts, so user can choose which one is best. It can be loaded in a list or a cards like interface, and the data is loaded using ajax.
In this page I also have a notifier for new messages that the user received. The ajax function is new, and when page was loaded by the php scripts, the js script (that add a badge with the number of unread messages to a link on a menu item) was working ok.
I'm using HTML5, PHP, jQuery and a mySQL DB.
jQuery is imported onto the HTML using
<script src="https://code.jquery.com/jquery.js"> </script>
So it's a recent version.
the problem
Now, when I load the data onto the page using ajax, the js script won't work anymore. I had the same issue with another js script and I managed to solve it by using the delegate event binder.
But my unread messages updater runs on a time interval, using
<body onload="setInterval('unread()', 1000)">
the unread() js is quite simple:
function unread() {
$(document).ready(function(){
$('#menu_item').load('ajax_countNewMsgs.php');
});
}
it calls a php script which grabs the unread msgs count from the DB and echo into a element that jQuery will point. Hope I'm being clear.
The problem is that I cannot figure out how I would call a timed event using delegate. Without much hope I've tried
$(document).on('ready()','#menu_item', function () {
$(this).load('ajax_countNewMsgs.php');
});
That didn't work.
I read many posts about js stop working after changes in the DOM, but, again, I couldn't figure out a way to solve that, nor found a similar question.
Any help or tips would be highly appreciated.
EDITED to change second php script's name
2nd EDIT - trying to make things clearer
I tried the way #carter suggested
$(document).ready(function(){
function unread(){
$.ajax({
url: 'ajax_countNewMsgs.php',
type: 'GET',
dataType: 'html',
success: function(response){
$('#menu_item').html(response);
},
error: function(response){
//no error handling at this time
}
});
}
setInterval(unread(), 1000);
});
the ajax_countNewMsgs.php script connects to the DB, fetch the unread messages, and echoes the number of unread messages.
If I try to apply the ajax reponse to another element, say, the <body> the results are as expected: at each 1 sec , the body html is changed. So the function is working.
As I said, none of my JS changes the #menu_item. Actuallly this element is part of another php scritp (menu.php) which is imported to the top of the page.
the page structure is this way:
<html>
<head>
some tags here
</head>
<body>
<?php include (php/menu.html); ?>this will include menu with the #menu_item element here
<div id='wrapper'>
<div id='data'>
here goes the data displayed in two ways (card and list like). Itens outside div wrapper are not being changed.
</div>
</div>
</body>
</html>
Even though the elemente is not being rewritten js cannot find it to update it's value.
It's not the full code, but I think you can see what is being done.
$(document).on('ready()','#menu_item', function () {
is an invalid event listener. If you wanted to be made aware of when the DOM is ready you should do this:
$(document).ready(function () {
However I don't think that is actually what you want. Your function unread will fire repeatedly but it attaches an event listener everytime. Instead if you want to make an ajax call every so many seconds after initial page load, you should do something like this (dataType property could be html, json, etc. pick your poison):
$(document).ready(function(){
function makeCall(){
$.ajax({
url: 'ajax_countNewMsgs.php',
type: 'GET',
dataType: 'html',
success: function(response){
//handle your response
},
error: function(response){
//handle your error
}
});
}
setInterval(makeCall, 1000);
});
remove that on your unread function:
$(document).ready(function(){
WHY?
The Document is already "ready" and this document state will only fired 1x - After that the "ready state" will never ever called. Use follwing syntax:
jQuery(function($){
What I am looking for is slightly subjective, but I am sure there is a better way to do this.
I am looking for a better way to perform javascript while a user is typing content into either a textarea or input box on a website. For instance, sites such as Google Docs are capable of saving changes to documents almost instantly without noticeable performance degradation. Many sites however use a bit of jQuery that might look like the following:
$("#element").on("keyup", function() { /* Do something */ });
This works fine for simple things like autocomplete in search boxes, but performance becomes a nightmare once you have any sizable corpus for it to have to deal with (or if a user types fast, yikes).
In trying to find a better way to analyze/save/what-have-you text as the user is typing, I started to do something like this:
var changed = false;
$("#element").on("keyup", function() { changed = true });
setInterval(function() { if(changed) { /* Do something */ changed = false; } }, 1000);
It seems to alleviate laggy or delayed text input, but to me it seems like a less than elegant solution.
So back to my question, is there a better way to have javascript execute when a corpus has been changed? Is there a solution outside of using intervals?
Thanks.
There is a jQuery plugin that does pretty much what you did.
Your example will be transformed into
$("#element").on("keyup", $.debounce(1000, function() { /* Do something */ }));
The code will execute after a user is not pressing any keys for 1000ms.
I have found a very good solution for this. This code will check whether the content has been changed and based on that it will save it otherwise the save functionality will not be executed !
Check out this demo JSFIDDLE
Here is the code :
HTML :
Content:<br>
<br>
(type some text into the textarea and it will get saved automatically)
<textarea rows="5" cols="25" id="content"></textarea>
<br>
<span id="sp_msg_saved" style="background-color:yellow; display:none">Content is saved as draft !</span>
JS:
var old_content = "";
function save_content()
{
var current_content = $('#content').val();
//check if content has been updated or not
if(current_content != old_content)
{
alert('content is updated ! Save via ajax');
old_content = current_content;
$('#sp_msg_saved').show(100);
$('#sp_msg_saved').fadeOut(3000);
}
}
setInterval(save_content,3000);
You can increase or decrease the amount of time for the save function to call by altering the values in setInterval function. Put the code for saving the content via ajax, that will save the current user content into your DB, I haven't included that one...
You can make your own little delay by using the window.setTimeout-Function:
var IntervalId = null;
function saveEdits(){
//Doing your savings...
}
$('input').keyup(function(){
if (IntervalId){
window.clearTimeout(IntervalId);
IntervalId = null;
}
IntervalId = window.setTimeout(function(){
saveEdits();
}, 3000);
});
I'm working on a website platform that doesn't allow for any server sided scripting, so jquery and javascript are pretty much all I have to work with. I am trying to create a script to work with the site that will update a div that contains an inbox message count every 10 seconds. I've been successful with making the div refresh every ten seconds, but the trouble lies in the page views count. My script is refreshing the whole page and counting for a page view, but I only want to refresh just the one div. An example of the trouble my script causes is when viewing anything on the site that has a page view counter (forum posts, blog posts, ect...), the page views go crazy because of the script refreshing. I'm pretty new to Javascript, so I'm not entirely sure there is a way around this.
What I'm working with is below:
<div id="msgalert" style="display: none"; "width: 100px !important">
You have $inbox_msg_count new messages.
</div>
$inbox_msg_count is a call that grabs the message count, and provided by the platform the site is on. It displays the message count automatically when used.
Then the script that does all the work is this:
<script>
setInterval(function(facepop){
var x= document.getElementById("SUI-WelcomeLine-InboxNum");
var z = x.innerText;
if(x.textContent.length > 0)
$("#msgalert").show('slow');
}, 1000);
facepop();
</script>
<script>
setInterval(function() {
$("#msgalert").load(location.href+" #msgalert>*","");
}, 1000); // seconds to wait, miliseconds
</script>
I realize I've probably not done the best job of explaining this, but that's because I'm pretty confused in it myself. Like I mentioned previously, this code function just how I want it, but I don't want it to refresh the entire page and rack up the page views. Any help is much appreciated.
You might try to look into iframe and use that as a way to update/refresh your content (div). First setup an iframe, and give it an id, then with JS grab the object and call refresh on it.
well your prob seems a little diff so i think submitting a from within the div might help you so ...
$(document).ready(function()
{
// bind 'myForm' and provide a simple callback function
$("#tempForm").ajaxForm({
url:'../member/uploadTempImage',//serverURL
type:'post',
beforeSend:function()
{
alert(" if any operation needed before the ajax call like setting the value or retrieving data from the div ");
},
success:function(e){
alert("this is the response data simply set it inside the div ");
}
});
});
I think this could probably be done without a form, and definitely without iframes (shudder)..
Maybe something like this?
$(document).ready(function()
{
setInterval(function(facepop)
{
var x= document.getElementById("SUI-WelcomeLine-InboxNum");
var z = x.innerText;
if(x.textContent.length > 0)
$("#msgalert").show('slow');
$.ajax({
type: "POST",
url: location.href,
success: function(msg)
{
$("#msgalert").html(msg);
}
});
},1000);
It's not entirely clear exactly what you're trying to do (or it may just be that I'm ultra tired (it is midnight...)), but the $.ajax() call in the above is the main thing I would suggest.
Encapsulating both functions in a single setInterval() makes things easier to read, and will extinguish the 1 second gap between showing the msgalert element, and "re-loading" it.