I have the following form on a wordpress template page. I'm getting a 404 error each time i submit the form but I'm not using any of the reserved workpress parameter names in the form.
<?php
/**
* Template Name: Registration Template
*/
if(isset($_POST['form-submitted']))
{
if(trim($_POST['runner']) === '') {
$runnerError = 'Please enter runner runner.';
$hasError = true;
} else {
$runner = trim($_POST['runner']);
}
if(trim($_POST['racenumber']) === '') {
$numberError = 'Please enter a race number.';
$hasError = true;
} else {
$racenumber = trim($_POST['racenumber']);
}
$race = trim($_POST['race']);
error_log($race.' '.$runner.' '.$racenumber);
$registrationSubmitted = true;
}
get_header();
echo "<pre>GET "; print_r($_GET); echo "</pre>";
echo "<pre>POST "; print_r($_POST); echo "</pre>";
?>
<div id="container">
<?php
if(isset($registrationSubmitted) && $registrationSubmitted == true)
{
echo '<div class="thanks"><p>The runner has been registered.</p></div>';
}
else
{
$races = // magic array
$selectRaces = '<select name="race" id="race">';
foreach($races as $racez)
{
$selectRaces .= sprintf('<option value=%d>%s</option>',$race->id,$race->name);
}
$selectRaces .= '</select>';
echo apply_filters('the_content','
<form action="'.get_permalink().'" id="form" method="POST">
[one_half last="no"]
<b>Race Details</b><br/>
RaceNumber<input type="text" name="racenumber" id="racenumber"/><br/>
Race'.$selectRaces.'<br/>
[/one_half]
[one_half last="yes"]
<b>Runner Details</b><br/>
ID<input type="text" name="runner" id="runner"/><br/>
Firstname<input type="text" name="first" id="first"/><br/>
Surname<input type="text" name="last" id="last"/><br/>
Gender<input type="text" name="gender" id="gender"/><br/>
DOB<input type="text" name="dob" id="dob"/><br/>
Standard<input type="text" name="standard" id="standard"/><br/>
Company<input type="text" name="company" id="company"/><br/>
[/one_half]
<input type="submit" value="Register Runner"/>
<input type="hidden" name="form-submitted" id="bhaa-submitted" value="true" />
</form>');
}
echo '</div>';
?>
<?php get_footer(); ?>
I've customised my 404 page to dump the $_POST values so i'm sure the parameter values are being submitted.
[racenumber] => 5
[race] => 2596
[runner] => 5
[first] =>
[last] =>
[gender] =>
[dob] =>
[standard] =>
[company] =>
[form-submitted] => true
Can anyone explain my the logic in my 'isset($_POST['form-submitted'])' is not being exercised?
The generated html
<form action="http://localhost/registration/" id="form" method="POST">
<div class="one_half">
<b>Race Details</b><br><br>
RaceNumber<input name="number" id="number" type="text"><br><br>
Race<br>
<select name="race" id="race">
<option value="2596" id="2596">4-Mile-M</option>
<option value="2595" id="2595">2-Mile-W</option>
</select>
EDIT
I've changed the code where is set the values of the select dropdown to use an incrementing int value rather than using sprintf to map a string value to an int value. When the first element is selected the form submits, if the second option is picked i get a 404!
$races = // magic array
$selectRaces = '<select name="race" id="race">';
$i=0;
foreach($races as $racez)
{
$selectRaces .= sprintf('<option value=%d>%s</option>',$i++,$race->name);
}
Problem is that WordPress have some words reserved and it will throw that error when submitting forms:
Some of the words that I found myself and surfing the web are:
Custom post type names
taxonomy names
"name"
"day"
"month"
"year"
"category"
"title"
So be careful when creating a a custom form and try to name your inputs with some prefix. In my case, I had a custom post type called "history" and I was naming the input the same way.
Have you tried resetting your permalinks?
Could be an issue there somewhere.
It doesn't seem or look like the issue is isset($_POST['form-submitted'])'
It's possible your page name is being used another plugin.
WordPress's get_permalink() is generating a URL that is being injected into your output HTML's form tag.
If you look at the HTML source, as it appears in your browser (eg right-click, view-source or right-click, inspect element), find this:
<form action='some_url_here' ...>.
I would expect that this URL should probably be the same as the one that you're currently browsing... ie it tells the browser to send the details back to that same PHP file to process its results.
Type unique Name and ID try this form
<form action="'.get_permalink().'" id="form" method="POST">
[one_half last="no"]
<b>Race Details</b><br/>
RaceNumber<input type="text" name="racenumber" id="racenumber"/><br/>
Race'.$selectRaces.'<br/>
[/one_half]
[one_half last="yes"]
<b>Runner Details</b><br/>
ID<input type="text" name="runner_id" id="runner_id"/><br/>
Firstname<input type="text" name="runner_first" id="runner_first"/><br/>
Surname<input type="text" name="runner_last" id="runner_last"/><br/>
Gender<input type="text" name="runner_gender" id="runner_gender"/><br/>
DOB<input type="text" name="runner_dob" id="runner_dob"/><br/>
Standard<input type="text" name="runner_standard" id="runner_standard"/><br/>
Company<input type="text" name="runner_company" id="runner_company"/><br/>
[/one_half]
<input type="submit" value="Register Runner"/>
<input type="hidden" name="form-submitted" id="bhaa-submitted" value="true" />
</form>
Here is what seems to be a full list:
attachment
attachment_id
author
author_name
calendar
cat
category
category__and
category__in
category__not_in
category_name
comments_per_page
comments_popup
custom
customize_messenger_channel
customized
cpage
day
debug
embed
error
exact
feed
hour
link_category
m
minute
monthnum
more
name
nav_menu
nonce
nopaging
offset
order
orderby
p
page
page_id
paged
pagename
pb
perm
post
post__in
post__not_in
post_format
post_mime_type
post_status
post_tag
post_type
posts
posts_per_archive_page
posts_per_page
preview
robots
s
search
second
sentence
showposts
static
subpost
subpost_id
tag
tag__and
tag__in
tag__not_in
tag_id
tag_slug__and
tag_slug__in
taxonomy
tb
term
terms
theme
title
type
w
withcomments
withoutcomments
year
I had the same issue but I found when I submitted empty input fields (without any value in input field) that's working fine then I leave few input fields remain empty and place value in others which was also working fine.
That's means the issue was one of my input field not in wordpress or
in my code.
You can't use this variables in POST FORM
_ajax_nonce
_page
_per_page
_signup_form
_total
_url
_wp_http_referer
_wp_original_http_referer
_wp_unfiltered_html_comment
_wpnonce
_wpnonce-custom-header-upload
aa
action
action2
active_post_lock
add_new
add_new_users
addmeta
admin_bar_front
admin_color
admin_email
admin_password
admin_password2
ajax
align
allblogs
allusers
alt
approve_parent
approved
attachment
attachment_id
attachments
auth_cookie
author
author_name
autocomplete_type
auto_draft
auto-add-pages
autosave
background-attachment
background-color
background-position-x
background-repeat
banned_email_domains
blog
blog_name
blog_public
blog_upload_space
blogname
bulk_edit
c
calendar
cat
category_base
category_name
catslist
changeit
changes
charset
checkbox
checked
clear-recent-list
closed
comment
comment_approved
comment_author
comment_author_email
comment_author_url
comment_content
comment_date
comment_ID
comment_parent
comment_post_ID
comment_shortcuts
comment_status
comments_listing
comments_popup
confirmdelete
connection_type
content
context
cpage
create-new-attachment
createuser
customize_messenger_channel
customized
customlink-tab
date
date_format
date_format_custom
day
default-header
delete
delete_all
delete_all2
delete_comments
delete_option
delete_tags
delete_widget
deletebookmarks
deletecomment
deleted
deletemeta
deletepost
description
detached
dismiss
display_name
do
edit_date
email
error
exact
excerpt
features
feed
fetch
fheight
file
fileupload_maxk
filter
find_detached
first_comment
first_comment_author
first_comment_url
first_name
first_page
first_post
found_post_id
fwidth
global_terms_enabled
GLOBALS
gmt_offset
guid
height
hh
hidden
hidden_aa
hidden_jj
hidden_mm
hidden_mn
hidden_hh
history
hostname
hour
html-upload
id
ID
ids
id_base
illegal_names
insert-gallery
insertonlybutton
interim-login
item-object
item-type
jj
json
json_data
key
last_name
limited_email_domains
link_id
link_image
link_name
link_rss
link_url
link_visible
linkcheck
locale
locked
log
logged_in_cookie
m
media
media_type
menu
menu_items
menu-item
menu-item-attr-title
menu-item-classes
menu-item-db-id
menu-item-description
menu-item-object
menu-item-object-id
menu-item-parent-id
menu-item-position
menu-item-target
menu-item-title
menu-item-type
menu-item-url
menu-item-xfn
menu-locations
menu-name
message
meta
metakeyinput
metakeyselect
metavalue
minute
mm
mn
mode
monthnum
more
move
multi_number
name
nav-menu-locations
new
new_role
new_slug
new_title
newcat
newcomment_author
newcomment_author_email
newcomment_author_url
newcontent
newuser
nickname
no_placeholder
noapi
noconfirmation
noredir
number
offset
oitar
option
option_page
order
orderby
p
pb
page
page_columns
page_id
page_options
paged
pagegen_timestamp
pagename
parent_id
pass1
pass2
password
permalink_structure
photo_description
photo_src
phperror
ping_status
plugin
plugin_status
pointer
position
post
post_category
post_data
post_format
post_ID
post_id
post_mime_type
post_password
post_status
post_title
post_type
post_view
postid
posts
preview
primary_blog
private_key
ps
public_key
publish
pwd
query
reassign_user
reauth
redirect
redirect_to
ref
referredby
registration
registrationnotification
rememberme
remove-background
removeheader
removewidget
reset-background
resetheader
review
rich_editing
robots
role
s
same
save
savewidget
savewidgets
screen
scrollto
search
second
section
selectall
selection
send
send_password
sentence
short
show_sticky
sidebar
sidebars
signup_for
signup_form_id
site_id
site_name
sitename
size
skip-cropping
spam
spammed
src
ss
stage
start
static
status
sticky
subdomain_install
submit
subpost
subpost_id
super_admin
tab
tag
tag_ID
tag-name
tag_base
tags_input
tax
tax_input
tag-name
target
taxonomy
tb
term
text-color
the-widget-id
theme
theme_status
thumb
timezone_string
time_format
time_format_custom
title
thumbnail_id
trash
trashed
type
undismiss
unspam
unspammed
untrash
untrashed
url
update_home_url
updated
upgrade
upload_filetypes
upload_space_check_disabled
use_ssl
user
user_id
user_login
user_name
username
users
verify-delete
version
visibility
visible
w
weblog_title
welcome_email
welcome_user_email
widget_id
widget_number
widget-id
widget-recent-comments
widget-rss
width
withcomments
withoutcomments
wp_customize
wp_http_referer
wp_screen_options
wp-preview
WPLANG
x1
y1
year
Related
I need your help with my situation in storing data.
I got a cart with several products, and now I want to store all these products in Order table at the same time by clicking submit button
My view blade.php
This view shows all products in the cart and I need to store these information in Ordertable
<form action="{{route('order.store')}}" method="post">
#csrf
#foreach ($cart as $ct)
<input type="text" name="product_id" value="{{$ct->id}}" hidden>
<input type="text" value="{{$ct->color}}" name="color" >
<input type="text" value="{{$ct->size}}" name="size" >
<input type="text" value="{{$ct->price}}" name="price" >
#endforeach
<button type="submit">submit</button>
</form>
In my Order table, I got these 4 columns need to fill in: product_id, color, size and price.
My foreach loop gets data from Cart table and all data were shown without errors.
My question is that How I can store these data to my Order table just by click on submit button once? What I should write in my store function in OrderController?
If my cart has 3 products then my expected value is the Order table will look like this:
id----product_id----size----color---price---+
---------------------------------------------
1 1 abc xyz 123
---------------------------------------------
2 2 abc2 xyz2 456
---------------------------------------------
3 3 aaa bbb 789
Thank for your help!
DB:
Order:
user_id
created_at
...
orderProducts:
price
color
size
order_id (relation)
product_id (relation)
...
View
<form action="{{route('order.store')}}" method="post">
#csrf
#foreach ($cart as $ct)
<input type="text" name="products[]" value="{{$ct->product_id}}" hidden>
<input type="text" value="{{$ct->color}}" name="color[]" >
<input type="text" value="{{$ct->size}}" name="size[]" >
<input type="text" value="{{$ct->price}}" name="price[]" >
#endforeach
<button type="submit">submit</button>
</form>
controller function store
$order= new Order;// change the model here
// .. complete your information's like user id or created_at
$order->save();
foreach($request->products as $key=>$product_id)
{
$product = Product::findOrFail($product_id); // validations the product id
// get your information's from db (color,size,price) don't trust get information's from user .
// $product->price , $product->color .... or get from cart
//from cart direct $color[$key] or $price[$key] or $size[$key] "I don't recomend to use this point"
// must be create new table
$orderProducts=new orderProducts; // create new table ordersProducts
$orderProducts->price = $product->price;
// .. complete your information's
$orderProducts->order_id = $order->id; // primary key
$orderProducts->product_id= $product->id;
$orderProducts->save();
}
Notice:
- You need to use try-catch to record info in order if fail in the step "findOrFail" or change to find and then if product not found in the table then record order not complete and show an error to the user
My Answer is quite similar to above answer but i would just like to put a different approach here with Database Transaction, Try Catch & Bulk Insert(to prevent placing queries in loop)
try {
DB::begintransaction();
$order = Order::create($orderData); // change the model here
$orderProductsData = [];
foreach($request->products as $product_id) {
$product = Product::find($product_id); // validations the product id
$orderProductsData[] = $tmpData = [
'price' => $product->price,
'order_id' => $order->id,
'product_id' => $product->id;
];
// must be create new table
// You can also store this way, but its still in loop so putting under comment.
// $orderProducts = orderProducts::create($tmpData);
}
orderProducts::insert($orderProductsData);
DB::commit();
} catch (Exception $e) {
DB::rollback();
thow $e; // modify with, How you handle your error response.
}
Again, Above answer is totally correct, However just putting a different approach, which i believe little more optimised way.
I have a form which will have dynamic value and it will check that property id and then save it to the database.
For example in my database there is a table with title having the id=1, type having the id=2, description having the id=3, and after the form is submitted it will check if the field is title or type or description and it will save it in database that is if it is title it will save value of field title with propertyid value 1.
<form method="post" action="something.php">
<input type="text" name="field[][title]" value="edison">
<input type="text" name="field[][type]" value="book">
<input type="text" name="field[][description]" value="some description">
</form>
it is not inputting normal array in php with using foreach, I am not understanding how to get the value inside the index of the array to check with the sql database, that is to check if the field[][title]" then title has id 1 and if the field is field[][description]" it will check the sql for the property id of description that is 3
You need to look at it in reverse.
You first need to query your database so that you have a mapping of which field associates with which ID.
Then, when your information is posted, you can iterate over that mapping, detect if they have been posted, and use them accordingly:
$mapping = loadFieldNamesToFieldId();
/*
mapping should look something like:
$mapping = [
'title' => 1,
'type' => 2
];
*/
foreach ($_POST as $field_name => $field_value) {
if (isset($mapping[$field_name]]) {
$id = $mapping[$field_name];
// at this point you know that the user submitted a field which
// had $field_value, and which ID it relates to in your database
}
}
At which point you can just format your form as so:
<input type="text" name="title" value="edison">
I found this answer and thought of posting this as this relates to the answer
foreach ($_POST as $param_name => $param_val)
{
echo "Param: $param_name; Value: $param_val<br />\n";
}
I have this code snippet in PHP:
if (strcasecmp($_POST['method'], 'assignId') == 0) {
$username = $_POST['username'];
$response['code'] = 1;
$response['status'] = $api_response_code[$response['code']]['HTTP Response'];
$sql = "CALL new_person('$username')";
if (($result = $conn->query($sql)) === TRUE) {
$row = $result->fetch_assoc();
$response['data'] = $row;
}
deliver_response($response);
new_person is a stored procedure which returns an id, it has been tested and works fine and deliver_response returns JSON format of the input. It has also been tested and works fine.
Why do POST Requests return 404 error?
The stored procedure is being executed, but it doesn't return the result. Finally, when I change the POST method to GET and make a get request instead it works fine!
404 Error means that the page that has to process the post request can't be loaded or not exists. You have to check the php and server logs and maybe you can find a answer to your question.
Prefix everything, especially your variables. The names you are using are used by WordPress internally (see the comment form), so WordPress might try to do something with your form values. If that fails you get an error.
While $_GET problems are usually rather easy to debug, $_POST and $_REQUEST names are not so simple.
The following list is probably not complete. But its bare length tells us a lesson:
Avoid any name you can find in a dictionary. Prefix your form names.
List of reserved names in $_POST and $_REQUEST used by WordPress 3.5
These names might have side effects when used in themes or plugins. Some are used on specific pages only (removeheader), others on multiple pages or requests. Avoid them all if you can.
_ajax_nonce
_page
_per_page
_signup_form
_total
_url
_wp_http_referer
_wp_original_http_referer
_wp_unfiltered_html_comment
_wpnonce
_wpnonce-custom-header-upload
aa
action
action2
active_post_lock
add_new
add_new_users
addmeta
admin_bar_front
admin_color
admin_email
admin_password
admin_password2
ajax
align
allblogs
allusers
alt
approve_parent
approved
attachment
attachment_id
attachments
auth_cookie
author
author_name
autocomplete_type
auto_draft
auto-add-pages
autosave
background-attachment
background-color
background-position-x
background-repeat
banned_email_domains
blog
blog_name
blog_public
blog_upload_space
blogname
bulk_edit
c
calendar
cat
category_base
category_name
catslist
changeit
changes
charset
checkbox
checked
clear-recent-list
closed
comment
comment_approved
comment_author
comment_author_email
comment_author_url
comment_content
comment_date
comment_ID
comment_parent
comment_post_ID
comment_shortcuts
comment_status
comments_listing
comments_popup
confirmdelete
connection_type
content
context
cpage
create-new-attachment
createuser
customize_messenger_channel
customized
customlink-tab
date
date_format
date_format_custom
day
default-header
delete
delete_all
delete_all2
delete_comments
delete_option
delete_tags
delete_widget
deletebookmarks
deletecomment
deleted
deletemeta
deletepost
description
detached
dismiss
display_name
do
edit_date
email
error
exact
excerpt
features
feed
fetch
fheight
file
fileupload_maxk
filter
find_detached
first_comment
first_comment_author
first_comment_url
first_name
first_page
first_post
found_post_id
fwidth
global_terms_enabled
GLOBALS
gmt_offset
guid
height
hh
hidden
hidden_aa
hidden_jj
hidden_mm
hidden_mn
hidden_hh
history
hostname
hour
html-upload
id
ID
ids
id_base
illegal_names
insert-gallery
insertonlybutton
interim-login
item-object
item-type
jj
json
json_data
key
last_name
limited_email_domains
link_id
link_image
link_name
link_rss
link_url
link_visible
linkcheck
locale
locked
log
logged_in_cookie
m
media
media_type
menu
menu_items
menu-item
menu-item-attr-title
menu-item-classes
menu-item-db-id
menu-item-description
menu-item-object
menu-item-object-id
menu-item-parent-id
menu-item-position
menu-item-target
menu-item-title
menu-item-type
menu-item-url
menu-item-xfn
menu-locations
menu-name
message
meta
metakeyinput
metakeyselect
metavalue
minute
mm
mn
mode
monthnum
more
move
multi_number
name
nav-menu-locations
new
new_role
new_slug
new_title
newcat
newcomment_author
newcomment_author_email
newcomment_author_url
newcontent
newuser
nickname
no_placeholder
noapi
noconfirmation
noredir
number
offset
oitar
option
option_page
order
orderby
p
pb
page
page_columns
page_id
page_options
paged
pagegen_timestamp
pagename
parent_id
pass1
pass2
password
permalink_structure
photo_description
photo_src
phperror
ping_status
plugin
plugin_status
pointer
position
post
post_category
post_data
post_format
post_ID
post_id
post_mime_type
post_password
post_status
post_title
post_type
post_view
postid
posts
preview
primary_blog
private_key
ps
public_key
publish
pwd
query
reassign_user
reauth
redirect
redirect_to
ref
referredby
registration
registrationnotification
rememberme
remove-background
removeheader
removewidget
reset-background
resetheader
review
rich_editing
robots
role
s
same
save
savewidget
savewidgets
screen
scrollto
search
second
section
selectall
selection
send
send_password
sentence
short
show_sticky
sidebar
sidebars
signup_for
signup_form_id
site_id
site_name
sitename
size
skip-cropping
spam
spammed
src
ss
stage
start
static
status
sticky
subdomain_install
submit
subpost
subpost_id
super_admin
tab
tag
tag_ID
tag-name
tag_base
tags_input
tax
tax_input
tag-name
target
taxonomy
tb
term
text-color
the-widget-id
theme
theme_status
thumb
timezone_string
time_format
time_format_custom
title
thumbnail_id
trash
trashed
type
undismiss
unspam
unspammed
untrash
untrashed
url
update_home_url
updated
upgrade
upload_filetypes
upload_space_check_disabled
use_ssl
user
user_id
user_login
user_name
username
users
verify-delete
version
visibility
visible
w
weblog_title
welcome_email
welcome_user_email
widget_id
widget_number
widget-id
widget-recent-comments
widget-rss
width
withcomments
withoutcomments
wp_customize
wp_http_referer
wp_screen_options
wp-preview
WPLANG
x1
y1
year
Variable names
$method // Filter: 'user_contactmethods'
$post_type_name . -tab
$sidebar_id . _position
$taxonomy_name . -tab
$whitelist_options // Filter: 'whitelist_options'
__i__ . $something // used in widgets
new . $taxonomy->name
new . $taxonomy->name . _parent
quick-search-posttype- . $post_type_name
quick-search-taxonomy- . $taxonomy_name
widget- . $id_base
Credit : fuxia
Your code starts with if (strcasecmp($_POST['method'], 'assignId') == 0) {
and the if statement is never closed, so your code runs only on post method
I assume deliver_response throw the 404
Please make sure that you have used the "POST" method in the form of the previous page.
Use the flower brackets properly(you have missed one ending flower bracket for first if condition)
On my site people search for something according on VIN they enter to form. I try to add VIN to session to be able to display it in form after they submit it.
This is how my contructor looks like:
public function __construct( $data = array() ) {
if( isset( $data['vin'] ) ) $this->vin = stripslashes( strip_tags( $data['vin']) );
$this->vin = str_replace("I","1",str_replace("O","0",$this->vin)); // replace i for 1 and o for 0
$_SESSION['vin'] = $this->vin;
}
My HTML site looks like:
<input type="text" maxlength="17" minlength="17" required autofocus name="vin" value="<?php if (isset($_SESSION['vin'])) {echo $_SESSION['vin'];} ?>">
And now the problem:
It display there old vin.
Example:
1. I search for vin XYZ
2. I pres submit and get result for vin XYZ but input bar is empty
3. I search for vin ABC and now after i submit it i get result for ABC but in input i have XYZ vin from session
My idea was that my php site do not reload or something but it should if i get result from submit..
Any idea how can i display current VIN in search input?
I have a invoice table and an invoice_item table. Each Invoice hasMany invoiceItem.
When creating an invoice the user is presented with a form with the invoice form fields and also a row with invoiceItem form fields.
What I want to do is to have a "add new item" link that dynamically (jQuery, AJAX) adds a new row of the item fields. User should be able to add as many rows as they want and each new row should appear below the last row.
Of course the row field attributes must also be correct so that the data can easily be inserted with the saveAll method.
What is the best and most proper way to accomplish this with CakePHP? I am using CakePHP 2.4.7.
Here's how I did it with data containing a hidden id, a label and an input field, all wrapped up in a fieldset. You could use actual tables to wrap it up.
Here's the generated HTML for two sets of fields and the link to click to add a row:
<fieldset>
<input type="hidden" name="data[VmfrDesignatedIncome][0][id]" value="668" id="VmfrDesignatedIncome0Id"/>
<div class="input text">
<label for="VmfrDesignatedIncome0Designation">Designation</label>
<input name="data[VmfrDesignatedIncome][0][designation]" value="blah" maxlength="512" type="text" id="VmfrDesignatedIncome0Designation"/></div>
</fieldset>
<fieldset>
<input type="hidden" name="data[VmfrDesignatedIncome][1][id]" value="669" id="VmfrDesignatedIncome1Id"/>
<div class="input text">
<label for="VmfrDesignatedIncome1Designation">Designation</label>
<input name="data[VmfrDesignatedIncome][1][designation]" value="blah2" maxlength="512" type="text" id="VmfrDesignatedIncome1Designation"/></div>
</fieldset>
Add row
and here's the Javascript which clones the last fieldset on the page, and then modifies the id, name and field values to increase the number in them by one. Note that the selectors have to accurately select each label or field using the > child selector.
/* As the strings to the function below may have [ or ]
** we want to stop it being treated as a regexp
*/
RegExp.quote = function(str) {
return str.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
};
function findNumberAddOne(attributeString) {
/*Finds the number in the given string
** and returns a string with that number increased by one
*/
var re = new RegExp("(.*)([0-9])(.*)");
var nPlusOne = attributeString.replace(re, "$2")+"+1";
var newstr = attributeString.replace(re, "$1")+eval(nPlusOne)+attributeString.replace(re, "$3");
return newstr;
}
$(document).ready(function() {
/* Duplicate the last set of designated income fields and increase the relevants id/name etc.
** so that it works as a new row in the table when saved*/
$('#addrow').click(function() {
$('fieldset:last').clone().insertAfter('fieldset:last');
$('fieldset:last > input').attr('id',findNumberAddOne($('fieldset:last > input').attr('id')));
$('fieldset:last > input').attr('value',''); /*Blank out the actual value*/
$('fieldset:last > input').attr('name',findNumberAddOne($('fieldset:last > input').attr('name')));
$('fieldset:last > div > label').attr('for',findNumberAddOne($('fieldset:last > div > label').attr('for')));
$('fieldset:last > div > input').attr('id',findNumberAddOne($('fieldset:last > div > input').attr('id')));
$('fieldset:last > div > input').attr('value',''); /*Blank out the actual value*/
$('fieldset:last > div > input').attr('name',findNumberAddOne($('fieldset:last > div > input').attr('name')));
});
});
Please check Dynamic form input fields in CakePHP tutorial. I used same for CakePHP 2.x and also for CakePHP 3.x. One problem in this tutorial is dynamic field ID creation. Each time it create same ID for same dynamic fields, like create GradeSubject for both Grade.0.subject and Grade.1.subject fields. If you need dynamic ID for each fields, you can modify this tutorial as like below.
According to tutorial just change View/Elements/grades.ctp content as:
<?php
$key = isset($key) ? $key : '{{ key }}';
// I changed <%= key %> to {{ key }}
?>
<tr>
<td>
<?php echo $this->Form->hidden("Grade.{$key}.id") ?>
<?php echo $this->Form->text("Grade.{$key}.subject",array("id"=>"Grade{$key}Subject")); ?>
</td>
<td>
<?php echo $this->Form->select("Grade.{$key}.grade", array(
'A+',
'A',
'B+',
'B',
'C+',
'C',
'D',
'E',
'F'
), array(
'empty' => '-- Select grade --',
"id"=>"Grade{$key}Grade"
)); ?>
</td>
<td class="actions">
Remove grade
</td>
</tr>
And also change your add.ctp javascript code as:
<script>
$(document).ready(function() {
//I changed undescore default template settings
_.templateSettings = {
interpolate: /\{\{(.+?)\}\}/g
}
var
gradeTable = $('#grade-table'),
gradeBody = gradeTable.find('tbody'),
gradeTemplate = _.template($('#grade-template').remove().text()),
numberRows = gradeTable.find('tbody > tr').length;
gradeTable
.on('click', 'a.add', function(e) {
e.preventDefault();
$(gradeTemplate({key: numberRows++}))
.hide()
.appendTo(gradeBody)
.fadeIn('fast');
})
.on('click', 'a.remove', function(e) {
e.preventDefault();
$(this)
.closest('tr')
.fadeOut('fast', function() {
$(this).remove();
});
});
if (numberRows === 0) {
gradeTable.find('a.add').click();
}
});
</script>
the simplest idea got in my mind
1- make your items input with name array (<input type="text" name="items[]"/>)
2- create a button with class "addmore"
3- use jquery clone to duplicate the input on the click event on that button
I think this will help