Combo box loads too slow - php

My page loads super slow right now. Basically, i want to pre-populate the combo boxes that i have. Right now, it pre-populates each one individually and then selects the default value. This is so slow. The user will have to wait about a minute before the page is fully loaded.
I'm grabbing the values to populate the combo boxes from a server. The values to pre-select the combo box value are received in an array through the response variable. How do i speed this whole process up?
Code is below:
EXTJS
xtype: "combo",
width: 250,
id: "nameId",
name: "comboName",
labelStyle: 'width:100px',
fieldLabel:"Name",
allowBlank: true,
displayField: "nameDisplay",
valueField: "nameValue",
url: "/thelink/toGetAllComboboxValues/fromPHPFile/",
return {
init: function (args) {
formPanel.on({
beforerender: function () {
Ext.Ajax.request({
url: 'url/to/another/PHP/file/',
scope: this,
method: 'GET',
params: {
code_id: 'myUser',
number: '12345'
},
success: function (response, opts) {
var result = Ext.decode(response.responseText);
Ext.getCmp('nameId').setValue(result.Name);
},
});
},
scope: this
});
//add form panel here
},
getFormPanel: function () {
return formPanel;
},
// load parameter values into the form
loadParams: function () {
},
goHome: function () {
},
};
}();
PHP TO GET COMBO BOX VALUES
//makes call to server for each individual combo box values
PHP TO GET PRE-SELECTED VALUES
//grabs all pre-selected values based on an ID and puts them in an array

If your stores each has less than about 300 records, and there aren't really 'that' many stores on your page, what you should do is return everything from the php at once (or more preferably load all the stores with the page load itself, but it sounds like you can't do that). So, instead of your one ajax call getting the values of the selected item in the combobox, think of it more like this:
Defined your models for each of the stores:
Ext.define("MyModel1", {
extend: "Ext.data.Model",
fields: [
{name:"field_code", type:"string"},
{name:"field_value", type:"string"}
]
});
Then define each of your stores in a very simple manner, notice that I left out the reader and proxy that you are probably currently including, for improved performance, use Ext.data.ArrayStore because it removes the necessity for each item in a record to have a named attribute (this reduces the text returned from the server and also the parsing time on the frontend):
var myStore = Ext.create("Ext.data.ArrayStore", {
model: "MyModel1",
data: []
});
Now in the ajax request that you already defined, add in the response from php all the data for the stores as attributes in the json object returned, and do them as array arrays making sure the element order matches how you defined the Ext.data.Model. The return object for my example would look something like this (the data is the array array):
{
my_combobox_value1: "CAD",
my_combobox_data1: [
["CAD","Somthing for display of this record"],
["AN","Another Entry]
]
}
Then change the ajax request to look something like this:
Ext.Ajax.request({
url: 'url/to/another/PHP/file/',
scope: this,
method: 'GET',
params: {
code_id: 'myUser',
number: '12345'
},
success: function (response, opts) {
var result = Ext.decode(response.responseText);
myStore.loadData(result.my_combobox_data1);
Ext.getCmp('nameId').setValue(result.my_combobox_value1);
... and rinse and repeat for all stores, make sure you set the value for each combobox after the store has been loaded :)
},
});
This will give you the best possible performance for you situation. If this does not work, you will have to use stores with proxies that handle everything on the server side and load data as needed.

First, I'd recommend not retrieving the full value list for each combo until the user needs it (either when changing the value or clicking the trigger). You can do this by giving your combo a store that is set up with a Proxy to your URL.
In order to save on the initial single-values displaying, one option would be to store the string value as well as the id in your record (or maybe not store it, per say, but send it down to the client anyway). However, this isn't that nice, and the load time may be fast enough after getting rid of the full list requests. If it isn't, try seeing if you can request ALL the single value displays in one request.

Related

capture Data from a database with Angular-js to use it for charts and Grahps

Yes I have really done my research including all the help from http://www.fusioncharts.com/dev/using-with-server-side-languages/php/creating-charts-with-data-from-a-database.html which happened to be the closed to what I needed. however I have failed to make all that I have encountered to work with a live database.
All i need is to be able to dynamically update my Angular-php built Ui charts and graphs using a combination of Angular with php as server side.
some thing like this..
//in some cases i tried google charts thus the dependency injection.
angular.module("myCharts", ["ngRoute", "googlechart","ng-fusioncharts"])
.controller('MyController', function ($scope,$http) {
$http.get('scripts/datacall.php')
.success(function (data) {
console.log(data); /* this actually shows me the json data in the console. but i just cant print it.*/
$scope.myDataSource = {
chart: {
caption: "My poll results",
subCaption: "Top ten Candidates",
numberPrefix: "Vote",
theme: ""
},
data: 'data'
}; // or data:$scope.data
});
});
Since you have claimed that you are able to show the data in the console. I believe the problem is binding the data to $scope.myDataSource.
The way that you did neither data:'data' nor data: $scope.data work.
First case: data: 'data'
You are binding an attribute called data to a string value data, which is not the data that can draw graphs.
Second case: data: '$scope.data'
Based on the code you just posted, you did not declare a variable called $scope.data. Therefore you will get error and will not be able to draw graphs.
How to fix it:
You are using $http()with a callback function return data. In this case, you can just binding the data to the data attribute, i.e. data: data.
$http.get('scripts/datacall.php')
.success(function (data) {
console.log(data);
$scope.myDataSource = {
chart: {
caption: "My poll results",
subCaption: "Top ten Candidates",
numberPrefix: "Vote",
theme: ""
},
data: data
};
});
I finally found the solution with following Googles geoCharts an example of the implementation is well elaborated hear.
https://leachcreative.com/geocharts-drill-and-associated-table/ (example)
https://developers.google.com/chart/interactive/docs/gallery/geomap#markers-example
in case the site goes down this was his original Chord but instead of using ajax to load the data i instead loaded it with angularjs. however for three way data binding, I did not get time to mess around with it due to the projects time frame given, but i will come back and update my answer

Submit and save data on an ajax call for multiple rows at once

I have a website in which changes are very constant on the user side. So to prevent from submitting an ajax request for each user every 3-6 seconds, I want to wait for the user to finish the actions and then submit all to the server.
So, instead of submitting many very small ajax requests, I want to hold it and submit all at once, when the user is inactive (not changing anything) for 1 minute or so. (a bit like an autosave function)
The problem is, since the user can update different parts of the application I need to update different rows in one call, so how would I do this?
Since the POST variable needs an identifier, my first idea is to submit one array of id's and another array of data. Then on the backend rebuild the arrays, iterate, and saving data accordingly. But something tells me it's not the optimal approach, could you guys give me some tips on how to go about this?
You could use setInterval in combination with $.ajax, like this:
function saveData() {
// Gather all the data you might want to post, in one object.
// This should happen dynamically, you add to the object as things
// are entered and need to be sent to the server.
// Some example data:
data = {
name: $('#name').val(),
age: $('#age').val(),
occupation: $('#occupation').val(),
list: [23, 1, 266, 34, 90],
words: ["this", "is", "some", "data"],
items: [{level: 11, width: 3}, {level: 22, width: 5}]
};
// If the data object is empty, it means there is nothing to save.
// Of course, with the above example data this condition is false:
if (!Object.keys(data).length) {
return; // nothing to do
}
// Post it
$.ajax({
url: 'script.php',
type: 'POST',
data: data,
}).done(function(response) {
alert(response);
// Mark that this data was sent, as you might not want to send it
// again the next round, unless the user changed some data.
data = {};
});
}
// Call the above function every 60 seconds.
setInterval(saveData, 60000);
The in PHP, you can access your data like this:
// Access the items passed:
$name = $_POST['name'];
foreach ($_POST["list"] as $number) {
//...
}
// ... etc
How about POSTing a JSON object that represents a DTO of for your page? So you'd be able to pack in all the data your backend should need for saving the state of that page in one object like:
{
'Attribute1' : 'Value1',
'Attribute2' : 'Value2',
'Attribute3' : 'Value3'
}
I'm not sure what your using to parse this on the server but almost any framework worth using can handle JSON with relative ease.

How to reload the grid after inline edit?

I'm using jqGrid PHP and adding an actions column.
The editing works fine but once the row is saved, the grid is not reloaded.
When I manually refresh the grid, the updated information appears.
I have tried adding edit options to the addCol (see below) but I read somewhere that editOptions only applies to form editing. Looking at the documentation, it seems like I could use the onSuccess or afterSave parameters but I am not sure how I would add the reloadAfterSubmit method to either of those parameters in PHP.
$grid->addCol(array(
"name"=>"Click to Edit",
"formatter"=>"actions",
"editable"=>false,
"sortable"=>false,
"resizable"=>false,
"fixed"=>true,
"width"=>45,
"loadonce"=>false,
"formatoptions"=>array("keys"=>true, "editbutton"=>true, "delbutton"=>false,"editOptions"=>array("reloadAfterSubmit"=>true))
), "first");
I'm using jQuery and jqGrid's cell editing feature which submits the new cell value to the server when leaving each cell. In my particualr app, when a cell changes it can affect other (calculated) columns in the same row AND possibly in other rows therefore I needed to update values which could be all over the grid.
In my case, the calculation itself is performed on the server when the cell is submitted and the database is updated so I needed to fetch the updated data to update the grid. I wanted to make the cell editing as fast as possible but also keep the rows updated. I also wanted to only update the rows that have been modified as determined by the server. I also wanted something that was generic and reusable.
I don't know how this translates to PHP but here's what I did in JavaScript.
var xhrUpdate = null;
// Handle jqGrid's afterSubmitCell.
$("#someGridId").jqGrid(
"setGridParam",
"afterSubmitCell",
function (response, rowid, name, val, iRow, iCol) {
// If an ajax request is already in progress from the last cell edit,
// abort it since the data is now moot with the new cell update.
// Sorry server, nobody's listening!
if (xhrUpdate != null) {
xhrUpdate.abort();
xhrUpdate = null;
}
// Call the generic grid update function (see below) asynchronously.
xhrUpdate = updateGrid(
"someGridId",
"someUpdateUrl",
{ someParam: someParamValue, ... },
"someIDFieldThatIdentifiesTheGridRow",
true);
// Return success.
return [true, ""];
});
// This function updates a jgGrid which already contains data.
// It will only update the rows and columns that are returned
// from the server.
function updateGrid(grid_id, url, data, idField, async) {
var grid = $("#" + grid_id)
return $.ajax({
async: async,
type: "GET",
datatype: "json",
url: url,
data: data,
success: function (result) {
// Loop over the returned rows.
$.each(result, function (index, row) {
// Loop over the returned fields in each row.
$.each(row, function (key, value) {
// Set the corresponding cell value.
// This won't touch any cell's that aren't
// represented in the JSON data.
grid.jqGrid("setCell", row[idField], key, value);
});
});
}
});
}
Things to note:
1) This definitely puts a load on the server.
2) Being asynchronous, this doesn't deal with bad cell data or other abnormal server responses from the cell submit. It very optimistic but those issues can be dealt with if need be.
3) The server needs to have the smarts to return the appropriate data or you can just return everything.
Sorry it's not PHP but I hope this helps.

cakephp: fetching matching records using email addr and displaying in the form

When the user enters his email address, I want to check if his/her data is in the database table using the email addr. If it is there, it should fetch the matching records (initial, name, address, city, state, postal code) and display them in the form. If the email addr is not in the db table, the user should be allowed to fill in the rest of the form.
I'm using cakePHP and MYSQL for this project. Can this be done using AJAX? What is the best way to do the above?
Thank you.
The best way is indeed using AJAX. I'd bind a function to the type event of the email field, then have it GET an action in your controller that specifically returns a JSON object with corresponding data if there is any, then fill this data into the corresponding fields using Javascript.
I have done this below using JQuery.
In your view:
notes: controller/action is the action it should call in the controller, also #emailbox is assumed to be the email form's id. #otherbox is a placeholder for the id's of the other form elements.
<script type="text/javascript">
$(document).ready(function () {
$('input#emailbox').keyup(function () {
// could do other stuff here, like show load bar or clear old results
//run the ajax
getPage();
});
});
function getPage() {
//generate the parameter for the php script
var data = {email: $("#emailbox").val()};
$.ajax({
url: '/controller/action',
type: 'GET',
data: data,
dataType: 'json',
cache: false,
success: function (data) {
//add the content retrieved from ajax into whatever forms you like
$("#otherbox").val(data.[User][information][here]);
$("#otherbox").val(data.[User][information][here]);
$("#otherbox").val(data.[User][information][here]);
$("#otherbox").val(data.[User][information][here]);
}
});
}
</script>
Note that chrome dev tools can help debug the JSON object you're getting back so you can figure out how to access the relevant data for each field.
In your controller:
public function searchForDetails() {
if($this->request->is('ajax')) {
$this->autoRender = false;
//Get the email parameter data- this is one way to do it, you could also do it plenty of other ways
$email = $this->request->query['email'];
//Get user data- I have given an example of how to do so:
$userdata = $this->User->find('first', array(
'conditions' => array(
'User.email' => $email,
'recursive' => -1));
return(json_encode($userdata));
}
}
This is one way you can go about it. The work you have to do is to debug the JSON object in chrome (use command shift j to access dev tools) and figure out the layout of the arrays inside the object so you can then set the values of the individual forms. I have not tested the efficiency of this approach and you probably shouldn't do something like this if you're developing Facebook.

Using jQuery to call a PHP function on many elements one by one, not at once

Let's say I use $.get to receive an array of user IDs.
Let us then presume that I want to go through all those user IDs (example: [13, 14, 15, 23, 34, 56]) and retrieve certain information on each, then populate a textfield based on the results, and move on to the next one.
$.each(array_of_users, function(i, id) {
$.get("/somefunction", {id}, function(data){
appendToField(data);
}, "json");
});
How would I make it so that these loops don't all happen at once and then wait for the result together asynchronously, as they do now, but one by one? That is, I want to stop the loop from going onto the next element until the ajax requests says it's fine to do so.
What is the best way to approach this without using delays or timeouts, but actual responses from the function doing the processing?
Cheers
Edit:
The stylish representation of a "command-prompt" look is important to me, which is why I would like the textarea to receive messages one by one as the entries are processed. I am aware I could do this via PHP much easier and without the hassle or potential JS breaks, but I would like to do it stylishly via JS to simulate this "console" look, as in:
10:01:33: User 13 processed: Changed expiry date to 13.02.2011.
10:01:34: User 16 not processed: Target immune to system changes..
10:01:34: User 17 not processed: Target immune to system changes..
10:01:35: User 23 processed: Changed expiry date to 19.02.2011.
etc..
Edit2:
I just found this brilliant little plugin which lets me do exactly what I want. However, I cannot find the means to stop the queue once it's been started. This is now a new issue. Any ideas, anyone? Reloading the page works, naturally, but I would like it to freeze in place as soon as I hit the Stop button so that the user can simply copy the entire report right out of the textfield.
Basically, use the first .get() to retrieve the list of values (array_of_users). Using this list, pass them off to a "worker" function that takes the first element, works with it, then sends the remaining elements off to do the same. Keep going until there are no more entries to process. (think of it like a FIFO Queue)
$.get('/loadfunction',{},function(data){
getinfo(data.array_of_users);
},'json');
function getInfo(array_of_users){
if (array_of_users.length == 0)
return;
$.get('/somefunction',{array_of_users[0]},function(data){
// handle the result of this id
appendToField(data);
// move on through the list, dropping the first element
getInfo(array_of_users.slice(1));
});
}
EDIT: used variables / GET paths similar to what you mentioned in your initial question.
Instead of returning an array numbers and then re-querying the server for more information for each id, why don't you return an array of objects? For example:
[
{"id":1, "uname":"jsmith", "admin":true},
{"id":2, "uname":"jdoe", "admin":false}
]
This is simple to do with PHP's json_encode function. When your JavaScript gets the array of objects, it will then have all of the data it needs for each iteration of the loop.
I agree with jsummers... it would probably be better to pull all the info down at once instead of sending separate requests. With that said you could do what you want using $.ajax with async: false:
$.each(array_of_users, function(i, id) {
$.ajax({
url: "/somefunction",
data: {id: id},
dataType: 'json',
type: 'get',
async: false,
success: function(data){
appendToField(data);
}
});
});
IMHO you should process all in backend then return JSON like this:
id: 2,
user: 'mary',
msg: 'Changed expiry date to 19.02.2011.'
},
{
id: 3,
user: 'marlon',
msg: 'Something went wrong..'
},
DEMO 2 : http://jsbin.com/okudi4/4
Hi Swader.
premising that i have the same point of view of jsummers
here is the kind of effect you are looking for.
DEMO: http://jsbin.com/okudi4
$(function() {
var results = ['brown', 'fox', 'jump', 'hover', 'the', 'lazy', 'dog'];
$.each(results,function(i, item) {
$('<li class="resultlistitem">').html(item).hide()
.appendTo('#resultList').delay(i + '000').fadeIn(200);
});
});

Categories