I have been trying to create a custom validation hook for Gravity Forms plugin.
The validation checks that at least one field has been filled in from a set of fields.
Check out the code below, I just can't get it too work. I think it is something to do with the variables for the inputs, even if a field is filled in, the error still shows on each field?
add_filter( 'gform_field_validation_2', function ( $result, $value, $form, $field ) {
if ( $field->type == 'number') {
$a = rgar( $value, $field->id . '10' );
$b = rgar( $value, $field->id . '12' );
$c = rgar( $value, $field->id . '13' );
$d = rgar( $value, $field->id . '14' );
$e = rgar( $value, $field->id . '15' );
$f = rgar( $value, $field->id . '17' );
$g = rgar( $value, $field->id . '18' );
$h = rgar( $value, $field->id . '20' );
$i = rgar( $value, $field->id . '21' );
$j = rgar( $value, $field->id . '22' );
$k = rgar( $value, $field->id . '23' );
if ( !empty($a) || !empty($b) || !empty($c) || !empty($d) || !empty($e) || !empty($f) || !empty($g) || !empty($h) || !empty($i) || !empty($j) || !empty($k) ) {
$result['is_valid'] = true;
$result['message'] ='';
} else {
$result['is_valid'] = false;
$result['message'] = 'Please select a quantity of materials to order';
}
}
return $result;
}, 10, 4 );
I think you maybe should use a field of type "radio buttons".
Anyway, if your form has several "number" fields and you need to validate that at least one of them has been filled, then you should use the gform_validation filter since you're validating the whole form, not just a single field.
TIP: Add a custom css class to each field in the group to identify them. for example "validate-quantity".
add_filter('gform_validation_2', 'quantity_validation', 1, 4);
function quantity_validation($validation_result) {
if ($validation_result['is_valid']) {
$valid=false;
$form = $validation_result['form'];
foreach( $form['fields'] as &$field ) {
if ( strpos( $field->cssClass, 'validate-quantity' ) === false ) {
continue;
}
$field_value = rgpost( "input_{$field['id']}" );
if (!empty($field_value)) {
$valid=true;
break;
}
}
if (!$valid) {
$field["failed_validation"] = true;
$field["validation_message"] = 'Please select a quantity of materials to order';
$validation_result['form'] = $form;
}
}
return $validation_result;
}
So heres a working version (Thanks for the gform_validation hint Francisco R) - Went down a slightly different route, but works perfectly, incase anyone interested in future!
add_filter( 'gform_validation_2', 'custom_validation_2' );
function custom_validation_2( $validation_result ) {
// array of field IDs to be checked
$field_ids = array (10, 12, 13, 14, 15, 17, 18, 20, 21, 23, 22);
// get the form object from the validation result
$form = $validation_result['form'];
// counter to store how many fields have a value > 0 submitted
$number_of_fields = 0;
// loop through all the fields to be sure one has a value > 0
foreach ( $field_ids as $input ) {
// the rgpost string we are going to check
$input_id = 'input_' . intval( $input );
// the value that was submitted
$input_value = rgpost ( $input_id );
if ( $input_value > 0 ) {
// if any field in the array has a value, we can just continue
$number_of_fields++;
} // end if
else {
// no value for this input, so continue without incrementing the counter
continue;
} // end else
} // end foreach
// check the $number_of_fields and if it is 0 return a validation error
if ( $number_of_fields == 0 ){
// set the form validation to false
$validation_result['is_valid'] = false;
// mark all the fields with a validation error
foreach( $form['fields'] as &$field ) {
// add a validation error to *all* the inputs if none were submitted > 0
if ( in_array( $field->id, $field_ids ) ) {
$field->failed_validation = true;
$field->validation_message = 'Please select a quantity of materials to order from one or all of these fields.';
} // end if
} // end foreach
} // end if
// assign modified $form object back to the validation result
$validation_result['form'] = $form;
return $validation_result;
}
It looks you should change your if clause to:
if ( empty($a) || empty($b) || empty($c) || empty($d) || empty($e) || empty($f) || empty($g) || empty($h) || empty($i) || empty($j) || empty($k) ) {
to validate if at least one option is selected.
To skip not targeted fields add the following code before complex if above:
$target_fields = array('name_1', 'name_2');
if (!in_array($field, $target_fields)) {
$result['is_valid'] = true;
$result['message'] = '';
}
Related
I am trying to build a form where when a user enters their order ID and unique serial code in the elementor form their order status is changed to completed. Heres the code i have written but i keep getting an error. The form has 2 fields 'a' & 'b'. A= order id and B= serial code.
add_action( 'elementor_pro/forms/validation', function ( $record, $ajax_handler ) {
$fields = $record->get_field( [
'id' => 'b'
], ['cid' => 'a'
]);
if ( empty( $fields ) ) {
return;
}
$field = current( $fields );
if ( 1 !== strlen( $field['value'] ) < 13 ) {
$ajax_handler->add_error( $field['id'], 'Invalid Serial Code, Please enter the 13 Digit Code mentioned on your delivery letter' );
} else {
$output['result'] = get_post_meta( $field['cid'], $key = 'shp_tkn', $single = true );
}
if ($output == $field['id']){
$order = $field['cid'] ;
$order->update_status('completed');
} else {
$ajax_handler->add_error( $field['id'], 'Invalid Serial Code, Please try again' );
}
}, 10, 2 );
If anyone could tell me where I'm going wrong.
I am not that proficient at coding so please bear with me.
I have this custom add to cart code:
public static function add_to_cart( $params, $uid ) {
$data = self::get_calc_data($uid);
foreach ($data as $calc_id => $calc_data) {
$product_id = isset($calc_data['woo_info']['product_id']) ? $calc_data['woo_info']['product_id'] : null;
if ( $product_id && intval($product_id) === intval($params['woo_info']['product_id']) ) {
$meta = [
'product_id' => $product_id,
'item_name' => isset($calc_data['item_name']) ? $calc_data['item_name'] : '',
];
if(!empty($calc_data['descriptions']) && is_array($calc_data['descriptions'])) {
foreach ($calc_data['descriptions'] as $calc_item) {
if ( $calc_item['hidden'] === true ){
continue;
}
if ( strpos($calc_item['alias'], 'datePicker_field_id_') !== false ) {
$val = $calc_item['converted'] ? ' ('. $calc_item['converted'] . ') ' . $calc_item['value'] : $calc_item['value'];
}else{
$labels = isset($calc_item['extra']) ? $calc_item['extra']: '';
if ( (strpos($calc_item['alias'], 'radio_field_id_') !== false
|| strpos($calc_item['alias'], 'dropDown_field_id_') !== false)
&& key_exists('options', $calc_item) ) {
$labels = CCBWooCheckout::getLabels($calc_item['options']);
}
if ( strpos($calc_item['alias'], 'multi_range_field_id_') !== false
&& key_exists('options', $calc_item) && count($calc_item['options']) > 0 ) {
$labels = key_exists('label', $calc_item['options'][0]) ?
$calc_item['options'][0]['label']: '';
}
$val = isset($labels) ? $labels . ' ' . $calc_item['converted'] : $calc_item['converted'];
}
$meta['calc_data'][$calc_item['label']] = $val;
}
}
/** add totals data */
if( !empty($calc_data['ccb_total_and_label']) && is_array($calc_data['ccb_total_and_label']) ) {
$meta['ccb_total'] = $calc_data['ccb_total_and_label']['total'];
}
WC()->cart->add_to_cart($product_id, 1, '', array(), array('ccb_calculator' => $meta));
}
}
}
It adds simple item from a plugin into Woocommerce Cart. I am trying to add a unique ID for every added item so that I can add multiples of the same item and they would show as unique items in the cart.
I was trying to create the unique ID with
public static function add_custom_cart_item_data( $cart_item_data, $cart_item_key ) {
$cart_item_data[custom_data]['unique_key'] = md5( microtime().rand() );
return $cart_item_data;
}
and then use the $cart_item_data; changing the 'product_id' => $product_id, to 'product_id' => $cart_item_data, but sadly this doesn't seem to work. What am I doing wrong?
Really appreciate all your help!
How do I make the gravity form name field only accept letters, numbers should give an error.
You need to use gform_field_validation validation filter to be able to do this kind of validation before the form submits.
In addition, we need to use preg_match function of PHP with a regex to ensure we are only taking Letters from Full Name input value.
Just add this code in your active theme functions.php file: (Code tested and working)
add_filter( 'gform_field_validation', function ( $result, $value, $form, $field ) {
if ( $field->type == 'name' ) {
// Input values
$fullName = rgar( $value, $field->id . '.3' );
if ( empty( $fullName )) {
$result['is_valid'] = false;
$result['message'] = empty( $field->errorMessage ) ? __( 'This field is required. Please enter a complete name.', 'gravityforms' ) : $field->errorMessage;
} else if (preg_match('/[A-Za-z].*[0-9]|[0-9].*[A-Za-z]/', $fullName)) { //check for letters only
$result['is_valid'] = false;
$result['message'] = empty( $field->errorMessage ) ? __( 'Full name must ony contains letters.', 'gravityforms' ) : $field->errorMessage;
} else {
$result['is_valid'] = true;
$result['message'] = '';
}
}
return $result; //return results
}, 10, 4 );
I searched for a while and I tried several options but I didn't find any solution. So, i have the following string that gets the status of a costum field to export to other websites.
<category><![CDATA[<?php listingpress_listing_status(); ?>]]></category>
It outputs something like this:
<category><![CDATA[For sale]]></category>
And what i need is to turn this value into a number.
Ex:
For sale » 100
For Rent » 110
Sold » 120
This is the original function:
if ( ! function_exists( 'listingpress_listing_status' ) ) :
/**
* Prints listing status
*
* #since ListingPress 1.0
*
* #uses listingpress_get_listing_status() To get listing status
*/
function listingpress_listing_status() {
echo listingpress_get_listing_status( 'name' );
}
endif; // listingpress_listing_status
if ( ! function_exists( 'listingpress_get_listing_status' ) ) :
function listingpress_get_listing_status( $fields = 'name' ) {
global $meta_prefix, $post;
if ( of_get_option( 'enable_listing_status', true ) ) {
$status = get_post_meta( $post->ID, $meta_prefix . 'status', true );
if ( $status == 'sold' ) {
if ( $fields == 'name' )
return __( 'Sold', 'listingpress' );
elseif ( $fields == 'slug' )
return 'sold';
} elseif ( $status == 'for-sale' ) {
if ( $fields == 'name' )
return __( 'For sale', 'listingpress' );
elseif ( $fields == 'slug' )
return 'for-sale';
} elseif ( $status == 'for-rent' ) {
if ( $fields == 'name' )
return __( 'For rent', 'listingpress' );
elseif ( $fields == 'slug' )
return 'for-rent';
}
} else {
return 'no-status';
}
}
endif; // listingpress_get_listing_status
Could someone please help me with this?
Thank you in advance.
So basically you can do something as mentioned below:
<?php
$listing_status = '';
if(listingpress_listing_status() == 'For sale') {
$listing_status = 100;
} elseif(listingpress_listing_status() == 'For rent') {
$listing_status = 110;
} elseif(listingpress_listing_status() == 'For rent') {
$listing_status = 120;
} else {
$listing_status = listingpress_listing_status();
}
?>
<category><![CDATA[<?php echo $listing_status; ?>]]></category>
A word of advice, share the problem directly with code from the beginning so that you can get help quicker.
I'm trying to get the $pi1 and $pi2 variable values inside of the add_custom_price function, but nothing seems to be working.
I have looked at setting variables to be accessible from function classes but I'm not sure I understand how to access them correctly.
add_filter( 'gform_confirmation', array(gravity_pi,custom_confirmation), 10, 4 );
class gravity_pi {
public $pi1;
public $pi2;
public function custom_confirmation( $confirmation, $form, $entry, $ajax, $product_id, $pi1, $pi2 ) {
if( $form['id'] == '2' ) {
$post = get_post( $entry['post_id'] );
$this->pi1 = rgar( $entry, '20' );
$this->pi2 = rgar( $entry, '21' );
$exclude_list = array("pi24","pi64","pi65","pi66","pi67","pi68","pi69","pi70","pi71","pi72","pi73","pi74","pi75","pi76","pi77","pi78","pi79","pi80","pi81","pi82");
if(!in_array($this->pi1, $exclude_list) && !empty($this->pi1)){
$target_product_id = '86';
$pid1 = '86';
}else{
$pid1 = preg_replace("/[^0-9,.]/", "", $this->pi1 );
}
if(!in_array($pi2, $exclude_list) && !empty($this->pi2)){
$target_product_id = '87';
$pid2 = '87';
}else{
$pid2 = preg_replace("/[^0-9,.]/", "", $this->pi2);
}
$product_ids = ''.$pid1.','.$pid2.'';
$url = 'https://*****.com/cart/?add-to-cart='.$product_ids.'';
$confirmation = array( 'redirect' => $url );
}
return $confirmation;
}
public function add_custom_price( $cart_object, $entry,$form, $field, $input_id ) {
foreach ( $cart_object->cart_contents as $key => $value ) {
if( 86 == $value['data']->id ) {
$value['data']->set_price( $this->pi1 );
}
if( 87 == $value['data']->id ) {
$value['data']->set_price( $this->pi2 );
}
}
}
}
add_action( 'woocommerce_before_calculate_totals', array(gravity_pi,add_custom_price));
You need to use $this to get/set any property in the class.
// set pi1 property value
$this->pi1 = 10;
//print/get property value
echo $this->pi1;
When you're setting the class properties (pi1 & pi2) you need to reference them in the same way you access them. Ex.
<?php
...
$this->pi1 = rgar($entry, '20');
Change all references (except where you declare them) of $pid1 to $this->pid1. Do this for $pid2 too.
Check this video out - https://www.youtube.com/watch?v=4c4nP7GLL1c