Dynamic path in new.AjaxRequest with Rails - ruby-on-rails

I was wondering if there's anyway to get a 'dynamic path' into a .js file through Ruby on Rails.
For example, I have the following:
new Ajax.Request('/tokens/destroy/' + GRID_ID, {asynchronous:true, evalScripts:true, onComplete:function(request){load('26', 'table1', request.responseText)}, parameters:'token=' + dsrc.id + '&authenticity_token=' + encodeURIComponent(AUTH_TOKEN)})
The main URL is '/tokens/destroy/:id', however on my production server this app runs as a sub folder. So the URL for this ajax call needs to be '/qrpsdrail/tokens/destroy/:id'
The URL this is being called from would be
/grids/1 or /qrpsdrail/grids/1
I could, of course, do ../../path -- but that seems a bit hackish. It is also dependent on the routing never changing, which at this stage I can't guarantee.
I'm just interested in seeing what other solutions there might be to this problem.
Thanks in advance :)

Maybe a bit hackish solution, but i have a configuration-file like described here, and so you could do something like, inside a config.yml :
development:
root: /
production:
root: /qrpsdrail/
and when you build your Ajaxrequest, you could write
new Ajax.Request("#{AppConfig.root}tokens/destroy/' + ...
But it still looks like there should be a cleaner way to solve this ;)

you can use Dynamic path in new.AjaxRequest using javascript in rails
javascript
function dynamic_ajax(GRID_ID)
{
new Ajax.Request("/tokens/destroy?"+GRID_ID, {asynchronous:true, evalScripts:true, onComplete:function(request){load('26', 'table1', request.responseText)}, parameters:'token=' + dsrc.id + '&authenticity_token=' + encodeURIComponent(AUTH_TOKEN)});
}
html
Grid Id 1
Grid Id 2
Grid Id 3

You can set the path as an attribute to your html object that initiates the ajax call. An example would be:
HTML
<a id='my_clicky_thing' href='#' rails_path='<%= tokens_destroy_path %>'>Click me</a>
JQuery
$('#my_clicky_thing').live('click', function(){
var ajax_path = $(this).attr('rails_path');
/* Do ajax stuff here with the path */
});
This would allow you to use the actual rails path in your .js files, as you do in your views.
(This code may not work, it is for the concept only)

Related

Ember: How to bind action to code generated with JS

I have a simple view which renders set of images depending on given items array (simplified code), using this as I need to collect some other data to 'build' required class name(s):
App.MyView = Ember.View.extend({
buildTemplate: function () {
var itemz = this.get('items');
var classname = 'classNameDependingOnSomeCalculations...';
var out = '<div>';
$.each(itemz, function (index, obj) {
out += '<img {{action myActionHere}} src="' + obj.href + '" alt="" class="'+classname+'"/>';
});
out += '</div>';
return out;
}.property('view'),
defaultTemplate: Ember.Handlebars.compile(
"<div>{{{view.buildTemplate}}}</div>"
)
});
And in template I'm using it as
{{#each myObj in myCollection}}
{{view App.MyView itemsBinding="myObj.items" otherBinding="otherProps" }}
{{/view}}
Unfortunately this way Ember instead of binding the action puts {{action myActionHere}} directly into code...
How can I bind an action instead while building dynamic template?
I'm using Ember 1.1.2
P.S. Or maybe I should use quite other approach for building this view?
There is a workaround to make this work with the view as you've laid it out here... But this is really not the ember way of doing it. If for some reason you need this kind of an approach, I'll append an answer for that, but I'm going to aim to fix the underlying issue.
Instead of doing this as shown here, you should instead have code that looks like the following directly in your JSP:
{{#each myObj in myCollection}}
<div>
{{#each item in myObj.items}}
<img {{action myActionHere}} src={{item.href}} alt='' class={{classNameFunction}}/>
{{/each}}
</div>
{{/each}}
If your reason for wanting to do this as a view is so that you can reuse this functionality without rewriting the code, take a look at partials which are specifically designed for that purpose.

TinyMCE, Rails 4 and execcommand_callback

I've been trying to get TinyMCE to use a custom execcommand_callback handler to perform actions when the File Menu::New Document option is selected, but have been unable to get it to work at all, even on the most basic level. The project is on Rails 4, and I'm using the tinyMCE-rails gem from:
https://github.com/spohlenz/tinymce-rails
and following the example from:
http://www.tinymce.com/wiki.php/Configuration3x:execcommand_callback
I've put the following in tinymce.yml
execcommand_callback: "myCustomExecCommandHandler"
The resulting html:
<script>
//<![CDATA[
function myCustomExecCommandHandler(editor_id, elm, command, user_interface, value) {
alert('hello');
}
//]]>
</script>
some html ...
<form accept-charset="UTF-8" action="" id="homepage_form" method="post">
<textarea class="tinymce" cols="10" id="editor" name="editor" rows="10"></textarea>
<script>
//<![CDATA[
tinyMCE.init({"selector":"textarea.tinymce","document_base_url":"/",
"theme_advanced_toolbar_location":"top","theme_advanced_toolbar_align":"left",
"theme_advanced_statusbar_location":"bottom",
"theme_advanced_buttons3_add":"tablecontrols,fullscreen,image,link",
"plugins":"table,fullscreen,image,link",
"execcommand_callback":"myCustomExecCommandHandler"});
//]]>
</script>
more form fields ...
</form>
To all appearances, this does nothing. Doesn't even raise a warning or error. What am I doing wrong?
Ok, I figure I should wrap this up for anyone else interested in this question, and thanks to Nishant for getting me on the right track.
Using TinyMCE 4 with the tinymce-rails gem (https://github.com/spohlenz/tinymce-rails) is straightforward and requires less configuration. Since I wanted the ability to embed links and images, my tinymce.yml file looks like:
document_base_url: /
plugins:
- image
- link
setup: "myNewDocumentHandler"
An my custom command handler looks like:
function myNewDocumentHandler(ed) {
ed.on('BeforeExecCommand', function(e) {
if (e.command === 'mceNewDocument') {
alert('New Document Command Handled');
}
});
}
You can see it work here: http://fiddle.tinymce.com/uRdaab/4
There is no problem in your callback . It works fine .
Check http://fiddle.tinymce.com/pRdaab
There is some problem here in plugins line , when you remove image and link it works . Check my fiddle and here is the code . I dont know why but try to figure that.
image is usually advimage , not sure about link plugin / feature however .
<script type="text/javascript">
function myCustomExecCommandHandler(editor_id, elm, command, user_interface, value) {alert('hello');}
tinyMCE.init({"selector":"textarea",
"document_base_url":"/",
"theme_advanced_toolbar_location":"top",
"theme_advanced_toolbar_align":"left",
"theme_advanced_statusbar_location":"bottom",
"theme_advanced_buttons3_add":"tablecontrols,fullscreen",
"plugins":"table,fullscreen",
"execcommand_callback":"myCustomExecCommandHandler"});
</script>
<form method="post" action="dump.php">
<textarea>Foo</textarea>
</form>
So normally its good to use a classic TinyMCE init and then work on it . Its better to first get TinyMCE working properly and then examine add the call back functionality . One issue at a time saves a lot of troubleshooting . I am trying to implement that in my programming skills too !

jquerymobile url parameters

Have asked two questions and not getting an answer and having spent a few hours trying to find the answer without success I am wondering if someone can finally help me.
I need to generate dynamic urls and pass through parameters on jquerymobile.
example..
Menu 2
Result No. 4
The above urls need to be dynamic and I need to be able to pass through a parameter of ID.
I then need to get the id parameter on the given page.
I have read lots regarding changePage etc but I can specify in the function which page will be next as it needs to be dynamic. I also need the ajax transitions to work so ajax-false needs to be true.
Please help once and for all and provide me with sample code.
Kind Regards.
Ok, to get the url parameter on the page you navigated in, use something similar to the following.
It uses pageshow event to get the ID from the current URL.
I have used the function from the answer on this question - Get escaped URL parameter:
$(document).on("pageshow", function(event, data) {
var id = getURLParameter("id");
console.log("ID = " + id);
});
function getURLParameter(name) {
return decodeURI(
(RegExp(name + '=' + '(.+?)(&|$)').exec(location.search)||[,null])[1]
);
}
If the above regex doesn't work means try with this change
function getURLParameter(name) {
return decodeURI(
(RegExp(name + '=' + '(.+?)(&|$)').exec(window.location.href)||[,null])[1]
);
}

Way to organize client-side templates into individual files?

I'm using Handlebars.js, and currently all my templates live inside script tags which live inside .html files housing dozens of other templates, also inside script tags.
<script type="text/template" id="template-1">
<div>{{variable}}</div>
</script>
<script type="text/template" id="template-2">
<div>{{variable}}</div>
</script>
<script type="text/template" id="template-3">
<div>{{variable}}</div>
</script>
...
Then I include this file on the server-side as a partial.
This has the following disadvantages:
A bunch of templates are crammed into HTML files.
Finding a given template is tedious.
I'm looking for a better way to organize my templates. I'd like each each template to live in its own file. For example:
/public/views/my_controller/my_action/some_template.html
/public/views/my_controller/my_action/some_other_template.html
/public/views/my_controller/my_other_action/another_template.html
/public/views/my_controller/my_other_action/yet_another_template.html
/public/views/shared/my_shared_template.html
Then at the top of my view, in the backend code, I can include these templates when the page loads, like this:
SomeTemplateLibrary.require(
"/public/views/my_controller/my_action/*",
"/public/views/shared/my_shared_template.html"
)
This would include all templates in /public/views/my_controller/my_action/ and also include /public/views/shared/my_shared_template.html.
My question: Are there any libraries out there that provide this or similar functionality? Or, does anyone have any alternative organizational suggestions?
RequireJS is really good library for AMD style dependency management. You can actually use the 'text' plugin of requireJS to load the template file in to your UI component. Once the template is attached to the DOM, you may use any MVVM, MVC library for bindings OR just use jQuery events for your logic.
I'm the author of BoilerplateJS. BoilerplateJS reference architecture uses requireJS for dependency management. It also provides a reference implementations to show how a self contained UI Components should be created. Self contained in the sense to handle its own view template, code behind, css, localization files, etc.
There is some more information available on the boilerplateJS homepage, under "UI components".
http://boilerplatejs.org/
I ended up using RequireJS, which pretty much let me do this. See http://aaronhardy.com/javascript/javascript-architecture-requirejs-dependency-management/.
I use a template loader that loads the template using ajax the first time it is needed, and caches it locally for future requests. I also use a debug variable to make sure the template is not cached when I am in development:
var template_loader = {
templates_cache : {},
load_template : function load_template (params, callback) {
var template;
if (this.templates_cache[params.url]){
callback(this.templates_cache[params.url]);
}
else{
if (debug){
params.url = params.url + '?t=' + new Date().getTime(), //add timestamp for dev (avoid caching)
console.log('avoid caching url in template loader...');
}
$.ajax({
url: params.url,
success: function(data) {
template = Handlebars.compile(data);
if (params.cache){
this.templates_cache[params.url] = template;
}
callback(template);
}
});
}
}
};
The template is loaded like this:
template_loader.load_template({url: '/templates/mytemplate.handlebars'}, function (template){
var template_data = {}; //get your data
$('#holder').html(template(template_data)); //render
})
there's this handy little jquery plugin I wrote for exactly this purpose.
https://github.com/cultofmetatron/handlebar-helper

How to do history.js in Rails the right way?

Hi everyone,
it's now my fourth try to implement history.js in a Rails app. I have one approach that is running quite okay, but the code is so ugly. Today again I looked at the code and thought: How can I make this better, easier, more DRY?!
What I have done so far (and working quite okay, not perfect):
Set remote: true to my links
jquery-ujs fetches the js.erb
My HTML looks like:
<body>
<div id="content">
some content with buttons, etc.
</div>
</body>
The js.erb contains:
History.pushState(
{
func: '$(\'#content\').html(data);',
data: '<%= j(render template: "news/index", formats: [:html]) %>'
},
'test title',
'<%= request.url %>'
);
And then history.js takes the function and gives it the data. So it replaces the content-div with the new generated code. And it also updates the URL. This code I have to put in every(!) js.erb file.
My last thoughts to make it a bit less ugly were:
Set remote: true to my links
When a link gets clicked it fetches some js.erb which replaces the content-div
All links with data-remote="true" will get a ajax:success-handler
On ajax:success the new URL gets pushed to history.js
But there's still one problem within. Then I have JavaScript code:
$(document).on('ajax:success', 'a[data-remote="true"]', function() { ... });
The problem is: ajax:success never fires if I replace the div-tag where the link (that should fire the event) was in.
Maybe someone can solve my problems...
Or is there a better way?
I only use jquery-ujs and pushState, popState.
See my answer here:
https://stackoverflow.com/a/27532946/345996
what about:
History.Adapter.bind(window, 'statechange', function() {
var state = History.getState();
...
});
I'm using the beforeSend event as global listener for all data-remote to change the handle the history of the browser.
I prefer the beforeSend because I want the link to change as soon as it is clicked, regardless of the result of the ajax request...
$(document).bind('ajax:beforeSend', function(event,data){
history.pushState(null, '', event.target.href)
});
This solve your problem because the event is fired before any modification to the DOM is done.
Have you tried turbolinks ?
It will be default in Rails 4.

Resources