I'm using WooCommerce to build a webshop.
The determined format for forms is that there's no labels, only placeholders. I've been removing the labels like so:
<?php
// WooCommerce Checkout Fields Hook
add_filter( 'woocommerce_checkout_fields' , 'custom_wc_checkout_fields' );
// Change the format of fields with type, label, placeholder, class, required, clear, label_class, options
function custom_wc_checkout_fields( $fields ) {
//BILLING
$fields['billing']['billing_first_name']['label'] = false;
return $fields;
}
?>
But since I want no labels anywhere, I was wondering if there's a way to remove all of them at once. Instead of going through them all individually. Does anybody have an idea?
Thanks!
EDIT:
I realize this is possible by just adding some css(display none), but since this is not a very clean solution, I was wondering if there is some other way to accomplish this.
You can remove any $field->property with unset.
Good reading and references can be found here: Customizing checkout fields using actions and filters
Now, for your question in how to do it globally, you can use a loop, something like:
// WooCommerce Checkout Fields Hook
add_filter('woocommerce_checkout_fields','custom_wc_checkout_fields_no_label');
// Our hooked in function - $fields is passed via the filter!
// Action: remove label from $fields
function custom_wc_checkout_fields_no_label($fields) {
// loop by category
foreach ($fields as $category => $value) {
// loop by fields
foreach ($value as $field => $property) {
// remove label property
unset($fields[$category][$field]['label']);
}
}
return $fields;
}
Online example: http://codepad.org/drvBYYS8
Related with good advise in acepted answer: WooCommerce Change Form Labels and Remove Fields
You can do this with css by adding the below, other than this I don't know of a way to remove all the labels at once.
.woocommerce form.checkout label
{
display: none;
}
Related
The MailChimp for WooCommerce plugin is great, but I've just been given a design where the 'Subscribe to our newsletter' checkbox in the WooCommerce checkout is immediately after the email field rather than at the bottom of a particular section:
The plugin allows you to type in an action hook for where you'd like the checkbox to appear; for example woocommerce_checkout_before_customer_details, woocommerce_after_checkout_billing_form, etc. which allows you to put the checkbox before or after a certain section (as long as there's a hook for it), but not in amongst the various fields.
Is there a way to add the MailChimp checkbox to very specific point before or after a certain field?
The checkout fields are outputted within a loop, which uses the woocommerce_form_field() function to echo out each field:
$fields = $checkout->get_checkout_fields( 'billing' );
foreach ( $fields as $key => $field ) {
woocommerce_form_field( $key, $field, $checkout->get_value( $key ) );
}
this function has a number of filters for each specific field type (e.g. woocommerce_form_field_email), but no action hooks.
However, you can use one of these filters and just a little trickery to add your own hooks:
///
// Add MailChimp checkbox after email field
///
function vnm_mc_after_email_field($field, $key, $args, $value) {
ob_start();
do_action('vnm_before_email_field');
echo $field;
do_action('vnm_after_email_field');
return ob_get_clean();
}
add_filter('woocommerce_form_field_email', 'vnm_mc_after_email_field', 10, 4);
Since a WordPress filter always has to return a version of the first parameter sent to it (in this case $field), all we do is open the output buffer, add our own actions for before and after the field (vnm_before_email_field, vnm_after_email_field), and then return the output buffer.
Then, in the MailChimp plugin settings under WooCommerce->MailChimp->Audience, just add the hook you've just created for your field:
...and done. Note you could in fact add action hooks around every WooCommerce checkout field if you wanted, just by adding the following (untested):
///
// Add `before` & `after` actions around every WooCommerce checkout field
///
function vnm_wc_form_field_actions($field, $key, $args, $value) {
ob_start();
do_action('vnm_before_' . $args['type'] . '_field');
echo $field;
do_action('vnm_after_' . $args['type'] . '_field');
return ob_get_clean();
}
add_filter('woocommerce_form_field', 'vnm_wc_form_field_actions', 10, 4);
I am trying to add the Bootstrap form-control to all input elements in WooCommerce. I did some searching on google and came up with the found code.
add_filter('woocommerce_checkout_fields', 'addBootstrapToCheckoutFields' );
function addBootstrapToCheckoutFields($fields) {
foreach ($fields as &$fieldset) {
foreach ($fieldset as &$field) {
// add form-control to the actual input
$field['input_class'][] = 'form-control';
}
}
return $fields;
}
The problem is that this code only does what I want for the fields on the checkout pages. Is there a simple way to use a filter to do this for all WooCommerce fields? Obviously, I could go through every file that has fields and place the code manually, but I'd like to avoid that.
Thanks!
I'm more or less a total newbie to php. My goal is to get the names of items from the logged in user's cart and dynamically populate a GravityForms template with the information. I've successfully managed to do that with the code below, but there are three things that I'm failing to do. 1: I only want to populate the form with all items of a certain variation. 2: the echo function will list all of the item names, but not inside the relevant field, and the return function will populate the field, but only with the first item name. 3: I'd like to have the output items listed with some form of separator in between each item name. Here's what I have so far:
<?php
add_filter( 'gform_field_value_beat_names', 'beat_names_function' );
function beat_names_function( $value ) {
global $woocommerce;
$items = $woocommerce->cart->get_cart();
foreach ($items as $item) {
$product_variation_id = $item['variation_id'];
$license_id = new WC_Product($product_variation_id);
$license_string = $license_id->get_formatted_name();
$beat_id = $item['data']->post;
$beat_name = $beat_id->post_title;
if (strpos($license_string, 'basic') !== false) {
echo $beat_name;
}
}
}?>
As you can see, I'm attempting to use strpos to isolate the particular item variation I want to target, using a certain word found in the name of the variation option, being "basic". I'm sure there's a more secure way of doing that, but it works for now. The problem lies with the return function I set up inside the conditional strpos statement, being that it will still just return the entire list of cart items, as opposed to only the items that I'm trying to isolate with the strpos conditional.
The ultimate goal is to create a license agreement that is dynamically populated with the relevant information, including the names of the items being licensed. The item variations are different license options that I have available for the products in my store. The purpose of the above code is to filter cart items by license type so that the wrong item names don't get listed on the wrong license agreement at checkout.
Any tips would be appreciated
Figured it out after some more tinkering. I broke it down step by step to help anyone as clueless as I am
add_filter( 'gform_field_value_basic_beat_names', 'basic_beat_names_function' );
function basic_beat_names_function( $value ) {
global $woocommerce;
$items = $woocommerce->cart->get_cart();
// the item names you want will be stored in this array
$license_check = array();
// Loop through cart items
foreach ($items as $item) {
// get the id number of each product variation in the cart. this won't work for "simple" products
$product_variation_id = $item['variation_id'];
// translate that id number into a string containing the name of the product, and the options applied to the product
$license_id = new WC_Product($product_variation_id);
$license_string = $license_id->get_formatted_name();
// check to see if the word "basic" is found anywhere in that string. "basic" is contained in the name of the product option being targeted
if (strpos($license_string, 'basic') !== false) {
// if the above condition is met, fetch the name of any products in the cart that have that option applied. The product name will be fetched from the title of the product's page
$beat_id = $item['data']->post;
$beat_name = $beat_id->post_title;
// store the retrieved product names in the $license_check array
$license_check [] = $beat_name;
}
}
// pull the stored product names from the $license_check array, and format them using implode and concatenation, then return the final result to the form field
return "\"" . implode("\", \"", $license_check) . "\"";
}
As a warning, the strpos method is a little hacky. It'll only work properly if your string is specific enough to target ONLY the option you're looking for.
As an example, here's the format for the product variation string being fed into the strpos function:
item-name-option-one-name-option-two-name – variation #xxx of item page title
So, if you want to filter items ONLY by option one, your safest bet would be to write the strpos function like so:
if (strpos($license_string, 'option-one-name') !== false) {
//do something
}
When all is said and done, the final result should look like: "item1", "item2", "item3", etc.
Then, to do the same with any other option, and output the result in a different field, or separate form altogether, I'll just duplicate this code, and replace any mention of the word "basic" with some different unique string contained in the other option. Don't forget to configure the gravity forms field as necessary too.
I'm using a str_replace to change the_content, using WordPress' default 'the_content'.
However, this does not seem to affect anything that has been submitted through the Advanced Custom Fields plugin.
My original function, that works with default WordPress editor:
function same_youtube_options($content) {
return str_replace("rel=0&", "rel0&theme=light&autohide=1&showinfo=0&controls=1&", $content);
}
add_filter('the_content', 'same_youtube_options');
And this, adjusted for the Advanced Custom Fields:
function same_youtube_options_controls_acf($field) {
$field = get_sub_field('iframe_url');
return str_replace("rel=0&", "rel0&&autohide=1&showinfo=0&controls=1&", $field);
}
add_filter('acf/load_field/name=iframe_url', 'same_youtube_options_controls_acf');
However, the latter does not work. It simply removes the field from the page. Would anyone know how to use these filters correctly?
Try this:--
function same_youtube_options_controls_acf($value, $post_id, $field )
{
// run the_content filter on all textarea values
$value = apply_filters('the_content',$value);
return $value;
}
add_filter('acf/load_value/name=iframe_url', 'same_youtube_options_controls_acf', 10, 3);
This hook will replace you custom field value with the_content filter.
Gravity Forms Product Add-ons for Woocommerce displays the form inputs of a user in the cart and checkout. I want to display these form fields in the user's Account page with their orders. I've been trying for a week and can't seem to get the right php code put together. How can I do this?
My code as it stands is like so:
$form_id = RGFormsModel::get_form_id('Domains');
$form = GFFormsModel::get_form_meta($form_id);
$field = GFFormsModel::get_field($form, 1);
$leads = RGFormsModel::get_leads($form['id']);
foreach($leads as $lead)
{
foreach($field as $field_id)
{
$value = rgar($lead, (string) $field_id);
echo $value;
}
}
This returns all entries for the field I want, however, I only want to return the entry that was submitted with that particular product. Help?
Here's a quick example for clarity on what I'm looking for. A user buys a shirt and selects size large from a Gravity Form that was attached to the product. On the cart and checkout pages, it says beneath the product title "Size: Large". I want to add that same text to the "My Account" page with their order.
The way I solved a similar problem may not be the best in coding practices but it works. It takes custom data associated with the order from Gravity Forms and displays it under the shipping address in WooCommerce individual order page:
<?php
add_action('woocommerce_admin_order_data_after_shipping_address', 'ips_show_signs_in_admin_under_shipping', 10, 1);
/*
function to put in functions.php of the theme to add custom gravityforms data to customer order page in admin area.
*/
function ips_show_signs_in_admin_under_shipping($order)
{
global $woocommerce, $post;
$order_items = $order->get_items(apply_filters('woocommerce_admin_order_item_types', array( 'line_item')));
foreach($order_items as $item_id => $item)
{
if ($metadata = $order->has_meta($item_id)) //not a comparison, so one equal sign. so if there is any data in there it would assign it and thus making it true, if no data it would be false
{
foreach($metadata as $meta)
{
// Skip hidden woocommerce core fields just in case
if (in_array($meta['meta_key'], apply_filters('woocommerce_hidden_order_itemmeta', array(
'_qty',
'_tax_class',
'_product_id',
'_variation_id',
'_line_subtotal',
'_line_subtotal_tax',
'_line_total',
'_line_tax',
)))) continue;
if (is_serialized($meta['meta_value'])) continue; // Skip serialised meta since we dont need it incase its in there
$meta['meta_key'] = esc_attr($meta['meta_key']); //just to make sure there is no surprises in there
$meta['meta_value'] = esc_textarea($meta['meta_value']); // using a textarea check for surprises (sql injection)
if ("Signpost Address" === $meta['meta_key']) //here comes the custom data from gravity forms
{
echo $meta['meta_value']; //this is what i was after from gravity forms collected with order
}
} //closes --- foreach($metadata as $meta)
} //closes --- if ($metadata = $order->has_meta($item_id))
} //closes --- foreach($order_items as $item_id => $item)
} //closes --- function
?>
Edit: This code searches the order meta data
I have added the above code in my functions.php file and unfortunately this hasn't worked for me. I have looked all over for a solution to this and this seems to exactly be what I'm after. Do i simply replace "Signpost Address" with say "Blanket Size" if that were one of my gravity form options?