I have this demo website that I'm making:
https://theme.artware.gr/
The problem I am facing is on the search functionality. You can click on the right/top side search to see the issue. When I am logged-in as admin, the search works fine, but when I view the page as a guest I get the error: "You do not have sufficient permissions to access this page".
This is my code so far:
// AJAX Search (no WooCommerce)
if ( !class_exists( 'WooCommerce' ) ) {
function simple_search_scripts(){
wp_enqueue_script( 'simple_search', get_stylesheet_directory_uri() . '/js/search.js', array(), '1.0.0', true);
wp_localize_script('simple_search', 'myAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php', 'relative' ), 'nonce' => wp_create_nonce('ajax-nonce') ));
}
// Create shortcode
function simple_search(){
simple_search_scripts(); ?>
<input type="text" name="keyword" id="keyword" onkeyup="fetch()" placeholder="<?php _e('Αναζήτηση...'); ?>" />
<div id="datafetch"></div>
<?php
}
add_shortcode('simple_search', 'simple_search');
// Fetch data
function simple_search_callback(){
$the_query = new WP_Query( array( 'posts_per_page' => 10, 's' => esc_attr( $_GET['keyword'] ), 'post_type' => 'post' ) );
if( $the_query->have_posts() ) : while( $the_query->have_posts() ) : $the_query->the_post();
$myquery = esc_attr( $_GET['keyword'] );
$a = $myquery;
$search = get_the_title();
if( stripos("/{$search}/", $a) !== false) { ?>
<div class="result-sin">
<?php $image = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'medium' ); ?>
<div class="result-sin-img">
<?php if ($image) { ?>
<img src="<?php echo $image[0]; ?>" width="<?php echo $image[1]; ?>" height="<?php echo $image[2]; ?>" />
<?php } ?>
</div>
<div class="result-sin-tit"><?php the_title();?></div>
<div class="result-sin-txt"><?php the_excerpt();?></div>
</div>
<?php }
endwhile;
wp_reset_postdata();
endif;
die();
}
add_action('wp_ajax_simple_search', 'simple_search_callback' );
add_action('wp_ajax_nopriv_simple_search', 'simple_search_callback' );
}
And the search.js:
function fetch(){
jQuery.ajax({
async: true,
url: myAjax.ajaxurl,
type: 'GET',
data: {
action: 'simple_search',
keyword: jQuery('#keyword').val(),
nonce: myAjax.nonce
},
success: function(data) {
jQuery('#datafetch').html( data );
}
});
}
And on the header, I simply call a shortcode [simple_search] . Everything post I read on SO said that the wp_ajax_nopriv_ACTION was missing. But I already have that.
UPDATE
I tried using method GET, that didn't work. I also used: wp_localize_script('simple_search', 'myAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php', 'relative' ), 'nonce' => wp_create_nonce('ajax-nonce') )); to better enqueue the admin-ajax.php, that didn't work either.
Somewhere In my theme I had require_once('file.php') that had the line below:
if ( !current_user_can( 'manage_options' ) ) { wp_die( __( 'You do not have sufficient permissions to access this page.' ) ); }
When I removed this, the problem was fixed.
If I add the CPTs ('applicazione' and 'miscele') to 'post' and 'page' in the array they are not searched. If I leave just the CPTs it works. What am I doing wrong?
This is the code I am using.
// add the ajax fetch js
add_action( 'wp_footer', 'ajax_fetch' );
function ajax_fetch() {
?>
<script type="text/javascript">
function fetch(){
jQuery.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'post',
data: { action: 'data_fetch', keyword: jQuery('#keyword').val() },
success: function(data) {
jQuery('#datafetch').html( data );
}
});
}
</script>
<?php
}
// the ajax function
add_action('wp_ajax_data_fetch' , 'data_fetch');
add_action('wp_ajax_nopriv_data_fetch','data_fetch');
function data_fetch(){
$the_query = new WP_Query(
array(
'post_type' => array('post','page','applicazione','miscele'),
'post_status' => 'publish',
'posts_per_page' => -1,
's' => esc_attr( $_POST['keyword'] )
)
);
if( $the_query->have_posts() ) :
while( $the_query->have_posts() ): $the_query->the_post(); ?>
<h4><?php the_title();?></h4>
<?php endwhile;
wp_reset_postdata();
endif;
die();
}
Solved.
The problem was the Polylang plugin. Adding the CPTs to the translation settings fixed the issue.
My form html code, where i set action and the attribute name.
<div class="search_form">
<form action="<?php esc_url( home_url( '/' ) ); ?>" method="POST">
<input type="text" name="s" value="<?php get_search_query(); ?>" placeholder="Search...">
<input type="submit" value="Send">
</form>
</div>
I use localize scripts to connect ajax-search.
wp_enqueue_script( 'wc-estore-ajax-search-js', get_template_directory_uri() . '/assets/js/ajax-search.js', array( 'jquery' ), _S_VERSION, true );
wp_localize_script( 'wc-estore-ajax-search-js', 'search_form', array(
'url' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'search-nonce' )
) );
In ajax-search got nonce, set action and set url.
jQuery(function ($) {
$('.search_form input[name="s"]').on('keyup', function () {
let search = $('.search_form input[name="s"]').val();
if (search.length < 4) {
return false;
}
let data = {
s: search,
action: 'search_action',
nonce: search_form.nonce
};
$.ajax({
url: search_form.url,
data: data,
type: 'POST',
dataType: 'json',
beforeSend: function (xhr) {
},
success: function (data) {
console.log(data);
}
});
});
});
And in functions.php i want to see, what is in $_POST.
The action is the same as in the search-ajax.js.
add_action( 'wp_ajax_search_action', 'esp_search_ajax_action_callback' );
add_action( 'wp_ajax_nopriv_search_action', 'esp_search_ajax_action_callback' );
function esp_search_ajax_action_callback() {
/**
* Проверяем нонсе из массива пости и из wp_localize script
*/
if(!wp_verify_nonce($_POST['nonce'], 'search-nonce')){
wp_die('Данные пришли с левого адреса');
}
$_POST = filter_input_array( INPUT_POST, FILTER_SANITIZE_STRING );
$args = [
'post_type' => ['post', 'product'],
'post_status' => 'public',
's' => $_POST['s'],
];
$query_ajax = new WP_Query($args);
?>
<?php if($query_ajax->have_posts()): ?>
<?php while($query_ajax->have_posts()): ?>
<?php $query_ajax->the_post(); ?>
<h3 class="title-search"><?php the_title(); ?></h3>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php endif; ?>
<?php
}
But the console is clear?
Where is my mistake?
Thanks for help.
Looks like you have a few things going on. Try these:
dataType is the type of data you're expecting back. You're not passing valid JSON back, so it is failing with a parse error (i.e. no success, no console.log).
vardump probably should be var_dump unless you've defined it elsewhere. If not, that's probably causing an error and sending back the error string (which again would not be valid JSON)
Although not necessarily the issue you're asking about, but you should also finish your callback with wp_die(); and pass whatever parameters you need for your situation.
If you want, while you're testing you can switch dataType to html.
You can also add in error (to see what the error is) and complete (to see that it actually came back) callbacks.
And just to be safe, you might want to filter your $_POST data with something like this:
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
or whatever filters fit your situation.
I have this code and its working fine, the only problem is that its not showing pagination. This code is on my functions.php file.
add_action( 'wp_ajax_nopriv_load-filter', 'prefix_load_cat_posts' );
add_action( 'wp_ajax_load-filter', 'prefix_load_cat_posts' );
function prefix_load_cat_posts () {
global $post;
$cat_id = $_POST[ 'cat' ];
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
$args = array (
'cat' => $cat_id,
'posts_per_page' => 6,
'order' => 'DESC',
'paged' => $paged
);
$cat_query = new WP_Query($args);
if($cat_query->have_posts()) :
while($cat_query->have_posts()) : $cat_query->the_post();
get_template_part( 'template-parts/content', get_post_format() );
endwhile;
wp_reset_query();
?>
<div class="page-nation">
<ul class="pagination pagination-large">
<?php
$pagination = get_the_posts_pagination(array(
'mid_size' => 2,
'prev_text' =>esc_html__('Previous', 'travel-tour'),
'next_text' => esc_html__('Next', 'travel-tour'),
'screen_reader_text' => ' ',
) );
echo $pagination;
?>
</ul>
</div>
<?php
endif;
die();
}
and this is my jquery ajax script
<script>
jQuery(document).ready(function () {
jQuery('.js-category-button').on('click', function(e){
e.preventDefault();
jQuery('.preloadswitch').addClass('addpreloader');
var catID = jQuery(this).data('slug');
var catName = jQuery(this).attr('href');
var ajaxurl = '<?php echo esc_js( admin_url( 'admin-ajax.php' ) ) ?>';
jQuery.ajax({
type: 'POST',
url: ajaxurl,
crossDomain : true,
dataType: 'html',
data: {"action": "load-filter", cat: catID },
beforeSend: function () {
jQuery(".the-categories").html('<div></div>').fadeIn('slow');
jQuery(".page-nation").hide();
//window.location.hash = "#"+jQuery("#comehere").attr("id");
jQuery('html,body').animate({scrollTop:jQuery('#comehere').offset().top}, 1000);
window.history.pushState('obj', 'newtitle', catName);
},
success: function(response) {
jQuery(".the-categories").append(response);
jQuery('.preloadswitch').removeClass('addpreloader');
return false;
}
});
})
});
</script>
I don't what to do here anymore, I have been searching on the web for possible working function but with no luck.
I just need to show the pagination
Comment out or remove the wp_reset_query();, or move it to after the pagination; and use paginate_links() instead of get_the_posts_pagination().
Here's the altered 'if-else' block in your prefix_load_cat_posts() function:
if($cat_query->have_posts()) :
while($cat_query->have_posts()) : $cat_query->the_post();
get_template_part( 'template-parts/content', get_post_format() );
endwhile;
//wp_reset_query();
?>
<div class="page-nation">
<ul class="pagination pagination-large">
<?php
$pagination = paginate_links(array(
'mid_size' => 2,
'prev_text' =>esc_html__('Previous', 'travel-tour'),
'next_text' => esc_html__('Next', 'travel-tour'),
'current' => $paged,
'total' => $cat_query->max_num_pages,
'type' => 'array',
'base' => home_url( '/%_%' ),
) );
echo '<li>' . implode( '</li><li>', $pagination ) . '</li>';
?>
</ul>
</div>
<?php
endif;
[EDIT] Try setting the base parameter.
How can i do form validation in codeigniter if i don't want to refresh the page?
Basically i do this:
$config = array(
array(
'field' => 'c_name',
'label' => 'Name',
'rules' => 'trim|required'
),
array(
'field' => 'c_job',
'label' => 'Job',
'rules' => 'trim|required',
)
);
$this->form_validation->set_rules($config);
if($this->form_validation->run() == true)
{
$this->load->model('model');
//.....
}
else{
$this->load->view('view');
}
But if i send data with ajax and the page doesn't refresh, How can i do form validation?
Edit:
Thanks # Amra Kojon. That's good and works but the new problem is this:
if ($this->form_validation->run() == FALSE) {
echo validation_errors();
}
else {
//echo 'hi';
$value = $this->input->post('value');
$values = array(
'c_name' => $value['c_name'],
'c_job'=> $value['c_job'],
'c_address'=> $value['c_address'],
'c_phone'=> $value['c_phone'],
'c_mail'=> $value['c_mail'],
'c_state'=> $value['c_state'],
'c_intrest'=> $value['c_intrest'],
'c_added_info'=> $value['c_added_info']
);
$add = $this->customers_model->add_customer($values);
echo $add;
}
If i just say echo "something" in the else part, It works and if the validation were OK, It echo hi but if i write theme in database (Which the value array has data and in not ajax way, it insert date), It doesn't work and the else part isn't working!!!
If you gave your JS- jquery Ajax code it would more efficient to understand your problem.. Don't worry! Try my following instruction...
Get get form value and pass to form as
$(document).ready(function(){
var dataString = $("#FormId").serialize();
var url="ControllerName/MethodName"
$.ajax({
type:"POST",
url:""+url,
data:dataString,
success:function (data) {
alert(data);
}
});
})
Controller :
Load library form_validation in construct as ...
$this->load->library('form_validation');
$this->load->helper('form');
Now write your controller as ...
function MethodName {
$this->form_validation->set_error_delimiters('', '');
$this->form_validation->set_rules('fname','First Name', 'required');
$this->form_validation->set_rules('lname','Last Name', 'required');
$this->form_validation->set_rules('email','Email Address','required|valid_email|is_unique[sec_users.email]');
if ($this->form_validation->run() == FALSE) {
echo validation_errors();
}
else {
// To who are you wanting with input value such to insert as
$data['frist_name']=$this->input->post('fname');
$data['last_name']=$this->input->post('lname');
$data['user_name']=$this->input->post('email');
// Then pass $data to Modal to insert bla bla!!
}
}
I know your question is a year old but you can use this for the latest bootstrap with codeigniter
<?php
class Yourcontroller extends CI_Controller {
public function __construct() {
parent::__construct();
$this->load->library('form_validation');
}
public function index() {
$this->load->view('template/register');
}
public function validate() {
$json = array();
$this->form_validation->set_rules('username', 'Username', 'required');
$this->form_validation->set_rules('email', 'Email', 'trim|required|valid_email');
$this->form_validation->set_rules('password', 'Password', 'required|min_length[5]');
$this->form_validation->set_rules('confirm_password', 'Confirm Password', 'required|matches[password]');
$this->form_validation->set_rules('code', 'Login Code', 'required|numeric|min_length[4]||max_length[8]');
$this->form_validation->set_message('required', 'You missed the input {field}!');
if (!$this->form_validation->run()) {
$json = array(
'username' => form_error('username', '<p class="mt-3 text-danger">', '</p>'),
'email' => form_error('email', '<p class="mt-3 text-danger">', '</p>'),
'password' => form_error('password', '<p class="mt-3 text-danger">', '</p>'),
'confirm_password' => form_error('confirm_password', '<p class="mt-3 text-danger">', '</p>'),
'code' => form_error('code', '<p class="mt-3 text-danger">', '</p>')
);
}
$this->output
->set_content_type('application/json')
->set_output(json_encode($json));
}
}
Ajax Script
<script type="text/javascript">
$( document ).ready(function() {
$('#error').html(" ");
$('#form-submit-button').on('click', function (e) {
e.preventDefault();
$.ajax({
type: "POST",
url: "<?php echo site_url('yourcontroller/validate');?>",
data: $("#form").serialize(),
dataType: "json",
success: function(data){
$.each(data, function(key, value) {
$('#input-' + key).addClass('is-invalid');
$('#input-' + key).parents('.form-group').find('#error').html(value);
});
}
});
});
$('#form input').on('keyup', function () {
$(this).removeClass('is-invalid').addClass('is-valid');
$(this).parents('.form-group').find('#error').html(" ");
});
});
</script>
Full View Code
<div class="container">
<div class="row">
<div class="col-sm-6 ml-auto mr-auto m-auto">
<div class="card mt-5">
<h5 class="card-header"></h5>
<div class="card-body">
<?php echo form_open('agent/register', array('id' => 'form', 'role' => 'form'));?>
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<?php echo form_input('username', '', array('class' => 'form-control', 'placeholder' => 'Enter Agent Username', 'id' => 'input-username'));?>
<div id="error"></div>
</div>
<hr/>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<?php echo form_input('email', '', array('class' => 'form-control', 'placeholder' => 'Enter Agent Email', 'id' => 'input-email'));?>
<div id="error"></div>
</div>
<hr/>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<?php echo form_password('password', '', array('class' => 'form-control', 'placeholder' => 'Enter Password', 'id' => 'input-password'));?>
<div id="error"></div>
</div>
<hr/>
</div>
<div class="col-sm-6">
<div class="form-group">
<?php echo form_password('confirm_password', '', array('class' => 'form-control', 'placeholder' => 'Enter Confirm Password', 'id' => 'input-confirm_password'));?>
<div id="error"></div>
</div>
<hr/>
</div>
</div>
<hr/>
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<button type="button" class="btn btn-block btn-dark" id="form-submit-button">Register Agent</button>
</div>
</div>
</div>
<?php echo form_close();?>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$( document ).ready(function() {
$('#error').html(" ");
$('#form-submit-button').on('click', function (e) {
e.preventDefault();
$.ajax({
type: "POST",
url: "<?php echo site_url('yourcontroller/validate');?>",
data: $("#form").serialize(),
dataType: "json",
success: function(data){
$.each(data, function(key, value) {
$('#input-' + key).addClass('is-invalid');
$('#input-' + key).parents('.form-group').find('#error').html(value);
});
}
});
});
$('#agent-register-form input').on('keyup', function () {
$(this).removeClass('is-invalid').addClass('is-valid');
$(this).parents('.form-group').find('#error').html(" ");
});
});
</script>
If you are aware about passing data with ajax, then the work flow is as follows.
1) Send form data through ajax to your controller.
2) Do form validation as of now.
3) If success then "echo" value 1
4) If failure, echo value 0
So that using the value in echo, you can determine whether the validation fails or not. I can give you an example if you need
Sample ajax code
$('#form').on('submit', function(e){
e.preventDefault();
var data = $(this).serialize();
$.ajax({
url: 'your url',
type: 'POST',
data: data,
success: function(data){
if(data == 1){
$('#form')[0].reset();
alret('success');
}
else if(data == 0){
alret('failed');
}
},
error: function(){
alert('error');
}
});
});
Create MY_Form_validation in libraries folder
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class MY_Form_validation extends CI_Form_validation {
private $json = array();
private $opts = array();
function get_json($extra_array = array(),$error_array=array())
{
if(count($extra_array)) {
foreach($extra_array as $addition_key=>$addition_value) {
$this->json[$addition_key] = $addition_value;
}
}
$this->json['options'] = $this->opts;
if(!empty($error_array)){
foreach($error_array AS $key => $row)
$error[] = array('field' => $key, 'error' => $row);
}
foreach($this->_error_array AS $key => $row)
$error[] = array('field' => $key, 'error' => $row);
if(isset($error)) {
$this->json['status'] = 'error';
$this->json['errorfields'] = $error;
} else {
$this->json['status'] = 'success';
}
return json_encode($this->json);
}
}
Call this function in controller if validation failed:
echo $this->form_validation->get_json();
You get the response with form fieldname and errormessage
Example:
{"options":[],"status":"error","errorfields":[{"field":"email","error":"The Mobile Number\/Email\/Username field is required."},{"field":"password","error":"The Password field is required."}]}
Try this is my working (Codeigniter 3.0) basic example to achieve what you want do
include filename.js in your view
document.getElementById("yourForm").reset();
$(document).ready( function() {
var yourForm = $('#yourForm');
yourForm.submit( function(event) {
event.preventDefault();
$.ajax( {
type: 'POST',
url: yourForm.attr( 'action' ),
data: yourForm.serialize(),
success: function(data) {
if (data.code == '200') {
$('#message').html(data.message);
document.getElementById("yourForm").reset();
}
},
error: function(data) {
var response = data.responseText;
var obj = jQuery.parseJSON(response);
if (obj.code == '500') {
var i;
for (i = 0; i < obj.field.length; i++) {
name = obj.field[i];
$('.label-'+name).addClass('label-error');
errors = JSON.stringify(obj.validation);
validate = jQuery.parseJSON(errors);
$('.helper-'+name).html(validate[name]);
}
}
}
} );
} );
} );
view HTML form example
In this example in am using className you can use id as well change filename.js file accordingly
<form id="yourForm" action="base_url/controller/function_name" action="POST">
// Important text after className "label-" & "helper-" must be input name
<label class="label-firstName">Name</label>
<input type="text" name="firstName" />
<span class="helper-firstName"></span>
</form>
<div id="message"></div>
controller PHP code
public function function_name()
{
if(!empty($_POST)) {
$this->load->library('form_validation');
$this->form_validation->set_rules('firstName','First Name','required|max_length[16]');
if($this->form_validation->run())
{
$params = array(
'firstName' => $this->input->post('firstName'),
);
// Model returning $data['newRecord'] with $params and insertId
$data['newRecord'] = $this->Record_model->newRecord($params);
$reply = array();
$reply['code'] = 200;
$reply['record'] = array(
'insertId' => $data['newRecord']['insertId'],
'firstName' => $data['newRecord']['firstName']
);
$reply['message'] = 'Hello, ' .$data['newRecord']['firstName']. ' - We have received your message. ' .$data['newRecord']['insertId']. ' is your reference ID, for this communication.';
header('Content-Type: application/json; charset=UTF-8');
print json_encode($reply);
}
else {
$validation = $this->form_validation->error_array();
$field = array();
foreach($validation as $key => $value) {
array_push($field,$key);
}
$reply = array(
'code' => 500,
'field' => $field,
'validation' => $validation,
'message' => 'Submission failed due to validation error.'
);
header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Problem', true, 500);
header('Content-Type: application/json; charset=UTF-8');
print json_encode($reply);
}
}
else {
$reply = array();
$reply['code'] = 403;
$reply['message'] = 'No Direct Access Allowed.';
header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden', true, 403);
header('Content-Type: application/json; charset=UTF-8');
print json_encode($reply);
}
}
If using ajax,...you can't use form_validation library
So you can validate on client side using jquery ...and on server side should use if statement to check submitted data