I am using contact from 7 plugin and my question is to open contact form 7 in popup via wordpress admin ajax but my code not working. Only popup open but contact form 7 not submitting. It is redirecting in admin ajax url and returns 0.
Here is the code that i am doing in functions.php
<?php
add_action('wp_head', 'my_action_popup_cf7_javascript');
function my_action_popup_cf7_javascript() {
?>
<script type="text/javascript" >
jQuery(document).ready(function($) {
$('.myajaxcarrer').click(function(){
//alert(1);
var mydata = $(this).data();
$(".overlay").fadeIn('slow');
var data = {
action: 'my_action_popup_cf7',
//whatever: 1234,
id: mydata.id
};
// since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
//console.log(ajaxurl);
$('.item').removeClass('active');
$('[data-id=' + mydata.id + ']').parent().addClass('active');
$.post('<?php echo esc_url( home_url() ); ?>/wp-admin/admin-ajax.php', data, function(response) {
// alert('Got this from the server: ' + response);
$('#testcarrer').html(response);
var offset = $(window).scrollTop();
$(".career-form").css("top", offset+50 );
$('.closeBtn').click(function(e){
e.preventDefault();
$(".overlay").fadeOut('slow');
$('.career-form').css("top", -1000+"%" )
});
});
});
});
</script>
<?php
}
add_action('wp_ajax_my_action_popup_cf7', 'my_action_popup_cf7_callback');
add_action( 'wp_ajax_nopriv_my_action_popup_cf7', 'my_action_popup_cf7_callback' );
function my_action_popup_cf7_callback() {
global $wpdb; // this is how you get access to the database
//$whatever = 'ID=> '. $_POST['id'];
//echo $whatever;
?>
X
<h3>Apply Now</h3>
<div class="formBox">
<?php echo do_shortcode('[contact-form-7 id="905" title="My New Carrer Form"]'); ?>
</div>
<?php
exit(); // this is required to return a proper result & exit is faster than die();
}
And code in page template file is
<span class="applyBtn"><a class="myajaxcarrer" data-id="903">Apply Now</a></span>
<div class="overlay"></div>
<div class="career-form">Ajax result Load here..</div>
And js code is below.
$('.applyBtn').click(function(e){
e.preventDefault();
var offset = $(window).scrollTop();
$(".overlay").fadeIn('slow');
$(".career-form").css("top", offset+50 )
});
$('.closeBtn, .overlay').click(function(e){
e.preventDefault();
$(".overlay").fadeOut('slow');
$('.career-form').css("top", -1000+"%" )
});
You can open it by echoing do_shortcode('[form name with id]'); it in you php function.
Related
I'm currently in the process of rewriting an entire site of mine so that it's compatible with CI. I'm fairly new with CI and the MVC pattern in general. I followed this tutorial and have made a pretty decent template for the view part of the MVC pattern. The thing is, a lot of my site uses jQuery/AJAX to make it more dynamic. For example, on all of my pages on my site, I have an input field that uses jQuery to load a PHP file upon keyup.
<script type="text/javascript">
$("#search_bar").keyup(function(){
var search = $("#search_bar").val();
var url = "search_bar.php";
var data = "q="+ search;
$('#livesearch').load(url, data);
$("#livesearch").slideDown("fast");
});
</script>
<input type='text' maxlength='30' id='search_bar' autocomplete='off' placeholder='Browse Teams' />
<div id='livesearch' style='display:none;'></div>
All of the backend work that's required to load the results happens in the PHP file that loaded via jQuery (search_bar.php). So, should "search_bar" be its own View that's triggered by its own Controller and then Modeled by a model called "search_bar"? Again, I'm very new to the MVC pattern and am not quite sure how properly integrate AJAX with a object oriented framework like CI.
Thanks
Directly calling the view in ajax request is not a good practice call the controller which loads the view or directly do the stuff in the controller's function
<script type='text/javascript'>
$('#search_bar').keyup(function(){
$.ajax({
url: 'yourcontrollername/search_bar_yourfunction',
type:'POST',
data: {q: search,
success: function(result){
$("#livesearch").html(result);
$("#livesearch").slideDown("fast");
}
});
});
</script>
Your controller code
class yourcontrollername extends My_Controller {
public function search_bar_yourfunction() {
//do your stuff and store in the $data[] array
$this->load->view("search_bar",$data); //search_bar.php
die();
}
}
}
You should go from your View to the Controller:
<script type='text/javascript' language='javascript'>
$('#search_bar').keyup(function(){
$.ajax({
url: 'search_bar.php',
type:'GET',
data: {q: search,
success: function(result){
//Insert code here
} // End of success function of ajax form
}); // End of ajax call
});
</script>
Then in your controller, load a model if necessary:
public function weigeren() {
$user = $this->CI->authex->getUserInfo();
$data['title'] = "Test";
$this->load->model('search_model');
$query = $this->input->get('q');
if (isset($user)) {
echo $this->search_model->search($query);
}
}
I find one way to load ajax (jquery) in CodeIgniter 3. Example,
structure of folder:
controllers/Upload.php
view/admin/ajax_view/ajax_images.php
controllers/upload:
public function process()
{
$data['my_picture'] = array(
'pic_id' => '1',
'pic_path' => 'http://example.com/images',
);
$this->load->view('admin/ajax_view/ajax_images', $data);
}
view/admin/ajax_view/ajax_images:
<?php foreach($my_picture as $key => $row): ?>
<td><?php echo $my_picture['pic_path']; ?></td>
<?php endforeach; ?>
view/admin/form_upload:
<tbody>
<tr class="trbody">
<th scope="row">1</th>
<!-- <td></td> --> <!--comments this because appends element jquery-->
</tr>
</tbody>
<script type="text/javascript">
$(document).ready(function(){
$('#my_button').click(function(e){
e.preventDefault;
$.ajax({
url: 'upload/process',
dataType: 'text',
type: 'post',
success: function(data){
$('.trbody')
.append(
'<td>'+ data + '</td>'
);
},
error: function(errorThrown){
console.log(errorThrown);
}
});
});
});
</script>
To this way, I separated view of ajax of whole pages and load ajax view when
event trigger.
I have followed a tutorial on an ajax lookup that informs the user if the username is already taken.
So the controller syntax is:
<?php
class Login extends CI_Controller
{
function index()
{
$this->load->view('loginView');
}
function getResultfromdb($username){
$this->db->where('username',$username);
$query = $this->db->get('users')->num_rows();
if($query == 0 ) echo 'userOk';
else echo 'userNo';
}
}
the view is:
<html>
<head>
<title>Check User Name</title>
<link type="text/css" rel="stylesheet" href="<?=base_url()?>css/style.css"/>
</head>
<body>
<form method="post" action="">
<label for="username">Enter Your Name</label>
<input type="text" id="username"/>
<span class="checkUser" ></span>
<input type="hidden" class="hiddenUrl"/>
</form>
<script type="text/javascript" src="<?=base_url()?>js/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="<?=base_url()?>js/check.js"></script>
</body>
</html>
the check.js is:
$(document).ready(function(){
$('#username').blur(function(){
if( $('#username').val().length >= 3 )
{
var username = $('#username').val();
getResult(username);
}
return false;
})
function getResult(name){
var baseurl = $('.hiddenUrl').val();
$('.checkUser').addClass('preloader');
$.ajax({
url : baseurl + 'index.php/login/getResultfromdb/' + name,
cache : false,
success : function(response){
$('.checkUser').removeClass('preloader');
if(response == 'userOk') $('.checkUser').removeClass('userNo').addClass('userOk');
else $('.checkUser').removeClass('userOk').addClass('userNo');;
}
})
}
})
As mentioned, this works great. so it will validate bob and andy perfectly. however it fails on bob smith and andy jones. How can the code be adapted to validate strings with spaces?
Thanks as always,
It's failing because you're trying to pass the username in the URL, the browser is likely encoding the space as %20 when passing it. So your CI function is looking for bob%20smith and not bob smith.
First of all I don't think it's great practice to even allow spaces in user names but to each their own. You need to decode the URL first
function getResultfromdb($username){
$this->db->where('username',urldecode($username));
$query = $this->db->get('users')->num_rows();
if($query == 0 ) echo 'userOk';
else echo 'userNo';
}
use the encodeURIComponent(string),for example :
var name = encodeURIComponent(name);
and you js will look like this
$(document).ready(function(){
$('#username').blur(function(){
if( $('#username').val().length >= 3 )
{
var username = $('#username').val();
getResult(username);
}
return false;
})
function getResult(name){
var name = encodeURIComponent(name); // Replace name before send it
var baseurl = $('.hiddenUrl').val();
$('.checkUser').addClass('preloader');
$.ajax({
url : baseurl + 'index.php/login/getResultfromdb/' + name,
cache : false,
success : function(response){
$('.checkUser').removeClass('preloader');
if(response == 'userOk') $('.checkUser').removeClass('userNo').addClass('userOk');
else $('.checkUser').removeClass('userOk').addClass('userNo');;
}
})
}
})
and the php :
<?php
$url = urldecode($_GET['name']); // Replace with your parameter
?>
Okay good luck
I'm new to stackoverflow and to CodeIgniter and I'm currently experimenting on some simple code examples I have found on the Internet in order to get a start. The one I'm working on right now is a form which uses CI and Ajax (jQuery) along with saving the inputs of the form in a database and then display the most recent of them on the same page as the form.
If I confused you it's the 4.7 application example from here. The initial source code lies here but I have modified it in order to work with the latest release of CI and I quote all my MVC files just below.
Controller:
<?php
class Message extends CI_Controller
{
function __construct()
{
parent::__construct();
$this->load->helper('form');
$this->load->helper('url');
$this->load->helper('security');
$this->load->model('Message_model');
}
function view()
{
//get data from database
$data['messages'] = $this->Message_model->get();
if ( $this->input->is_ajax_request() ) // load inline view for call from ajax
$this->load->view('messages_list', $data);
else // load the default view
$this->load->view('default', $data);
}
//when we pres the submit button from the form
function add()
{
if ($_POST && $_POST['message'] != NULL)
{
$message['message'] = $this->security->xss_clean($_POST['message']);
$this->Message_model->add($message);
}
else
{
redirect('message/view');
}
}
}
?>
Model:
<?php
class Message_model extends CI_Model
{
function __construct()
{
parent::__construct();
$this->load->database();
}
function add($data)
{
$this->db->insert('messages', $data);
}
function get($limit=5, $offset=0)
{
$this->db->order_by('id', 'DESC');
$this->db->limit($limit, $offset);
return $this->db->get('messages')->result();
}
}
?>
Views
default.php:
<!-- called using message/view -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="<?php echo base_url('js/jquery-1.8.1.min.js'); ?>" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function()
{
$('#submit').click(function(e)
{
e.preventDefault();
var msg = $('#message').val();
$.post("", {message: msg}, function() {
$('#content').load("");
$('#message').val('');
});
});
});
</script>
</head>
<body>
<?php echo form_open("message/add"); ?>
<input type="text" name="message" id="message">
<input type="submit" value="submit" name="submit" id="submit">
<?php echo form_close(); ?>
<div id="content"></div>
</body>
</html>
messages_list.php:
<!-- called from ajax call -->
<ol>
<?php foreach ($messages as $cur): ?>
<li><?php echo $cur->message; ?></li>
<?php endforeach; ?>
</ol>
The problem mainly lies in the 1st of the views (default.php). That is, if I omit the e.preventDefault(); line from the javascript code then the form loads a different page (message/add as the form action parameter implies) which is a blank page, also cancelling the ajax behavior of my application that way.
On the other hand, if I actually add this line then the add method of my message controller isn' t called, thus not adding what I've typed into the database.
Finally, I tried the following js code instead of the other above:
$(document).ready(function()
{
$('#submit').click(function(e)
{
e.preventDefault();
var msg = $('#message').val();
$.post("<?php echo base_url(); ?>message/add", {message: msg}, function() {
$('#content').load("");
$('#message').val('');
});
});
});
but that way it seems as the $.post() crashes because nothing is executed in the function which is supposed to run on a successful post() call.
Any help appreciated and sorry for the big post. :)
You are correct that you must call e.PreventDefault();, but you must also deal with the response from the callback function, which you are not. The callback takes a few arguments but the first one is what you're interested in, it is the response from your server. I've denoted it as r below:
$(document).ready(function(){
$('#submit').click(function(e){
e.preventDefault();
var msg = $('#message').val();
$.post("<?php echo base_url(); ?>message/add", {message: msg}, function(r) {
//do something with r... log it for example.
console.log(r);
});
});
});
I've also removed $.("#content").load(...);. This would actually perform another AJAX request when the first one is complete.
Now, inspecting your controller...please refrain from using $_POST. CodeIgniter provides you with $this->input->post() as part of the Input Library. If you turn on Global XSS filtering in config/config.php you won't have to xss clean it either. You can clean on a post-by-post basis by using $this->input->post('name', true);
I recommend this instead:
function add(){
$m = $this->input->post('message', true);
if($m){
$this->Message_model->add($m);
}
}
The problem doesn't lie with the CI, its the JS that is wrong,
$(document).ready(function()
{
$('#submit').click(function(e)
{
e.preventDefault();
var msg = $('#message').val();
$.post("<?php echo base_url(); ?>message/add", {message: msg}, function() {
$('#content').load("<?php echo base_url(); ?>/message/view");
$('#message').val('');
});
});
});
The e.preventDefault() is used to stop the default behaviour of the submit button (which will take you to message/add), which we don't want. You are correct in adding the URl paramter to the $.post() function later, but in the callback function, the .load loads the URL that is passed to it into the #content, so without passing any url, of course there won't be anything to load.
I am having massive problems re-parsing my dojo elements in an ajax response in Zend framework. I have a simple validationTextBox and a submit button. When the index page is first rendered, all the dojo/dijit tundra styles/attributes etc are parsed correctly. However, when I have an ajax call that rebuilds the dojo form and posts it back to the Index View. The form if posted back ok but the tundra styles are no longer working. I have tried so many different things but have spent many hours getting nowhere. I thank anyone in advance who attempts to assist. I have added the simplest example to this post to explain.
layout.phtml
<?php
echo '<?xml version="1.0" encoding="UTF-8"?>';
echo $this->doctype();
?>
<html>
<head>
<meta content="text/html; charset=UTF-8" />
<script>
function showForm()
{
dojo.xhrGet( {
url: "../public/index.php?ajax=true",
// The load function is called on successful response from server
// It inserts the response to the HTML div “put_here” placeholder
handleAs:"text",
sync:true,
load: function(response, ioArgs)
{ dojo.byId("welcome").innerHTML = response;
return response;
},
// The error function displays error message if server does not
// respond right
error: function(response, ioArgs)
{
console.error("HTTP status code: ", ioArgs.xhr.status);
return response;
}
});
// dojo.parser.parse(dojo.byId("welcome"));
}
</script>
<?php
echo $this->headTitle();
echo $this->headStyle();
echo $this->headScript();
echo $this->dojo()->setDjConfigOption('parseOnLoad', true);
echo $this->dojo()->addStyleSheetModule('dijit.themes.tundra');
echo $this->dojo();
?>
</head>
<body class='tundra'>
<div id='ajaxcontent'>
<?php echo $this->layout()->content; ?>
</div>
</body>
indexController.php
<?php
//require_once '../public/js/custom.js';
class IndexController extends Zend_Controller_Action
{
public function init()
{
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('index', 'html')
->initContext();
}
public function indexAction()
{
$form = new Zend_Dojo_Form('dojoForm', array('dojotype'=> 'dijit.layout.ContentPane'));
$element = new Zend_Dojo_Form_Element_ValidationTextBox('TestBoxName',
array(
'id' => 'TextBoxId',
'required' => true
)
);
$button = new Zend_Dojo_Form_Element_Button('TestButton',
array(
'value'=> 'Button',
'onclick' => 'showForm()'
));
$form->addElements(array($element,$button));
$this->view->form = $form;
}
}
View index.phtml
<div id="welcome" >
<?php
echo $this->form;
?>
Try to run your page through the http://validator.w3.org/ - it is probably the DOCTYPE, and issues with non-closed tags?
The line with addStyleSheetModule simply adds a css file, the class set on your <body> asserts, that all nodes below body 'inherits' the theme (CSS selectors). Selectors however is highly depending on wellconstructed DOM (hence the validation)
But the main issue here seems to be that the dijit classes are not set - probably because data-dojo-type's are not initialized. There are two approaches
1.1 In layout.phtml
function showForm() { dijit.byId('welcome').set('href', '../public/index.php?ajax=true'); }
1.2 In index.phtml
Create a contentpane (which defaults to parseOnLoad) in your <div id='welcome'..
<div id="welcome" data-dojo-type="dijit.layout.ContentPane">
2.0 call parser manually
load: function(response, ioArgs)
{ var domnode = dojo.byId("welcome");
domnode.innerHTML = response;
dojo.parser.parse(domnode);
return response;
}
I'm adding a button to every list_item on page.
The buttons are generated, with their correct id.
And the button value changes as it should - as shown in the alert.
But on a single button click, the alert fires as many times as there are buttons on the page.
The alert always shows the same (and correct) button id.
Without the alert, this causes the button value to switch back and forth if other buttons are clicked in the meantime.
Generate the buttons:
function create_saved_message_button( ) {
$button_label = "Save";
?>
<td width="15%" class="thread-options">
<input type="button" class="savedbutton" value = "<?php echo $button_label ?>" id = "<?php echo message_thread_id(); ?>" />
</td>
<?php
}
The ajax:
function saved_message_button_javascript() {
?>
<script type="text/javascript" >
jQuery(document).ready(function($) {
$('.savedbutton').click(function(event){
event.preventDefault();
var button = $(this);
var butt_txt = $(button).attr('value');
alert($(button).attr("id"));
$(button).attr({'disabled': true});
var data = {
action: 'saved_button_clicked',
};
$.get(ajaxurl, data, function(response) {
if(butt_txt == 'Save') {
$(button).attr('value', 'Un-Save');
}
else {
$(button).attr('value', 'Save');
}
});
$(button).attr({'disabled': false});
return false;
});
});
</script>
<?php
}
Is there any way to stop the multiple alerts?
I think that would solve the value switching problem.
Then I just need to pass the button id to the php function saved_button_clicked
The add_actions:
add_action( 'messages_inbox_list_item', 'create_saved_message_button', 1 );
//this was the problem
//add_action('messages_inbox_list_item', 'saved_message_button_javascript');
//the solution - use this instead
add_action('after_member_messages_threads', 'saved_message_button_javascript');
add_action('wp_ajax_saved_button_clicked', 'process_save_button_clicked');
Maybe I misunderstood something. I created a html with 5 buttons and your javascript in it but I couldn't find the behavior you described. Look here.