Disqus comment count doesn't show up with Turbolinks - ruby-on-rails

I created a simple Rails 4 cms. There is an article list with disqus comment count on the homepage and also on the category and archive pages.
The disqus code responsible for displaying comment count is just before the closing body tag.
When I enable Turbolinks the comment count shows up only on initial page load. If I visit an article then go back to the article list, there is no comment count. If I reload the page the comment count is there though.
I tried to add jquery.turbolinks gem.
I tried to edit the disqus code so it executes on page:change or page:load.
I tried to put it inside the head.
I tried to add disqus identifiers to the code.
UPDATE:
Here is what I am trying right now (edited my shortname):
var disqus_shortname = 'my_shortname'; // required: replace example with your forum shortname
/* * * DON'T EDIT BELOW THIS LINE * * */
($(document).on('page:change',function () {
var s = document.createElement('script'); s.async = true;
s.type = 'text/javascript';
s.src = '//' + disqus_shortname + '.disqus.com/count.js';
(document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s);
})());
This way the comment count shows up on initial page load and also when I visit the post list pages the first time. But when I visit them the second time the comment count doesn't show up. Tried this with page:load and page:update also without results.
Anyone encountered this problem?

I couldn't make this work with the default disqus comment count code, so I used the disqus api instead which works like a charm:
$(document).on('page:change', function () {
var disqusPublicKey = "MY_PUBLIC_KEY"; // Replace with your own public key
var disqusShortname = "my_shortname"; // Replace with your own shortname
var urlArray = [];
$('.comment-link-marker').each(function () {
var url = $(this).attr('data-disqus-url');
urlArray.push('link:' + url);
});
$.ajax({
type: 'GET',
url: "https://disqus.com/api/3.0/threads/set.jsonp",
data: { api_key: disqusPublicKey, forum : disqusShortname, thread : urlArray },
cache: false,
dataType: 'jsonp',
success: function (result) {
for (var i in result.response) {
var countText = " comments";
var count = result.response[i].posts;
if (count == 1)
countText = " comments";
$('a[data-disqus-url="' + result.response[i].link + '"]').html(count + countText);
}
}
});
});

This is a Turbolinks issue. With Turbolinks pages will change without a full reload, so you can't rely on DOMContentLoaded or jQuery.ready() to trigger your code.
Try this: add jquery.turbolinks gem, update application.js and restart the server.

Related

Rails 3: update URL params with AJAX request

I have a filter and a list of products (id, name, creation_date).
I can filter by id, name or creation_date. With an AJAX request I update a content div... but obviously the URL not change.
How can I append params to URL? For example:
localhost:3000/dashboard/catalog?name=radio&?date_creation=23-06-2013
I know that history.pushState(html5) exists... but I need that my app works in html4 browsers like IE9.
I tried Wiselinks (https://github.com/igor-alexandrov/wiselinks) which it uses History.js but it doesn´t use AJAX request.
Any ideas?
thanks
Finally I follow those RailsCasts tutorials:
http://railscasts.com/episodes/240-search-sort-paginate-with-ajax?language=es&view=asciicast
http://railscasts.com/episodes/246-ajax-history-state?language=es&view=asciicast
You are doing some AJAX call means, you must have invoked the AJAX part on radio button change
So I am assuming, you have done it using by radio button and the radio button name is 'choose_product'
You can add a hidden field in your view, where you can store your current date.
<div id='parentDiv'>
<%= hidden_field_tag 'current_date', Time.now.strftime('%d-%m-%Y') %>
Your radio button code
</div>
In the javascript add the following code. It is just a sample not complete solution.
$(document).ready(function(){
var showProducts = function(){
$("#parentDiv").on('click', "input[name='choose_product']", function(){
var ajax_url = 'localhost:3000/dashboard/catalog';
var url_param = '';
switch($(this).val()){
case 'creation_date':
var param_date = $('#current_date').val();
url_param = '?name=radio&date_creation=' + param_date;
break;
case 'name':
// Your code goes here
default:
//Your code goes here
}
// Here you will get the modified url dynamically
ajax_url += url_param
$.ajax({
url: ajax_url,
// your code goes here
});
});
}
showProducts();
});
A lot of time has passed, but it may be useful.
The code is also updated so if you have more then one ajax\remote link you will be able to merge the params of multiple urls.
Based on user1364684 answer and this for combine urls.
# change ".someClassA" or "pagination" to the a link of the ajax elemen
$(document).on('click', '.someClassA a, .pagination a', function(){
var this_params = this.href.split('?')[1], ueryParameters = {},
queryString = location.search.substring(1), re = /([^&=]+)=([^&]*)/g, m;
queryString = queryString + '&' + this_params;
#Creates a map with the query string parameters
while m = re.exec(queryString)
queryParameters[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
url = window.location.href.split('?')[0] + "?" + $.param(queryParameters);
$.getScript(url);
history.pushState(null, "", url);
return false;
});
# make back button work
$(window).on("popstate", function(){
$.getScript(location.href);
});

Autorefresh in Dashboard using ActiveAdmin

I'm developing an application in Rails wich acts as a network and apps monitor. I'm using Active Admin Dashboard as a main page, showing the status of every server and some apps in my network. I'd like to configure the dashboard page to autorefresh every x minutes, but I don't know where to configure this setting, because I don't have full control of the html rendered by the dashboard. Have anyone managed to do it?
Thanks
In config/initializers/active_admin.rb you can register javascripts:
config.register_javascript "/javascripts/admin-auto-refresh.js"
Then create a admin-auto-refresh.js that does exactly that.
You'll also want to register admin-auto-refresh.js in your config/environments/production.rb
config.assets.precompile += "admin-auto-refresh.js"
UPDATE:
Added some code to refresh the page after 5 seconds. Add this to /javascripts/admin-auto-refresh.js
$(function() {
setTimeout(location.reload(true), 5000);
})
Here's the final code, thanks very much to #JesseWolgamott.
$(function() {
var sPath = window.location.pathname;
var sPage = sPath.substring(sPath.lastIndexOf('/') + 1);
if (sPage == 'admin'){
setTimeout("location.reload(true);", 10000);
}
})
Below is code that will refresh without the page flashing. It is enabled by having at least one element in the page with a class tag of needs_updating. Include this code snippet in any javascript that is loaded and then add the tag any where on the page.
The only downside is this ONLY updates the html body of the page.
For example
show do |my_model|
...
if my_model.processing?
row :status, class: 'needs_updating' do
'we are working on it...'
end
else
row :status do
'ready'
end
end
....
end
so if the model is still processing then you get the class tag 'needs_updating' which will cause the below javascript to be invoked every 10 seconds
jQuery(document).ready(function($) {
if ($('.needs_updating').length > 0) {
console.log("we need some updating soon");
var timer = setTimeout(function () {
console.log("re-loading now");
$.ajax({
url: "",
context: document.body,
success: function(s,x) {
$(this).html(s);
if ($('.needs_updating').length == 0) {
clearInterval(timer);
}
}
});
}, 10000)
}
})

jquerymobile and AJAX

seems to me that I didn't fully understand the concept behind jquerymobile, because I have no idea how to solve this issue.
What I want to do is load some HTML Content via AJAX, according to location.hash, put it into a new page and load this page.
But if I create a page myself by using the pagebeforechange event, jquerymobile just ignores it, creates its own div and my content won't be displayed.
How do I have to do it?
Edit:
This is how I am currently doing it, but it wont't work.
$(function() {
getPageContent(top.location.href, false);
$(document).bind( "pagebeforechange", function( e, data ) {
getPageContent(data.toPage, true);
});
});
function getPageContent(pageUrl, changedPage) {
var re = /.*\/#(.*)/;
var result;
result = re.exec(pageUrl);
window.page = result[1].substr(0,3);
window.id = result[1].substr(3);
window.ajaxUrl = "request.php?page="+window.page+"&id="+window.id;
$.ajax({
url: window.ajaxUrl,
success: function(data) {
if(data.error) {
alert(data.error);
}
else if(data.data) {
if(changedPage) {
changePage(data.data));
}
else {
$('#content[role="main"]').html(atob(data.data));
setupPage();
}
}
else {
alert("UNKNOWN ERROR: "+data);
}
}
});
}
function changePage(html) {
var div = "<div></div>";
var newPage = $(div).attr("data-role", "page").attr("data-url", window.page+window.id);
var header = $(div).attr("data-role", "header");
var content = $(div).attr("data-role", "content");
var footer = $(div).attr("data-role", "footer");
$("body").append(newPage);
newPage.append(header, content, footer);
content.html(html);
newPage.page();
}
Complete edit of the whole answer:
First. Set your body id to id=body. Then when you want to load the new page and change to it, use an ajax call like this:
$.get(window.ajaxUrl, function(data){
$('#body').append("<div id='newPage' data-role='page'></div>"); //Creates a new page.
$('#newPage').html(data); //Loads the html content into the new page.
$.mobile.changePage('#newPage'); //Navigates to the new page.
}
This sends an ajax call with the method GET to the url found in your window.ajaxUrl. If the call is successful, it creates a new page named "newPage", and fills it with the data received from the ajax call. Then redirects to the newly created page.
This jsFiddle shows the basics of how it works. However, it doesn't use any ajax call.
You have to refresh the page with jQueryMobile :
$("#your-page").trigger("create");
--Edit
<script>
$("#thepage").live("pageshow", function(){
$("#thepage).trigger("create");
});
</script>
Change the content of #thepage before 'pageshow' event
It does this for you automatically - just make a regular link to the page and jquery mobile will shwo the loading spinner, load it in the background via ajax, then transition to the new page.
Make sure all your pages are decide with unique IDs and data-role='page'. Check out the start guide here:
http://jquerymobile.com/demos/1.1.0/docs/about/getting-started.html

jquery ajax progress bar

I am trying to setup a ajax progress bar for my site. Sometimes multiple ajax calls are chained together Here is my code
var xhrs = [];
function ajaxCall(){
xhr = $.ajax({
...other ajax code...
success: function(data){
anotherAjaxCall(data);
}
});
xhr.onreadystatechange = reportStatus;
xhrs.push(xhr);
}
function anotherAjaxCall(data){
xhr = $.ajax({
...other ajax code...
});
xhr.onreadystatechange = reportStatus;
xhrs.push(xhr);
}
...lots more functions that make ajax calls....
function reportStatus(){
var overallPercent = 0;
for(i = 0; i < xhrs.length; i++){
overallPercent += (xhrs[i].readyState * 20);
}
var percent = overallPercent / xhrs.length;
alert(percent + " = " + overallPercent + " / " + xhrs.length);
//update progress bar
updateProgressPercentage(percent);
}
From the alert in the reportStatus function all happens is the first ajax call gets to readyState of 4 and it calls the second function that doesn't run the ajax call inside of it. Does anyone have any idea why the second function runs but that ajax call inside doesn't. Thanks in advance.
Tim
I believe you have the syntax wrong for the AJAX call with no parameters. Try changing
xhr = $.ajax({});
to
xhr = $.ajax();
The documentation says this is how you're supposed to call the function with no parameters: http://api.jquery.com/jQuery.ajax/
They changed it to use what they call jqXHR objects. These expose readyState, but do not allow for arbitrary setting of other values. See jQuery.ajax for more details. What you can try, however, is using the "xhrFields" option that was added in 1.5.1 to add your onreadystatechange callback.
I found out the answer. To do this i need to user jQuery 1.3.2. Version 1.4.2 must change the xhr somehow, version 1.5.1 completely changes it. Thanks for the responses everyone.

.Ajax with jQuery and MVC2

Im trying to create an ajax (post) event that will populate a table in a div on button click.
I have a list of groups, when you click on a group, I would like the table to "disappear" and the members that belong to that group to "appear".
My problem comes up when using jQuery's .ajax...
When I click on the button, it is looking for a controller that doesnt exist, and a controller that is NOT referenced. I am, however, using AREAS (MVC2), and the area is named Member_Select where the controller is named MemberSelect. When I click on the button, I get a 404 stating it cannot find the controller Member_Select. I have examined the link button and it is set to Member_Select when clicked on, but here's the ajax call:
$.ajax({
type: "POST",
url: '/MemberSelect/GetMembersFromGroup',
success: function(html) { $("#groupResults").html(html); }
});
I havent been able to find any examples/help online.
Any thoughts/suggestions/hints would be greatly appreciated.
Thanks!
Have you tried navigating to /MemberSelect/GetMembersFromGroup to see what you get? - if it's 404'ing it's because the route can't be matched to a controller/ action.
I've not used the new areas functionality, but I'm not sure that the URL you've got is correct...I would have thought it would have been /AREANAME/MemberSelect/GetMembersFromGroup...but I could be wrong..!
When I did this, it worked fine. I didn't use POST and I don't know what AREAS means.
$("#item").autocomplete({
source: function(req, responseFn) {
addMessage("search on: '" + req.term + "'<br/>", true);
$.ajax({
url : ajaxUrlBase1 + "GetMatchedCities/" + req.term,
cache : false,
type : "GET", // http method
success : function(msg){
// ajax call has returned
var result = msg;
var a = [];
if (result !== null){
for(var i=0; i < result.length; i++) {
a.push({label: result[i].prop1, id: result[i].prop2});
}
}
responseFn(a);
}
});
}
});
Use:
area_name/controller_name/action_name
Instead of doing $.ajax I would use jQuery Form Plugin.
and have my form set as:
Html.BeginForm("Index","AdminArea/Admin",FormMethod.Post,
new { id="form-user", name="form-user"})
To use jQuery Form Plugin have a look here:
http://arturito.net/2010/12/02/asp-net-mvc2-jquery-form-post-tutorial/
You cold save your url in a Hidden Form element in (Html.HiddenForm()) and use the #id javascript operator to retrieve it. Just found this out today.

Resources