Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Dynamically Add More Fields To Form (Theme Options) WordPress

  • REFUNDED

I have a theme options page, [[LINK href="http://wptheming.com/options-framework-plugin/"]]this one[[/LINK]], and I have multiple fields for a single item/row with a mix of select and text fields.

Luis has given me a decent method below, however, it's not saving correctly. When I save the form, it will only save one set and also only save "Array" as the value. Here's the latest I have:

in my [[LINK href="http://pastebin.com/ajYrcm23"]]options.php[[/LINK]]

in my [[LINK href="http://pastebin.com/TKvAYSwc"]]options-interface.php[[/LINK]]

Answers (4)

2011-11-17

Luis Abarca answers:

Yep, i done something similar before

Check this answer amigo

[[LINK href="http://wpquestions.com/question/showLoggedIn/id/3170"]]http://wpquestions.com/question/showLoggedIn/id/3170[[/LINK]]

And here is the code

Form and JS
[[LINK href="http://pastebin.com/CTmPyGRc"]]http://pastebin.com/CTmPyGRc[[/LINK]]

In this case the save_post hook, but you can get the idea of how to get the values and store in the DB.
[[LINK href="http://pastebin.com/cVwGt77L"]]http://pastebin.com/cVwGt77L[[/LINK]]


Luis Abarca comments:

As my amigo Jevusi said, you can use and adjust the code to your needs


Jon Stephen comments:

But how do I make it work with that exact options panel. I need to have also both a SELECT and TEXT field like my image. I also can't figure out how to make it save. So, if I have...
array( "name" => "Item Name",
"desc" => "blah blah blah",
"id" => $shortname."_itemname",
"type" => "multifield",
"std" => ""),

and then
"case: multifield"

How does that work?


Luis Abarca comments:

In the multifield you need to add something like this



case 'multifiled':
?>
<div class="rm_input rm_text">
<label for="<?php echo $value['id']; ?>"><?php echo $value['name']; ?></label>
<input name="<?php echo $value['id']; ?>[]" id="<?php echo $value['id']; ?>[]" type="text" value="<?php if ( get_settings( $value['id'] ) != "") { echo stripslashes(get_settings( $value['id']) ); } else { echo $value['std']; } ?>" />
<small><?php echo $value['desc']; ?></small><div class="clearfix"></div>
</div>

<div id="placeholder"></div>
<?php
break;



The las DIV is a placeholder to add new items when "+" or "Add" button is cliked.

Then add the js in the footer.


Luis Abarca comments:

I just got 3 emails about updates in this questions, but i can't see any changes


Jon Stephen comments:

hmm, this is the updated question...

I have a theme options page, [[LINK href="http://wptheming.com/options-framework-plugin/"]]this one[[/LINK]], and I have multiple fields for a single item/row with a mix of select and text fields. My issue is I'm trying to have an add more and delete item buttons so that I can just add more instantly. See my image example. Any ideas how to make it work with my code below?


case 'filmcredit':

$film_stored = $val;



$output .= '<select class="of-typography of-typography-size" name="' . esc_attr( $option_name . '[' . $value['id'] . '][filmyear]' ) . '" id="' . esc_attr( $value['id'] . '_filmyear' ) . '">';

for ($i = 2011; $i > 1949; $i--) {

$filmyear = $i;

$output .= '<option value="' . esc_attr( $filmyear ) . '" ' . selected( $film_stored['filmyear'], $filmyear, false ) . '>' . esc_html( $filmyear ) . '</option>';

}

$output .= '</select>';

$theroles_array = array("" => "Role","Actor/Actress" => "Actor/Actress","Reality Participant" => "Reality Participant","Dancer" => "Dancer","Model" => "Model","Singer" => "Singer");

$output .= '<select class="of-input" name="' . esc_attr( $option_name . '[' . $value['id'] . '][filmrole]' ) . '" id="' . esc_attr( $value['id'] . '_filmrole' ) . '">';

foreach ($theroles_array as $key => $theroles ) {

$output .= '<option value="' . esc_attr( $key ) . '" ' . selected( $film_stored['filmrole'], $key, false ) . '>'. $theroles .'</option>';

}

$output .= '</select>';

$output .= '<input id="' . esc_attr( $value['id'] . '_filmproduction' ) . '" class="of-input" name="' . esc_attr( $option_name . '[' . $value['id'] . '][filmproduction]' ) . '" type="text" value="' . esc_attr( $film_stored['filmproduction']) . '" />';



break;


Luis Abarca comments:

Can you post the full theme ? to replicate it in my dev server ?

I think you should raise the award a little bit.


Jon Stephen comments:

I'm just simply using the [[LINK href="http://wptheming.com/options-framework-plugin/"]]options framework[[/LINK]] I have in the link and it's not dependent on a particular theme yet. That's why I just included the case that I created above which I know works and saves the data in the fields. So I'm only looking for the working bit that dynamically duplicates those fields correctly. I will raise the reward amount.


Luis Abarca comments:

This is what i did.

options-interface.php

case 'filmcredit':
$film_stored = $val;
$output .= '<div id="filmtpl" style="display: none"><div class="item" style="margin: 20px 5px">';
$output .= '<select class="of-typography of-typography-size" name="' . esc_attr( $option_name . '[' . $value['id'] . '][filmyear]' ) . '" id="' . esc_attr( $value['id'] . '_filmyear' ) . '">';

for ($i = 2011; $i > 1949; $i--) {
$filmyear = $i;
$output .= '<option value="' . esc_attr( $filmyear ) . '" ' . selected( $film_stored['filmyear'], $filmyear, false ) . '>' . esc_html( $filmyear ) . '</option>';
}

$output .= '</select>';

$theroles_array = array("" => "Role","Actor/Actress" => "Actor/Actress","Reality Participant" => "Reality Participant","Dancer" => "Dancer","Model" => "Model","Singer" => "Singer");

$output .= '<select style="width: 200px" class="of-input" name="' . esc_attr( $option_name . '[' . $value['id'] . '][filmrole]' ) . '" id="' . esc_attr( $value['id'] . '_filmrole' ) . '">';

foreach ($theroles_array as $key => $theroles ) {
$output .= '<option value="' . esc_attr( $key ) . '" ' . selected( $film_stored['filmrole'], $key, false ) . '>'. $theroles .'</option>';
}

$output .= '</select>';
$output .= '<input style="width: 290px" id="' . esc_attr( $value['id'] . '_filmproduction' ) . '" class="of-input" name="' . esc_attr( $option_name . '[' . $value['id'] . '][filmproduction]' ) . '" type="text" value="' . esc_attr( $film_stored['filmproduction']) . '" />';
$output .= '<div class="commands" style="display: inline"><a rel="delete" class="button">-</a> <a rel="add" class="button">+</a></div>';
$output .= '</div></div>';
$output .= '<div id="filmplaceholder"></div>';

break;



in options.php in your theme

add_action('admin_footer-appearance_page_options-framework', 'add_admin_footer');

function add_admin_footer()
{
?>
<script>
(function($)
{
var lines = 0;
var template = 0;

function items_init()
{
<?php $data = ''; // get the stored data ?>

<?php if ( empty($data) ) : ?>
items_add();
<?php else: ?>

<?php
// Show stored records
foreach ($data as $item) : ?>
items_add({
title: '<?php echo $item['testflight_filmproduction'] ?>',
});
<?php endforeach ?>
<?php endif ?>

// Delete the "-" button in first row
$('#filmplaceholder .item .commands a[rel="delete"]').remove();
}

function items_add()
{
$('#filmtpl .item').clone().appendTo('#filmplaceholder');

lines++;

if (arguments.length > 0) {
options = arguments[0];

$('.testflight_filmproduction', obj).val( options.title ); // to fill values
}
}

$('#filmplaceholder').delegate('.commands a', 'click', function()
{
var action = $(this).attr('rel');
var confirm_delete = true;

// Add action
if ('add' == action) {
items_add();
}

// Delete action
if ('delete' == action) {
// La TR en la tabla
var oTr = $(this).parent().parent();


if ( !confirm('Are you sure you want to delete this item ?') ) {
confirm_delete = false;
}

if (confirm_delete) {
oTr.remove();
lines--;
}
}
});

$(document).ready(function()
{
items_init();
});

})(jQuery);

</script>
<?php
}


function optionsframework_options() {

// If using image radio buttons, define a directory path
$imagepath = get_bloginfo('template_url') . '/images/';

// Options array
$options = array();

$options[] = array( "name" => __('General Settings','portfoliopress'),
"type" => "heading");

<strong> $options[] = array( "name" => __('Custom multifield','portfoliopress'),
"desc" => __('Test Flight.','portfoliopress'),
"id" => "testflight",
"type" => "filmcredit");</strong>
....
} // end function


Notice: i using the Portfolio Press 0.8.3 by Devin Price


Jon Stephen comments:

Thanks Luis. This is looking good. However it's only saving one of the new groups. How can it increment the ids and names to save them?


Luis Abarca comments:

You need to change this code


$output .= '<input style="width: 290px" id="' . esc_attr( $value['id'] . '_filmproduction' ) . '" class="of-input" name="' . esc_attr( $option_name . '[' . $value['id'] . '][filmproduction]' ) . '" type="text" value="' . esc_attr( $film_stored['filmproduction']) . '" />';


To something like this

$id = esc_attr( $value['id'] . '_filmproduction[]' );
$name = esc_attr( $option_name . '_' . $value['id'] . '_filmproduction[]' );

$output .= '<input style="width: 290px" id="' . $id . '" class="of-input" name="' . $name . '" type="text" value="'" />';


This way, you will recive the data in an array.

When you have data already stored in your post meta, you can fill the fields with javascript with add_item()


Jon Stephen comments:

hmm, I just can't get it to work. Am I missing something?

2011-11-17

jevusi answers:

Use the code i have BUY
http://wpquestions.com/question/showLoggedIn/id/3170

2011-11-17

John Cotton answers:

You could do it javascript...


jQuery('#add-button').click( function() {
var rows_count = $('#rows> div').size();

$('#rows').append( 'WHATEVER HTML YOU WANT HERE' );

});


The key thing with the html you add is to have pseudo-array names for the input fields ie

<input type="text" name="title[1]" />

That way, when you post it back to the server, you will get an array in S_POST['title'] for each entry.

You could figure out what's new and old from a hidden input value or (since you're giving them the option to delete as well) just take what you get each time and overwrite whatever is in the database.

2011-12-02

Julio Potier answers:

This can be done using a simple jQuery function, one like John Cotton did.
And same thing for delete a row.
I can do this with FTP account and source.


Jon Stephen comments:

I can't give ftp info. But here's what I have based from Luis above for [[LINK href="http://wptheming.com/options-framework-plugin/"]]this options framework[[/LINK]]:

[[LINK href="http://pastebin.com/ajYrcm23"]]in my options.php[[/LINK]]

[[LINK href="http://pastebin.com/TKvAYSwc"]]in my options-interface.php[[/LINK]]