Render partial from jQuery ruby on rails - ruby-on-rails

I wanted to render a partial that contains a form inside of view from application js, I am reading the event of attached button without submitting because I need to process the headers of a file CSV before doing submit.
This is the function:
$(document).ready(function () {
$("#attached_attached_csv").change(function (e) {
if (e.target.files != undefined) {
var reader = new FileReader();
reader.onload = function (e) {
// this line isn't working - I try of many ways, but none are working
$("#text").html("<%= j render partial: 'layouts/form') %>".html_safe);
};
reader.readAsText(e.target.files.item(0));
}
return false;
});
});
I see also how any people using ajax, but I don't know how to use this for the trigger event of an attached button without submitting, I prob sending without html_safe but I obtain the string:
<%= j render partial: 'layouts/form') %>
My partial is "layouts/form", which is a file with extension html.erb. here share where I found the code for handle the event http://jsfiddle.net/FSc8y/2/, but it's not important the most important for me its render the embedded ruby form. Thanks in advance.

You can use rails syntax in your javascript files by adding .js.erb extension to the file name like my_file.js.erb.

Related

updating javascript_include_tag dynamically on show.html.erb

So here is the scenario:
I have 4 entries in a database, they are 4 map routes.
Each map route has its own XML file containing the co-ordinates of each route, I have written an ajax function to pull the data from the xml and write it to a google map
this is an extract from the code
$.ajax({
type: 'GET',
url: '/route4.gpx',
dataType: 'xml',
success: function(track) {
var grids = [];
var bounds = new google.maps.LatLngBounds ();
$(track).find('trkpt').each(function() {
var lat = $(this).attr('lat');
var lon = $(this).attr('lon');
var point = new google.maps.LatLng(lat, lon);
grids.push(point);
bounds.extend(point);
I have this code saved into 4 javascript files where the URL line is different on each (route1.gpx, route2.gpx etc)
What I want to do is on the show.html.erb file is to change the javascript_include_tag to update to the relevant javascript file
So the show.html.erb tags look like the following
<%= javascript_include_tag "http://maps.google.com/maps/api/js?sensor=false" ,"http://code.jquery.com/jquery-1.9.1.min.js", "/js/script1.js" =%>
what I would like is the last reference to change when I visit a different page so
when linked to show/1 the javascript file would be "/js/script1.js"
when linked to show/2 the javascript file would be "/js/script2.js"
when linked to show/3 the javascript file would be "/js/script3.js"
when linked to show/4 the javascript file would be "/js/script4.js"
So is there anyway to write into the javascript_include_tag to achieve this?
All help/suggestions/comments appreciated
You could interpolate the string passed to javascript_include_tag, pass it as an instance variable etc, but I think you are heading down the wrong track. I would have a single javascript function that takes the url to make the ajax request to as a parameter.
You would then call that function with that parameter. You've got several choices here.
You could have a script tag where you generate the function call dynamically, ie you do something along the lines of
$(function(){
my_function(<%= #url.to_json %>)
})
You could have a script tag where you set a window property with the url and use that later:
window.map_url = <%= #url.to_json %>
and then somewhere else
$(function(){
my_function(window.map_url)
})
You could have the function call be part of the static javascript, but have it pull its parameters either from the data attribute of some relevant DOM element
$(function(){
my_function($('some_element').data('url'))
})
I'd usually go for the latter
Why don't you interpolate?
<%= javascript_include_tag "http://maps.google.com/maps/api/js?sensor=false" ,"http://code.jquery.com/jquery-1.9.1.min.js", "/js/script#{controller_variable_for_example_id}.js" =%>

Jquery calls not working in $viewContentLoaded of Angular

Unable to call jquery functions in $viewContentLoaded event of Angular controller, here is the code for the same.
$scope.$on('$viewContentLoaded', function() {
jQuery.growlUI('Growl Notification', 'Saved Succesfully');
jQuery('#category').tree()
});
Is any configuration required here?? I tried even noConflict(); var $jq = jQuery.noConflict();
Does it require any other configuration?
Thanks,
Abdul
First thing first, don't do DOM manipulation from controller. Instead do it from directives.
You can do same thing in directive link method. You can access the element on which directive is applied.
Make sure you load jquery before angularjs scripts, then grawlUI, three, angularJS and finally your application script. Below is directive sample
var app = angular.module("someModule", []);
app.directive("myDirective", function () {
return function (scope, element, attrs) {
$.growlUI('Growl Notification', 'Saved Succesfully');
element.tree();
};
});
angularjs has built in jQuery lite.
if you load full jquery after angular, since jQuery is already defined, the full jquery script will skip execution.
==Update after your comment==
I reviewed again your question after comment and realised that content which is loaded trough ajax is appended to some div in your angular view. Then you want to apply element.tree() jquery plugin to that content. Unfortunately example above will not work since it is fired on linking which happened before your content from ajax response is appended to element with directive I showed to you. But don't worry, there is a way :) tho it is quick and dirty but it is just for demo.
Let's say this is your controller
function ContentCtrl($scope, $http){
$scope.trees=[];
$scope.submitSomethingToServer=function(something){
$http.post("/article/1.html", something)
.success(function(response,status){
// don't forget to set correct order of jquery, angular javascript lib load
$.growlUI('Growl Notification', 'Saved Succesfully');
$scope.trees.push(response); // append response, I hope it is HTML
});
}
}
Now, directive which is in controller scope (it uses same scope as controller)
var app = angular.module("someModule", []);
app.directive("myDirective", function () {
return function (scope, element, attrs) {
scope.$watch("trees", function(){
var newParagraph=$("<p>" + scope.trees[scope.trees.length-1] + "</p>" ); // I hope this is ul>li>ul>li...or what ever you want to make as tree
element.append(newParagraph);
newParagraph.tree(); //it will apply tree plugin after content is appended to DOM in view
});
};
});
The second approach would be to $broadcast or $emit event from controller (depends where directive is, out or in scope of controller) after your ajax completes and you get content from server. Then directive should be subscribed to this event and handle it by receiving passed data (data=content as string) and do the rest as I showed you above.
The thing is, threat that content from ajax as data all the way it comes to directive, then inject it to element in which you want to render it and apply tree plugin to that content.

jQuery UI in Backbone View adds elements, but doesn't respond to events

I'm building an app in which I'm using Django on the backend and jQuery UI/Backbone to build the front. I'm pulling a Django-generated form into a page with jQuery.get() inside of a Backbone View. That part works fine, but now I want to add some jQuery UI stuff to the form (e.g. a datepicker, some buttons that open dialogs, etc). So, here's the relevant code:
var InstructionForm = Backbone.View.extend({
render: function() {
var that = this;
$.get(
'/tlstats/instruction/new/',
function(data) {
var elements = $(data);
$('#id_date', elements).datepicker();
that.$el.html(elements.html());
}
};
return this;
}
});
The path /tlstats/instruction/new/ returns an HTML fragment with the form Django has generated. What's happening is that input#id_date is getting the hasDatePicker class added and the datepicker div is appended to my <body> element (both as expected), but when I click on input#id_date, nothing happens. No datepicker widget appears, no errors in the console. Why might this be happening?
Also, somewhat off-topic, but in trying to figure this problem out on my own, I've come across several code examples where people are doing stuff like:
$(function() {
$('#dialog').dialog(...);
...
});
Then later:
var MyView = Backbone.View.extend({
initialize(): function() {
this.el = $('#dialog');
}
});
Isn't this defeating the purpose of Backbone, having all that jQuery UI code completely outside any Backbone structure? Or do I misunderstand the role of Backbone?
Thanks.
I think your problem is right here:
$('#id_date', elements).datepicker();
that.$el.html(elements.html());
First you bind the datepicker with .datepicker() and then you throw it all away by converting your elements to an HTML string:
that.$el.html(elements.html());
and you put that string into $el. When you say e.html(), you're taking a wrapped DOM object with event bindings and everything else and turning into a simple piece of HTML in a string, that process throws away everything (such as event bindings) that isn't simple HTML.
Either give .html() the jQuery object itself:
$('#id_date', elements).datepicker();
that.$el.html(elements);
or bind the datepicker after adding the HTML:
that.$el.html(elements);
that.$('#id_date').datepicker();

How to show images after uploading with Plupload without page refreshing?

Plupload/paperclip/rails 3.1.4/ruby 1.9.3
i successfully upload multiple images with Plupload, and as usual i've put in 'images/create.js.erb' code, which appends images to page.
nothing happens. even primitive alert has no visual response, but i hear how my hard disk grunts (actually i made endless cycle of alerts to hear that something happens inside :)
images_controller
def create
#image=Image.create(:photo => params[:file])
respond_to :js
end
views/images/create.js.erb
$('body').append('<%= escape_javascript(image_tag(#image.photo.url(:medium))) %>');
after each image creating, it must appear on page.
i found the answer.
views/images/create.js.erb
<%=#image.id %>:<%= #image.photo.url(:medium) %>
views/items/_form.js.erb
<script>
...
uploader.bind('FileUploaded', function (up, file, info) {
var response = info['response'].split(':');
var image_id= response[0];
var image_url= response[1];
...
use it as you want, my lord!..
...
});
...
</script>

Rails 3, bootstrap modal multiple layers of remote calling

I've been racking my head against this for 2 days now. I'm massively frustrated, and I can't seem to find any information on this with searching.
The issue. I'm using a :remote => true link to load some html from a different controller.
$('.managed_locations').bind('ajax:complete', function(evt, xhr, status){
$('#locations_modal').modal('show')
$('#locations_modal').html(xhr.responseText);
});
So it gets the html, dumps it into the bootstrap modal and displays the modal. This is working fine.
But inside of the modal I ALSO have a form which also uses :remote => true. Now to make life harder, when a button is pressed I clone the form and display it. So the user could have many forms.
Now the issue. Whenever the form is submitted it just loads it like a normal page. It's as if the :remote => true is being ignored. But this only in the modal. If I just load the modal controller by itself it works just fine. I also had this developed before using another jquery lightbox where it was working fine. I'm just switching in bootstrap for consistency.
So my initial thoughts are that the jquery_ujs.js isn't finding the new forms. So I added some code to output the form elements.
$("#log_events").click(function () {
$(document).find(".new_stored_physical_location").each(function() {
console.log( $(this).data() );
console.log( $(this).data('events') );
});
return false;
});
Which outputs in the console:
Object { type="html", remote=true}
Object { ajax:complete=[1]}
So I see that the events are being set in jQuery. Each of these forms has :remote => true and has the ajax event for when the request is complete. But it's just not doing an ajax request when I hit submit.
Is there something I'm missing that is required to make sure an ajax request will happen from the form???? The data() looks fine, the data('events') look fine. But is there some other event/binding that I need to look at?
The html that is loaded in from the modal right now is loading a layout. But i've done it both with a layout, without a layout. It's driving me nuts. Thanks for the help guys.
Edit: Some extra weirdness. The modal also loads some additional remote links, all of which are working correctly. It's only the form links which don't seem to work.
I got a solution. The big issue was within jquery_ujs.js Especially this line:
$(document).delegate(rails.formSubmitSelector, 'submit.rails', function(e) {
FYI, rails.formSubmitSelector = 'form'. So this code found all of the forms in the document, overwrote the submit with this function. But the issue was that once you loaded in some ajax, and that ajax contained a it wouldn't add this fancy event to it. You need to re-add it.
So this is what I did.
Inside of jquery_ujs there is a bunch of functions that are accessible outside of it using $.rails. So things like: $.rails.enableElement, $.rails.nonBlankInputs. And the code for the submit event was sitting around all willy nilly. It only executes once when the page is loaded. So I put that in a function addSubmitEvent():
// Add the form submit event
addSubmitEvent: function(element) {
//$(element) was before $(document) but I changed it
$(element).delegate(rails.formSubmitSelector, 'submit.rails', function(e) {
var form = $(this),
remote = form.data('remote') !== undefined,
blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector),
nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector);
if (!rails.allowAction(form)) return rails.stopEverything(e);
// skip other logic when required values are missing or file upload is present
if (blankRequiredInputs && form.attr("novalidate") == undefined && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) {
return rails.stopEverything(e);
}
if (remote) {
if (nonBlankFileInputs) {
return rails.fire(form, 'ajax:aborted:file', [nonBlankFileInputs]);
}
// If browser does not support submit bubbling, then this live-binding will be called before direct
// bindings. Therefore, we should directly call any direct bindings before remotely submitting form.
if (!$.support.submitBubbles && $().jquery < '1.7' && rails.callFormSubmitBindings(form, e) === false) return rails.stopEverything(e);
rails.handleRemote(form);
return false;
} else {
// slight timeout so that the submit button gets properly serialized
setTimeout(function(){ rails.disableFormElements(form); }, 13);
}
});
}
This is basically the exact same code. But now it's $(element) instead of $(document). This was changed because now I can sniff for when the modal has loaded in the html. Then I can call:
$.rails.addSubmitEvent('#my_modal');
I then had an issue of it adding the event too many times from when I opened/closed the modal multiple times. So I just put a simple true/false if around it to call it once only.

Resources