I am working on integrating jquery pageless plugin with a rails application. The pageless plugin works seamlessly when i write out the javascript. The issue lies in trying to have a javascript method issued upon complete. What i am trying to accomplish is having a helper method to generate it, but it renders the javascript with quotes around my callback method which then generates an error in the javascript
Uncaught TypeError: Object reloadMasonry has no method 'call'
here is the helper method code
def pageless(total_pages, url=nil, container=nil) opts = {
:totalPages => total_pages,
:url => url,
:loaderMsg => 'Loading more results',
:loaderImage => image_path("load.gif"),
:complete => "reloadMasonry"
}
container && opts[:container] ||= container
javascript_tag("$('#masonry-container').pageless(#{opts.to_json});")
end
This is the produced javascript code
<script type="text/javascript">
//<![CDATA[
$('#masonry-container').pageless({"totalPages":3,
"url":"/articles",
"loaderMsg":"Loading more results",
"loaderImage":"/assets/load.gif",
"complete":"reloadMasonry"});
//]]>
</script>
the javascript results in having quotes around the reloadMasonry callback function
reloadMasonry = function(){
$('#masonry-container').masonry('reload');
}
if i copy the exact javascript produced, and simply remove the double quotes around the javascript callback method ( reloadMasonry ) in this case, everything works seamlessly.
does anyone have any suggestions.
Related
We have hosted jsreport node application on EBS. We created template and using css and javascripts from a static website(hosted internally). In the external javascript file we are using variables similar to what jsreport requires i.e. {{variablename}} which does not work. When we add the javascript inline in the template it works.
We know there should be some other way around to specify this but could not find it.
This won't work. jsreport templating engines only compile and process the html output, not the referenced scripts.
However you can try this approach:
Put a placeholder in a template content where you want to put external script. Lets say we want to put inline jquery
<script>
$$$myScript
</script>
<script>
$(() => {
alert('yes I have jquery inlined')
})
</script>
Create jsreport custom server script which downloads your external script, in this case jquery, and replace the placeholder with its content
var getReq = require('request').get
function beforeRender(req, res, done) {
getReq('https://code.jquery.com/jquery-3.1.0.min.js', (err, res, body) => {
req.template.content = req.template.content.replace('$$$myScript', body.toString())
done()
})
}
The script will run before the templating engines are executed therefore you can use templating engines tags inside it now.
playground live demo here
I am trying to integrate SMS in my web application. I added the code in my last line of function:
header("Location:http://www.bulksmsservice.co.in");
But its not redirecting to that site. (Function is in model page)
If you use the PHP Command header, be sure there is no output before you call it. To do it in the Yii view file is too late. But to do this in the Yii Controller is not a good Practice. Better would be $this->redirect() or in the view File use Javascript Code:
<script>
window.location ='http://www.bulksmsservice.co.in';
</script>
i added my function sendbulk in controller and replace code with below
function sendbulk($num,$msg)
{
$link = "http://www.bulksmsservice.co.in/api/sentsms.php?username=****&api_password=*******&to=".$no."&priority=2&sender=******&message=".$msg. "&unicode=1";
$ctx = stream_context_create(array(
'http' => array(
'timeout' => 1
)
)
);
file_get_contents($link, 0, $ctx);
}
Now it's working perfectly for single messages and multiple messages :)
I'm having a bunch of problems getting jQuery's .on to work with my Rails ajax link.
Specifically, I've got this link:
<div id="item_7_tools" class="item_tools">
<a rel="nofollow" id="book_item_7" data-remote="true" data-method="post" class="book_link" href="bookings">Book this item</a>
</div>
I've trimmed some of the text in the HTML, but suffice to say that that, and my controller response work.
I click "Book this item", it goes off to the controller, the controller does its magic, and sends back my partial that replaces the contents of that div.
So I'm now trying to replace the contents with an ajax spinner while the loading is working, and that's where its going pear-shape.
I'm trying this initial bunch of jQuery code just to make sure I've got my javascript working:
$('div.item_tools')
.on('click', 'a', function() {
console.log("clicky click")
})
.on('ajax:beforeSend', "a", function() {
console.log('the a in div.item_tools is sending its ajax command');
})
.on('ajax:complete', "a", function() {
console.log('ajax request completed');
})
My understanding of that, is that when I then click any link (a) that lives within an element with the item_tools class, it will bubble up to this function, and then log the message into the console. Similarly, a link that has triggered an ajax request will get the same treatment...
(And assuming I can get that to work, then I'll go to work doing the ajax loader spinner).
The behaviour I'm seeing instead, is that when I click the link, there are no messages appearing in my console (trying this on both firefox and chrome), and my ajax link goes off and does its stuff correctly. Just completely ignoring the javascript...
Is this because my clicking the ajax link somehow has blocked the click event from bubbling up? I know that there's a way to do that, but I don't think I've done it anywhere knowingly. Unless OOTB rails/ujs does that?
So my questions:
Is there a way to tell what has had a binding attached to it?
What am I doing wrong with my javascript?
Thanks!
I use this all the time... and it seems to work fine.
Have you tried adding one that's .on('ajax:success')?
Besides that try putting the . for each line on the previous line...? It's possible that it gets to $('div.item_tools') and then auto-inserts a semi-colon as per javascript's standard... Although if that were the case I'd expect it to give you a JS error about the . on the next line. In any case try changing it to:
$('div.item_tools').
on('click', 'a', function() {
console.log("clicky click")
}).
on('ajax:beforeSend', "a", function() {
console.log('the a in div.item_tools is sending its ajax command');
}).
on('ajax:complete', "a", function() {
console.log('ajax request completed');
})
If worse comes to worse try just doing:
$("a").on("ajax:success", function(){
console.log('ajax:success done');
})
And see if it works without the event delegation...
Then change it to this:
$(document).on("ajax:success", "a", function(){
console.log("ajax:success with delegation to document");
})
And see if delegation works all the way up to document instead of just your item_tools
Are you sure that you've named everything right? it's div.item_tools a in your markup?
Turns out that the javascript was being triggered before the DOM had loaded, which meant that stuff weren't being bound...
$(function () {
$('div.item_tools')
.on('click', 'a', function itemToolsAjaxy() {
console.log("clicky click");
})
.on('ajax:beforeSend', "a", function() {
console.log('the a in div.item_tools is sending its ajax command');
$(this).closest('div').html('<img src=/assets/ajax-loader.gif>');
})
});
Added the $(function()) right at the beginning and it delayed the binding until after the DOM had loaded, and then it started working.
Figured this out by using the Chrome developer tools to stick a break on the div.item_tools selector and watched as the browser hit that even before the DOM had been loaded. /facepalm
(I removed the .on('ajax:complete') callback, because it turns out that there's a known limitation where the original trigger element no longer exists because it had been replaced, so there's nothing to perform the callback on. Not relevant to my original problem, but I thought I'd mention it.)
As far as i'm aware, you can either do ajax stuff 2 ways:
By using :remote => true
By using jQuery's $.ajax (or $.post).
With number 2, make sure to change your href='#'
My suggeston is to remove the :remote => true and manually make a jQuery ajax call. That way you can use beforeSend, complete, etc.
If i'm way off track here, someone please help clarify things for me as well.
I have a Rails app with Haml views. Now I want to add AngularJS to some parts of the application, but the problem is that the Haml views are rendered server-side and the AngularJS code is not working, because it is rendered client-side.
Let's say I have just this in my index.html.haml:
!!!
%html{"ng-app" => "Test"}
%head
%script{:src => "http://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.js"}
:javascript
function Clock($scope) {
$scope.currentTime = new Date();
}
%title Welcome to AngularJS
%body
%h1 Hello, World.
%p{"ng-controller" => "Clock"}
The current time is {{currentTime | date:'h:mm:ss a'}}.
So currently, it's just printing out everything within the curly brackets without actually processing it. There are solutions but they for situations where your complete view is replaced by an AngularJS template. I want to use AngularJS mainly for small bits of functionality in my Rails app. Any ideas how to solve this?
John,
I have edited your code a bit here: http://codepen.io/anon/pen/vKiwH
%html{"ng-app"=>true}
%p{"ng-controller" => "clock"}
The current time is {{currentTime | date:'h:mm:ss a'}}.
and the javascript is:
function clock($scope) {
$scope.currentTime = new Date().getTime();
}
In my Rails project, in which I am using Coffeescript, I want to be able to do something like this in a view:
f.text_area :content, :size => "77x4", :oninput => 'Helpers.expandTextarea(300)'
This would call a coffeescript function that would expand the textarea when required. My problem is that I can't seem to properly namespace the coffeescript to get this to work. I tried to do it like this
# site.js.coffee
Helpers =
expandTextarea: ->
alert "function found!"
This doesn't work. Trying to call Helpers in the browser console will throw an undefined error. My question is this:
What code would I use in site.js.coffee to achieve the namespacing I want?
You could manually put Helpers into the global namespace:
window.Helpers =
expandTextarea: ->
alert "function found!"
Then you should be able to say Helpers.expandTextarea(300) anywhere you want. Assuming, of course, that site.js.coffee is included on every page.
CoffeeScript files are wrapped in functions by default:
(function() { /* compiled CoffeeScript goes here */ })();
to avoid polluting the global namespace. You can supply options to the CoffeeScript compiler to not wrap like this but you're better off explicitly putting global things into window.