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.
Related
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...
}
?>
I am having a problem with setInterval in the $(document).ready(function(){}
What I am doing is setting the interval to do is call a PHP script that runs some MySQL queries to check the condition of 4 switches and then updating the screen with the values are in the database like so:
$(document).ready(function(){
setInterval(function(){
<?php require('fetchSwitchStatuses.php'); ?>
$("#switch1").css('background', 'rgb(<?php echo $switchColor1 ?>)');
$("#switch1").html('<?php echo $switchState1 ?>');
$("#switch2").css('background', 'rgb(<?php echo $switchColor2 ?>)');
$("#switch2").html('<?php echo $switchState2 ?>');
$("#switch3").css('background', 'rgb(<?php echo $switchColor3 ?>)');
$("#switch3").html('<?php echo $switchState3 ?>');
$("#switch4").css('background', 'rgb(<?php echo $switchColor4 ?>)');
$("#switch4").html('<?php echo $switchState4 ?>');
},1000);
});
Here is the code for fetchSwitchStatuses.php:
$connect = mysqli_connect("localhost", "root", "root");
mysqli_select_db($connect, "db_name");
$fetch1 = mysqli_query($connect,
"SELECT SwitchStatus FROM Switches WHERE PinNumber = '3'"
);
$fetch2 = mysqli_query($connect,
"SELECT SwitchStatus FROM Switches WHERE PinNumber = '5'"
);
$fetch3 = mysqli_query($connect,
"SELECT SwitchStatus FROM Switches WHERE PinNumber = '6'"
);
$fetch4 = mysqli_query($connect,
"SELECT SwitchStatus FROM Switches WHERE PinNumber = '9'"
);
$i = 1;
while($row = mysqli_fetch_array(${'fetch'.$i}))
{
if($row['SwitchStatus'] == 0)
{
${'switchColor'.$i} = "255, 0, 0";
${'switchState'.$i} = "OFF";
}
else if ($row['SwitchStatus'] == 1){
${'switchColor'.$i} = "0, 255, 0";
${'switchState'.$i} = "ON";
}
else {
${'switchColor'.$i} = "100, 100, 100";
${'switchState'.$i} = "ERROR";
}
$i++;
}
mysqli_close($connect);
When the page is loaded the information is correct, whatever is in the database is what is reflected by the colors on the screen.
When I click on the object to change the value, all of the necessary changes are made and the database is updated. However, the problem arises when the Interval is repeated. The values are switched back to whatever the original values were when the page was loaded. So, although the information is correctly changed in the database, for some reason the colors of the buttons is always reset to the first value read by the queries.
How can I fix this so that the information that is reflected on the screen is accurate?
With AJAX technology you can:
Send a request and get results from server by requesting a page (a .txt .js .html or even php).
So with AJAX you can get result of a page save something to database, get something from data base, you can work with sessions and anything you can do with a php file.
When you send an AJAX request to a see a page(i.e /userData.php?userId=5) the page /userData.php?userId=5 will be executed and its output will be returned.(HTML or just a word ‘yes’ or ‘no’ or ‘you can’t access to this user’s information’).
You can send data to file with POST or GET. But the question is how you can get data from page. Because the result AJAX will give you is what the requested page echoed to page like this
<html>
….
</html>
Or
‘Yes’
Or
<?php echo ‘something’; ?>
So what about getting a row of Date or lots of data? Because the only thing you are getting is a text or maybe a long text.
For that you can use JSON which Is something like nested arrays.
[
{
"term": "BACCHUS",
"part": "n.",
"definition": "A convenient deity invented by the...",
"quote": [
"Is public worship, then, a sin,",
"That for devotions paid to Bacchus",
"The lictors dare to run us in,",
"And resolutely thump and whack us?"
],
"author": "Jorace"
},
…
And this is a string too. But you can get Data in it with $.getJSON in jQuery and you can generate JSON data in server side like this.
<?php
$arr=array(
‘data’=>’ffff’,
‘anotherData’=>array(‘rrrrr’,’sssss’);
);
Echo json_encode($arr);
?>
Json_encode() in PHP gets an array and returns json string of it. And we echo it.
Now we can use jQuery to get Data which will be retrieved from server.
This section if from
Learning jQuery 1.3
Better Interaction Design and Web Development with Simple JavaScript Techniques
Jonathan Chaffer
Karl Swedberg
Global jQuery functions
To this point, all jQuery methods that we've used have been attached to a jQuery object that we've built with the $() factory function. The selectors have allowed us to specify a set of DOM nodes to work with, and the methods have operated on them in some way. This $.getJSON() function, however, is different. There is no logical DOM element to which it could apply; the resulting object has to be provided to the script, not injected into the page. For this reason, getJSON() is defined as a method of the global jQuery object (a single object called jQuery or $ defined once by the jQuery library), rather than of an individual jQuery object instance (the objects we create with the $() function).
If JavaScript had classes like other object-oriented languages, we'd call $.getJSON() a class method. For our purposes, we'll refer to this type of method as a global function; in effect, they are functions that use the jQuery namespace so as not to conflict with other function names.
To use this function, we pass it the file name as before:
$(document).ready(function() {
$('#letter-b a').click(function() {
$.getJSON('b.json');
return false;
});
});
This code has no apparent effect when we click the link. The function call loads the file, but we have not told JavaScript what to do with the resulting data. For this, we need to use a callback function.
The $.getJSON() function takes a second argument, which is a function to be called when the load is complete. As mentioned before, AJAX calls are asynchronous, and the callback provides a way to wait for the data to be transmitted rather than executing code right away. The callback function also takes an argument, which is filled with the resulting data. So, we can write:
$(document).ready(function() {
$('#letter-b a').click(function() {
$.getJSON('b.json', function(data) {
});
return false;
});
});
Here we are using an anonymous function as our callback, as has been common in our jQuery code for brevity. A named function could equally be provided as the callback.
Inside this function, we can use the data variable to traverse the data structure as necessary. We'll need to iterate over the top-level array, building the HTML for each item. We could do this with a standard for loop, but instead we'll introduce another of jQuery's useful global functions, $.each(). We saw its counterpart, the .each() method, in Chapter 5. Instead of operating on a jQuery object, this function takes an array or map as its first parameter and a callback function as its second. Each time through the loop, the current iteration index and the current item in the array or map are passed as two parameters to the callback function.
$(document).ready(function() {
$('#letter-b a').click(function() {
$.getJSON('b.json', function(data) {
$('#dictionary').empty();
$.each(data, function(entryIndex, entry) {
var html = '<div class="entry">';
html += '<h3 class="term">' + entry['term'] + '</h3>';
html += '<div class="part">' + entry['part'] + '</div>';
html += '<div class="definition">';
html += entry['definition'];
html += '</div>';
html += '</div>';
$('#dictionary').append(html);
});
});
return false;
});
});
Before the loop, we empty out so that we can fill it with our newly-constructed HTML. Then we use $.each() to examine each item in turn, building an HTML structure using the contents of the entry map. Finally, we turn this HTML into a DOM tree by appending it to the .
This approach presumes that the data is safe for HTML consumption; it should not contain any stray < characters, for example.
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'm trying to pass a collection of parameters to a PHP page to be processed, from a JavaScript function:
entries: "test data from JavaScript"
In my PHP page I'm trying to grab the value that was posted back to the page:
$_POST['entries']
but this keeps return 'emtpy', regardless of what I try to push through. I'm new to PHP so this might be a stupid thing to fix.
This is invoked from a button click like such:
$("#submitButton").click(function(){});
Should the be wrapped in a form, as I don't see the need for this?
Update [full code]
var proxy = new ServiceProxy("submit.php");
$("#submit").click(function () {
var store = $("#store_name").val();
var contact = $("#contact_person").val();
proxy.invoke("", { entries: store }, success, error, false);
return false;
});
Note on the ServiceProxy. This proxy class wraps the default $.ajax {...} into a neat little proxy class, thanks to Rick Strahl over at west-wind. I've used this proxy class successfully in numerous single HTML and ASP.Net solutions in the past, so I don't it's the proxy service that's causing the issue.
Looks like your using jQuery, so why not use their post function?
$.post("/file/location/post.php", { Name: "Hello", Email: "email#address.com" } );
Then in your php code you can use:
$_POST['Name'] and $_POST['Email']
Hope this helps.
Sorry, just seen your updated code - this should work:
$("#submit").click(function () {
var store = $("#store_name").val();
var contact = $("#contact_person").val();
$.post("submit.php", { entries: store } );
return false; });
I'm a stuck with the following function:
<script type="text/javascript">
function removeElement($parentDiv, $childDiv){
if (document.getElementById($childDiv)) {
var child = document.getElementById($childDiv);
var parent = document.getElementById($parentDiv);
parent.removeChild($child);
}
}
</script>
x
This function deletes a child element, and its content, which works great client-side! But I am wanting to pass a value to the server, in the same instance, so the content of the element can be deleted from the mysql database too. I have no idea how to do this, so any suggestions will be very appreciated!
Notes: $child, and $parent are strings generated within the php file, that I use to give each element a unique ID.
To make your life easier, use jQuery or similar framework. Here's how you would do it in jQuery:
$(function() {
$('.delete').click(function() {
var link = $(this);
var id = link.attr('id').replace('element_', '');
$.ajax({
url: 'handler.php',
data: {
element: id
},
type: 'post',
success: function() {
link.remove();
// Or link.closest('tr').remove() if you want to remove a table row where this link is
}
});
return false;
});
});
The HTML:
Remove
And handler.php:
mysql_query("DELETE FROM `table` WHERE id = '".mysql_real_escape_string($_POST['element'])."'");
Always remember to escape database input!
If you're a total noob as you said, you probably won't understand all of this so I suggest you read something about jQuery's AJAX capabilities and about overall development using jQuery or similar JavaScript framework.
Lets say I want to delete an entity using a ID
JQUERY - $.post()
This is an easy way to send a simple POST request to a server without having to use the more complex $.ajax function. It allows a single callback function to be specified that will be executed when the request is complete (and only if the response has a successful response code). Jquery post docs
On the server assuming you have an open database connection.
mysql_query("DELETE FROM TABLE WHERE ID = ".$_POST['ID']);
more on mysql_query found here
EDIT:
So the following will only remove the element when the ajax post is complete. Note the first arg is the url to the script that will take the action , second is the data to be sent, in this case the ID post value will be {child.id} and the third is a anon inline callback function that will take action to remove the element client side.
<script type="text/javascript">
function removeElement($parentDiv, $childDiv){
if (document.getElementById($childDiv)) {
var child = document.getElementById($childDiv);
var parent = document.getElementById($parentDiv);
$.post('{URLTOSCRIPT}', 'ID=$child.id',function () { parent.removeChild($child); });
}}
</script>
When you call the function, you'd want to put your PHP variables in tags like so:
<?php echo $parent; ?>
and
<?php echo $child; ?>
In the function definition, you will want to get rid of the PHP style variables and use something like:
function removeElement(parentDiv, childDiv) {
//CODE
}