how to check if the request is from Ajax Mojolicious?
I tried to use Mojo::Message::Request
use Mojo::Message::Request;
my $req = Mojo::Message::Request->new;
my $bool = $req->is_xhr;
$req->is_xhr it is explained "Check X-Requested-With header for XMLHttpRequest value."
But I don't see any value returned.
Thanks in advance!
The returned value is a boolean, look at the example code snippet below:
post '/ajax' => sub {
my $c = shift;
my $is_xhr = $c->req->is_xhr;
$c->render( text => sprintf('Is XHR: %s',($is_xhr)?'true':'false'));
};
I have a created a demo at https://limitless-eyrie-46853.herokuapp.com/ajax
Related
I've been struggling for a few days with this issue and I really hope you can help me out.
I've created a plugin, which is located in:
'/wp-content/plugins/my-cool-plugin'.
My plugin allows users to post a custom post type via a form on a public page, basically anyone should be able to post something.
Using jQuery, I listen to when my frontend form is submitted and using Ajax I pass the data from the form to a php file to process it into a post.
This file is located at:
'/wp-content/plugins/my-cool-plugin/inc/processor.php'.
Below is the content of my processor file:
$var1= $_POST['some'];
$var2= $_POST['data'];
$new_post = array(
'post_type' => 'my_custom_post',
'post_status' => 'publish',
'mcp_1' => $var1,
'mcp_2' => $var2
);
$post_id = wp_insert_post( $new_post, $wp_error );
if ($wp_error == 'false'){
$post_url = get_permalink( $post_id );
echo $post_url;
}else {
// some sort of error
}
When I test my form, it results in the following error:
Call to undefined function wp_insert_post() on line ... which is the following line:
$post_id = wp_insert_post( $new_post, $wp_error );
Do I need to include something since I'm not in the WordPress 'scope' anymore?
Or is there another (much better) way for inserting custom posts from a front end form?
Why are you running the file out of wordpress scope? That is not the best practive. Instead you could run it in wordpress scope and user wordpress native ajax.
add_action('wp_ajax_yourplugin_create_post', 'yourplugin_create_post');
add_action('wp_ajax_nopriv_yourplugin_create_post', 'yourplugin_create_post');
function yourplugin_create_post() {
// your code here
}
Then you would need your ajax url to be passed from php to js:
function your_plugin_ajaxurl() {
?>
<script type="text/javascript">
var yourPluginAjaxUrl = "<?php echo admin_url('admin-ajax.php'); ?>";
</script>
<?php
}
add_action('wp_head','your_plugin_ajaxurl');
Then you can use your ajax request but you would need to indicate action:yourplugin_create_post and url = yourPluginAjaxUrl
Try adding
require(dirname(__FILE__) . '/wp-load.php');
It took me some time to process Nick's answer, but I finally got it to work! Like Nick said, I dropped using the process file because is was out of the scope of WordPress. I moved my post creation from my proces file to a new function in the plugin init file (my-cool-plugin.php), as Nick suggested. This resulted in the following new function:
add_action('wp_ajax_coolplugin_create_post', 'coolplugin_create_post');
add_action('wp_ajax_nopriv_coolplugin_create_post', 'coolplugin_create_post');
function coolplugin_create_post() {
$var1 = $_POST['some'];
$var2 = $_POST['data'];
$new_post = array(
'post_type' => 'my_custom_post',
'post_status' => 'publish'
'post_title' => 'Some title'
);
$post_id = wp_insert_post( $new_post, $wp_error );
// check if there is a post id and use it to add custom meta
if ($post_id) {
update_post_meta($post_id, 'mcp_1', $var1);
update_post_meta($post_id, 'mcp_2', $var2);
}
if ($wp_error == false){
$post_url = get_permalink( $post_id );
echo $post_url;
}else {
// some sort of error
}
}
I also had to change the way I inserted my custom values into the newly created post, because the wp_insert_post() function only accepts default post parameters (see the wp_insert_post documentation for these parameters).
Next to my insert/create post function I also had to make some adjustments to my javascript file, which retrieves the filled in data from my form. Therefore (as Nick suggested) I needed to pass my Ajax URL from PHP to JS by adding the following function to my-cool-plugin.php like this:
function your_plugin_ajaxurl() { ?>
<script type="text/javascript">
var coolPluginAjaxUrl = "<?php echo admin_url('admin-ajax.php'); ?>";
</script>
<?php }
add_action('wp_head','your_plugin_ajaxurl');
By adding the coolPluginAjaxUrl variable to the head I'm able to use the URL in my javascript to post the data to when my form is submitted, like this:
$( '#form' ).on( 'submit', function(e) {
var request;
e.preventDefault();
var val_one = $( '#val-one' ).val();
var val_two = $( '#val-two' ).val();
var formData = {
action: 'coolplugin_create_post',
some: val_one,
data: val_two,
};
request = $.ajax({
type: 'POST',
url: coolPluginAjaxUrl,
data: formData,
});
});
The formData holds the coolplugin_create_post action defined in PHP and the request is posted to the coolPluginAjaxUrl URL, defined in the head.
Thanks Nick for pointing me into the right direction and I hope that my solution will also help others. Please note that I've stripped my code of several security measures for others to easily understand how the code works.
I have an <ul id="keuze_lijst"> , an input field with id #sykje and an button with class .search .
Now when i press the button i would like to clear the UL and repopulate it with data, for this i currently got this .js file.
$(document).ready(function() {
$(".search").click(function(){
var searchValue = $("#sykje").val();
$("#keuze_lijst").empty();
$.ajax({
url: 'http://www.autive.nl/frysk/simulator/sim.php?action=getSongs&search='+searchValue,
data: "",
dataType: 'json',
success: function(rows) {
for(var i in rows){
var row = rows[i];
var id = row[1];
var titel = row[2];
var artiest = row[9];
$("#keuze_lijst").append("<li class='mag_droppen'>"+
"<div class='song_left'>"+
"<div class='titel'>"+titel+"</div>"+
"<div class='artiest'>"+artiest+"</div>"+
"</div><!-- .song_left -->"+
"</li>");
}
}
});
});
});
When i remove the ajax command and put something like $("#keuze_lijst").html("hello"); it works fine. But the ajax command isn't working. Though the var searchValue does his work. (ajax uses the correct url). And when i enter that url the page echoes an fine json with multiple rows.
But in my page the ajax script isn't adding the <li>.
What am i doing wrong?
edit: added an jsfiddle -> http://jsfiddle.net/TVvKb/1/
.html() totally replaces the HTML. So at the end, your "#keuze_list will contain </li>.
Just execute one html() command after you build your html into a string var or something.
From a quick glance, I can say that the problem might be with your use of the html() function. This actually replaces the entire html content.
You might want to try using append() or prepend().
Possible Problems:
You are running into a Same Origin Problem. Per default you can only make Ajax-Requests to your own domain. If you need to make cross-domain calls use JSONP or CORS.
Use the html() only once, and hand over your complete string, otherwise you will override your previous html all the time.
You are not landing in the success handler due to an error (e.g. invalid JSON).
Not sure, but I think if you insert a string in the .append() and other jQuery methods, it parses to (valid) HTML first. That means that unclosed tags are closed, making your HTML invalid.
$('<div />'); // parses to <div></div>
So, I assume that your DOM ends up like this this:
$('ul').append('<li>').append('foo').append('</li>'); // <ul><li></li>foo</li></ul>
Please, just format your string first. You don't want jQuery to parse every input.
var str = '<li>';
str += 'foo';
str += '</li>';
$('ul').html(str);
For cross-domain AJAX requests (without JSONP):
proxy.php
header('Content-Type: application/json');
if(empty($_GET['search'])) exit;
$url = 'http://www.autive.nl/frysk/simulator/sim.php?action=getSongs&search=' . $_GET['search'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_exec($ch);
curl_close($ch);
Javascript
$.getJSON({
url: 'proxy.php&search='+searchValue,
success: callback
});
In my CakePHP 1.3 version, I have two submit type image tags as mentioned below:
echo $form->submit('save-print.jpg' , array('name'=>'savenprint','value'=>"savenprint",'id'=>"savenprint"));
echo $form->submit('save.jpg');
Now, What I want is to identify in my Controller, that which button is submitted, whether "Save" or "Print & Save"
So I have applied name and value to each of them and in Chrome browser, i am getting name and value pair, while in Mozilla Firefox, I do not get the same.
Any idea, how that can be achieved? or what is wrong or missing in my code.
Earliest response will be appreciated.
Thanks !
Your Form should looks like:
echo $form->submit('save-print.jpg' , array('name'=>'savenprint','value'=>"save",'id'=>"savenprint"));
echo $form->submit('save.jpg', array('name'=>'savenprint','value'=>"savenprint",'id'=>"savenprint"));
In your Controller use:
if($this->data['ModelName']['sbmtfrm_x'] == 'save')
{
//Your save code here
}
else if($this->data['ModelName']['sbmtfrm_x'] == 'savenprint')
{
//Your savenprint code here
}
One another solution is to make a hidden field and set the value of it onclick of submit button in your jquery code like in the following way:
Your form:
echo $form->submit('save-print.jpg' , array('name'=>'savenprint','value'=>"save",'id'=>"savenprint", 'class' => 'submitBtn'));
echo $form->submit('save.jpg', array('name'=>'savenprint','value'=>"savenprint",'id'=>"savenprint", 'class' => 'submitBtn'));
echo $form->hidden('sbmtValue', array('id' => 'sbmtValue', 'value' => ''));
And your jquery code should looks like:
$(document).ready(function(){
$('.submitBtn').click(function(){
$('#sbmtValue').val($(this).val());
});
});
And in your controller's action use:
if($this->data['ModelName']['sbmtValue'] == 'save')
{
//Your save code here
}
else if($this->data['ModelName']['sbmtValue'] == 'savenprint')
{
//Your savenprint code here
}
Hope it will work for you.
I have a form which is generated from a database. In the database I have strings such as 'Española' which will become options in a drop down menu.
A the moment my html looks like:
<option value="Española">Española</option>
I am using these values for a dynamic part of the form from which I need to send AJAX requests.
I can see that, when using IE, the header is like so:
GET /collections/find_island?island_group=Espa�ola HTTP/1.1" 500 63206
when it should be:
GET /collections/find_island/?island_group=Espa%C3%B1ola HTTP/1.1" 200 164
As generated by other browsers.
Is there some way I can get this output in my template:
<option value="Espa%C3%B1ola">Española</option>
Any help much appreciated.
EDIT:
My form:
def form(forms.Form):
...
island_group = forms.ModelChoiceField(
required=False,
label=ugettext_lazy('Island Group'),
initial=None,
queryset=Localityonline.objects.values_list('islandgroup', flat=True).distinct('islandgroup').order_by('islandgroup'),
empty_label=ugettext_lazy("Not Specified"),
widget=forms.Select(attrs={"class":'searchfield', "onChange":'getIslandName()'})
)
the javascript:
function getIslandName(lang) {
var islandGroup = document.getElementById("id_island_group").value;
if (islandGroup == '') {
// if Not Specified re-selected then set data to null and bypass updatePage()
var data = null;
update_select($('select[name=island_name]'), data);
}
else {
var url = "../collections/find_island?island_group=" + islandGroup;
request.open("GET", url, true);
request.onreadystatechange = updatePage;
request.send(null);
}
}
You can call encodeURI in javascipt to give the encoded value that you are looking for. Perhaps mozilla and chrome do it automatically and IE doesn't???
encodeURI('Española')
// "Espa%C3%B1ola"
var url = "../collections/find_island?island_group=" + encodeURI(islandGroup);
or encode the whole url I don't know which one makes more sense...
Encode URL in JavaScript?
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/encodeURIComponent
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/encodeURI
For a project I need to get the source code of web page of different other domains.
I have tried following code:
$('#container').load('http://google.com');
$.ajax({
url: 'http://news.bbc.co.uk',
type: 'GET',
success: function(res) {
var headline = $(res.responseText).find('a.tsh').text();
alert(headline);
}
});
Still I am not getting any results but just a blank alert box.
By default all browsers restrict cross-domain requests, you can get around this by using YQL as a proxy. See a guide here: http://ajaxian.com/archives/using-yql-as-a-proxy-for-cross-domain-ajax
For security reasons scripts aren't able to access content from other domains. Mozilla has a long article about HTTP access control, but the bottom line is that without the website themselves adding support for cross-domain requests, you're screwed.
This code is Working Perfectly with the help of JQuery and YQL
$(document).ready(function(){
var container = $('#target');
$('.ajaxtrigger').click(function(){
doAjax($(this).attr('href'));
return false;
});
function doAjax(url){
if(url.match('^http')){
$.getJSON("http://query.yahooapis.com/v1/public/yql?"+
"q=select%20*%20from%20html%20where%20url%3D%22"+
encodeURIComponent("http://www.yahoo.com")+
"%22&format=xml'&callback=?",
function(data){
if(data.results[0]){
var data = filterData(data.results[0]);
container.html(data);
} else {
var errormsg = '<p>Error: could not load the page.</p>';
container.html(errormsg);
}
}
);
} else {
$('#target').load(url);
}
}
function filterData(data){
data = data.replace(/<?\/body[^>]*>/g,'');
data = data.replace(/[\r|\n]+/g,'');
data = data.replace(/<--[\S\s]*?-->/g,'');
data = data.replace(/<noscript[^>]*>[\S\s]*?<\/noscript>/g,'');
data = data.replace(/<script[^>]*>[\S\s]*?<\/script>/g,'');
data = data.replace(/<script.*\/>/,'');
return data;
}
});
The solution for your case is JSON with padding or JSONP.
You will need an HTML element that specified for its src attribute a URL that returns JSON like this:
<script type="text/javascript" src="http://differentDomain.com/RetrieveUser?UserId=1234">
You can search online for a more in-depth explanation, but JSONP is definitely your solution for this.
Do the following steps.
1: Add datatype:jsonp to the script.
2: Add a "callback" parameter to the url
3: Create a javascript function with name same as "callback" param value.
4: The output can be received inside javascript function.
Found one more solution for this :
function getData(url){
if(url.match('^http')){
$.get(url,
function(data){
process(data);
}//end function(data)
);//end get
}
}
This is really a pretty easier way to handle cross-domain requests. As some of the sites like www.imdb.com rejects YQL requests.