So I have a database of artists and they all show by default, if I click photographers they become hidden and only the photographers load after that, same for the makeup artists.
I'm achieving this by creating 3 php pages for fetching each with a different sql query--is there a way to do that without having 3 separate pages?
Because when I want to update the fetch page I need to update 3 of them now.
//click to load ph/mk
$( "#ph" ).click(function() {
$(".feed_item").hide();
fetch = 'fetch_ph.php';
load_contents(1);
});
$( "#mk" ).click(function() {
$(".feed_item").hide();
fetch = 'fetch_mk.php';
load_contents(1);
});
The best way (in my opinion) to achieve this is by putting all three functions into one PHP file and calling the actual method by sending a trigger to activate that function and return the information.
So make three functions (fetch_ph(), fetch_mk(), fetch_artists()) and then use a trigger word to get one of the functions to call.
So from my understanding of your question, this would be the best thing to do.
<?php
$triggerword = $_POST['triggerword'];
if ($triggerword === "mk")
{
fetch_mk();
}
else if ($triggerword === "ph")
{
fetch_ph();
}
else if ($triggerword === "artists")
{
fetch_artists();
}
function fetch_artists()
{
//function to get artists here...
}
function fetch_mk()
{
//function to fetch makeup artists...
}
function fetch_ph()
{
//function to fetch photographers...
}
?>
Related
I have a table containing data read from a MySQL database via PHP. The first column holds all item names. Now, on clicking a td element in the first column of the table would link to a page with more detailed information about the item contained in the td.
Now I came up with the following idea:
$(document).ready(function() {
$('#table td:first-child').click(function() {
$('div.main').animate({
height: "50px"
}, 600);
setTimeout(function() {
$('div.data').fadeIn(1000);
}, 600);
});
});
div.main is the div-container that has the table included. What I want to do now is to slide that container up and fade a new div-container in, right below it, the new container include()s a PHP page which holds a dynamic query (pseudocode, no string escaping, simplified version):
SELECT detail FROM items WHERE items.name = $_GET['name'];
What I couldn't figure out is if and how I can tell the PHP file that is included in the in-fading div-container which item name it has to grab details for, off the database.
Right now I can read the item name via JavaScript/jQuery, but I couldn't figure a way out to pass that value to the PHP file without having to reload the page.
Any ideas or suggestions welcome!
I think what you're looking for is asynchronous JavaScript and XML (AJAX). It sounds intimidating, but fortunately jQuery makes it very easy.
You can call $.ajax() directly, but for most cases, you can use one of the convenience wrappers. In this case, I think $.load() will meet your needs.
So, let's say your PHP file is called detail_ajax.php and it returns the HTML you wish to put in your div (with class data). All you would have to do then is this:
$('div.data').load( '/detail_ajax.php', function(data){
$(this).html(data);
});
If you want to pass data TO detail_ajax.php, you can pass it along this way:
$('div.data').load( '/detail_ajax.php', { 'someField' : 'someValue' },
function(data) {
$(this).html(data);
}
});
In detail_ajax.php, if you examine $_POST['someField'], you will see the value passed in.
You can do this by using ajax. Output your query on a separate page in JSON format then fetch it using jquery ajax
you need to use ajax to do the same thing. create an event like onclick and call a
method on click call ajax set variable in js and pass it to and do as you want,
show data in particular div in response. Hope it will help you.
You are looking for $.ajax(). However, 3 things will need to take place for this to happen as you intend.
First, we need a reference held in the HTML that is generated by the table so we can streamline the server request. When you generate the table, add a unique data-name string to the TD.
<td data-name="<?php echo $row['name']; ?>">
If, for instance, the td's were generated in a foreach loop, where we expect an array to be returned.
Now, we need to detect the request on our page so we can properly return the data to the browser, we'll look for $_GET['name'] as per your example.
<?php
if(isset($_GET['name'])):
$mysqli = new mysqli('host', 'user', 'pass', 'db');
$ret;
if($stmt = $mysqli->prepare('SELECT detail FROM items WHERE items.name = ?')):
$stmt ->bind_param('s', $_GET['name']);
$stmt ->execute();
$stmt ->bind_result($details); // we only want one column
$stmt ->fetch(); //get our row
$ret['success'] = TRUE;
$ret['html'] = '<div>'. $details .'</div>';
else:
$ret['success'] = FALSE;
endif;
echo json_encode($ret); //return to the browser
endif;
?>
Now we need to employ ajax to bridge the gap between the server and the browser.
Edit - I forgot to modify the click function.
$('#table td:first-child').click(function() {
$('div.main').animate({
height:'0px'
}, function(){
//once the animation completes
$.ajax({
url: '/',
type: 'GET', //this is default anyway
data:{name: $(this).data('name')}, //send the name from the td clicked
dataType: 'json', //what we expect back from the server
success: function(data){ //will fire when complete. data is the servers response
if(data.success !== false){
$('div').html(data.html);
$('div.main').animate({
height: "50px"
}, 600);
}else{
alert("Something went wrong");
}
}
});
}, 600);
});
A site I'm working on takes table data, counts that table data and uses a standard loop to display it. Here's some of the code:
<?php
$output='';
$count=count($deal_datas);
$face_value="";
$deal_price="";
//var_dump(400*20/100);
$save_value='';
$save_value_present='';
$category_name='';
$cat_ids=array();
$deal_link='';
$address_array=array();
$address='';
$website_name='';
$website_data=array();
if($count!=0) {
for($i=0;$i<$count;$i++) {
$website_data=get_single_row("web_sites",array("id"=>$deal_datas[$i]->site_id));
if(count($website_data)!=0) {
$website_name=$website_data[0]->name;
}
$address_array=array();
$cat_ids=explode(",",$deal_datas[$i]->sub_category_ids);
if(count($cat_ids)!=0) {
$where_class=array("id"=>$cat_ids[0]);
$category_names=get_single_row("sub_category",$where_class);
if(count($category_names)!=0) {
$category_name=$category_names[0]->name;
} else {
$category_name="All";
}
} else {
$category_name="All";
}
$face_value=str_replace("USD","",$deal_datas[$i]->deal_face_value);
$face_value=str_replace("$","",$face_value);
$face_value=(int)str_replace(",","",$face_value);
$save_value_present=(int)str_replace("%","",$deal_datas[$i]->deal_save_percent);
if($deal_datas[$i]->deal_price!="") {
$deal_price=str_replace("USD","",$deal_datas[$i]->deal_price);
$deal_price=(int)str_replace("$","",$deal_price);
$save_value=$deal_price;
} else {
$save_value=$face_value*$save_value_present/100;
}
$time_zone_utc=$deal_datas[$i]->deal_oe_end_date;
$end_date=$time_zone_utc;
if($website_name!="kgbdeals") {
$deal_link=base_url()."deals/iframe/".$deal_datas[$i]->slug;
} else {
$deal_link=$deal_datas[$i]->deal_link;
}
if($deal_datas[$i]->deal_address==0 or $deal_datas[$i]->deal_zip_code==0) {
$deal_datas[$i]->deal_address="";
$deal_datas[$i]->deal_zip_code="";
}
if($deal_datas[$i]->deal_zip_code!="") {
$address_array[]=$deal_datas[$i]->deal_zip_code;
}
if($deal_datas[$i]->deal_address!="") {
$address_array[]=$deal_datas[$i]->deal_address;
}
$address=implode(" ",$address_array);
if($deal_datas[$i]->deal_city!="") {
if(empty($address_array)) {
$address.=$deal_datas[$i]->deal_city;
} else {
$address.=" - ".$deal_datas[$i]->deal_city;
}
//Check for valid image
$deal_image=base_url().'uploads/deals/'.$deal_datas[$i]->slug.'.jpg';
if(getimagesize($deal_image)) {
$valid_image=1;
} else {
$valid_image=0;
}
if($i%2==0) {
$output.='<div class="clsDeal_Whole_Cont clearfix">
Then it outputs the tabled list of data, etc.
Problem is, sometimes that data is sometimes 120 entries that are placed on the screen and the load takes ages.
What I want to do display the data 4 or 8 entries at a time. Then, as the user scrolls, add more in.
Alternatively - to load 4. Display them. Then load 4 more, display them. And so on, so that way the user actually gets to view the contents rather than waiting for the whole list (if this is simpler). Is that possible?
I'm not using jquery for this, though I know I would need to for the whole scroll down bit. So, would there be a way to rewrite the above php in order to display chunks of 4 until the final result is reached?
You have several problems here, beginning with how you ask the question. Be sure to include all the relevant code. You have a truncated code listing that doesn't deal with the problem at hand; how to break up a long set of data into a human readable format. You do not describe how you're getting your initial data $deals_data. The implementation details of how your format your output is not relevant to this question. Further, your code is a bit of the mess and doesn't follow the Single Responsibility Principle.
You should put your data selection and display functionality into single functions:
//returns n through z rows of data. If '0' is provided for finish, returns all rows
function getData($start=0, $finish=0 {
$data = array();
if ($finish == 0) {
//get all data
} else {
//get limited amount of data
}
return $data;
}
//returns first $limit rows of data as an html-encoded output string
function displayDeals($deal_data, $limit) {
...
}
That function should call a separate function for each of your rows:
//Returns a string of html-encoded data for one row
function displayRow($row_data) {
...
}
This displayRow function will be called $limit number of times by displayDeals. Once you get that working, it becomes much simpler to use AJAX for infinite scrolling. You simply create a php function:
function getMoreRows($start, $numberOfRows) {
$data = getData($start, $start+$numberOfRows);
$output = displayDeals($data, $numberOfRows);
return $ouput;
}
This will return that output to the AJAX function that called the php code. Because it's encoded as HTML you simply replace whatever available div with that new string.
Note that JQuery will make this AJAX easy, but you will need some javascript in order to make this functional, or suffer a long round-trip call to a new php page each time. The latter is easy, but avoids making the user interface smooth and lazy-loaded like you want. Here is how:
$.ajax({ url: '/my/site',
data: {action: 'getMoreData'},
type: 'post',
success: function(output) {
//replace your div with new data
}
});
On the server side you need a php page to handle the request:
if(isset($_POST['action']) && !empty($_POST['action'])) {
$action = $_POST['action'];
switch($action) {
case 'getMoreData' : getMoreRows($_POST['lastDataIndex'], $_POST['numberOfRowsToFetch']);break;
// ...etc...
}
}
As a minor post-script about style: you should be cautious about mixing if and if-else styles, in regards to brackets. Generally, you want you code to be tight and quickly readable, and you want to never be in doubt if code is in a block. Personally, I always use brackets with if and if-else, but you should avoid using brackets in your if statement and not in your else case at the very least. Keep an eye on human readability, or you will find that you'll be frustrated by random bugs that arise because you assume a thing is or is not in a block when it's the opposite case.
It seems to me that, ostensibly, you want to paginate the data. That's easy to do. Just have next and previous buttons on your page which are dynamically generated to link to offsets in your list (i.e. page?offset = 4, page?offset = 8). Then just load four items (offset+1, offset+2, offset+3, and offset+4) on each page.
I have a text based game site (Mafia game) written in old php/mysql style. I have no to very less knowledge of PHP/MYSQL i am learning it though. So i am having problems with one of file which reloads every 5 second via ajax , it contains few Mysql query which checks messages, forum messages,transfer,attacks etc and depending on the check it shows alert to users if they get any new message,forum messages,transfer,attacks etc. My site is using VPS right now and if i set the refresh rate to 5 seconds it overlaods the VPS within few minutes so i have to set the refresh time to 20 seconds or more. I would like to know if there is any problems with query or any suggestion to optimize query/php code. Below is code of my file ajax.php which needs to be reloaded every 5 seconds
<?php
include("funcs.php");
global $tab, $time, $id, $tru, $old;
$round=$_GET['tru'];
$tO=0;
$moFo='r'.$round.'_mafiosi';
$brd=$tab['board'];
$query="select msg,atk,ivt,transf from $moFo where id='$id'";
$result=mysql_query($query);
$ans=mysql_fetch_assoc($result);
foreach($ans as $key=>$value)
{
$tO+=$value;
}
$rtn='#'.$mafioMsg;
echo "$tO$rtn";
?>
#
and below is the jquery/javascript i am using :
<script type="text/javascript" >
var onOff=false;
var replyText='';
window.onload=mainF;
function hideRedNotif()
{
document.getElementById('redNotif').style.display='none';
}
function mainF()
{
fetchNotif();
Updtr=window.setInterval(fetchNotif,25000);
}
function toggleNotif()
{
document.getElementById('redNotif').style.display='none';
if(onOff==false)
{
document.getElementById('parentReply').style.display='';
onOff=true;
}
else
{
document.getElementById('parentReply').style.display='none';
onOff=false;
}
}
function getAjxObject()
{
try {
var o=new XMLHttpRequest();
}
catch(exception)
{
var o=new ActiveXObject('Microsoft.XMLHTTP');
}
return o;
}
function fetchNotif()
{
roundN=document.getElementById('roundName').value;
var o=getAjxObject();
o.open('GET','notifAjx.php?openSes=in&&tru='+roundN,true);
o.onreadystatechange=execute;
o.send();
function execute()
{
if(o.readyState==4 && o.status==200)
{
var countF=0;
resp=o.responseText;
rsp=resp.split('#');
dom=document.getElementById('notifM');
dom.innerHTML=rsp[0];
//document.getElementById('chatRoller').innerHTML=rsp[1];
//if(rsp[1]!=replyText )
//{
//document.getElementById('redNotif').style.display='';
//replyText=rsp[1];
//}
}
}
}
function sendReply()
{
var o2=getAjxObject();
roundN=document.getElementById('roundName').value;
m=document.getElementById('replyText').value;
msg='&&reply=1&&msg='+m;
url='notifAjx.php?tru='+roundN+msg;
o2.open('GET',url,true);
document.getElementById('replyText').value='';
o2.onreadystatechange=execute;
o2.send();
function execute()
{
if(o2.readyState==4 && o2.status==200)
{
}
}
}
</script>
UPDATE- Thanks to everyone for checking my issue, I took screenshots of my DB tables please check if it helps or let me know what else should i provide.
http://i.imgur.com/VJSU2.jpg
http://i.imgur.com/5O6T0.jpg
I will appreciate any suggestion/help.
Thanks & Regards
Prashant
please check for indexing in the table '$moFo'
and check whats the volume of the data you are dealing with, if its high then do archive them or use sharding.
I expect you may have issues because if your asynchronous request takes more than 5 seconds, you'll start to get a backlog. It might sound counter-intuitive, but I recommend making your asynchronous requests a bit more synchronous:
Currently you're using setInterval to run your check every five seconds, regardless of whether a response has come back. What you could do instead is use setTimeout to get it started and then set another timeout when your response has come back, whether it was successful or not. This way, your responses will never start to overlap.
In practice:
Change your mainF() function to be
function mainF()
{
fetchNotif();
Updtr=window.setTimeout(fetchNotif,25000);
}
Then change your fetchNotif() execute() function to set another timeout once it's processed
Updtr=window.setTimeout(fetchNotif,25000);
You may want to wrap that one in an if to check for readyState == 4 but don't check for status == 200 because you probably want it to try again even if the previous attempt failed.
I'm using the legacy jquery autocomplete plugin and would like to trigger an event if my search box is cleared. Here is my current code:
jQuery(function($){
$("#searchbox").Watermark("Search");
});
$("#searchbox").autocomplete("search_names.php", {
width: 250,
selectFirst: false
});
$("#searchbox").result(function(event, data, formatted) {
if (data) {
filterView( data );
}
});
I've tried using the result trigger but it's expecting a valid result. Any idea how I can trigger an event when the search box is empty? Basically I want to restore the search results prior to the filtered results.
Thanks
a possible solution might be to use the .focus to run a while loop that checks for an empty field when the user is clicked in the search box and close the while loop in using .blur when they leave the searchbox. I haven't tried this, so please let me know if it works. Sincerely,
Kevin
$("#searchbox").focus(function () {
var checkNull = true;
while (checkNull == true){
if (!data) {
if (previous results are not displayed) {
your code here to display prior results;
}
}
}
}
$("#searchbox").blur(function () {
checkNull = false;
}
I'm developing an application which relies heavily on jQuery for user interaction.
(and if you're browser doesn't support jQuery, then upgrade or don't use my application :)
As normal, one have functions to GET, SET and DELETE data from a table.
In my application, I'm GET'ing and SET'ing a lot of information without page reload. To do this, I mostly use jQuery.post.
A typical code in my JS file looks like this:
jQuery.post("mypath/jquery_getset_data.php", { instance: 'getItems_A', itemID: itemID_value},
function(data) {
populateItemList(data);
});
The jquery_getset_data.php contains of many if statements:
if($_POST['instance'] == 'getItems_A'){
// PHP code to get and process data from MySQL DB
}
if($_POST['instance'] == 'setItems_A'){
// PHP code to process and insert data to MySQL DB
}
Here's my question:
Is tehre a better way for interaction between JS file and jquery_getset_data.php?
How can I dynamically call different "remove item" functions inside createStoreList? See update 1.
Update 1:
This is the code that I use to create many different lists.
function createStoreList(data)
{
var ul = jQuery("<ul/>");
// We need to build the html structure in order for this to be registered in DOM.
// If we don't, jQuery events like .click, .change etc. will not work.
for (var i = 0; i < data.length; i++)
{
ul.append(
jQuery("<li/>")
.attr("id", "listItem_"+data[i].id)
.append(jQuery("<span/>")
.addClass("btnRemoveItem")
.attr("title", "Remove store from list")
.attr("id", data[i].id)
.click(function() { removeItemA(this); })
)
.append(data[i].name + ', ' + data[i].street)
);
}
return ul;
}
Update 2
I figured I just could use switch statements. I've tested it and it works.
.click(function() {
switch(instance)
{
case 'removeListItemA': removeListItemA(this); break;
case 'removeListItemA': removeListItemB(this); break;
case 'removeListItemA': removeListItemC(this); break;
}
})
In order to reduce the jquery_getset_data.php I would use the OOP design patterns to avoid switches and if statements.
class ICommand
{
public:
function execute( );
};
class CommandGetItemA
{
public:
function execute( )
{
//do some staff here
};
};
and then:
CommandsMap['getItemA'] = new CommandGetItemA( );
CommandsMap['setItemA'] = new CommandGetItemB( );
....
CommandsMap[ $_POST['instance']].execute( );
I know looks complicated, but for my taste looks much better.
And regarding your second question I'm not sure I understood it, can you add more explanation?
After I saw you update, I think for second question you can do:
.click(function() {
window[instance]( this);
});
There the "instance" is the function name, or you can update or append it latter to make it be the function name;
The only thing I would change is in jquery_getset_data.php I would use a switch statement instead of many if statements. jQuery's $.post method is fine for what you're doing, talking to a script that affects the database (deletes/updates/etc) using one of the GET ajax methods ($.load or $.get) breaks the HTTP specification.