Farbtastic is broken and wont update my input fields - php

So, I have a foreach loop creating a bunch of form fields to allow users to use farbtastic to select colors for font and such. The loop creates fields for probably 60 fields and while the colorpicking works, for whatever reason after 20 fields farbtastic stops updating the input fields with the hexcode. It changes the input field background colors but it doesn't update the field.
What's even more weird, is that all these fields are in separate tabs, and the way wordpress handles tabs is by putting each on a new page. So the page has to reload. So once you get to the later tabs (and therefore later fields) one of two of the fields will work correctly but most do not. So like, field 2 on one tab works ok, but the same field on a different tab does not.
Right now I have a single jQuery method controlling the color picker:
// Color Picker for js file
jQuery('.pickcolor').click( function(e) {
colorPicker = jQuery(this).next('div');
input = jQuery(this).prev('input');
jQuery(colorPicker).farbtastic(input);
colorPicker.show();
e.preventDefault();
jQuery(document).mousedown( function() {
jQuery(colorPicker).hide();
});
});
and the form fields pretty much all look like this:
$name is the section name and $element is the thing the color is being chosen form (nested foreach loop)
<div class="color_option option" style="position: relative;">
<label for="<?php echo $name; ?>_fonts"><?php echo $elementName;?> Color</label>
<input class="link_color" type="text" id="<?php echo $name; ?>_fonts"
name="kjd_<?php echo $name;?>_settings[kjd_<?php echo $name; ?>_fonts][<?php echo $element; ?>]"
value="<?php echo $options['kjd_'.$name.'_fonts'][$element] ? $options['kjd_'.$name.'_fonts'][$element] : ''; ?>"
style="background:<?php echo $options['kjd_'.$name.'_fonts'][$element]?>; color:<?php echo $options['kjd_'.$name.'_fonts'][$element]?>;"
/>
<input type='button' class='pickcolor button-secondary' value='Select Color'>
<div style="position: absolute;" class="colorpicker"></div>
So the jQuery looks right, but I wonder if I should dynamically create the jquery in the foreach loop to target each field by ID

I solved it kinda of.
value="<?php echo $options['kjd_'.$name.'_fonts'][$element] ? $options['kjd_'.$name.'_fonts'][$element] : ''; ?>
the last part of that if-statement cant be empty, it has to be ' ' (blank space), rather, in order for farbtastic to update the input there has to be some value in there. so I used 'none' to avoid confusing users.
my code now says
value="<?php echo $options['kjd_'.$name.'_fonts'][$element] ? $options['kjd_'.$name.'_fonts'][$element] : 'none'; ?>

Related

Reading HTML5 input (type color) value with PHP

I'm creating my first theme in WordPress, and have added a theme settings page where I'm using an input field of the HTML5 type "color" to allow the theme user to select the color of an element on the page.
The input type renders and works just fine, but on the theme options page I want it to show a text string of the hex value (e.g. "#FFFFFF" or "#31A1FF" or whatever) of the currently selected color next to the color swatch/input field. This part is not working. I'm fairly new to PHP, so I'm probably just doing something wrong. But I would've figured reading the value property of the input field would work. It isn't--it does not show any text at all.
Below is the code I'm working with. Can anyone help point me in the right direction here?
Ultimately, I will be wanting to do the same thing with other input types used for other settings such as a slider input for opacity/transparency values. But this is my starting point, and I can get going with this one, the others probably won't be hard to figure out.
function fp_Field_BackgroundColor () {
$options = get_option('fp-OptionsArray');
echo "<input id='fp_BackgroundColor' name='fp-OptionsArray[BackgroundColor]' type='color' value='{$options['BackgroundColor']}' />";
echo "<div float='left'>" . $_POST['fp_BackgroundColor.value'] . "</div>";
}
On your HTML5 part:
<form action="" method="post">
Select you favorite color:
<input name="clr" type="color">
<input type="submit" name="submit">
</form>
On the php part:
<?php
if(isset($_POST['clr']))
$selected_color= $_POST['clr'];
// To show Hexadecimal code of the selected color
echo "Color code is: " . $selected_color;
?>
To preserve/keep the selected color after form submission assign the color submitted to the server back into "value" attribute of input form. i.e The input of color type would look like this:
<input name="clr" type="color" value="<?= htmlspecialchars($_POST['clr']) ?>">
dont take name as array.take it as a simple variable
<input type='color' id='fp_BackgroundColor' name='fp-BackgroundColor' type='color' value='<?php if(isset($_POST['submit'])){echo $fp-BackgroundColor;} ?>' />
and 1 more imp thing.... u have to specify the input 'type'

Image upload script only works for latest <li></li> saved in DB

Below is a script to upload images and save them to the DB.
On one page of the website, there's a table and inside each <li></li>, there is an upload icon where users can add one image.
The issue is the image upload only works for the "highest" empty <li> on the table.
Here, "highest" means the latest <li> saved in the DB (table is sorted by TIME DESC).
For instance, if I want to upload an image to a random <li></li> on the page, once I select an image, nothing happens. But if I select the "highest" empty (empty = no image saved in DB) <li></li>, it works like a charm.
HTML:
<li id="entry<?php echo $recipe_id ?>">
<div class="addimage_icon" id="upload<?php echo $recipe_id; ?>">
<form id="upload_icon" action="upload_extra.php" method="POST"
enctype="multipart/form-data">
<input class="upload" id="file" type="file" style="display:none" />
<input type="hidden" name="recipe_id" value="<?php echo $recipe_id; ?>"/>
<img class="upload_icon" src="/upload_icon.png">
</form>
</div>
</li>
JAVASCRIPT (upload gets triggered as soon as one image is chosen):
<script>
$('.upload_icon').click(function(){
$(this).parent().find('.upload').click();
});
document.getElementById("file").onchange = function() {
document.getElementById("upload_icon").submit();
}
</script>
PHP:
<?php
include "includes/connnect.php";
$id = $_SESSION['id'];
$recipe_id = mysql_real_escape_string($_POST['recipe_id']);
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$recipe_id= $_POST['recipe_id'];
//get image attributes
$add = query("UPDATE cookbook SET recipe_pic = '".$location."' WHERE recipe_id =
'$recipe_id'");
header(Location:"home.php");
}
?>
What's going here ?
There are many, many problems with your question. First of all the HTML you've posted is invalid. I suspect that your Javascript code has a problem with such invalid HTML. However, the following code has not (for your HTML code duplicated once for demonstration purposes):
NodeList.prototype.forEach = Array.prototype.forEach;
document.querySelectorAll('input[type="file"]').forEach(function (file) {
var click = function() {
file.click();
};
var change = function() {
console.log('change:', file.value);
};
file.form.querySelector('img').addEventListener('click', click);
file.addEventListener('change', change);
});
http://jsfiddle.net/eBLL5/
All you need is to assign the correct listeners to the correct elements, as you can see, I do not use any ID values because they are duplicated.
I can use as well duplicate IDs in case you think this is not an argument, this is demonstrated in a related answer:
remove text from multiple spans having same id
I hope this helps you to get the feets again on the ground so that you can continue to validate the HTML and clean up a little bit.
It appears that your html form has
<input type="hidden" value="<?php echo $recipe_id; ?>"/>
However, the input field name attribute is not present so the post data stream will not have a definition for $_POST["recipe_id"] field. The undefined value is likely being interpreted by your script as 0 and so only the top or "highest" li image is updated.
If you alter the input field thus:
<input type="hidden" name="recipe_id" value="<?php echo $recipe_id; ?>"/>
You may have better results...
Just change this part :
document.getElementById("file").onchange = function() {
document.getElementById("upload_icon").submit();
}
With :
$("#file").change(function(){$(this).parents("form").get(0).submit();})
In your HTML, you have:
<form id="upload_icon" action="upload_extra.php" method="POST"
enctype="multipart/form-data">
Then your Javascript mentions:
document.getElementById("file").onchange = function() {
document.getElementById("upload_icon").submit();
}
According to some specifications (HTML4, HTML5), there shouldn't be same IDs on multiple elements. So, when you use an iteration, avoid printing ids without appending something unique on them, like:
<form id="upload_icon<?php print $recipe_id; ?>"
action="upload_extra.php" method="POST" enctype="multipart/form-data">
Your Javascript can be turned into something like the following. (please mind that you need to call this function after the page is loaded)
function afterPageLoad() {
var buttons = document.getElementsByClassName("upload");
for (i = 0; i < buttons.length; i++) {
buttons[i].onchange = function() {
this.form.submit();
}
}
}
Now, if your PHP code has stopped working, we would need to see that, too, at the part you omitted by writing
//get image attributes
where the $location variable is initiated.
In JavaScript provided its submitting the form by finding the element by ID, As in the HTML code the IDs are repeating (not a standard method, IDS can't repeat but class can) so the browser will always submit the last (highest) form only, that's why when adding image to highest row its working and in between its not.
Please check this code out
<script>
$(document).ready(function()
{
id = '';
$('.upload_icon').click(function(){
id = $(this).attr('id');
$(this).parent().find('#file'+id).click();
});
$(".upload").change(function () {
$('#upload_icon'+id).submit();
});
});
</script>
<style>
.upload_icon {
cursor:pointer;
}
</style>
<ul>
<?php for($recipe_id=1;$recipe_id<10;$recipe_id++): ?>
<li id="entry<?php echo $recipe_id ?>">
<div class="addimage_icon" id="upload<?php echo $recipe_id; ?>">
<form action="upload.php" method="POST" enctype="multipart/form-data" id="upload_icon<?php echo $recipe_id; ?>">
<input class="upload" id="file<?php echo $recipe_id; ?>" type="file" name="image" style="display:none"/>
<input type="hidden" name="recipe_id" value="<?php echo $recipe_id; ?>" />
<img class="upload_icon" src="https://cdn2.iconfinder.com/data/icons/picons-basic-2/57/basic2-036_cloud_upload-128.png" id="<?php echo $recipe_id; ?>">
</form>
</div>
</li>
<?php endfor; ?>
</li>
In the HTMl code I have provided have different IDs for each forms (used the $recipe_id as suffix), when ever click event on the upload icon is fired it will check which upload icon is clicked by its attribute Id and then the respective input type file value is changed by finding the element by Id (used the same $recipe_id as suffix here also). On input type change event also same logic is used to fire the respective form.

Show one row of data, click next, hide original row and show next row... and so on

I'm using the http://www.advancedcustomfields.com plugin to create custom fields in Wordpress. I'm specifically using the repeater field functionality.
On a page I have a repeater that has an unlimited amount of rows. The usual way of echoing out all the data is the following:
<?php $counter = 1; if(get_field('step_by_step_training')): ?>
<?php while(the_repeater_field('step_by_step_training')): ?>
<p class="training-<?php echo $counter; ?>"><?php the_sub_field('introduction'); ?></p>
<?php $counter++; endwhile; ?>
<?php endif; ?>
Is it possible to show one row of data at a time with a next button that when pressed will show the next row of data? I only want one row of data showing at a time so if row 1 is originally showing, when next is clicked it hides row 1 and shows row 2. Essentially creating a step by step process.
Eventually I'd like to include a form so the user can submit data.
UPDATE:
<form class="form" method="POST" action="<?php the_permalink(); ?>">
<?php $counter = 1; if(get_field('step_by_step_training')): ?>
<?php while(the_repeater_field('step_by_step_training')): ?>
<div class="form-row">
<p class="training"><?php echo the_sub_field('introduction'); ?></p>
<button class="next">Next Form Element</button>
</div>
<?php $counter++; endwhile; ?>
<?php endif; ?>
</form>
<script type="text/javascript">
jQuery(function($) {
$(document).ready(function() {
// hide all form-rows, but not the first one
$('.form-row').not(':first').hide();
$('button.next').click(function(e) {
// prevent the next buttons from submitting the form
e.preventDefault();
// hide this form-row, and show the next one
$(this).parent('div.form-row').hide().next('div.form-row').show();
});
});
});
</script>
You could do something simple like this using jQuery (I think this is what you wanted?):
$(document).ready(function() {
// prepend a 'previous' button to all form-rows except the first
$('<button>').addClass('previous').text('Previous').prependTo($('.form-row').not(':first'));
// hide all form-rows, but not the first one
$('.form-row').not(':first').hide();
// add the submit button to the last form-row
$('<input>').prop('type', 'submit').val('Submit Form').appendTo($('.form-row:last'));
// handle the previous button, we need to use 'on' here as the
// previous buttons don't exist in the dom at page load
$('.form-row').on('click', 'button.previous', function(e) {
e.preventDefault();
$(this).parent('div.form-row').hide().prev('div.form-row').show();
});
$('button.next').click(function(e) {
// prevent the next buttons from submitting the form
e.preventDefault();
// hide this form-row, and show the next one
$(this).parent('div.form-row').hide().next('div.form-row').show();
});
});
some example markup:
<form action="index.php" method="post">
<div class="form-row">
<label for="forename">Forename</label>
<input type="text" name="forename" />
<button class="next">Next Form Element</button>
</div>
<div class="form-row">
<label for="forename">Surname</label>
<input type="text" name="surname" />
<div style="clear: both;"></div>
<label for="another">Another</label>
<input type="text" name="another" />
<button class="next">Next Form Element</button>
</div>
<div class="form-row">
<label for="last">Last Form Element</label>
<input type="text" name="last" />
</div>
</form>
You can add as many form elements to each form-row as you want, here's a fiddle to play with
edit
Things to note here are that the previous buttons are injected to the DOM dynamically, and so is the forms submit button (notice how I've removed it from the last form-row in the markup)
Here's an updated fiddle
You could start with a jQuery accordion menu. Some CSS will allow you to minimize the real estate occupied by the deselected rows. If you want to actually discard and retrieve certain rows based on some identifiable characteristic (for instance, ID number), you'll need to go with AJAX.
You could write your own custom method with something like JQuery.
Assign a class to each row, and keep track of which one is selected, when viewing another row simply .hide() the one that was showing and .show() the one you wish to display.
If you want to keep your HTML cleaner, you could use the JQuery .data() functionality to assign identifiers to each element and refer to them that way as well.
Most of this all depends on your constraints with wordpress, how it looks & your actual HTML layout
After it's all written to the screen, can't you just hide everything but the first row? And then each time you click the button, have it hide everything and show the next row. Try using jquery's next() function. jquery - next()
Ah, looks like deifwud beat me to it with a better explanation.

using jQuery to copy column specific form values

I've used jQuery before to copy billing addresses to shipping addresses, but if I am dynamically generating form rows with various values from PHP, how do I set up the form so that upon a checkmark, a recommended item quantity will be automatically copied just to the quantity of the same item?
Here is the basic version of the billing/shipping copy script.
<script src="../Scripts/jquery-1.7.2.min.js"></script>
<script>
$(document).ready(function(){
$("input#same").click(function()
{
if ($("input#same").is(':checked'))
{
// Checked, copy values
$("input#qty").val($("input#same").val());
}
else
{
// Clear on uncheck
$("input#quantity").val("");
}
});
});
</script>
And here is the PHP code dynamically gathering items with their suggested quantity.
while( $row = mysql_fetch_array($histresult) )
{
echo '<tr height = "50px">';
echo '<td>'.$product_id.'</td>';
echo '<td>'.$suggested_quantity.'<input id="same" name="same" type="checkbox" value ="'.$suggested_quantity.'"/> </td>';
echo '<td><input name="qty" type="text"size="4" maxlength="4"></td>';
///Other form elements go here, as well as an Add to Cart Button
}
For each item, a suggested wholesale quantity based on a user's favorite items is retrieved from the database. There is also a text field so that they can enter any amount they want before sending it to their cart. But if they check the checkbox, I want it to copy that value to the text field.
No only does this code not seem to do the trick, the difference between this and the billing/shipping copy is that now I'm dealing with a dynamic number of fields. How do I make each individual row achieve this task?
Using jQuery, you would essentially want to grab the suggested value from checkbox and put it in the other form element. Let's say this is your HTML:
<table>
<tr>
<td>
100 <input id="check-1" name="same" type="checkbox" value ="100"/>
<input id="qty-1" name="qty" type="text"size="4" maxlength="4">
</td>
<td>
100 <input id="check-2" name="same" type="checkbox" value ="100"/>
<input id="qty-2" name="qty" type="text"size="4" maxlength="4">
</td>
<td>
100 <input id="check-3" name="same" type="checkbox" value ="100"/>
<input id="qty-3" name="qty" type="text"size="4" maxlength="4">
</td>
</tr>
</table>
And then this would be your javascript/jQuery:
// Bind click event to ALL checkboxes
$("#same-*").live("click", function(e) {
// Only change it if box is checked
if( $(this).is(":checked") )
{
// Get suggested value
suggested_val = $(this).val();
// Place in next element (textbox)
$(this).next().val(suggested_val);
}
)};
I haven't tested this, but this is basically how it would work.
In your PHP, you would want to dynamically make those ID numbers so each row uses a unique ID. This is usually simple enough to match to your database row id.
<td>'.$suggested_quantity.'<input id="same-' . $row->id . '" name="same" type="checkbox" value ="'.$suggested_quantity.'"/> </td>
Change your code this way
<script>
$(document).ready(function(){
$("input.same").click(function()
{
if ($(this).is(':checked'))
{
// Checked, copy values
var temp = $(this).attr("title");
$("input#qty"+temp).val($("input#same"+temp).val());
}
else
{
// Clear on uncheck
$("input#qty"+temp).val("");
}
});
});
</script>
$i=0;
while( $row = mysql_fetch_array($histresult) )
{
echo '<tr height = "50px">';
echo '<td>'.$product_id.'</td>';
echo '<td>'.$suggested_quantity.'<input class="same" id="same'.$i.'" title="'.$i.'" name="same'.$i.'" type="checkbox" value ="'.$suggested_quantity.'"/> </td>';
echo '<td><input class="qty" name="qty'.$i.'" id="qty'.$i.'" type="text"size="4" maxlength="4"></td>';
///Other form elements go here, as well as an Add to Cart Button
$i++;
}
Hope this will helpful to you
Recycling IDs/names amongst several html elements is a bad idea I find.
I think it's best to make them unique.
But anyways, here's a suggestion that won't modify your html structure a lot.
Change the form tag as follows:
<form id="Order">
...
</form>
Change your PHP code as follows (added a label tag to isolate your suggested quantity better in the DOM, got rid of some unnecessary structure for your checkboxes):
while($row=mysql_fetch_array($histresult))
{
echo '<tr height = "50px">';
echo '<td>'.$product_id.'</td>';
echo '<td><label>'.$suggested_quantity.'<label><input type="checkbox" class="Same"/> </td>';
echo '<td><input name="qty" id="qty_'.$product_id.'" type="text"size="4" maxlength="4"></td>';
///Other form elements go here, as well as an Add to Cart Button
}
Finally, here is the jQuery code:
<script src="../Scripts/jquery-1.7.2.min.js"></script>
<script>
jQuery(document).ready(function(){
jQuery("form#Order").click(function(Event){ //One event handler for the form, more efficient that way and you need less html structure to keep track of things
var Target = jQuery(Event.target); //This is the html element that got clicked on
if(Target.is("input:checkbox.Same")) //Make sure it's a checkbox that suggests quantity
{
var Text = jQuery(Target.closest('tr').children().get(2)).children(); //Get the parent TR tag, get it's third child (td tag containing the text field), get it's child (the text field)
var Suggested_quantity = Target.prev().html(); //Get the previous sibling which is the label containing the quantity and get it's html content which is the quantity
if(Target.is(":checked"))
{
Text.val(Suggested_quantity);
}
else
{
Text.val("");
}
});
});
</script>
EDIT: Removed some redundant html code. Added a class to isolate the right checkboxes. Added IDs for the text field (forgot).

Clearing hardcoded text from textarea

I'm trying to empty a textarea that is populated from a database with php.
Here's the code:
<select name="facility" id="facility">
<option></option>
<?php
global $__CMS_CONN__;
$sqlqry = "SELECT * FROM facility_db";
$stmt = $__CMS_CONN__->prepare($sqlqry);
$stmt->execute();
while($row = $stmt->fetchObject())
{
echo "<option value=\"$row->id\">$row->facility</option>";
}
?>
</select>
<button type="button" onclick="addFacility()">Add</button><button type="button" onclick="reset()">Reset</button>
<textarea readonly="readonly" id="facilities" name="facilities" rows="10" cols="50" value="<?php echo $facilitylist; ?>" ><?php echo $facilitylist; ?></textarea>
<input type="text" id="facilityids" name="facilityids" value="<?php echo $facilities; ?>"/>
The select box is populated from the database, and the Add button adds the selected facility to the textarea, and the id to the hidden field for database storage.
Up to this point everything works beautifully. The reset button will clear both the textarea and the hidden field and start over. The problem arises whan a user has saved their profile and had some facilities selected. The reset button only works on additions, but won't clear anything that was pulled from the database.
The javascript for the reset is just setting the value of those fields id to empty.
function reset()
{
document.getElementById('facilities').value = null;
document.getElementById('facilityids').value = null;
}
But it doesn't work on the hidden field either. I set it to text for testing and even when i manually delete what's in the textbox, if I click the reset button it comes back.
What is going on?
Give the function another name. There is a predefined method reset() inside forms, that function restores the initial values of form-fields.
A button is a form-field, by this the reset()-method of his form is invoked instead of your custom method.
function reset(){
document.getElementById('facilities').value= '';
document.getElementById('facilityids').value = '';
}
for textarea might have to do innerHTML = '';
as dr molle says the default reset method might have been used over your reset()
reset method

Categories