Ajax URL generated by paginator/jquery helper encodes & as & - ajax

Read bottom edit for workaround.
I'm having trouble implementing ajax pagination in my cakephp app. I've looked for resources and tutorials to help with the issue however most deal with cake 1.3. I've got my fingers crossed for a glaring and simple mistake on my part...
A description of where I'm at so far: I have built a simple search interface for my application - a used car search interface that searches the cars in my database. The search interface actually seems to be working fine. I have a hidden form that creates or destroys hidden elements based on the users input in the search form. This hidden form is submitted via Ajax successfully and I can return a set of paginated results such as "1-5 displayed of 16 found".
The problem I seem to be having is with the javascript enhanced number, next, and prev link/ajax requests that are being generated by the paginator helper.
My CarsController has the find_cars function that expects a get request (the $paginate var in my controller and the $this->Paginator options in the view both have dataType = querystring). The function works fine on the initial form submission with a Get request url like: http://localhost/myapp/cars/findCars?price=any&year=any&miles=any
I have in my ajax.ctp layout $this->Js->writeBuffer(); and in the ajax response I can see the jquery events written for the next, number, and prev links. An example of one event:
$("#link-1448104972").bind("click", function (event) {$.ajax({
dataType:"html", evalScripts:true, paramType:"querystring",
success:function (data, textStatus) {
$("#results").html(data);}, url:"\/myapp\/cars\/findCars?price=any&year=any&miles=any&page=2"});
The problem I'm having is with the URL value. When I paste the url in a browser, my find_cars function processes the parameters correctly as the &'s get sent to the controller as plain &. However when I click one of the pagination links that sends the ajax request, the URL still contains the & encoded ampersands and $this->request->query; in a var_dump after a pagination click looks something like:
array
'price' => string 'any' (length=3)
'amp;year' => string 'any' (length=3)
'amp;miles' => string 'any' (length=3)
'amp;body' =>
array
0 => string '1' (length=1)
1 => string '2' (length=1)
2 => string '6' (length=1)
'amp;page' => string '2' (length=1)
The only other discussion I can find anywhere that seems to mention this same issue is in this cakephp lighthouse bug ticket #127 . However the discussion is for cakephp 1.3 and the github commit it links to is a 404.
Edit: I guess I should also add that I was trying to use GET requests so that I would have an easier time implementing expected user navigation & bookmarking capabilities to save search queries and navigate forward and backward through results with the browser as well as in app pagination links.
Edit (Workaround / Solution) -
Working from #islandmyth's suggestion I switched over from doing a Get request to doing a Post, changed the paramType from 'querystring' to 'named'. I pass the query info from $this->request->named to the view save the info to $this->Paginator->options['data'] having used php's http_build_query() function to preserve the nested arrays.

Cake php Ajax Paginator not seems to be working fine. I had similar issues also.
I would recommend you to use the cakephp plugin Cakephp-DataTable
This plugin has implemented the pagination and it has most of the features by default. They have also provided documentation and if you find any difficulty in implementing please go throught the issues section
Also the developer is very responsive and can get clarifications for that plugin if you have any.

Related

Unlimited value field in Drupal 7 module form

Trying to implement an unlimited value date field in a custom module form. I've been trying to follow the examples in a blog post on unlimited item values in forms and Drupal documentation on ajax forms.
I've tried adding the equivalent of the custom_registration_form function code from the blog post above to my form builder function and ajax callback, but can't get additional date fields to show up when my ajax-enabled button is clicked. The $form_state['storage'] data is available after clicking the save button for the form as a whole, but I can't tell if it's being used in the ajax callback properly.
Any ideas on implementing an unlimited value field in a module or links to examples would be appreciated. Unlimited fields seem like such basic functionality to Drupal's Field API, but I can't find any good examples of implementing this in custom code.
Never tried something like that but what if you do like this, you first create an unlimited field somewhere in a content type, then you var_dump or dpm $page['content']['system_main']['THE_FIELD']) you will see stuff like :
'#process' =>
array (size=1)
0 => string 'file_field_widget_process_multiple'
and maybe get an idea how that field looks and implement it in your module

$fn.yiiGridView.update calls for multiple grids

In a view, I display two grids with data.
The user is able to submit data in the following way:
The data is sent using a form displayed in the same page
On submit, the form data is sent through an ajax call to a controller
The ajax call has a callback on success that executes
$.fn.yiiGridView.update("grid1");
$.fn.yiiGridView.update("grid2");
as both grids will have their data changed by the submitted form.
The $.fn.yiiGridView.update method will update the grids by retrieving the same page and extracting what is required.
In this particular situation, it will happen twice, which raises the need to find a way to avoid this extra call and reduce unnecessary traffic.
Is there a way to modify the yiiGridView callbacks to update both grids with a single call?
I've tried to hack the methods, but with no success.
Ok, after some struggle I have found a solution.
I realise that there's a field called ajaxUpdate that in the yiiGridView documentation (jquery.gridview.js line: 39) says :
ajaxUpdate: array, IDs of the containers whose content may be updated by ajax response
This value is extracted from the CGridView parameters (http://www.yiiframework.com/doc/api/1.1/CGridView#ajaxUpdate-detail)
So I defined
$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'grid1', //or could be grid2
'dataProvider' => $model->search(),
'ajaxUpdate'=>'grid1,grid2', //string separated with commas
......
));
and now just by calling
$.fn.yiiGridView.update("grid1"); //or grid2 if you set ajaxUpdate in grid2
both grids will get updated.
I wonder if there's a way to override the value using the options parameter for the gridview function (using the $('#grid1').yiiGridView('update',options) syntax)

Laravel pagination get variables

I have a page that list apartments depending on book dates like this
mypage.com/finder?date-from=2011-03-04&date-to=2011-03-12
Everything is right, I am getting the date-from and date-get from the url and searching the database with those values. The problem is when I paginate and I click to go to another page the url changes to.
mypage.com/finder?page=9
and get an error Value must be provided
The correct url must be
mypage.com/finder?date-from=2011-03-04&date-to=2011-03-12&page=9
I am using paginate at the controller and $searchResult->links(); to generate the links
What can I do pass the date values from page to page so the pagination works?
Thanks
If you want to tack on existing query string data, use this:
$searchResult->appends(array(
'date-from' => Input::get('date-from'),
'date-to' => Input::get('date-to'),
));
Read the docs: Appending To Pagination Links.
You can shorten that a little:
$searchResult->appends( Input::only('data-from', 'date-to') );
which ends up being the same thing.
you can do this using the 'appends' feature. There are examples in the documentation: http://laravel.com/docs/pagination

How to pass route values to controllers in Laravel 4?

I am struggling to understand something that I am sure one of you will be able to easily explain. I am somewhat new to MVC so please bear with me.
I have created a controller that handles all of the work involved with connecting to the Twitter API and processing the returned JSON into HTML.
Route::get('/about', 'TwitterController#getTweets');
I then use:
return View::make('templates.about', array('twitter_html' => $twitter_html ))
Within my controller to pass the generated HTML to my view and everything works well.
My issue is that I have multiple pages that I use to display a different Twitter user's tweets on each page. What I would like to do is pass my controller an array of values (twitter handles) which it would then use in the API call. What I do not want to have to do is have a different Controller for each user group. If I set $twitter_user_ids within my Controller I can use that array to pull the tweets, but I want to set the array and pass it into the Controller somehow. I would think there would be something like
Route::get('/about', 'TwitterController#getTweets('twitter_id')');
But that last doesn't work.
I believe that my issue is related to variable scope somehow, but I could be way off.
Am I going down the wrong track here? How do I pass my Controllers different sets of data to produce different results?
EDIT - More Info
Markus suggested using Route Parameters, but I'm not sure that will work with what I am going for. Here is my specific use case.
I have an about page that will pull my tweets from Twitters API and display them on the page.
I also have a "Tweets" page that will pull the most recent tweets from several developers accounts and display them.
In both cases I have $twitter_user_ids = array() with different values in the array.
The controller that I have built takes that array of usernames and accesses the API and generates HTML which is passed to my view.
Because I am working with an array (the second of which is a large array), I don't think that Route Parameters will work.
Thanks again for the help. I couldn't do it without you all!
First of all, here's a quick tip:
Instead of
return View::make('templates.about', array('twitter_html' => $twitter_html ))
...use
return View::make('templates.about', compact('twitter_html'))
This creates the $twitter_html automatically for you. Check it out in the PHP Manual.
 
Now to your problem:
You did the route part wrong. Try:
Route::get('/about/{twitter_id}', 'TwitterController#getTweets');
This passes the twitter_id param to your getTweets function.
Check out the Laravel Docs: http://laravel.com/docs/routing#route-parameters

Yii importcsv module headaches

I have the importcsv module installed and the importcsv page loads fine. The file upload button appears when I load the url- https://web/importcsv
I upload a file, and the ajax "loading" text appears, however the ajax response turns out to be the entire layout of my site and the default importcsv upload page, rather that what I would assume is supposed to load in the importCsvFirstStepResult div (the "next step" fields), after the ajax request in download.js completes
...
onComplete : function(file, response) {
this.enable();
$("input#fileName").val(file);
$("div#importCsvFirstStepResult").html(response);
}
The /importcsv/default/upload ajax response apparently contains the wrong layout, failed to detect the request, or ???? and loads that default view into the response div, menus and all. I'm fairly new to Yii so maybe this is obvious someone out there.
Thanks for your assistance.
Solved my own problem. The ajax issue was due to me having tweaked (breaking) my urlManager rules. I changed the original rules to accomodate non-numeric primary keys on tables. For example the url to view a patient would be https://web/patients/view/ABC_1234 instead of https://web/patients/view/1234
I tend to use existing db schema where possible and the way my clients db schema is set up now, they're using a non-numeric primary key. I wanted to continue this for certain reasons so I had to edit the url params becuase \d only matches digits. Unfortunately changing it to \w also matched some ajax requests and broke the whole thing.
Yii orginal rules. Works fine but doesn't work for alphanumeric primary keys:
'rules'=>array(
'<controller:\w+>/<id:\d+>'=>'<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
),
First I changed it to the following, to handle alphanumeric foreign keys, but this broke some ajax:
'rules'=>array(
'<controller:\w+>/<action:\w+>/<id:\w+>'=>'<controller>/<action>',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
'/gii'=>'/gii/default/login',
),
Finally arrived at the following, which allows ajax modules to function properly, and handles my non-numeric keys:
'rules'=>array(
'/libraries/<action:\w+>/<id:\w+>'=>'/libraries/<action>',
'/patients/<action:\w+>/<id:\w+>'=>'/patients/<action>',
'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
),
I ended up explicitly setting rules just for the controllers that need it. Most of them use integer primary keys
Hope this helps someone else. I was new to Yii and didn't fully understand the rules and ajax system in Yii when I changed the rules.
Cheers

Resources