This should be really simple, so, either I am over thinking it or making it more complicated than it should be.
I would like to update a DIV without having to reload the webpage.
A form on Canvas.asp queries the database and returns the coordinates of a GPS device. The coordinates are updated every minute and would like the script to return the latest coordinates without having to refresh the page. The coordinates are appended to a separate XML file.
I have written this;
<script type="text/javascript">
$(document).ready(function() {
$("#map").load('canvas.asp');
var auto_refresh = setInterval(function() {
$("#map").load('canvas.asp?std=<%=session("7digit")%>&submit=Search&execute=1');
}, 60000);
$.ajaxSetup({ cache: false });
});
</script>
The div to be reloaded;
<div id="map"></div>
The script returns an error by duplicating the header and content, after 60 seconds the map DIV is nowhere to be seen... Simply disappears! The coordinates are appended to the XML file every 60 seconds, even after the error.
What am I doing wrong?
Looks like you are always returning the full result of your canvas.asp page which will always be a full HTML document which will not play nice with your <div>.
The issue here is how you handle passing partial content back and that comes down to how you structure your ASP page. Here is a bare bones template I use often for this type of thing.
<%
Option Explicit
Dim action, def_action
Const BASE_ERROR_VAL = 1000
Const DISPLAY_PAGE = 0
Const DISPLAY_CANVAS_CONTENT = 1
'Without this the page does nothing, this is the gateway to your page.
Call init()
'First code that get's run when page is requested
Sub init()
'Defaults
def_action = DISPLAY_PAGE
'Process query string
action = Request.QueryString("a") & ""
If Len(action) > 0 and Isnumeric(action) then action = CInt(action) Else action = def_action
Select Case action
Case DISPLAY_PAGE
Call load_page()
Case DISPLAY_CANVAS_CONTENT
Call load_canvas()
Case Else
'As we have a default this should NEVER happen, but always worth covering your bases.
Call Err.Raise(vbObjectError + BASE_ERROR_VAL + 1, "canvas.asp", "Action required")
End Select
End Sub
Sub load_page()
>%
<html>
<head>
...
</head>
<body>
<% Call load_canvas() %>
</body>
</html>
<%
End Sub
Sub load_canvas()
%>
<canvas>
...
</canvas>
<%
End Sub
%>
This is purely bare bones and is just designed to give you an idea of how you could approach it, so for example to call just the canvas part of the HTML you would use something like
canvas.asp?std=<%=session("7digit")%>&a=1
and either not pass &a at all (as DISPLAY_PAGE is the default) or pass
canvas.asp?std=<%=session("7digit")%>&a=0
to display the whole HTML.
You might also noticed I included
<% Call load_canvas() %>
inside the load_page() procedure, this is just for the situation where you might want the content of the canvas also rendered on the full pass and then changed later on via a partial pass using a=1 for example.
While the answer provided by #Lankymart demonstrates the desired page template and the correct layout of code which enables greater flexibility, the answer is a simple Ajax function.
setInterval(ajaxRequest, 15000);
function ajaxRequest() {
$.ajax({
type: 'GET',
url: 'xmlUpdateScript.asp',
data: {
7digit: "<%=session("7digit")%>"
}
});
}
The Ajax request executes the 'xmlUpdateScript.asp' and returns the next set of coordinates which are placed inside the XML document and can be rendered to the map.
Related
So I've been trying to get this to work with Ajax and JQuery, but I can't seem to get it. I'm new to both of these. Sorry if this is trivial, I've been searching and working off previous answers for awhile now.
Info:
I have a Jinja tag in my page html that I would like to update once per second:
<pre id="#system_info_tag">{{ system_info_text }}</pre>
The information is originally (and successfully) populated from my main python script in a larger function called get_system_info():
#app.route('/')
def root():
return render_template('system_info.html', system_info_text=get_system_info())
I would like the element to automatically reload once per second though, so I am trying to do that with JS as follows (which I thought would re-run my python function, as re-loading the page updates it):
function() {
setInterval(function() {
$("#system_info_tag").load(location.href + " #system_info_tag");
}, 1000);
});
which is loaded in my html file with:
<script src="static/js/update_refresh.js"></script>
The page loads fine with the correct information, but the element doesn't auto-reload. Any help would be much appreciated.
main.py
#app.route('/')
def root():
return render_template('system_info.html', system_info_text=get_system_info())
#app.route("/sys_info.json")
def system_info(): # you need an endpoint on the server that returns your info...
return get_system_info()
templates/system_info.html
<script src="https://code.jquery.com/jquery-3.2.1.js"></script>
<div id="content">{{ system_info }}</div> {# this is the original system_info passed in from the root view #}
<script>
setInterval(function(){ // load the data from your endpoint into the div
$("#content").load("/sys_info.json")
},1000)
</script>
I think anyway
The self-invoking function you've wrapped your script in isn't being called. It should be:
(function() {
// your code
})();
Note the extra () at the end. That's what's actually calling that function that's defined inside the previous parenthesis.
Next, in your HTML, remove the # from your id on the <pre> tag. The # is only used in selectors, not actual attributes.
<pre id="system_info_tag">{{ system_info_text }}</pre>
Next, remove the space from the beginning of your anchor you're appending to the URL.
location.href + '#system_info_tag'
Finally, check your Network tab in your browser's dev tools to see if those load() requests are even firing. If they are, see which URL they're calling. There is a good chance they're hitting the wrong URL and won't load anything as a result.
I have an asp.net page and when a textbox is empty I need to hide the whole page from code behind. The problem is I have javascript and jquery code that is executed on document ready and gets data from some page controls and since the controls are not rendered this code fails and throws an exception.
At code behind i hide the whole page
// allPageTable is an html table
// with runat=server
this.allPageTable.Visible = false;
At Javascript I check if a textbox is null, if not so I run the code, else i don't. But mytxt is not defined so it enters into the if and fails.
if ($('#myTxt') != null) {
// My JQUERY / JS CODE
var data = $('#anotherTxt').val(); // Fails cause anotherTxt is not rendered
}
So I need a way to avoid javascript execution when the page is not rendered.
The selector $('#myTxt') will not return null when you control with id, myTxt, does not exists. You need to check the length of object returned by selector.
if ($('#myTxt').length > 0) {
// My JQUERY / JS CODE
var data = $('#anotherTxt').val(); // Fails cause anotherTxt is not rendered
}
First of all, You need this script executed on "documentReady", "onLoad" is not so necessary. To check if checkbox exists or not, You can use $('#myTxt').length > 0 because everything which is returned from jQuery selector mechanism is represented in array of elements, even if its one html element.
$(window).load executes after everything is loaded and html page has been rendered with css included. If your script will work on windows load then you'll obtain some "blink" effect. (disappear after everything is rendered)
var i = 0;
var interval = setInterval(function () {
i = i + 1;
if(typeof($('#myTxt')) != 'undefined') {
// do your stuff
clearInterval(interval);
}
}, 1000);
Don't if it's best approach, maybe someone else will post better one...
You could place your javascript code inside a Placeholder control and then set the visibility of that control the same way you set it for the html table. This way your script will not end up on the page. It needs some extra care to avoid "broken usages" of functions/variables but it's a general solution.
<table id="allPageTable" runat="server">
...
</table>
<%= "<script type=\"text/javascript\" language=\"javascript\">" %>
<asp:PlaceHolder runat="server" ID="PlaceholderJS">
javascript code here
</asp:PlaceHolder>
<%= "</script>"%>
.
this.allPageTable.Visible = PlaceholderJS.Visible = false;
I have different headers that I would like to loop through based on a timer which should be executed every time a page loads. Currently what I have works one time but then stops after it changes the header the first time. I am not very good with javascript and would appreciate it if someone could point me in the right direction.
Below is what I have in place currently.
In lib/Rotator.rb:
class Rotator
def self.header_rotator(number)
partials = ["header", "header2", "header3", "header4", "header5"]
random_header = partials[number]
return random_header
end
end
Then in the header section of application.html.haml I have:
var start_rotate = setTimeout(rotate, 5000);
function rotate() {
remote_function(:url => {:action})
$("#header").replaceWith('#{escape_javascript( render :partial => "shared/#{Rotator.header_rotator(rand(5))}")}')
start_rotate = setTimeout(rotate, 5000);
}
As I said this works fine but only rotates one time then stops.
Any help would be greatly appreciated!
This is less about js and more about understanding what is running where and when.
If you look at the HTML that is being rendered things should become clearer. That call to escape_javascript, render happens precisely once: when that string gets interpolated during the rendering of the main page load. So the second (and third, fourth, fifth...) times rotate() runs it is replacing the header with exactly the same HTML.
Assuming you are using jquery, the load method can do this:
$('#header').load('/some/server/path')
Don't forget to render without the layout when you respond to this request.
Lastly, are you sure you want to use Ajax at all? You could just load all the header variants up front and use JavaScript to show them in turn. (there are a number of jquery cycle or slideshiw plugins that do precisely this)
I want to display time on my page in real tics format like running on simple watch without
refresh the whole page.I am using rails 3.Give any idea
Yes interesting situation I think you should put your portion of display time in some partial and refresh it with jquery ajax call. So you need to refresh it with every second and also you can set frequency of that ajax call. Here is some code may be it help you.
Html code:
<div class="time-rect-container">
<%= render :partial => 'shared/time_portion' %>
</div>
Code of partial of time_portion. It just shows time.
<h1>System Time</h1>
<div class="time-detail"><p><%=#time%></p></div>
Controller code:
def give_time
#time = Time.now.strftime("%H:%M:%S ")
render :partial => 'shared/time_portion'
end
And refresh this partial by jquery ajax call and I set frequency of it for one second and you can change.
$(document).ready(function () {
setInterval(function () {
$('.time-rect-container').load('/dashboard/give_time');
}, 1000);
});
JS Clock
$(document).ready(function(){
$('some-selector').jsclock();
});
Let's say that I have a single page site, and I want to wait to load any content below the fold (using ajax) until the user clicks a link to go to that content on the same page. However, I don't want users who have JavaScript disabled to just not see any content below the fold. The whole reason to load the content with ajax is so that the initial page load is faster, so having the content load either way and then hide until the user clicks would be pointless. I'm sure it's possible to only load content if JavaScript is enabled, but is it possible to not load specific "static" or server-side generated content if JavaScript is enabled in the browser?
Is there any way to prevent specific static content from being loaded by the server on initial page load at all if JavaScript is enabled in the browser?
You might consider using the noscript tag.
<body>
<h1>Above the fold header</h1>
<video src="fancy-cat.mp4" ... />
<div id="below-the-fold">
<noscript>
<!-- Users with Javascript disabled get this content -->
<h2>My cat plays piano</h2>
<video src="piano-cat.mp4" ... />
<h2>My cat knows how to use the toilet</h2>
<video src="potty-cat.mp4" ... />
</noscript>
</div>
You can then use javascript to copy the contents of these <noscript> tags on page load and insert them into the DOM.
The innerHTML property of a noscript tag will return an encoded string of HTML. But you can use the handy dandy Encoder script to convert it to something the DOM will like.
<script src="http://www.strictly-software.com/scripts/downloads/encoder.js"></script>
<script>
$(window).load(function() {
// Copy the 'noscript' contents into the DOM
$("noscript").each(function() {
$(this).after(Encoder.htmlDecode($(this).html()));
});
});
</script>
</body>
Alternatively, if the "below the fold" content is really image/video heavy, you might just want to consider Lazy Loading the content.
If you want to avoid loading data in the case of a client with JS enabled, then you might have to combine server-side and client-side techniques.
This could be used as a rough guide. Disclosure - I've not tested any of this!
For example, if your site structure looked like this:
/
page1.jsp
fragment1_1.jsp
fragment1_2.jsp
page2.jsp
fragment2_1.jsp
fragment2_2.jsp
...
Then page1.jsp could look like this (apologies if you don't know JSP and jQuery, but this is mostly pseudo-code anyway):
<%!
// Define a method to help us import fragments into the current page.
// Conditional import of fragment based on isJSEnabled
void myImport (String fragment, boolean isJSEnabled, HttpServletResponse res) {
if (!isJSEnabled) {
// output fragment contents directly to response
String contents = // get contents of fragment
res.getWriter().write(contents);
}
}
%>
<%
// How to work out if JS is enabled on the server-side?
// Not sure it can be done. So need to be told by the browser somehow.
// Maybe a request parameter. So if param not present, assume no JS.
boolean isJSEnabled = (null != req.getParameter("js"));
%>
<html>
<head>
<script>
// Try and redirect to JS version of page as soon as possible,
// if we're not already using the JS version of the page.
// This code does not take into account any existing request parameters for
// the sake of brevity.
// A browser with JS-enabled that was incrementally downloading and parsing
// the page would go to the new URL.
if (window.location.href.indexOf("js=true") < 0) {
window.location.href += "?js=true";
}
</script>
</head>
<body>
<h1 class="fragment_header" data-fragment-id="fragment1_1">Fragment 1</h1>
<div>
<%
// Conditionally import "fragment1_1".
myImport("fragment1_1", isJSEnabled);
%>
</div>
<h1 class="fragment_header" data-fragment-id="fragment1_2">Fragment 2</h1>
<div>
<%
// Conditionally import "fragment1_2".
myImport("fragment1_2", isJSEnabled);
%>
</div>
<script>
// For each fragment header, we attach a click handler that loads the
// appropriate content for that header.
$(".fragment_header").click(function (evt) {
var header = $(evt.target);
// Find the div following the header.
var div = header.next("div");
if (div.children().length < 1) {
// Only load content if there is nothing already there.
div.load(header.attr("data-fragment-id") + ".jsp");
}
});
$("a").click(function (evt) {
// Stop the browser handling the link normally.
evt.preventDefault();
// Rudimentary way of trying to ensure that links clicked use the
// js=true parameter to keep us is JS mode.
var href = anchor.attr("href");
var isLocalHref = // logic to determine if link is local and should be JS-ified.
if (isLocalHref) {
href = href + "?js=true";
}
window.location.href = href;
});
</script>
</body>
</html>
A user browsing to page1.jsp would get the static version initially, though a JS enabled browser would switch to the JS enabled version as soon as possible.
As we attach click handlers to all the links, we can control the loading of the next page. If JS is switched off at some point, the js=true parameter will not be appended to each href and the user will revert to a static page.