I added the custom fields in the WordPress admin panel I added a button called Add more fields so that users can add more than one. Now my issue is, I have to display fields dynamically by clicking on the Add more fields button.
I tried the below code but when I click on the Add more fields button then I am getting the browser warning and clicking on the leave button page then the page refreshed.
What is the issue with my code?
Full code here
function woocommerce_register_2col_layout_fields() {
global $post;
// Nonce field to validate form request came from current site
wp_nonce_field( basename( __FILE__ ), 'layout' );
// Output the field
echo '<button id="addMore_layout">Add more fields</button>';
echo '<div class="create_custom_layout" id="create_custom_layout"><div class="row">';
echo '<div class="col-md-6">';
echo '<h4>Description</h4>';
//We first get the post_meta from the DB if there's any there.
$description = get_post_meta( $post->ID, 'pDescription', true );
//Second ID the field.
$description_field = 'pDescription';
//Provide the settings arguments for this specific editor in an array
$description_args = array( 'media_buttons' => false, 'textarea_rows' => 12, 'textarea_name' => 'pDescription[]',
'editor_class' => 'description-editor widefat', 'wpautop' => true );
wp_editor( $description, $description_field, $description_args );
echo '</div>';
echo '<div class="col-md-6">
<h4>Banner image</h4>
<input type="button" id="meta-image-button" class="button" value="Choose or Upload an Image" style="padding: 8px 10px; height: auto; line-height: normal;"/>
<input type="hidden" name="pimage[]" id="meta-image" class="meta_image" value="'.get_post_meta(get_the_ID(), 'pimage', true ).'" /><br />
<img style="width: 100px;height: 100px;object-fit: cover;" id="meta-image-preview" src="'.get_post_meta(get_the_ID(), 'pimage', true ).'" />
</div>
</div>
</div>
<style>
.create_custom_layout .row{display: flex;flex-wrap: wrap;}
.create_custom_layout .col-md-6 {
flex: 0 0 auto;
width: 50%;
}
</style>
<script>
jQuery("#meta-image-button").click(function() {
var send_attachment_bkp = wp.media.editor.send.attachment;
wp.media.editor.send.attachment = function(props, attachment) {
jQuery("#meta-image").val(attachment.url);
jQuery("#meta-image-preview").attr("src",attachment.url);
wp.media.editor.send.attachment = send_attachment_bkp;
}
wp.media.editor.open();
return false;
});
jQuery(function() {
jQuery("#addMore_layout").click(function(e) {
e.preventDefault();
jQuery("#create_custom_layout").append("
<div class="row"><div class="col-md-6"><h4>Description</h4>';
//We first get the post_meta from the DB if there's any there.
$description = get_post_meta( $post->ID, 'pDescription', true );
//Second ID the field.
$description_field = 'pDescription';
//Provide the settings arguments for this specific editor in an array
$description_args = array( 'media_buttons' => false, 'textarea_rows' => 12, 'textarea_name' => 'pDescription[]',
'editor_class' => 'description-editor widefat', 'wpautop' => true );
wp_editor( $description, $description_field, $description_args );
'</div>
<div class="col-md-6">
<h4>Banner image</h4>
<input type="button" id="meta-image-button" class="button" value="Choose or Upload an Image" style="padding: 8px 10px; height: auto; line-height: normal;"/>
<input type="hidden" name="pimage[]" id="meta-image" class="meta_image" value="'.get_post_meta(get_the_ID(), 'pimage', true ).'" /><br />
<img style="width: 100px;height: 100px;object-fit: cover;" id="meta-image-preview" src="'.get_post_meta(get_the_ID(), 'pimage', true ).'" />
</div>
</div>
");
});
});
</script>';
}
Related
A brief explanation of how this simple jQuery wizard works
Sessions are used to save data for each step.
consists of a session variable to save in what step we are.
consists of a session variable to store the form data.
Each time we change the step we save the data of the form and the step in session with an ajax request.
If the data is updated the data is retrieved from the session.
This wizard form consists of 3 steps.
As I can correct the errors and validate the form with php if there is a field without data do not let go to the next step, until all fields of the form are completed by the user.
There are warning errors in each of the form fields in each text input shows me a warning message.
Notice: Undefined index: datos_form in C:\xampp\htdocs\prueba\wizar.php on line 229
I would like to add a cookie to the session where the steps are saved to avoid erasing the data stored in the session in case the browser is closed in error, create a session cookie with a validation time of 30 days.
now to remove the cookie from the data saved by the user create a cancel button, the cancel button will delete the cookie, including the data saved in the session.
My complete code:
wizar.php
<?php
session_start();
// check if there is a previous step.
if ( !empty($_SESSION['datos_form']['__paso__']) ) {
$paso = $_SESSION['datos_form']['__paso__'];
}
// if there is no previous step we set step 1.
else{
$paso = '1';
}
?><!DOCTYPE html>
<html>
<head>
<title>Form por pasos</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
mostrar_paso(<?= $paso; ?>);
});
function animacion(caso){
switch(caso) {
case 1:
$(".backdrop").css("background-position", `0px 0px`);
break;
case 2:
$(".backdrop").css("background-position", `0px -16px`);
break;
case 3:
$(".backdrop").css("background-position", `0px -32px`);
break;
default:
$(".backdrop").css("background-position", `0px 0px`);
};
};
function mostrar_paso(paso)
{
var data = $( "#form" ).serialize();
var url = 'saveTemp.php?paso=' + paso;
var valor_radio = $('input:radio[name=radio]:checked').next("label").text();
$.ajax({
type: "POST",
url: url,
data: data
})
.done(function( resp ) {
$('.step').css( "display", "none" );
$('#paso'+paso).fadeIn("slow");
$('#div_producto').html(valor_radio);
animacion(paso);
});
};
</script>
</head>
<body>
<div class="setup">
<ul class="backdrop">
<li class="process item1">step 1</li>
<li class="process item2">step 2</li>
<li class="process item3">FINALIZE</li>
</ul>
</div>
<form id="form" action="procesar.php">
<div id="paso1" class="step">
<input type="text" name="campo1" value="<?= $_SESSION['datos_form']['campo1']; ?>">
<select class="form-select" name="sexo">
<?php
if( !empty($_SESSION['datos_form']['sexo']) ) {
$sexo = $_SESSION['datos_form']['sexo'];
echo '<option value="'.$sexo.'" selected="selected">'.$sexo.'</option>';
}
else{
echo '<option disabled selected="selected">I am...</option>';
}
?>
<option value="Mem">Men</option>
<option value="Woman">Woman</option>
<option value="I prefer not to say">I prefer not to say</option>
</select>
<?php
if( !empty($_SESSION['datos_form']['condiciones']) ) {
echo '<input type="checkbox" name="condiciones" checked>';
}
else{
echo '<input type="checkbox" name="condiciones">';
}
?>
...
onclick="mostrar_paso('numero de paso') -->
continuar
</div>
<div id="paso2" class="step">
<?php
$r =array(
1 => 'Product 1',
2 => 'Product 2',
3 => 'Product 3',
);
foreach ($r as $key => $value)
{
if( $_SESSION['datos_form']['radio'] == $key ) {
echo '<input name="radio" type="radio" id="'.$key.'" value="'.$key.'" checked="checked" >';
echo '<label for="'.$key.'" title="'.$value.'">'.$value.'</label>';
}
else{
echo '<input name="radio" type="radio" id="'.$key.'" value="'.$key.'" >';
echo '<label for="'.$key.'" title="'.$value.'">'.$value.'</label>';
}
}
?>
Atras
continuar
</div>
<div id="paso3" class="step">
<div id="div_producto"></div><br>
<input type="text" name="campo3" value="<?= $_SESSION['datos_form']['campo3']; ?>">
<input type="submit" name="cancel">
Atras
<input type="submit" name="Terminar">
</div>
</form>
</body>
</html>
saveTemp.php
Note: This file is responsible for saving the step and data of the form.
<?php
session_start();
// We save the form data in a session variable
$_SESSION['datos_form'] = $_POST;
// we added the step also to the array, you can not use this name (__paso__) as name in the form
$_SESSION['datos_form']['__paso__'] = $_GET['paso'];
As I can correct the errors and validate the form with php if there is
a field without data do not let go to the next step, until all fields
of the form are completed by the user.
You need to code validation rules under saveTemp.php something like this :
<?php
session_start();
//form validation
switch($_GET['paso']){
case 2:
if(empty($_POST['campo1'])){//you may add any validation rule you want here
die(json_encode(array('status' => FALSE,'message' => 'please fill campo ....')));
}
if(empty($_POST['sexo'])){
die(json_encode(array('status' => FALSE,'message' => 'please select sexo ....')));
}
if(empty($_POST['condiciones'])){
die(json_encode(array('status' => FALSE,'message' => 'please select condiciones ....')));
}
break;
case 3: //step 2 validation here
if(empty($_POST['radio'])){//you may add any validation rule you want here
die(json_encode(array('status' => FALSE,'message' => 'please fill radio1 ....')));
}
break;
}
// We save the form data in a session variable
$_SESSION['datos_form'] = $_POST;
// we added the step also to the array, you can not use this name (__paso__) as name in the form
$_SESSION['datos_form']['__paso__'] = $_GET['paso'];
die(json_encode(array('status' => TRUE,'message' => 'Temporary saved....')));
and then check response under ajax call for status, so you need to change ajax call like this:
$.ajax({
type: "POST",
url: url,
data: data,
dataType: 'json'
})
.done(function( resp ) {
if(resp.status)
{
$('.step').css( "display", "none" );
$('#paso'+paso).fadeIn("slow");
$('#div_producto').html(valor_radio);
animacion(paso);
}else{
var old_paso = paso-1;
alert(resp.message);
$('.step').css( "display", "none" );
$('#paso'+old_paso).fadeIn("slow");
$('#div_producto').html(valor_radio);
animacion(old_paso);
}
});
notice that I add "dataType" to your ajax call and set it to json
There are warning errors in each of the form fields in each text input
shows me a warning message.
that because you did not check for existence of variable before getting its value, the code you post is form.php but warning complain about wizar.php line number 229, check that line and use empty function just like the rest of your code
here is a sample wizar.php without notice/warning:
<?php
session_start();
// check if there is a previous step.
if ( !empty($_SESSION['datos_form']['__paso__']) ) {
$paso = $_SESSION['datos_form']['__paso__'];
}
// if there is no previous step we set step 1.
else{
$paso = '1';
}
?><!DOCTYPE html>
<html>
<head>
<title>Form por pasos</title>
<style type="text/css">
.backdrop {
position: absolute;
width: 630px;
height: 16px;
background: url(//drh.img.digitalriver.com/DRHM/Storefront/Site/avast/cm/images/avast/2014/breadcrumb-3.png) no-repeat;
list-style-type: none;
text-transform: uppercase;
}
.step {
padding-top: 30px;
display: none;
}
.step-1 {
display: block;
}
.setup {
width: 100%;
height: 100px;
padding: 50px 0px 0px 50px;
background-color: rgba(29, 36, 36, 0.25);
}
.process {
position: absolute;
top: -30px;
color: #e8e8e8;
font-size: 1.1em;
}
.process.item2 {
padding-left: 190px;
}
.process.item3 {
padding-left: 400px;
}
.process.item4 {
padding-left: 580px;
}
.process.item5 {
padding-left: 690px;
}
.process.item6 {
padding-left: 790px;
}
ul li {
margin: 0;
padding: 0;
border: none;
list-style: none;
list-style-type: none;
white-space: nowrap;
}
.step{
display: none;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('.step').css( "display", "none" );
$('#paso'+<?= $paso; ?>).fadeIn("slow");
$('#div_producto').html(valor_radio);
animacion(<?= $paso; ?>);
});
function animacion(caso){
switch(caso) {
case 1:
$(".backdrop").css("background-position", `0px 0px`);
break;
case 2:
$(".backdrop").css("background-position", `0px -16px`);
break;
case 3:
$(".backdrop").css("background-position", `0px -32px`);
break;
default:
$(".backdrop").css("background-position", `0px 0px`);
};
};
function mostrar_paso(paso)
{
var data = $( "#form" ).serialize();
var url = 'saveTemp.php?paso=' + paso;
var valor_radio = $('input:radio[name=radio]:checked').next("label").text();
$.ajax({
type: "POST",
url: url,
data: data,
dataType: 'json'
})
.done(function( resp ) {
if(resp.status)
{
$('.step').css( "display", "none" );
$('#paso'+paso).fadeIn("slow");
$('#div_producto').html(valor_radio);
animacion(paso);
}else{
var old_paso = paso-1;
alert(resp.message);
$('.step').css( "display", "none" );
$('#paso'+old_paso).fadeIn("slow");
$('#div_producto').html(valor_radio);
animacion(old_paso);
}
});
};
</script>
</head>
<body>
<div class="setup">
<ul class="backdrop">
<li class="process item1">step 1</li>
<li class="process item2">step 2</li>
<li class="process item3">FINALIZE</li>
</ul>
</div>
<form id="form" action="procesar.php">
<div id="paso1" class="step">
<input type="text" name="campo1" value="<?= (!empty($_SESSION['datos_form']['campo1'])) ? $_SESSION['datos_form']['campo1'] : '' ; ?>">
<select class="form-select" name="sexo">
<?php
if( !empty($_SESSION['datos_form']['sexo']) ) {
$sexo = $_SESSION['datos_form']['sexo'];
echo '<option value="'.$sexo.'" selected="selected">'.$sexo.'</option>';
}
else{
echo '<option disabled selected="selected">I am...</option>';
}
?>
<option value="Mem">Men</option>
<option value="Woman">Woman</option>
<option value="I prefer not to say">I prefer not to say</option>
</select>
<?php
if( !empty($_SESSION['datos_form']['condiciones']) ) {
echo '<input type="checkbox" name="condiciones" checked>';
}
else{
echo '<input type="checkbox" name="condiciones">';
}
?>
...
onclick="mostrar_paso('numero de paso') -->
continuar
</div>
<div id="paso2" class="step">
<?php
$r =array(
1 => 'Product 1',
2 => 'Product 2',
3 => 'Product 3',
);
foreach ($r as $key => $value)
{
if( !empty($_SESSION['datos_form']['radio']) AND $_SESSION['datos_form']['radio'] == $key ) {
echo '<input name="radio" type="radio" id="'.$key.'" value="'.$key.'" checked="checked" >';
echo '<label for="'.$key.'" title="'.$value.'">'.$value.'</label>';
}
else{
echo '<input name="radio" type="radio" id="'.$key.'" value="'.$key.'" >';
echo '<label for="'.$key.'" title="'.$value.'">'.$value.'</label>';
}
}
?>
Atras
continuar
</div>
<div id="paso3" class="step">
<div id="div_producto"></div><br>
<input type="text" name="campo3" value="<?= (!empty($_SESSION['datos_form']['campo3'])) ? $_SESSION['datos_form']['campo3'] : ''; ?>">
<input type="submit" name="cancel">
Atras
<input type="submit" name="Terminar">
</div>
</form>
</body>
</html>
I would like to add a cookie to the session where the steps are saved
to avoid erasing the data stored in the session in case the browser is
closed in error, create a session cookie with a validation time of 30
days.
PHP's native session, already using cookie if visitor browser support cookie and the expiration time can be set in php.ini or at runtime by setting session.cookie_lifetime
now to remove the cookie from the data saved by the user create a
cancel button, the cancel button will delete the cookie, including the
data saved in the session.
And finally use session_destroy function to delete that cookie under procesar.php file
I want to add logout link(button) in the left side of my wordpress admin dashboard. Like on the picture.. How can I do it?
UPDATED
You can achive this using admin_init action hook and global $menu.
Here is this code:
add_action('admin_init', 'text_domain_logout_link');
function text_domain_logout_link() {
global $menu;
$menu[9999] = array(__('Logout'), 'manage_options', wp_logout_url());
}
This code goes in function.php file of your active child theme (or theme) or also in any plugin file.
The code is tested and fully functional.
References:
admin_init
global $menu
Customizing Your WordPress Admin
Use following code
add_action('admin_menu', 'register_custom_menu_page');
function register_custom_menu_page() {
add_menu_page( 'admin_menu', 'Logout', '0', 'logout', 'users_add_login_logout_link');
}
function users_add_login_logout_link(){ ?>
<div id="dashboard" class="wrap">
<div style="float: left; height: 48px margin: 7px 8px 0 0; width: 48px;">
<br>
</div>
<h2>Log Out</h2>
</div>
<div style="text-align: center;"><img src="put you image link" width="128px" height="128px" /></div>
<div style="text-align: center;">Please wait we are logging you out ...</div>
<br/>
<br/>
<div style="padding: 10px 0; font-size: 25px;"><p>
</div>
<?php
$location = '"Location: ' . wp_logout_url() . '"';
echo '<meta http-equiv="refresh" content="4; url=' . wp_logout_url(home_url()) . '"/>';
}
Another alternative, with a dashicon. Based on this answer.
add_action('admin_menu', 'logout_menu_item');
function logout_menu_item() {
add_menu_page('', 'Logout', 'manage_options', 'logout', '__return_false', 'dashicons-external', 999);
}
add_action('after_setup_theme', 'redirect_loggingout');
function redirect_loggingout() {
if ( isset($_GET['page']) && $_GET['page'] == 'logout' ) {
wp_redirect( wp_logout_url() );
exit();
}
}
I have a slider in my page and every slider has it's own overlay descriptions and this descriptions are in the HTML format.
In my admin module there is a setting there that the user can create their own slider images with custom message using CKEditor.
And my problem is when I try to display the descriptions in the slider it's just plain HTML code.
Here's a bit of my code:
Controller Part
foreach($results as $result) {
if ($result['banner_image'] && file_exists(DIR_IMAGE . $result['banner_image'])) {
$image = $this->model_tool_image->resize($result['banner_image'], 40, 40);
$banner_image_large = HTTP_IMAGE . $result['banner_image'];
} else {
$image = $this->model_tool_image->resize('no_image.jpg', 40, 40);
}
$url = '&banner_id=' . (int)$result['banner_id'];
$this->data['banners'][] = array(
'banner_id' => $result['banner_id'],
'banner_image' => $image,
'banner_image_large' => $banner_image_large, // here's the image to be use in the slider
'code_description' => $result['banner_description'], //here's the raw HTML formatted description
'description' => strip_tags(html_entity_decode($result['banner_description'])),
'banner_link' => $result['banner_link'],
'action' => $this->url->link('project/banner_slider/update', 'token=' . $this->session->data['token'] . $url, 'SSL')
);
}
In my View
<h1>Carousel Demo</h1>
<div id="owl-demo" class="owl-carousel owl-theme">
<?php foreach($banners as $banner) { ?>
<div class="item">
<div class="textoverlay"><?php echo $banner['code_description']; ?></div> <!-- overlay the decription -->
<img src="<?php echo $banner['banner_image_large']; ?>" />
</div>
<?php } ?>
</div>
Here's some CSS
#owl-demo .item img{
display: block;
width: 100%;
height: auto;
}
.textoverlay{
position: absolute;
display:block;
}
And JS:
$('#owl-demo').owlCarousel({
autoPlay : 3000,
stopOnHover : true,
navigation : false, // Show next and prev buttons
slideSpeed : 300,
paginationSpeed : 400,
singleItem:true,
autoHeight : true,
transitionStyle:"fade"
});
surround the raw html with $.parseHTML("your html here");
Ok I solved it by using html_entity_decode() function
I want to show different posts on my page but the problem is that every post has a unique background image which is, at the moment, added via background image property.
I need to replace this with WordPress, but I don't now how to achieve that. The idea I have is to use post thumbnail image as a background image, but in the post there is also a thumbnail showing up in the content.
It's the scenario of the post, background image, then comes the title, description and then comes the thumbnail. Sorry I could not upload any screen shot of my work, but I am trying my best to describe the whole scenario. Any suggestions will be appreciated.
This sounds like an excellent time to use a plugin like Advanced Custom Fields. Once you have it installed, you can follow these steps:
Create a new field group.
Add a new field of type "image".
Make the rules for post-type is equal to post.
Now in your template file, you can fetch the image like this:
<?php
// Where 'image' is the name of the field you added
$image = get_field('image');
?>
Then you can include the image wherever you like later in the same template file, for example:
<div class="hentry" style="background-image:url(<?php echo $image['url']; ?>)"></div>
And in your CSS, assuming you want the background image to take up the whole background of the post:
<style type="text/css">
.hentry {
background-size:cover;
background-position:center;
}
</style>
Let me know if that helps.
I believe my first answer will still be helpful to some, but since you cannot use Advanced Custom Fields or another plugin, you could add the following code in your functions.php file instead.
Note that I have taken and slightly modified the code from this Stack Overflow post to limit it to one image instead of a group of images, and I have made use of the more modern media uploader.
Also, this will only add the custom field to your post type, and not your pages, custom post types, etc. Look through the code, and I'm sure your can figure out how to change that if so desired.
add_action( 'admin_init', 'add_post_image_so_30337102' );
add_action( 'admin_head-post.php', 'print_scripts_so_30337102' );
add_action( 'admin_head-post-new.php', 'print_scripts_so_30337102' );
add_action( 'save_post', 'update_post_image_so_30337102', 10, 2 );
/**
* Add custom Meta Box to Posts post type
*/
function add_post_image_so_30337102()
{
wp_enqueue_media();
add_meta_box(
'post_image',
'Custom Uploader',
'post_image_options_so_30337102',
'post',
'normal',
'core'
);
}
/**
* Print the Meta Box content
*/
function post_image_options_so_30337102()
{
global $post;
$image_data = get_post_meta( $post->ID, 'image_data', true );
// Use nonce for verification
wp_nonce_field( plugin_basename( __FILE__ ), 'noncename_so_30337102' );
?>
<div id="dynamic_form">
<div id="field_wrap">
<div class="field_row">
<div class="field_left">
<div class="form_field">
<label>Image URL</label>
<input type="text"
class="meta_image_url"
name="image[image_url]"
value="<?php esc_html_e( isset($image_data['image_url']) ? $image_data['image_url'] : '' ); ?>"
/>
</div>
<div class="form_field">
<label>Description</label>
<input type="text"
class="meta_image_desc"
name="image[image_desc]"
value="<?php esc_html_e( isset($image_data['image_desc']) ? $image_data['image_desc'] : '' ); ?>"
/>
</div>
</div>
<div class="field_right image_wrap">
<img src="<?php esc_html_e( $image_data['image_url'] ); ?>" height="48" width="48" />
</div>
<div class="field_right">
<input class="button" type="button" value="Choose File" onclick="add_image(this)" /><br />
</div>
<div class="clear" /></div>
</div>
</div>
</div>
<?php
}
/**
* Print styles and scripts
*/
function print_scripts_so_30337102()
{
// Check for correct post_type
global $post;
if( 'post' != $post->post_type )
return;
?>
<style type="text/css">
.field_left {
float:left;
}
.field_right {
float:left;
margin-left:10px;
}
.clear {
clear:both;
}
#dynamic_form {
width:580px;
}
#dynamic_form input[type=text] {
width:300px;
}
#dynamic_form .field_row {
border:1px solid #999;
margin-bottom:10px;
padding:10px;
}
#dynamic_form label {
padding:0 6px;
}
</style>
<!-- New script taken from here: http://brinidesigner.com/use-wordpress-3-5-new-media-uploader-for-your-plugin-and-theme-options-panel-development/ -->
<script type="text/javascript">
function add_image(obj) {
var parent=jQuery(obj).parent().parent('div.field_row');
var inputField = jQuery(parent).find("input.meta_image_url");
var image = wp.media({
title: 'Upload Image',
// mutiple: true if you want to upload multiple files at once
multiple: false
}).open()
.on('select', function(e){
// This will return the selected image from the Media Uploader, the result is an object
var uploaded_image = image.state().get('selection').first();
// We convert uploaded_image to a JSON object to make accessing it easier
// Output to the console uploaded_image
//console.log(uploaded_image);
var image_url = uploaded_image.toJSON().url;
// Let's assign the url value to the input field
inputField.val(image_url);
jQuery(parent)
.find("div.image_wrap")
.html('<img src="'+image_url+'" height="48" width="48" />');
});
return false;
}
</script>
<?php
}
/**
* Save post action, process fields
*/
function update_post_image_so_30337102( $post_id, $post_object )
{
// Doing revision, exit earlier **can be removed**
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
// Doing revision, exit earlier
if ( 'revision' == $post_object->post_type )
return;
// Verify authenticity
if ( !wp_verify_nonce( $_POST['noncename_so_30337102'], plugin_basename( __FILE__ ) ) )
return;
// Correct post type
if ( 'post' != $_POST['post_type'] )
return;
if ( $_POST['image'] )
{
// Build array for saving post meta
$image_data = array();
if ( '' != $_POST['image']['image_url'] )
{
$image_data['image_url'] = $_POST['image']['image_url'];
$image_data['image_desc'] = $_POST['image']['image_desc'];
}
if ( $image_data )
update_post_meta( $post_id, 'image_data', $image_data );
else
delete_post_meta( $post_id, 'image_data' );
}
// Nothing received, all fields are empty, delete option
else
{
delete_post_meta( $post_id, 'image_data' );
}
}
Now you can get the image URL (and description) inside of your the_post() loop of your template like this:
$image_data = get_post_meta( $post->ID, 'image_data', true );
And then echo the image like this. You can re-use the CSS from my first answer.
<div class="hentry" style="background-image:url(<?php echo $image_data['image_url']; ?>)"></div>
Please have a look at the below CakePHP code
Flip2.php (Model)
<?php
class Flip2 extends AppModel {
var $name = 'Flip2';
public $useTable = false;
//Increment the correct_answer field of the specific user
public function correctAnswer($userID=89, $word)
{
$setQuery = "UPDATE `users_words` SET `correctanswer` = `correctanswer`+1 WHERE `userid`=$userID && `wordid`='$word' ";
query($setQuery);
}
}
Flip2Controller.php (Controller)
<?php
class Flip2Controller extends AppController {
public function index()
{
}
}
?>
index.ctp (View)
<?php
//echo $this->Html->css(array('bootstrap', 'mark', 'style'));
echo $this->Html->script(array('timer','swfobject','bootstrap.min.js'));
?>
<style>
#hideall {
display: none;
opacity: 0.7;
position: fixed;
height: 100%;
width: 100%;
top: 0;
left: 0;
background: #000;
border: 1px solid #cecece;
z-index: 1;
vertical-align:middle;
text-align:center;
}
.removeCardflip{
transition: rotateY(0deg);
-webkit-transition: rotateY(0deg);
transition-duration: 0s;
}
/* SECTIONS */
.section {
clear: both;
padding: 0 10px 0 10px;
margin: 0px;
}
</style>
<div id="hideall">
<?php //echo $this->Html->image('progress.gif', array('alt' => 'Wait', 'style' => 'text-align:center; padding-top:200px;'));?>
</div>
<!--<div class="wrapper" style="border: 1px solid red; width: 100%;">-->
<div class="section group" style="margin-top: 50px;">
<div class="col span_3_of_3">
<h3 style="margin:0px; font-size:22px;">Play word game: </h3>
</div>
</div>
<div class="">
<div>
<div>
<span class="remainWords"><?php //echo count($words);?></span> oxxxxxxxxxxxxxxxf <?php //echo $totalWords;?>
</div>
<div>
<?php
echo $this->Html->image("comic_edit.png",
array(
"alt" => "Pareto List",
"id" => "paretoList",
'url' => "javascript:;"
)
);
?>
</div>
</div>
</div>
<div class="container"><div class="row">
<?php
foreach($worddeck as $worcard)
{
?>
<div class="xy col-lg-3 col-md-4 col-sm-6 img-rounded" id="card1" style="width:250px; height:200px; background-color:grey; heiht:170px; margin: 10px 10px;">
<div id="enside1" >
<h1 data-pos="<?php //echo ; ?>" ><?php echo $worcard['unique_wordsforcards']['en_word']; $enSpell = $worcard['unique_wordsforcards']['en_word']; ?></h1>
</div>
<div id="ptside1" style="display:none;">
<?php echo $phonemer[$enSpell]; ?>
<p><?php echo $worcard['unique_wordsforcards']['hint']; ?></p>
</div>
<div id="cntrol1">
<button type="button" id="2" class="a btn btn-success mr5 btn-lg">Acertei</button>
<button type="button" id="2" class="e btn btn-danger mr5 btn-lg">Errei</button>
</div>
</div>
<?php
}
?>
</div></div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script type="text/javascript">
$(document).ready(function(){
$( ".btn-danger" ).click(function(){
console.log("Red Button");
var toclose = $(this).parent().parent();
$.ajax({
url: "../img/media.jpg",
}).done(function() {
console.log( "The act has been done");
toclose.toggle();
});
});
$( ".btn-success" ).click(function(){
console.log("Red Button");
var toclose = $(this).parent().parent();
$.ajax({
url: "../img/media.jpg",
}).done(function() {
console.log( "The act has been done");
toclose.toggle();
});
});
$( ".xy" ).click(function(){
$(this).find("#enside1").toggle();
$(this).find("#ptside1").toggle();
console.log(this);
});
});
</script>
Now, what I need to do is, this. When the user click on the Acertei button, I need to execute the function correctAnswer. I am very new to PHP and CakePHP so I am really confused about how to do this when a button is clicked. Any advice please?
You have
<div id="cntrol1">
<button type="button" id="2" class="a btn btn-success mr5 btn-lg">Acertei</button>
<button type="button" id="2" class="e btn btn-danger mr5 btn-lg">Errei</button>
</div>
You should use different IDs for each button.
You can call the correctAnswer function with ajax:
Change the button to something like
<button type="button" id="2" data-word="<?php $worcard['unique_wordsforcards']['en_word'] ?>" class="a btn btn-success mr5 btn-lg">Acertei</button>
And then add the following code in $(document).ready()
$(document).ready(function(){
$(".btn-success").click(function(){
var word = $(this).data('word');
$.post('/flip2/correct.json', { word: word })
.done(function(data) {
alert('Saved');
});
I am not sure how the user part works. You should probably have that in the session, and not sent to the function. I hardcoded user 89 and added a way for you to send the word.
Use an appropriate model method
The function correctAnswer in the model would better be written using updateAll:
public function correctAnswer($userId, $word) {
return $this->updateAll(
array('correctanswer' => 'correctanswer + 1'),
array(
'userid' => $userId,
'wordid' => $word
)
);
}
Written in this way the inputs ($userId and $word) will be escaped appropriately and not susceptible to sql injection.
Create a controller action
The doorway to the web for an application is a controller action, create a simple function, calling the model method, and write it to output json:
public function correct() {
$postData = $this->request->data;
$word = $this->request->data['word'];
$userId = $this->Auth->user('id');
$result = false;
if ($userId && $word) {
$result = $this->Flip2->correctAnswer($userId, $word);
}
$this->set('_serialize', array('result'));
$this->set('result', $result);
}
Note that
It'll only work via a post request.
The Auth component (the session) is used to get the current user id, it's not a user-defined input.
This function is defined such that it'll work as a json response.
There's no need to create a view file with the above code.
Be sure to setup your app to handle json requests:
After adding Router::parseExtensions('json'); to your routes file, CakePHP will automatically switch view classes when a request is done with the .json extension, or the Accept header is application/json.
Call the controller action
The required js would be of the form:
$(".btn-success").click(function(){
var word = ...;
$.post(
'/flip2/correct.json',
{word: word},
function (data) {
console.log(data);
// {result: bool}
}
);
});
Note that:
The url ends in .json which is a simple and robust way to provoke CakePHP to respond as json.
It is a post request.
The response will be of the form defined by _serializein the controller action.