Turbolinks, limit javascript to one page - ruby-on-rails

I am using highlight.js and applying this code to initialise the syntax highlighting for my code snippets on a blog app.
The following code is on my index.html page :
<script>
$(document).on('ready page:load', function() {
$('pre code').each(function(i, e) {hljs.highlightBlock(e)});
});
</script>
A code snippet should look like this originally:
<pre><code>A
B</code></pre>
And after applying the new style it turns into this:
<pre><code class=" hljs">A
B</code></pre>
The problem is that when I try to edit one of those posts on the edit.html page, in the editor I get the stylized version instead of the plain one, which I do not want. I want the new styles to be applied only to the index page. How can I make that happen?
I should mention I have generated a scaffold with all the included views: index, new, edit etc.
Also I have the jquery-turbolinks gem installed.
The problem goes this way: I load index.html and I get highlighted code. I navigate to edit.html and get highlighted code. I refresh the edit.html page and lose the highlight (which is how it should be).
--------------------------------------------EDIT-------------------------------------
Tried this and it did not work:
in my aplication.html.erb:
<body data-action="<%= action_name %>" data-controller="<%= controller_name %>">
in my index.html.erb
<script>
var data = $('body').data();
if (data.controller === 'posts' && data.action != 'edit'){
$(document).on('ready page:load', function() {
$('pre code').each(function(i, e) {hljs.highlightBlock(e)});
});
};
</script>

<body data-action="<%= action_name %>" data-controller="<%= controller_name %>">
You can then read this in your script:
$(document).on('page:change', function(){
var data = $('body').data();
if (data.controller === 'foo' && data.action === 'bar'){
};
});

Related

Ruby on Rails script not being loaded

In my ruby on rails application, I'm generating a view via an ajax call.
I'm using following piece of code.
$("#a_div_id").html("<%= escape_javascript(render 'index')%>");
And the view I'm trying to render is _index.html.erb:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
First Name: <input type="text" ng-model="firstName"><br>
Last Name: <input type="text" ng-model="lastName"><br>
<br>
Full Name: {{firstName + " " + lastName}}
</div>
<script>
alert('first');
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
alert('second');
$scope.firstName = "John";
$scope.lastName = "Doe";
});
alert('third');
</script>
When I render the view, I'm getting only first and third messages. However, when I add this piece of code into dashboard.html.erb rather than rendering it via the ajax code, it perfectly works.
In the first case, I'm getting the following error.
angular.min.js:6 Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.4.8/$injector/modulerr?p0=myApp&p1=Error%3A%2…ogleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.4.8%2Fangular.min.js%3A20%3A274)
at angular.min.js:6
at angular.min.js:38
at n (angular.min.js:7)
at g (angular.min.js:37)
at eb (angular.min.js:41)
at c (angular.min.js:19)
at yc (angular.min.js:20)
at Zd (angular.min.js:19)
at HTMLDocument.<anonymous> (angular.min.js:294)
at fire (jquery.self-bd7ddd3….js?body=1:3233)
I'm be at my wits' end, I couln't decide what I'm missing,
Any suggestions,
Thanks.
​
Can you try without escape_javascript.
Also put a debugger like this, this will put a break point when chrome executes the js.
debugger;
$("#a_div_id").html("<%= render 'index' %>");
That would help you see what exactly jquery is trying to add as HTML.
If this doesn't work,
Probably you should take the js in script tag and put it in some method and call that method after you have added index to dom.
$("#a_div_id").html("<%= render 'index' %>");
myMethodToRenderAngular();

Rendering a partial using ajax

It seems simple but my partial is not rendered in a view(dash.html.erb) using ajax.
routes.rb
match "users/dash" => "users#dash"
users controller
def dash
respond_to do |format|
format.js
end
end
dash.html.erb
<div id= "mydiv">This view is not shown using ajax.</div>
dash.js.erb
$('#mydiv').html('<%= raw escape_javascript render("cart_payment") %>');
My partial- _cart_payment.html.erb
<p>This is a partial.</p>
UPDATE:
users/index.html.erb
<script type= "text/javascript">
$.ajax({
url: "users/dash",
data: {
//params if needed
}
});
</script>
Please note that I am calling- users url in browser because ajax is called from here.
Is it not correct way or Am I missing something?
When you call the dash method remotely, it actually is executing the $('#mydiv').html... code. The problem is, your index.html.erb file has no <div id='mydiv'> to update in the first place.
If you replace your index.html.erb with this, it should work:
<div id='mydiv'></div>
<script type= "text/javascript">
$.ajax({
url: "users/dash",
data: {
//params if needed
}
});
</script>

Backbone & Jquery Mobile rendering styles not working - Written in CoffeeScript

I'm using backbone jquery mobile and coffee script to develop a simple twitter application. My problem is the jquery mobile styles are failing to render. My View is
class HomeView extends Backbone.View
constructor: ->
super
initialize: ->
#Twitter= new TwitterCollection
template: _.template($('#home').html())
render: ->
#loadResults()
loadResults: ->
#Twitter.fetch({
success: (data) =>
$(#.el).html(#template({data: data.models, _:_}))
error: ->
alert('Error!')
})
This works fine in terms of pulling information from Twitter, however when
$(#.el).html(#template({data: data.models, _:_}))
is within the fetch function, jquerys styles do not render. Can anyone show me how to refresh the styles? Help would be much appreciated!
For reference, the html template is:
<script type="text/template" id="home">
<div data-role="header" data-position="fixed">
<h1>TWITTER DATA</h1>
</div>
<div data-role="content">
<ul data-role="listview" data-inset="true">
<% _.each(data, function (row) { %>
<li><%= row.get('text') %></li>
<% }); %>
</ul>
</ul>
</div>
Ok, I fixed it by adding ".listview('refresh').trigger('create');" to the end of
$(#.el).html(#template({data: data.models, _:_}))
When the fix is applied afterwards (after the view page has been rendered and displayed by $.mobile.changePage()) the user gets an unpleasant side-effect: the view flickers due to the change of style applied by jquery mobile.
My solution to the problem was to trigger custom event from the view once the dynamic rendering is complete and bind the $.mobile.changePage() to that event. This causes the output to be "buffered" until complete and then styled altogether.
Here's an example:
In the initialize function of my view I have code waiting for an event to be fired by the model/collection when fetched and a function to render the dynamic part of the html:
window.MyView = Backbone.View.extend({
// some other code here
initialize: function() {
this.listenTo(this.collection, "fetchCompleted:CollectionName", this.renderRows);
},
renderRows: function (eventName) {
$(this.el).find('div[class="content-primary"]').html(this.template_ul({data: this.collection}));
this.trigger( 'view:ready' );
},
//...
... then in the router I have the following code for the changePage():
myViewObject.on( 'view:ready', function() {
$.mobile.changePage($(next.el), {changeHash:false, transition: transition});
});

many draggable to many droppable

I am developing an app having UI which is used for mapping fields (Source => Destination).
These fields would appear in UL -> LI -> DIV
The lists are going to be created dynamically by PHP.
Source fields are draggable with revert:true, where as Destination fields (droppable) would accept source field. I know the accept : "#divsource"
I am able to make many div's draggable, but my problem is how to define many LI->Div as droppable.
At then end the drop event would call ajax and that I can handle as well.
I am new to jQuery and whatever I have learned till now is with this task is all I know. But, my quick learning ability is not a problem.
Please help with some example.
thanks
Wikki
Below code is something I have been playing with. I know it's bit far off from what eventually it should look like:
<script type="text/javascript">
$(document).ready(function(){
$('.srcfield').draggable({
revert: true,
helper: "clone"
});
$('#destinationfeilds').droppable({
accept : ".srcfield",
over: function(){
$(this).removeClass('out').addClass('over');
},
out: function(){
$(this).removeClass('over').addClass('out');
},
drop: function(ev, ui){
//var answer = confirm('Delete this item?');
var theTitle = $(ui.draggable).attr("title");
$(this).html("<u>"+theTitle+"</u><br/> is mapped!");
//$(this).removeClass('over').addClass('out');
//alert(theTitle);
}
});
});
</script>
</head>
<body>
<div id="destinationfeilds" class="out">
<span>Destination</span>
</div>
<div id="destinationfeilds" class="out">
<span>Destination</span>
</div>
<div id="sourcefields">
<div class="srcfield" title="First Name"><span>First Name</span></div>
<div class="srcfield" title="Last Name"><span>Last Name</span></div>
<div class="srcfield" title="Age"><span>Age</span></div>
</div>
</body>

how to close view template in Rails 3

I have opened the view template as popup by using the following code:
<%= link_to 'New User', "/users/new", :method => :get, :target => "_blank" %>
controller code:
def new
render :layout => false
end
the new.html.erb is having few textboxes and buttons as Save and Cancel
My problem is how can i close the popup upon clicking Save or Cancel button?
Thank u,
Sudhir C.N.
This a more a javascript question rather than one specific to Rails.
Your Cancel button is easy enough, something like:
<html>
<script>
function CloseWindow() {
ww = window.open(window.location, "_self");
ww.close();
}
</script>
<button type="button" onclick="CloseWindow();">Cancel</button>
</html>
(stolen from http://snippets.dzone.com/posts/show/267)
Your submit button shouldn't change. It will need to POST to your controller as normal. The successful response rendered by the controller should display a "Success" message in the flash and could then close the window automatically after, say, three seconds:
<script>
setTimeout( function() { CloseWindow(); }, 3000);
</script>
This is a pretty simple solution. Maybe consider investigating some popup libraries for either prototype or jquery (depending on the library you're using). Not sure whether modern popup blockers render these D.O.A. though. Your target="_blank" approach should play nice with popup blockers.
Edit: if you're using jquery maybe consider something like the modal dialog: http://jqueryui.com/demos/dialog/#modal-form
You will need to do it with javascript. After the user saves you can respond with another view that sends this:
<script type="text/javascript">
window.close();
</script>

Resources