When form validation fails unable to receive ajax data in codeIgniter - php

This is my very first project in codeIgniter. Here I am trying to validate a form using form_submit() method of Validator controller class ...I am generating two drop-down field in my form using jquery’s ajax method by calling get_cities() method and get_sub_category () method of Validator controller. Worth to mention that I am using an external dropdown.js file which I have linked with my form view. Here is the dropdown.js file
$(document).ready(function () {
$('#city_h').hide();
$('#sub_category_h').hide();
//function to dynamically populate CITY according to STATE
$('#state').change(function () {
var state_id = $('#state').val();
var state_id = state_id.trim();
if (state_id/* != ""*/) {
//Need to handle form submission more efficiently
/**
* For the time being, i am checking if the user has submitted the form or not
* By the following if else block but in future i will try to handle it from CONTROLLER
*/
if ($(location).attr('href') == "http://localhost/ci_practice/") {
var post_url = "index.php/validator/get_cities/" + state_id;
} else {
var post_url = "get_cities/" + state_id;
}
//Need to handle form submission more efficiently
$.ajax({
type: "POST",
url: post_url,
success: function (cities) //we're calling the response json array 'cities'
{
$('#city').empty();
$('#city_h').show();
$.each(cities, function (ci_id, ci_name)
{
var opt = $('<option />'); // here we're creating a new select option for each group
opt.val(ci_id);
opt.text(ci_name);
$('#city').append(opt);
});
} //end success
}); //end AJAX
} else {
$('#city').empty();
$('#city_h').hide();
}//end if
}); //end change
//function to dynamically populate SUBCATEGORY according to CATEGORY
$('#category').change(function () {
var category_id = $('#category').val();
var category_id = category_id.trim();
if (category_id/* != ""*/) {
//Need to handle form submission more efficiently
/**
* For the time being, i am checking if the user has submitted the form or not
* By the following if else block but in future i will try to handle it from CONTROLLER
*/
if ($(location).attr('href') == "http://localhost/ci_practice/") {
var post_url = "index.php/validator/get_sub_category/" + category_id;
} else {
var post_url = "get_sub_category/" + category_id;
}
//Need to handle form submission more efficiently
$.ajax({
type: "POST",
url: post_url,
success: function (subcategories) //we're calling the response json array 'cities'
{
$('#sub_category').empty();
$('#sub_category_h').show();
$.each(subcategories, function (sc_id, sc_name)
{
var opt = $('<option />'); // here we're creating a new select option for each group
opt.val(sc_id);
opt.text(sc_name);
$('#sub_category').append(opt);
});
} //end success
}); //end AJAX
} else {
$('#sub_category').empty();
$('#sub_category_h').hide();
}//end if
}); //end change
});
here is the Validator controller........
public function form_submit(){
//all form validation code goes here
}
public function get_cities($state){
//this method is called from dropdown.js file to populate subcategory dropdown
//but when url changes... this function become unaccessible by dropdown.js
header('Content-Type: application/x-json; charset=utf-8');
echo(json_encode($this->form_model->get_cities_by_state($state)));
}
public function get_sub_category($category){
//this method is called from dropdown.js file to populate subcategory dropdown
//but when url changes... this function become unaccessible by dropdown.js
header('Content-Type: application/x-json; charset=utf-8');
echo(json_encode($this->form_model->get_subcategory_by_category($category)));
}
}`
So when I submit form to fail validation it goes to the url (http://localhost/ci_practice/index.php/validator/form_submit) and then jquery’s ajax method is unable to access get_cities() method and get_sub_category() method of Validator controller so I can’t repopulate my dropdown list. How to handle this problem? For the time being I am going with this solution
/**
* For the time being, i am checking if the user has submitted the form or not
* By the following if else block but this is not a portable solution
*/
if($(location).attr('href')=="http://localhost/ci_practice/"){
var post_url = "index.php/validator/get_cities/"+state_id;
} else{
var post_url ="get_cities/"+state_id;
}
in my external javascript file but I think this is not a portable solution.

Problme solved......... just needed to use the full url in var post_url in external dropdown.js file like localhost/ci_practice/index.php/validator/get_sub_category instead of relative url like (index.php/validator/get_cities/)

Related

How to get data attribute to controller from ajax?

I’m having trouble passing my $_POST variable to my controller from an jQuery/ajax request.
Ultimately I want to be able to use that to update a field in my database.
My problem is that in trying to access $_POST[‘quantity’] in my controller. I keep getting the notice quantity is undefined and I’m var_dumping it and it’s null.
I’m new to jQuery/ajax and I’m not really sure how to go about fixing this issue. I could really use help in getting the data attribute, quantity, in my ajax request to my controller and understanding why $_POST[‘quantity’] is null.
I hope I am clear in my questioning and thanks for your help!
Controller function:
/**
* Updates quantity using ajax/jQuery request from showCart twig file
*
* #Route("/{id}/quantityUpdate", name="product_quantityUpdate")
* #Method("POST")
* #Template()
*/
public function quantityUpdateAction(Request $request, $id) {
$em = $this->getDoctrine()->getManager();
$productId = $em->getRepository('ShopBundle:Product')->find($id);
$cart = $em->getRepository('ShopBundle:UserCart')->findOneBy(['user' => $this->getUser(), 'submitted' => false]);
$quantity = $em->getRepository(ShopBundle:Quantity')->findOneBy(['quantity' => $productId->getId()]);
var_dump($this->get('request')->request->get('quantity'));
$quantity = isset($_POST['quantity']) ? var_dump($_POST['quantity']) : false;
// $quantity->setQuantity(/* Code for finding correct product to update quantity */);
// $em->persist($quantity);
// $em->flush();
return new Response ("This has been successful!");
}
twig / ajax & jQuery:
<script type="text/javascript">
$(".spinner").spinner();
$('input.spinner').on('spinstop', function(){
min: 0
console.log('spinner changed');
var $this = $(this);
var value = $('spinner').val();
var request = $.ajax({
url: "{{ path('product_quantityUpdate', {'id': prodId }) }}",
method: "POST",
data : {
quantity: value
}
}).done(function(result){
console.log('success', result);
}).error(function(err){
console.log('error');
});
});
</script>
Change
var value = $('spinner').val();
to
var value = $('.spinner').val();
Your selector is having problem as I see that is missing.
If you have multiple elements with same class then better use this.value;

posting array using ajax to the controller in cakePHP

I am relatively new to cake and I am struggling with a custom filter that im making in order to display products based on which checkboxes have been ticked. The checkboxes get populated based on which attributes the user creates in the backend, i then collect all the values of the selected boxes into an array with javascript and post it to the controller, but for some reason I cannot access the controller variable named '$find_tags' in my view, it throughs undefined variable.
Here is my javascript and ajax which collects and posts correctly (when i firebug it 'data' in my controller has array values which im posting) so thats fine
$("#clickme").click(function(event){
event.preventDefault();
var searchIDs = $("#checkboxes input:checkbox:checked").map(function(){
return $(this).val();
}).get();
var contentType = "application/x-www-form-urlencoded";
var data = 'data[ID]='+searchIDs;
$.post("",data,function(data){
console.log(data);
});
});
Here is my controller code which im assuming is where the fault lies
if ($this->request->is('post') ) {
$data = $this->request->data['ID'];
$find_tags = array();
$selected_tags = $data;
foreach($selected_tags as $tag)
{
array_push($find_tags,$this->Product->findByTag($tag));
$this->set('find_tags', _($find_tags));
}
}
And here is my view code where i get Undefined variable: find_tags
foreach($find_tags as $all_tag)
{
echo $all_tag['Product']['name'];
echo '</br>';
}
Any help or suggestions would really be appreciated been struggling with this for a while now
If searchIDs is array of ids you just need to make the json of array and then send to your controller
$("#clickme").click(function(event){
event.preventDefault();
var searchIDs = $("#checkboxes input:checkbox:checked").map(function(){
return $(this).val();
}).get();
var contentType = "application/x-www-form-urlencoded";
var data = 'ids='+JSON.stringify(searchIDs);
$.post("controller url",data,function(data){
console.log(data);
});
});
On php side you are getting wrong variable
if ($this->request->is('post') ) {
$data = $this->request->data['ids'];
$find_tags = array();
$selected_tags = $data;
foreach($selected_tags as $tag)
{
array_push($find_tags,$this->Product->findByTag($tag));
}
$this->set('find_tags', _($find_tags));
}

php website and Jquery $.ajax()

The website I'm developing is structured in this way:
It has a function that switches the module for the homepage content when $_GET['module'] is set, example:
function switchmodules()
{
$module=$_GET['module'];
switch($module)
{
case 'getnews': news(); break;
default: def();
}
}
As you can see, this switch calls another function for each module.
For example I wrote getNews() to work in this way:
function getNews()
{
$id=$_GET['id'];
if(!id)
{
//CODE TO LIST ALL NEWS
}
if(isset($id))
{
//CODE TO GET ONLY 1 NEWS BY ID
}
}
So, as you can see I'm not using an unique file for each module; all operations of a module are part of an unique function in which an action is switched again to change the result.
If I want to get a news from database I should use an url like this: ?index.php&module=getnews&id=1
My question now is:
With jQuery and $.ajax() method is there a way to get a news (for example) using this structure based on functions switched by a get? Or do I have to change everything and make a file for each function?
you can simply call the same url via $.ajax(). the only thing which should be changed for axjax calls is that you don't output your layout, but only the news itsself.
in php you can check for an ajax request like
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
// dont output layout
}
If this code is in say 'test.php' you can do:
<script>
$.get(
'/test.php',
{
module: 'news',
id: 1
},
function( data ) {
alert( data );
}
);
</script>
And js will send GET request to test.php with needed params. Then your server script will decide how to process request.
jQuery
$(document).ready( function() {
var form = '#my_awesome_form';
$(form + ' input[type=submit]').click(function(e) {
e.preventDefault();
$.ajax({
type: "GET",
url: 'index.php',
data: $(form).serialize(),
success: function( response ) {
alert('DONE!');
}
});
});
});
HTML
<form id="my_awesome_form" // OTHERS PROPERTIES //>
// LOT OF FIELDS HERE //
<input type="submit" value="Send">
</form>

Filtering dropdown menu's with ajax and PHP

I have a CodeIgniter MVC application.
I have a model called city that has a method:
<?php
class Cities_model extends Model{
function Cities_model(){
parent::Model();
}
function get_cities($id = null){
$this->db->select('id, city_name');
if($id != NULL){
$this->db->where('country_id', $id);
}
$query = $this->db->get('cities');
$cities = array();
if($query->result()){
foreach ($query->result() as $city) {
$cities[$city->id] = $city->city_name;
}
return $cities;
}else{
return FALSE;
}
}
...
Controller:
function Post(){
$this->load->helper('form');
$this->load->model('cities_model');
$this->load->model('country_model');
$this->load->model('field_model');
$data['cities'] = $this->cities_model->get_cities();//optional $id parameter
$data['countries'] = $this->country_model->get_countries();
$data['fields'] = $this->field_model->get_fields(); //subject field
$this->load->view('post_view',$data);
}
This method is used to fill the contents of a dropdown list. I have a similar model for countries, which also has a dropdown.
You can see that the get_cities method is set up to accept a country_id. This would be used to filter the results if a country was selected.
My question is I need help calling this method using Ajax (preferably jQuery). I'm new to ajax and have never done anything like this before.
Any help most appreciated!
Billy
UPDATE
I've added jquery library and have created method in my controller:
function get_cities($country){
header('Content-Type: application/x-json; charset=utf-8');
echo(json_encode(array($this->cities_model->get_cities($country))));
}
here is my javascript on my view:
<script type="text/javascript">
$(document).ready(function(){
$('#country').change(function(){
var country_id = $('#country').val(); // here we are taking country id of the selected one.
$.ajax({
type: "POST",
url: "<?php echo base_url(); ?>home/get_cities/"+country_id,
data: ({country : country_id}),
success: function(cities){
$.each(cities,function(i,city)
{
var opt = $('<option />');
opt.val(city.value);
opt.text(city.text);
$('#cities').append(opt);
});
}
});
});
});
This is the json reply:
[{"2":"Accra"}]
So it is successfully retriving the correct data. the only problem is it's adding blank values/text to the drop down. and each time I change the city the data is being added on, so I guess i'd have to clear the dropdown first?
extending Alpesh's answer:
you should have a controller's function which return cities filtered by country:
/controller/get_cities/<country>
i'm assuming that your controller's function will return a json object, you can obtain it by doing:
function get_cities($country)
{
header('Content-Type: application/x-json; charset=utf-8');
echo(json_encode(array($this->cities_model->get_cities($country))));
}
then on the view you'll have 2 select boxes:
one filled up with the contries
one empty and to be filled up with the cities retrived via ajax
now, you have to write something like Alpesh did in order to retrive the cities of the selected country; URL will be
url: '/controller/get_cities/'+country_id
while the success function would be something like
success: function(cities)
{
$('#cities').empty();
$.each(cities,function(i,city)
{
var opt = $('<option />');
opt.val(city.value);
opt.text(city.text);
$('#cities').append(opt);
});
}
UPDATE
in your ajax success function you are dealing with a json objects, infact you are doing this:
opt.val(city.value);
opt.text(city.text);
where city is a json object and value and text are its properties.
when you generate the json via php you have to respect what you use in jquery so your model should return an array like this:
array
(
array("value"=>"2","text"=>"Accra"),
array("value"=>"3","text"=>"Kumasi"),
....
);
the json_encode that array and it should work. Maybe you don't need to wrap the model call into an array but i'm not sure depens on how you return the array
echo(json_encode(array($this->cities_model->get_cities($country))));
or
echo(json_encode($this->cities_model->get_cities($country)));
You can do it this way by jquery -
lets say you have 'country' as an id for the select for country -
then on change of country you can bring it's specific cities as follows -
$(document).ready(function(){
$('#country').change(function(){
var country_id = $('#country').val(); // here we are taking country id of the selected one.
$.ajax({
type: "POST",
url: "the url you want to call",
data: ({id : country_id}),
success: function(cities){
//populate the options of your cities dropdown here.
}
});
});
});
you can refer detailed documentation here -
JQuery
Ajax API
Ajax

codeigniter and ajax cannot access the post

On my website I am using ajax post request to show content around my site, this is done using this code,
$("a.contentlink").click(function(ev) {
ev.preventDefault();
$('#main_menu').hide();
var url = $(this).attr("href");
var data = "calltype=full&url="+url;
$.ajax({
url:url,
type: "POST",
data: data,
success : function (html) {
$('#left-content-holder').html(html);
}
})
});
as you can see I am passing the url into the `$_POST' and I can access this in the method the javascript calls, this method is called get_content_abstract and looks like this,
public function get_content_abstract() {
$this->load->model('content_model');
if($this->input->post('calltype') == "abstract"){
if($query = $this->content_model->get_content_by_id($this->uri->segment(3))) {
$data['abstract'] = $query;
}
$this->load->view('template/abstract', $data);
}
elseif($this->input->post('calltype') == "full") {
if($query = $this->content_model->get_content_by_id($this->uri->segment(3))) {
$data['full'] = $query;
}
$this->load->view('template/full-content', $data);
}
}
How ever I have no added a new function that will allow the user to save the content to 'bookmarking system', however in my method I cannot access the post using codeigniters $this->input-post('url') (where URL is the one of peices of data passed in the javascript), it says that the post is empty when I var dump it, this is done using this method,
public function love_this() {
die(var_dump($this->post->input('url')));
}
can anyone help as to why the post is empty in this love_this method?
Shouldn't:
public function love_this() {
die(var_dump($this->post->input('url')));
}
Actually be
public function love_this() {
die(var_dump($this->input->post('url')));
}
See:
http://codeigniter.com/user_guide/libraries/input.html

Categories