I try to submit a simple form with coffeescript/ajax in play. But I'm doing something wrong and can't figure out what.
I started with a working form for creating questions (without ajax) and then followed Playframwork doc on javascript routing:
So first I created the router resource in my Application controller:
def javascriptRoutes = Action { implicit request =>
Ok(
Routes.javascriptRouter("jsRoutes")(
routes.javascript.Questions.create
)
).as("text/javascript")
}
added in routes:
GET /javascriptRoutes controllers.Application.javascriptRoutes
added to my template:
<script type="text/javascript" src='#routes.Application.javascriptRoutes()'></script>
and then included the coffescript:
$ ->
$('#save').on "click", (e) ->
jsRoutes.controllers.Questions.create.ajax
data: $('#questionForm').serialize()
success: (data) ->
alert("success")
error: (err) ->
alert("error")
#save points to a link and the onclick event works for a simple alert. $('#questionForm').serialize() also seems to output the right data.
The script simply does nothing and I don't know how to debug it properly with the chrome javascript debugger as I don't know where to look. At least intellij
tells me that Questions.create is never called.
edit: Thanks to Infinity I noticed that the chrome javascript debugger throws:
Uncaught TypeError: jsRoutes.controllers.Questions.create.ajax is not a function(anonymous function) # save.coffee:3m.event.dispatch # jquery.js:4641m.event.add.r.handle # jquery.js:4309
Thanks to Infinity and the new console error input I noticed that
jsRoutes.controllers.Questions.create.ajax
must be
jsRoutes.controllers.Questions.create().ajax
Related
Could anybody help me calling a validation function in can.js?
I'm adding can.jquery.js and can.map.validations.js
and then create such a small example:
var mymap = can.Map.extend({
init: function () {
this.validatePresenceOf('myfield'); // this line reports an error
}
});
when loading page with this script, I get an error in browser:
"Uncaught TypeError: undefined is not a function"
Actually any this.validate* function does not work
After some research I notice that when I put this code under
$(document).ready{}
it works, but if I put it into .js file and load via tag - browser reports an error.
And I'm not going to write all of my js code in the page itself
see here it tells pretty clearly(helped me last time) that you have to use $document.ready() or else it wont work, so try making a new file.js, have $document.ready() contain all your todo-code, and link it up, I hope I am helpful in this regard, if not then bug me up I wont mind at all :) ..
Commenting it late but anyway - it didn't work for me in either case so I just took the sample from http://jsbin.com/jofeq/5/edit?html,js,output - and copied it to my code. Surprisingly it worked after copying - not sure what was wrong on my side.
In that example it looks like this:
var Person = can.Map({
init: function () {
this.validatePresenceOf('firstName');
this.validatePresenceOf('lastName');
}
}, {});
and it works without document.ready tricks or anything else - just included into body tag
I'm not terribly experienced with AJAX and so am using some tools and attempting to integrate and customize them. First, this is a wordpress site using an AJAX form to submit a post. It all works great! Now, of course, I have to add a WYSIWYG editor to the mix and need to figure out how to get the html content to submit properly.
Here's the submit code:
jQuery("form.pfs").submit(function() {
// vvv I ADDED THIS LINE!!! vvv
jQuery('textarea#postcontent').val(jQuery('div.workzone iframe').contents().find('body').html());
jQuery(this).ajaxSubmit({
type: "POST",
url: jQuery(this).attr('action'),
dataType:'json',
beforeSend: function() {
jQuery('.pfs-post-form #post').val('posting...');
},
complete: function(request,textStatus,error) {
data = jQuery.parseJSON(request.responseText);
if (data && data.error) {
jQuery('#pfs-alert').addClass('error').html('<p>'+data.error+'</p>').show();
jQuery('.pfs-post-form #post').val('Post');
} else {
jQuery('form.pfs').reset();
location.reload();
}
}
});
return false;
});
As you can see, I've added that first line where I take the content of the HTML in the WYSIWYG (http://elrte.org/) and set it as the value of what would have been the original textarea (#postcontent).
The AJAX works perfectly if there's an error, so it is only the "else" portion of the routine that is throwing the error:
Uncaught SyntaxError: Unexpected token < jquery.js:2
e.extend.parseJSON jquery.js:2
jQuery.submit.jQuery.ajaxSubmit.complete pfs-script.js:31
F
So as you see, I need to validate for malicious code (not part of this help request!!) but more importantly I just want to be able to accept HTML in my form posts. Ideas? I am not 100% sure I understand what is failing and where...
turns out there was a conflict with another Plugin. tracing out the request.responseText revealed it. This code works just fine.
So i I have a page that contains links that call an httpRequest. The request calls a php file that grabs data from mysql and pre populates a form which is then returned to the browser/webpage. My problem is that when the page is returned to the browser via the httpRequest/ajax the text area does not display the tinymce editor, it just displays a normal text area. It looks like my request and ajax is working fine the text area just doesn't have the tinycme editor on it.
When i don't use ajax it works fine but when i put it in a separate file and call it via ajax it doesn't bring in the tinymce editor.
Does anyone know how to fix this problem so that my ajax generated page displays the text area with the tinymce editor. Thank you.
Lets presume that your thinyMCE instance is initialized with code below
// initialize tinyMCE in page
tinyMCE.init({
mode: "textareas",
theme: "advanced"
});
and you have some kind of button somewhere in the page. For purpose of this tip, i will not give it any ID but you may. Now, using jQuery you can easily attach event handler to that button which will call through AJAX your server and take content which you want to put tinyMCE editor. Code which will do such job would look somehow like below.
$(function() {
$("button").bind("click", function() {
var ed = tinyMCE.get('content');
ed.setProgressState(1); // Show progress
$.getJSON('/page/12.json', { /* your data */
}, function(data) {
ed.setProgressState(0); // Hide progress
ed.setContent(data["body"]);
}
});
});
});
You can see that on button.click ajax will call url /page/12.json which will return JSON as response. bare minimum of that response could be:
{
title: "Page title",
body: "<html><head><title>Page title</title>......</html>"
}
I attached anonymous function as callback which will handle response from server. and hide progress indicator which is shown before ajax call.
About JSON
JSON is shorten of JavaScript Object Notation. It is JavaScript code!!! So don't be confused about it. Using JSON you can make javascript object which can have attributes you can use later in your code to access particular peace of data which that object "holds". You can look at it as some kind of data structure if it is easier to you.
Anyway, to show you how this JSON can be created by hand look at examples below
var data = new Object();
data.title = "Page title";
data.body = "<html....";
or
var data = {
title: "page title",
body: "<html...."
};
it is very same thing.
If you want to learn more about JSON point your browser to http://json.org.
===== alternative =====
Alternative to json solution could be just plane ajax call to server and response can be plain HTML (from your question I can assume that you have something like this already). So instad of calling $.getJSON you can use $.get(url, callback); to do same thing. The code at the top of my answer will not dramatically change. Instead of geting JSON in response you will get string which is HTML.
----------- BOTTOM LINE -------
I prefer JSON since it can be easily extended later with other attributes, so there is no painful code changes later ;)
Problem here will be that when you return the full page and render it using the ajax response, your tinymce instance has not been shut down before.
In order to do this you can call this small piece of code before you render the ajax response:
tinymce.execCommand('mceRemoveControl',true,'editor_id');
In this case the editor should initialize correctly. You are not allowed to initialize a tinymce editor with the same id before shutting the first one down.
Strangely i ran into this problem yesterday. Following code should work, but YMMV. Trick is to use the correct steps in ajax events. I used the Regular TinyMCE and made use of the jQuery library already included.
Following goes into your tinyMCE initialization tinyMCE.init() . All of the below block should be outside the document.ready.
myTinyInit = {
//.......All essential keys/values ...........
setup : function(ed) {
ed.onChange.add(function( ed ) {
tinyMCE.triggerSave();
}) }
//.....................
};
// Init the tinyMCE
tinyMCE.init(myTinyInit);
This ensures the content is being saved regularly onto the textarea that holds the value. Next step is setting up the request events.
Normally tinyMCE mceAddControl before the ajax post and mceRemoveControl after the ajax success should do the trick. But I found that often does not work.
I used the form as the jQuery selector in my case.
jQuery( '.myForm' )
.find( 'textarea#myTextArea' )
.ajaxStart(function() {
// If you need to copy over the values, you can do it here.
// If you are using jQuery form plugin you can bind to form-pre-serialize event instead.
// jQuery( this ).val( tinyMCE.get( jQuery( this ).attr( 'id' )).getContent() );
}).ajaxSend( function() {
// ! - step 2
// My case was multiple editors.
myEds = tinyMCE.editors;
for( edd in myEds ) {
myEds[ eds ].remove();
}
// tinyMCE.get( 'myTextarea' ).remove();
// strangely mceRemoveControl didnt work for me.
// tinyMCE.execCommand( 'mceRemoveControl', false, jQuery( this ).attr('id'));
}).ajaxSuccess(function() {
// Now we got the form again, Let's put up tinyMCE again.
txtID = jQuery( this ).attr( 'id' );
// ! - step 3
tinyMCE.execCommand( 'mceAddControl', false, txtID );
// Restore the contents into TinyMCE.
tinyMCE.get( txtID ).setContent( jQuery( this ).val());
});
Problems i came across :
Using mceRemoveControl always gave me r is undefined error persistently.
If you get a blank tinyMCE editor, check the DOM whether the ID of the textarea is replaced with something like mce_02, this means that TinyMCE is being initialized again or something is wrong with the order. If so, the tinyMCE is duplicated with each save.
if you are new to JS, I recommend using jQuery with the form plugin, it might be easier for you. But do use the regular non-jquery tinyMCE, as it is well documented.
I fixed this problem by recalling the function after the ajax call. In this part of my ajax:
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("Content").innerHTML=xmlhttp.responseText;
tinymce();
Now it works fine.
I've been struggling through my first Backbone app and have started to get the hang of things. I now have a few successful reports that load JSON data from my server (NodeJS), populate a template (Handlebars), and render relatively nicely on the frontend.
The issue I'm running into is that I'm trying to add event handlers to a <select> object coming in from one of my templates and I'm not having much luck.
Here's the template:
// Report - New Clients
script(type='text/x-handlebars-template', id='newClients-template')
// Start Listing
{{#each report}}
.listingName
.youSearched
| Stylist:
.srchResult
select.chzn-select(id='stylists', style='width:350px')
option(value='null') All Stylists
{{#each stylists}}
option(value='{{uid}}') {{name}}
{{/each}}
.clear
And here's the Backbone View:
note: I'm calling the view from within a $ -> so it shouldn't be loading until DocumentReady
# View
class window.NewClientsView extends Backbone.View
events:
'click #stylists': 'selectStylist'
initialize: ->
#el = $('.containerOuter')
_.bindAll this, 'render'
#collection.bind 'reset', #render
# Compile Handlebars template at init (Not sure if we have to do this each time or not)
source = $('#newClients-template').html()
#template = Handlebars.compile source
# Get the latest collections
#collection.fetch()
render: ->
# Render Handlebars template
renderedContent = #template { report: #collection.toJSON() }
$(#el).html renderedContent
return this
selectStylist: (e) ->
console.log 'hit it!'
console.log e
I'm expecting that any time the dropdown is clicked or changed, I'll see the selectStylist function fired. Unfortunately that hasn't happened yet :( I also have inspected the element in Chrome Dev Tools and there are no event listeners set on the object.
I've been stuck on this for a bunch of hours now and have reviewed all the other suggestions for Backbone event listeners (i.e. pass in your this.el as a parameter when instantiating your view), but haven't had any success.
Any help or ideas would be appreciated!
In initialize, you write
#el = $('.containerOuter')
But Backbone.js processes events before initialize—meaning that it's already bound those events to a different #el (which you should see in the DOM as a lonely div).
You can hack this by overriding make, the function that's used to create #el:
make: ->
$('.containerOuter')[0]
I have a page which needs to use $.post() but for some reason the exact code works when I run it from the firebug console but not from my script? My script is:
$(document).ready(function () {
$('#dl_btn').click(function () {
$.post(
"news_csv.php",
$("#dl_form").serialize(), function (data) {
alert('error');
if (data == 'success') {
alert('Thanks for signing up to our newsletter');
window.open("<?php echo $_GET['link']; ?>");
parent.Shadowbox.close();
} else {
alert(data);
}
});
});
});
It isn't the link as that does get printed properly but it gives me an error on line 140 of jquery min, I have tried using different versions of jquery and to no avail. I really dont understand why this isn't working.
When I changed from $.post to $.ajax and used the error callback I did receive an error of 'error' and the error is undefined?
Don't suppose anyone has any ideas? Would be much appreciated.
Thanks,
Tom
Is your click button placed inside a form element?
Cause doing so, clicking on it will not only trigger the onClick event you have binded to, but form submit as well, so you will end up in a case where your browser is executing both requests in parallel - with unpredicted outcome, of course.
I tried the same code with an element that does not trigger form submit and it worked as expected.
One point though: if you plan to use simple string as a return value and to do something with it (display it or so) then is ok to do what you do right now. However, if you have more complex response from the ajax request, you should specify the response type (xml, json..) as the last parameter of the post method.
Hope this helps.