CasperJS not submitting $_POST array - casperjs

I have a form which contains a hidden field;
<input name="qsID" type="hidden" value="1368113958" />
This is a hidden field added by Concrete5.
When submitting the form its like the hidden field does not exist, Concrete5 (PHP) cannot see the hidden field so presumably CasperJS is not sending the hidden field.
Why is this happening?
Update
Using var_dump I can see that the whole $_POST array is empty
Update 2
It seems that this single piece of code is the difference between the form being posted correctly and failing;
casper.waitForSelector("#Question33",
function success() {
this.test.assertExists("#Question33");
this.click("#Question33");
},
function fail() {
this.test.assertExists("#Question33");
});
This code also breaks the posting of form data
casper.waitForSelector("form#miniSurveyView576 input[name='Question34']",
function success() {
this.test.assertExists("form#miniSurveyView576 input[name='Question34']");
this.click("form#miniSurveyView576 input[name='Question34']");
},
function fail() {
this.test.assertExists("form#miniSurveyView576 input[name='Question34']");
});

I basically had to scrap this code as it did not work at all.
What I ended up with was something like this
casper.test.begin('web site up', 4, function(test) {
casper.start(url).then(function() {
this.test.assert(
this.getCurrentUrl() === url, 'url is the one expected'
);
this.test.assertHttpStatus(200, url + ' is up');
functions.viewPortCapture(casper, viewports[0], "1001");
test.assertExists(x("//a[normalize-space(text())='ABC']"));
this.click(x("//a[normalize-space(text())='ABC']"));
this.waitForUrl(/abc\/$/, function(){
test.assertExists("input[type='submit']");
});
});
casper.run(function() {
test.done();
});
});

Related

How to initialize select2 that uses a query for data when I already have a value

I have a view with 2 select boxes which are "cascading". A user selects a value from the first box and the second is populated based on the new value. This is done with Select2's query option, and works fine on the first load of the page. However, when I post the page and then render it, both select boxes already have values (say A and 1), but the dependent checkbox is not initialized. I have done a few things with initSelection and it didn't help much, sometimes just getting me into an loop.
What I am trying to do is this:
Link the two boxes
When the first box changes, reset the data in the second box and clear the value
When the page is re-drawn, and a value has already been selected (e.g. response to POST)
Go to server and get the data
Show the correct value for the existing <input type='hidden' value='xxx'>
if that value exists in the list, of course
if not, set value to blank (optionally fire jquery validation
Searching/constant querying is not needed. Just load once on change
I am thinking about changing this entire, so if this is really the wrong way to go about this, I'd be happy to know.
// caches ajax result based on `data`
// if data has been requested before, retrieves from the cache (nothing special)
// based on other code that did it all inside the `query` function directly
var locationsCache = new AjaxCacheClassThing( {
url: '...',
data: function() { return { masterId: $('#ParentBox').val(); } }
});
$(function() {
$('#ParentBox').change(function () {
$('#ChildBox').select2('data', null);
});
$('#ChildBox').select2({
query: locationsCache.queryCallbackHandler,
selectOnBlur: true,
});
});
The HTML uses the standard MVC helpers, and the HTML is rendered just fine.
#Html.DropDownListFor(m => m.ParentBox, SelectListOfStuff) // standard <select>
#Html.HiddenFor(m => m.ChildBox)
Here is how this scenario goes:
ParentBox is required (no empty option)
First Load: there is no value selected
Open the DependentBox
Ajax query issues correctly
Dropdown populates as expected
Second Load
Master box selects value just fine
ChildBox hidden input has value="xx" just fine
It does not show a selected item
Clicking dropdown populates the box as expected (from cache)
After some time spent, and lots of time on here and other places, I figured out how this all works (at least some parts of it!). Way simpler than I thought it was, but still surprised this isn't supported out of the box in some way. Seems like a really common request.
query and ajax and initselection aren't that useful in this scenario
They query each time a the search box changes (not desired)
They complicate everything
You need to init the select2 manually
If you use { data: ... } then you don't need query or ajax
Set the "value" on your hidden input if you have one, so the item gets selected
You have to recreate the box when you get new data
It is really simple. This is the simplest case, using no extra features or attributes
Javascript:
$(function() {
$('#ParentBox').change(createChildSelect2);
createChildSelect2();
});
function createChildSelect2() {
makeAjaxRequest( function( newData ) {
$('#ChildBox').select2( { data: newData } );
});
}
function makeAjaxRequest(callback) {
// calls a.jsp?parentId={?} and then the callback when done.
jQuery.ajax({
url: 'a.jsp', dataType: 'json',
data: function() {
return { parentId: $("#parentBox").val() };
}
})
.done(function (data) {
callback(data);
});
}
The HTML is all the same. A type=text and type=hidden both work:
<select id="ParentBox">
<option ... >
<option ... >
<select>
<input id="ChildBox" type="hidden" class="input-medium" value="1"/>
Or using Razor:
#Html.DropDownListFor(m => m.MasterBox, SelectListOfStuff) // standard <select>
#Html.HiddenFor(m => m.DependentBox)

Strange issue with ajax POST

I have this html page with the form
<form method="post" id="form1" name="form1" action="/status_comment/save">
//Some text inputs
<input type="text" name="new_comment" id="new_comment" onkeydown="post_comment(event,'13')" >
</form>
And this is my javascript function to do the POST call
function post_comment(event,item_id)
{
var keyCode = ('which' in event) ? event.which : event.keyCode;
if(parseInt(keyCode)==13 && event.shiftKey!=1)
{
var str = $('#form1').serialize(); // Gets all the filled details
$.post('/status_comment/save',
str,
function(data){
alert(data);
});
}}
Backend is done using Django and this is the return statement
data=simplejson.dumps(data)
return HttpResponse(data, mimetype='application/json')
The referral url is say "/xyz".
The thing is, after the form gets submitted, it is being automatically redirect to the "/status_comment/save" page instead of remaining on the same page.
I tried the get method and it works fine but not the POST method.
I tried debugging it, so changed the url in post call to the referral url, then it refreshs the page instead of doing nothing.
Also the alert() command inside the function above doesnt work, so its probably not being entered into.
Interesting thing I have noticed, when looking at the web developer console, the Initiator for the POST call in this page is being displayed as "Other" while the initiator for GET call and POST call (in other pages, where its working) is "jquery-1.8.0.min.js:2"
Any thoughts? Thanks...
First you really shouldn't try to capture the enter if you can avoid it. Use the submit binding. It makes everything more obvious and easier for your fellow developers (I bet I am not the only one who thought "What the heck is KeyCode 13?").
I'm wondering if perhaps being more explicit might help. Have you tried calling preventDefault and stopImmediatePropagation?
$('#form1').submit(function(evt) {
evt.preventDefault();
evt.stopImmediatePropagation();
// serialize and be AJAXy yada yada yada
If that doesn't work, or for some reason you prefer to handle capturing enter on your own, then you might want to have the above code in addition to your keydown handler. So it would be:
<input type="text" name="new_comment" id="new_comment" onkeydown="post_comment(event,'13')" >
...
$('#form1').submit(function(event) {
event.preventDefault();
event.stopImmediatePropagation();
}
function post_comment(event,item_id)
{
event.preventDefault();
event.stopImmediatePropagation();
var keyCode = ('which' in event) ? event.which : event.keyCode;
if(parseInt(keyCode)==13 && event.shiftKey!=1)
{
var str = $('#form1').serialize(); // Gets all the filled details
$.post('/status_comment/save',
str,
function(data){
alert(data);
});
}
}
Start by getting rid of the onkeydown attribute from the input:
<form method="post" id="form1" name="form1" action="/status_comment/save">
//Some text inputs
<input type="text" name="new_comment" id="new_comment" />
</form>
And then simply subscribe to the .submit() event of this form using jquery and perform the AJAX request in there. Don't forget to return false from it to ensure that the default action is canceled and the browser stays on the same page:
$('#form1').submit(function() {
var str = $(this).serialize(); // Gets all the filled details
$.post(this.action, str, function(data) {
alert(data);
});
return false; // <!-- that's the important part
});

Validate $.getJSON before its being sent to the server in JQmobile

I'm trying to Validate my form before it's being sent to the server. I tried couple of J/S plugins for regular validation and none of them seem to work.
I tried looking for getJSON validation method with jquerymobile but haven't seen anything related. Is using $.getJSON the right approach?
Here is a fiddle http://jsfiddle.net/Kimbley/kMsXK/2/
Thanks :D
Code Here:
function mAddBusiness() {
$.getJSON("API.php", {
command: "addBusiness",
bsnName: $("#mBsnName").attr("value"),
bsnCity: $("#mBsnCity").attr("value"),
bsnAddress: $("#mBsnAddress").attr("value"),
bsnMenu: $("#mBsnMenu").attr("value"),
bsnLat: bsnLat,
bsnLong: bsnLong
},
function () {
$("#mBsnName").attr("value", "");
$("#mBsnCity").attr("value", "");
$("#mBsnAddress").attr("value", "");
$("#mBsnMenu").attr("value", "");
alert("Business was added successfully ");
}
);
}
Inside your mAddBusiness() function you can just do your validation before sending the AJAX request. Something like:
function mAddBusiness() {
if ($("#mBsnName").val() !== '') {
$.getJSON("API.php", {
command: "addBusiness",
bsnName: $("#mBsnName").val(),
bsnCity: $("#mBsnCity").val(),
bsnAddress: $("#mBsnAddress").val(),
bsnMenu: $("#mBsnMenu").val(),
bsnLat: bsnLat,
bsnLong: bsnLong
},
function () {
$("#mBsnName").val("");
$("#mBsnCity").val("");
$("#mBsnAddress").val("");
$("#mBsnMenu").val("");
alert("Business was added successfully ");
}
);
} else {
alert('Please enter a business name.');
}
}
Note that you will have to add the data-ajax="false" attribute to the <form> tag in question so that jQuery Mobile does not attempt to submit the form itself.
Also, note that $('input').attr('value') will not return the current value of an input, it will return the initial value before the user had a chance to input anything. To get the current value of a form input, use .val(): http://api.jquery.com/val

How to avoid redirect after form submission if you have a URL in your form's action?

I have a form that looks like this:
<form name="formi" method="post" action="http://domain.name/folder/UserSignUp?f=111222&postMethod=HTML&m=0&j=MAS2" style="display:none">
...
<button type="submit" class="moreinfo-send moreinfo-button" tabindex="1006">Subscribe</button>
In the script file I have this code segment where I submit the datas, while in a modal box I say thank you for the subscribers after they passed the validation.
function () {
$.ajax({
url: 'data/moreinfo.php',
data: $('#moreinfo-container form').serialize() + '&action=send',
type: 'post',
cache: false,
dataType: 'html',
success: function (data) {
$('#moreinfo-container .moreinfo-loading').fadeOut(200, function () {
$('form[name=formi]').submit();
$('#moreinfo-container .moreinfo-title').html('Thank you!');
msg.html(data).fadeIn(200);
});
},
Unfortunately, after I submit the datas, I'm navigated to the domain given in the form's action. I tried to insert return false; in the code (first into the form tag, then into the js code) but then the datas were not inserted into the database. What do I need to do if I just want to post the data and stay on my site and give my own feedback.
I edited Eric Martin's SimpleModal Contact Form, so if more code would be necessary to solve my problem, you can check the original here: http://www.ericmmartin.com/projects/simplemodal-demos/ (Contact Form)
Usually returning false is enough to prevent form submission, so double check your code. It should be something like this
$('form[name="formi"]').submit(function() {
$.ajax(...); // do your ajax call here
return false; // this prevent form submission
});
Update
Here is the full answer to your comment
I tried this, but it didn't work. I need to submit the data in the succes part, no?
Maybe, it depends from your logic and your exact needs. Normally to do what you asking for I use the jQuery Form Plugin which handle this kind of behavior pretty well.
From your comment I see that you're not submitting the form itself with the $.ajax call, but you retrieve some kind of data from that call, isn't it? Then you have two choices here:
With plain jQuery (no form plugin)
$('form[name="formi"]').submit(function() {
$.ajax(...); // your existing ajax call
// this will post the form using ajax
$.post($(this).attr('action'), { /* pass here form data */ }, function(data) {
// here you have server response from form submission in data
})
// this prevent form submission
return false;
});
With form plugin it's the same, but you don't have to handle form data retrieval (the commented part above) and return false, because the plugin handle this for you. The code would be
$(document).ready(function() {
// bind 'myForm' and provide a simple callback function
$(form[name="formi"]).ajaxForm(function() {
// this call back is executed when the form is submitted with success
$.ajax(...); // your existing ajax call
});
});
That's it. Keep in mind that with the above code your existing ajax call will be executed after the form submission. So if this is a problem for your needs, you should change the code above and use the alternative ajaxForm call which accepts an options object. So the above code could be rewritten as
$(document).ready(function() {
// bind 'myForm' and provide a simple callback function
$(form[name="formi"]).ajaxForm({
beforeSubmit: function() { $.ajax(...); /* your existing ajax call */},
success: function(data) { /* handle form success here if you need that */ }
});
});

get $.post to work with the validate plugin on multiple forms without seperate functions

On a fansite im doing http://yamikowebs.com/ee/
I have a few forms (2 atm). I used $.post to find out what form is being submited. submit the form and display that pages results where the form was originally with .html().
My next step was to use the validator which is working fine but im not sure how to put the 2 together.
submitHandler: function(form){} seems to be the setting for how its submitted. However, I can't get this to work with my $.post function or find out what form is being processed.
If I leave the defaults for validation plug-in if there no errors it will send you to the page. the ajax plug-in that it works with doesn't do what I want. Below is my $.post function
form validation:
//ajax post
$("form").submit(function(event)
{
event.preventDefault();//stop from submiting
//set needed variables
var $form = $(this)
var $div = $form.parent("div")
$url = $form.attr("action");
//submit via post and put results in div
$.post( $url, $form.serialize() , function(data)
{ $div.html(data) })
})
http://docs.jquery.com/Plugins/validation#source is the validation plugin
You're correct in thinking that submitHandler is the right callback to use. However, I ran into some interesting issues while using it with multiple forms (like you're trying to do). For example, in this code:
$("#form1, #form2").validate({
submitHandler: function(form) {
alert(form.action);
alert(form.id);
}
});
The submitHandler callback does not get supplied the correct parameter (it always gets #form1). I believe this is actually a bug in jQuery-validate (so I've filed it here).
Anyway, a decent workaround would be to wrap the validate call in .each():
$("form").each(function() {
$(this).validate({
submitHandler: function(form) {
/* 'form' has the correct value */
var values = $(form).serialize(),
$div = $(form).parent("div");
alert(form.action);
alert(form.id);
/* Perform AJAX call here */
}
});
});
Example: http://jsfiddle.net/andrewwhitaker/MmCXN/

Resources