cakephp saving data without reload page - php

I have a label called price, and this label automatically updates its value every two seconds from the server. Also I have a button or link, which increases this price in database when I do click. The problem is how save the data without redirect to the same page.
My code:
<?php
echo $this->html->link('Increase price', array('controller' => 'example', 'action' => 'increase_price', $param1), array ('id' => 'btPrice'));
?>
And in ExampleController the code is
function increase_price($param1)
{
$this->autoRender = false; //Don't want a view
$example = $this->Example->findById($param1);
$example ['Example ']['price'] = $example ['Example ']['price'] + 1;
$this->Example->save($example );
}
The price is increased but cakePhp is asking me for a view, and if I do autoRender=false then my page will be blank and I want to stay on the same page.
I don't know if this is a CakePhp question or if is Jquery question. In both cases, I appreciate your help

if you don't wanna reload the page to do this, you need to use Ajax..since you've already got unique id for this, what you need to do is use Jquery Ajax to handle this.
first download jquery lib and put it into your app/webroot/js folder and load it
http://jquery.com/download/ download Jquery lib here
then you can do:
<script>
$( document ).ready(function() {
//do sth when click on #btPrice
$('#btPrice').click(function(){
$.ajax({
type:"POST",
//the function u wanna call
url:"<?php echo $this->webroot;?>example/increase_price/",
/* data you wanna pass, as your $param1 is serverSide variable,
you need to first assign to js variable then you can pass:
var param1 = '<?php echo $param1;?>';*/
data:{increase_price:param1},
success:function(data)
{
//update your div
}
});
});
});
</script>
Also you have to modify your increase_price function
As we are passing increse_price as parameter in ajax call and method is post, in your function, you have to use $_POST['increase_price'] to catch it then assign to another variable
eg: $param1 = $_POST['increase_price']; then you can use it..
Should do the trick for you

The normal flow is that when you click on a link, the browser requests a new page from the server and then renders the contents.
If you want to change something in the DOM from the client's side you need Javascript.
With the use of Javascript you can skip the complete page reload because you can request the exact information you need and then update the DOM with it. This is known as AJAX.
While you can do AJAX with plain Javascript it is usually much easier to use a Javascript framework like jQuery to make things easier.

Related

Best practice for using jquery to interact with php classes?

I have a dropdown selector on a page that allows a user to select a template type (for example, "human" or "dog").
Based on what template is selected, different fields will need to populate below the dropdown (for example, text fields for "parents names" or a dropdown list for "breed") that are unique to each template.
I will have a button that the user will click once the data fields are put in that will output data to an "output div" section of the same page when clicked (no POSTing data as it's not being saved). The output will have different output logic based on the selected template (for example, "I'm a human named X" or "I'm a dog, my breed is Y").
My real program will be more complex and each template will have a php class that stores all of the logic. Since I will be dealing with both php objects and variables gathered by jquery, what's the best way to let them interact?
For 1., I know I can do something easy like -
var selected_template = $('#my-template-dropdown :selected').text();
if (selected_template == 'Human'){
$('#my-fields').html('<?php echo HumanTemplate::render_fields(); ?>');
}
which is easy enough, but for 2. I need to pass variables from jquery to php, then return output back to jquery.
I would like some advice on the easiest way to do this before I start down the wrong path.
HTML
Allow the user to select the template type:
<form>
<select id="my-template-dropdown" name='template'>
<option value="dogs">Dogs</option>
<option value="humans">Humans</option>
</select>
</form>
<div id="my-fields"><div>
<div id="output"><div>
jQuery
Any time the user changes the template selection, request new content to display via AJAX, and insert it on the current page so the page does not have to refresh:
$('#my-template-dropdown').on('change', function() {
var template = $(this).val();
$.ajax({
url: 'http://your-site/path/to/' + template,
success: function(resp) {
$('#my-fields').html(resp);
}
});
});
PHP
http://your-site/path/to/template simply generates the HTML you want to display for that template, eg (just an example, don't know if this is suitable for your app):
if ($template == 'humans') {
echo HumanTemplate::render_fields();
} else if ($template == 'dogs') {
echo DogTemplate::render_fields();
}
For part 2, assuming all the logic you refer to is in the template rendered by PHP, you could then handle it with jQuery. This is pretty crude, you probably need something more sophisticated (eg a full template which you swap variables into?), but you get the idea:
$('#output').on('click', 'button', function(e) {
e.preventDefault();
// fields in your template which the user will fill
var species = $('#species').val(),
title = $('#title').val();
// Probably better to have this text as a template in your source
$('#output').html("I'm a " + species + ' named ' + title);
});
NOTE the gotcha in the event handler. Event handlers will only attach to elements that exist at the time the handler is defined. Since the content is injected after page load, an event handler like $('#button).on('click', function() {... would have no effect when clicking a button inserted via AJAX. The syntax here attaches to the parent #output div, which does exist at page load, and filters for clicks on a button. See the jQuery event delegation docs for more info.
Another option would be to POST the submitted data to some PHP controller, which generates and returns the output. This way all your logic is in the one place. For example, here the user's click will query the same PHP file which generated the initial template, this time including the values the user has entered. It could then generate the required output and return it, to be inserted on the page. You'd need to update the PHP so it can determine which of these cases it is handling (eg hidden field?); alternatively if you wanted to keep those separate you could hit another PHP file all together.
$('#output').on('click', 'button', function(e) {
var template = $('#my-template-dropdown').val(),
$form = $('form'),
data = $form.serialize(); // Values from all fields user has entered
$.ajax({
url: 'http://your-site/path/to/' + template,
data: data,
success: function(resp) {
$('#output').html(resp);
}
});
});
The best way to pass data from jQuery to PHP, is by using AJAX.
Mozilla has an excellent guide on getting started, that i recommend you follow.
An example of how you can achieve what you are requesting, is by trying the following:
var selected_template = $('#my-template-dropdown :selected').text();
var ajaxurl = 'ajax.php',
data = {'select_template': selected_template };
$.post(ajaxurl, data, function (response) {
console.log(response);
});
On the PHP end (Ajax.php in my example) It could look something like this
if(isset($_POST['select_template'])) {
// do something with the input from jQuery
$selected_template = $_POST['select_template'];
// return the result back to the client
echo $seleted_template;
}
?>
$selected_template will be sent back to the client, and response in the AJAX function will be whatever the server returned. So the console.log(response) should display whatever was being sent to the server
You can have a look to the function wp_localize_script.
This function make available PHP datas to JS files on the page load through the wp_enqueue_scripts action.
This will not work like an Ajax request and only populate data for a specific handle on page load. But you can mix this method with ajax in the same script.
Hope it helps even it doesn't seems to fit to your case.
As your class not fires on page load, you can use the action wp_ajax_{custom _action} and wp_ajax_nopriv_{custom_action} . For example, that's usually used to populate multiple dropdown, each time an event is trigger by the user, a php function returns result the js script.

get an iframe's "src" value in PHP?

I have an iframe on my page, where on click (a menu) will update the iframe with a new URL depending on what menuitem they select.
I do that by calling javascript function on 'onclick' passing the URL from the menu :
function frameclick(pageurl)
{
$("#iFrame1").attr('src', pageurl);
}
What i would like to do whenever they press a menuitem is to store what iframe is loaded, because i have another button (select page language) and when they press that i want to reload the page but pass on the iframe-url that is currently displayed as a variable in the site url.
Since PHP is serverside and JS is clientside, i cannot do ex. "$current_iframe_url = pageurl" - which would have enabled me to pass it on as a variable on refresh.
You know how i could get around this ?
That works fine.
What i want to do now, is to whenever they click a menuitem i want to store that URL
on every click create a hidden field save the value of url in a hidden field then only change the url. then after that you can simple submit the form using ajax .
or when ever user clicks call an ajax function so that u can copy the url in database or session what ever you like.
sample
function frameclick(pageurl)
{
$.post("server.php", { url: pageurl } );
$("#iFrame1").attr('src', pageurl);
}
your php server.php should do something like this
if(isset($_POST['url']){
//INSERT IN TO DB
}
Following fiddle used to get its URL, http://jsfiddle.net/sameerast/FUUz9/1/
Hope this also helpful,
$('iframe').bind('mouseover', function(){
var iframeID = $(this).attr('src');
$(this).contents().find('html').unbind();
$(this).contents().find('html').bind('click', function(){
alert(iframeID);
});
})
; ​

PHP post and get value to a jQuery box page, refresh page as `msnbc.com`

Finally, I find some article in http://code.google.com/intl/en/web/ajaxcrawling/docs/getting-started.html msnbc use this method. Thanks for all the friends.
Thanks for your all help. I will study it for myself :-}
Today, I updated my question again, remove all of my code. Maybe my thinking all wrong.
I want make a products show page.
One is index.php, another is search.php (as a jquery box page). index.php has some products catagory lists; each click on product catagory item will pass each value to search.php. search.php will create a mysql query and view products details. It(search.php) also has a search box.(search.php can turn a page to show multiple products; the search result looks similar to a jQuery gallery...).
I need to do any thing in search.php but without refreshing index.php.
I tried many method while I was thinking: Make search.php as an iframe (but can not judge search.php height when it turn page and index.php without refresh); use jquery ajax/json pass value from index.php to search.php, then get back all page's value to index.php. (still met some url rule trouble. php depend on url pass values in search.php, but if the value change, the two page will refresh all. )
so. I think, ask, find, try...
Accidental, I find a site like my request.
in this url, change search word after %3D, only the box page refresh
in this url, change search word after = the page will refresh
I found somthing in its source code, is this the key rules?
<script type="text/javascript">
var fastReplace = function() {
var href = document.location.href;
var siteUrl = window.location.port ? window.location.protocol+'//'+window.location.hostname +':'+window.location.port : window.location.protocol+'//'+window.location.hostname;
var delimiter = href.indexOf('#!') !== -1 ? '#!wallState=' : '#wallState=';
var pieces = href.split(delimiter);
if ( pieces[1] ) {
var pieces2 = pieces[1].split('__');
if ( pieces2[1] && pieces2[1].length > 1) {
window.location.replace( unescape(pieces2[1].replace(/\+/g, " ")));
}
}
}();
</script>
If so. in my condition. one page is index.php. another is search.php.
How to use js make a search url like
index.php#search.php?word=XXX&page=XXX
then how to pass value from one to another and avoid refreshing index.php?
Still waiting for help, waiting for some simple working code, only js, pass value get value.
Thanks to all.
I have read your problem, though I can not write complete code for you (lack of time ) So I can suggest you to what to do for your best practice
use dataType ='json' in jQuery.ajax function and
write json_encode() on B.php
and json_decode() on A.php or $.getJSON()
Alternate:
Read
jQuery.load()
assuming you really want to do something like here: http://powerwall.msnbc.msn.com/
I guess they are using a combination of ajax-requests and something like this: http://tkyk.github.com/jquery-history-plugin/
make shure that the navigation (all links, etc.) in the box works via ajax - check all the links and give them new functionality by js. you can write some function which requests the href url via ajax and then replace the content of your box. ...
function change_box_links(output_area){
output_area.find('a').each(function(){
$(this).bind('click', function(e){
e.preventDefault();
var url = $(this).attr('href');
$.ajax({
url: url,
success: function(data){
output_area.html(data);
//update url in addressbar
change_box_links(output_area);
}
});
});
});
}
it is upgradeable but shell show the main idea...
addendum[2011-05-15]
Get away from thinking you will have two files, that can handle some many "boxes". i mean you can do this but it's worth it.
but to be able to set up your templates like normal html page you could use the above script to parse the ajax requested html pages.
build your html-pages for
viewing the content,
viewing the search result
, etc.
on your main page you have to provide some "box" where you can display what u need. i recommand a div:
<div id="yourbox"></div>
your main page has buttons to display that box with different content, like in the example page you have showed us. if you click one of those a JS will create an ajax call to the desired page:
(here with jquery)
$('#showsearch_button').bind('click', function(){showsearch();});
function show_search() {
$.ajax({
url: 'search.php',
success: function(data){
var output_area = $('#yourbox');
output_area.html(data);
$.address.hash('search');
change_box_links(output_area);
}
});
});
for other buttons you will have similar functions.
the first function (see above) provides that the requested box-content can be written as a normal html page (so you can call it as stand-alone as well). here is the update of it where it also provides the hashtag url changes:
jquery and requireing the history-plugin
function change_box_links(output_area){
output_area.find('a').each(function(){
$(this).bind('click', function(e){
e.preventDefault();
var url = $(this).attr('href');
$.ajax({
url: url,
success: function(data){
output_area.html(data);
var name = url.replace('/\.php/','');
$.address.hash(name);
change_box_links(output_area);
}
});
});
});
}
and you will need some kind of this function, which will bind the back and forward buttons of your browser:
$.address.change(function(event) {
var name = $.address.hash();
switch(name){
case 'search': show_search(); break;
default: alert("page not found: "+name);
}
});
the above code should give an idea of how you can solve your problem. you will have to be very consequnt with filenames if you just copy and past this. again: it is improveable but shell show you the trick ;-)
im not sure that i fully understood what you want, but correct me if i didnt,
i think u need something like a dropdown that once the user select one item some div inside ur page show the result of another page result..
if so u can do it with jquery .load() and here is an example (no need for json)
Step 1:
Index.php
<p>
brand:<select id=jquerybrand>$jquerybrands</select><br />
Model:<select id=jquerycars></select><br />
</p>
<script type=\"text/javascript\">
$(document).ready(function(){
$('#jquerybrand').change(function(){
var value=$(this).value;
var url='api/quick.php?'+this.id+'='+this.value+' option';
$('#jquerycars').load(url);
});
});
</script>
This will simply show 2 dowpdown boxs (can be text or anything u like). and will add a listener to any change in value. once changed it will submit the id of the field and the new value to api/quick.php , then quick.php responce will be loaded into #jquerycars dropdown.
Step 2 quick.php
if(isset($_GET['jquerybrand'])){
$jquerycars="";
require_once("../lib/database.php");
$sql_db = new database();
$l=$sql_db->Item_in_table("car","sheet1","WHERE `brand`='$jquerybrand';");
foreach($l as $l)$jquerycars .="<option>$l</option>";
echo $jquerycars;//response that will replace the old #jquerycars
}
this will confirm that this is a request to get the query result only, then it will do the query and echo the results.
now once the results come back it will replace the old :)
hope it helps :).

How to get element id into PHP variable

Is it possible to get an element id into a PHP variable?
Let's say I have a number of element with IDs:
<span id="1" class="myElement"></span>
<span id="2" class="myElement"></span>
How do I get this into a PHP variable in order to submit a query. I suppose I would have to resubmit the page, which is OK. I would like to use POST. Can I do something like:
<script language="JavaScript">
$(document).ready(function(){
$(".myElement").click(function() {
$.post("'.$_SERVER['REQUEST_URI'].'", { id: $(this).attr("id") });
});
});
</script>
I need to pass $(this).attr('id') into $newID in order to run
SELECT * from t1 WHERE id = $newID
jQuery is a very powerful tool and I would like to figure out a way to combine its power with server-side code.
Thanks.
This is like your question: ajax post with jQuery
If you want this all in one file (posting to active file) here is what you would need in general:
<?php
// Place this at the top of your file
if (isset($_POST['id'])) {
$newID = $_POST['id']; // You need to sanitize this before using in a query
// Perform some db queries, etc here
// Format a desired response (text, html, etc)
$response = 'Format a response here';
// This will return your formatted response to the $.post() call in jQuery
return print_r($response);
}
?>
<script type='text/javascript'>
$(document).ready(function() {
$('.myElement').click(function() {
$.post(location.href, { id: $(this).attr('id') }, function(response) {
// Inserts your chosen response into the page in 'response-content' DIV
$('#response-content').html(response); // Can also use .text(), .append(), etc
});
});
});
</script>
<span id="1" class="myElement"></span>
<span id="2" class="myElement"></span>
<div id='response-content'></div>
From here you can customize the queries and response and what you would like to do with the response.
You have two "good" choices in my mind.
The first is to initiate a post request every time the ordering changes. You might be changing the ordering using jQuery UI sortable. Most libraries that support dragging and dropping also allow you to put an event callback on the drop simply within the initialization function.
In this even callback, you'd initiate the $.post as you have written it in your code (although I would urge you to look up the actual documentation on the matter to make sure you're POSTing to the correct location).
The second strategy is to piggyback on a form submission action. If you're using the jQuery Form Plugin to handle your form submissions, they allow you to indicate a before serialize callback where you can simply add into your form a field that specifies the ordering of the elements.
In both cases, you'd need to write your own function that actually serializes the element IDs. Something like the following would do just fine (totally untested; may contain syntax errors):
var order = [];
$('span.myElement').each(function(){
// N.B., "this" here is a DOM element, not a jQuery container
order.push(this.id);
});
return order.join(',');
You're quite right, something along those lines would work. Here's an example:
(btw, using $.post or $.get doesn't resubmit the page but sends an AJAX request that can call a callback function once the server returns, which is pretty neat)
<script language="JavaScript">
$(document).ready(function(){
$(".myElement").click(function() {
$.post(document.location, { id: $(this).attr("id") },
function (data) {
// say data will be some new HTML the server sends our way
// update some component on the page with contents representing the element with that new id
$('div#someContentSpace').html(data);
});
});
});
</script>
Your approach looks perfectly fine to me, but jQuery does not have a $_SERVER variable like PHP does. The url you would want to provide would be window.location (I believe an empty string will also work, or you can just specify the url on your own). You seem to be sending the ID just fine, though, so this will work.
If you want the page to react to this change, you can add a callback function to $.post(). You can do a variety of things.
$.post(window.location, {id: this.id}, function (data) {
//one
location.reload();
//two
$("#responsedata").html(data);
//three
$("#responsedata").load("affected_page.php #output");
});
I think number 2 is the most elegent. It does not require a page reload. Have your server side php script echo whatever data you want back (json, html, whatever), and it will be put in data above for jQuery to handle however you wish.
By the way, on the server side running the query, don't forget to sanitize the $id and put it in quotes. You don't want someone SQL Injecting you.

Want to show "loading....." in PHP page

I am developing a web-page in PHP that needs following functionality:
1. When User click on "Say Thanks" it should be changed with "Done!".
2. At the same time I want to call an action in indexController.
3. At this time I want to show "loading...."
4. The current page has a lot of dynamic contents that should also not change.
Please suggest me what should I do to complete above tasks......
I figure you need an AJAX call. I usually do that for loading comments and such when you press "more". In my case, there's an empty div and an <a> tag with the link to the comments view (with a separate action, ofc). Then I use jQuery for the AJAX magic:
$(function() {
$("a.CommentsListBtn").click(function() {
var tmpHref = $(this).attr("href");
var tmpLayer = $(this).parent().children("div.CommentsList");
tmpLayer.load(tmpHref, function() {
tmpLayer.stop().slideDown("medium");
});
return false;
});
});
I hope this helps.
Learn to use JQuery, JQuery UI. It isn't that hard! What I think you need to learn is the following for your problem:
.click()
.html()
jQuery.get()

Categories