I'm using the ACF tutorial here to build from.
What I'd like to do is use the values in a text sub-field to populate other select sub-fields within the same repeater field. I know it sounds recursive and maybe that's prohibitive. The field admin will not be to ajax-y or update on the fly, it's more of an admin field for other site functionality.
Anyway, here's what I have so far.
ACF Repeater field = core_values
Page the field is on = valuesadmin
Source text sub-field within core_values = value_name
Target sub-fields (
each needing dynamically propagated selects from value_name) =
constructor1_name
constructor2_name
constructor3_name
destructor1_name
destructor2_name
I've tried to modify the code at the tutorial linked above and put it in the theme's functions.php and in the main file of a plugin I'm building other custom functions.
/**
* ACF population functions
*/
function acf_load_core_values_field_choices( $field ) {
// reset choices
$field['choices'] = array();
// if has rows
if( have_rows('core_values', 'valuesadmin') ) {
// while has rows
while( have_rows('core_values', 'valuesadmin') ) {
// instantiate row
the_row();
// vars
$value = get_sub_field('value_name');
$label = get_sub_field('value_name');
// append to choices
$field['constructor1_name'][ $value ] = $label;
$field['constructor2_name'][ $value ] = $label;
$field['constructor3_name'][ $value ] = $label;
$field['destructor1_name'][ $value ] = $label;
$field['destructor2_name'][ $value ] = $label;
}
}
// return the field
return $field;
}
add_filter('acf/load_field/name=constructor1_name', 'acf_load_core_values_field_choices');
add_filter('acf/load_field/name=constructor2_name', 'acf_load_core_values_field_choices');
add_filter('acf/load_field/name=constructor3_name', 'acf_load_core_values_field_choices');
add_filter('acf/load_field/name=destructor1_name', 'acf_load_core_values_field_choices');
add_filter('acf/load_field/name=destructor2_name', 'acf_load_core_values_field_choices');
Obviously this isn't propagating the select sub-fields as I'd like.
Questions:
- Is this even possible ( the value_name fields are all filled with values already )
- Where should the function code go?
- Maybe I've mangled the code somehow
Thanks in advance!
Well, I achieved the functionality I was looking for by first moving this all to an ACF options page and then creating another ACF field ( values_master) with which I could populate the values dynamically in a second field on the options page. So I'm not sure if this was not working because of some recursively but it IS working.
function acf_load_value_field_choices( $field ) {
// reset choices
$field['choices'] = array();
// if has rows
if( have_rows('values_master', 'option') ) {
// while has rows
while( have_rows('values_master', 'option') ) {
// instantiate row
the_row();
// vars
$value = get_sub_field('value_name');
$label = get_sub_field('value_name');
// append to choices
$field['choices'][ $value ] = $label;
}
}
// return the field
return $field;
}
add_filter('acf/load_field/name=constructor1_name', 'acf_load_value_field_choices');
add_filter('acf/load_field/name=constructor2_name', 'acf_load_value_field_choices');
add_filter('acf/load_field/name=constructor3_name', 'acf_load_value_field_choices');
add_filter('acf/load_field/name=destructor1_name', 'acf_load_value_field_choices');
add_filter('acf/load_field/name=destructor2_name', 'acf_load_value_field_choices');
add_filter('acf/load_field/name=value_mstr_name', 'acf_load_value_field_choices');
Related
I have this code where I need to insert a value based on a condition in: **///////// HERE THE MY CODE /////////**
Here I have overridden single-product/add-to-cart/variation.php Woocommerce template file via my active theme:
<script type="text/template" id="tmpl-variation-template">
<div class="woocommerce-variation-description">
{{{ data.variation.variation_description }}}
</div>
<div class="woocommerce-variation-price">
{{{ data.variation.price_html }}}
</div>
<div class="woocommerce-variation-custom_field">
{{{ data.variation.custom_field}}}
///////// HERE MY CODE /////////
</div>
<div class="woocommerce-variation-availability">
{{{ data.variation.availability_html }}}
</div>
</script>
The condition should check the value of the variable `{{{ data.variation.custom_field}}}` and if this data is greater than 10 then the code should print "Yes".
**Something like**:
if( $data.variation.custom_field > 10 ){
echo "yes";
}
But it's not working. I guess, this should be done using Javascript instead of php but I don't know how grab the variable value.
There is no need to use additional javascript (or jQuery) code for that.
The following will handle a product variation custom field displaying "YES" if the custom field value is bigger than 10 (otherwise nothing).
You will need to replace your exiting hooked function that use woocommerce_available_variation hook, with one of the following ways.
There are mainly 2 ways:
1). The simplest way, without overriding variation.php template:
// Frontend: Handle Conditional display and include custom field value on product variation
add_filter( 'woocommerce_available_variation', 'variation_data_custom_field_conditional_display', 10, 3 );
function variation_data_custom_field_conditional_display( $data, $product, $variation ) {
// Get custom field value and set it in the variation data array (not for display)
$data['custom_field'] = $variation->get_meta('custom_field');
// Defined custom field conditional display
$displayed_value = $data['custom_field'] > 10 ? 'YES' : '';
// Frontend variation: Display value below formatted price
$data['price_html'] .= '</div>' . $displayed_value . '
<div class="woocommerce-variation-custom_field_html">';
return $data;
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
2). Another simple way (overriding variation.php template):
// Frontend: Handle Conditional display and include custom field value on product variation
add_filter( 'woocommerce_available_variation', 'variation_data_custom_field_conditional_display', 10, 3 );
function variation_data_custom_field_conditional_display( $data, $product, $variation ) {
// Get custom field value and set it in the variation data array (not for display)
$data['custom_field'] = $variation->get_meta('custom_field');
// Frontend display: Define custom field conditional display
$data['custom_field_html'] = $data['custom_field'] > 10 ? "YES" : "";
return $data;
}
Code goes in functions.php file of the active child theme (or active theme).
Then in your custom template single-product/add-to-cart/variation.php you will replace:
{{{ data.variation.custom_field}}}
with:
{{{ data.variation.custom_field_html }}}
It will work nicely without any additional requirements.
Here is a complete code example for the community, based on the 2nd Way:
1). Admin variations: Display a custom field and save it's value
// Admin: Add a custom field in product variations options pricing
add_action( 'woocommerce_variation_options_pricing', 'add_admin_variation_custom_field', 10, 3 );
function add_admin_variation_custom_field( $loop, $variation_data, $variation ){
woocommerce_wp_text_input( array(
'id' => 'custom_field['.$loop.']',
'label' => __('Custom Field', 'woocommerce' ),
'placeholder' => __('Enter Custom Field value here', 'woocommerce' ),
'desc_tip' => true,
'description' => __('This field is for … (explanation / description).', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, 'custom_field', true )
) );
}
// Admin: Save custom field value from product variations options pricing
add_action( 'woocommerce_save_product_variation', 'save_admin_variation_custom_field', 10, 2 );
function save_admin_variation_custom_field( $variation_id, $i ){
if( isset($_POST['custom_field'][$i]) ){
update_post_meta( $variation_id, 'custom_field', sanitize_text_field($_POST['custom_field'][$i]) );
}
}
Code goes in functions.php file of the active child theme (or active theme).
2). Frontend variations: Conditional display based on selected variation and custom field value
// Frontend: Handle Conditional display and include custom field value on product variation
add_filter( 'woocommerce_available_variation', 'variation_data_custom_field_conditional_display', 10, 3 );
function variation_data_custom_field_conditional_display( $data, $product, $variation ) {
// Get custom field value and set it in the variation data array (not for display)
$data['custom_field'] = $variation->get_meta('custom_field');
// Frontend display: Define custom field conditional display
$data['custom_field_html'] = $data['custom_field'] > 10 ? __("YES", "woocommerce") : "";
return $data;
}
Code goes in functions.php file of the active child theme (or active theme).
3). Template override: single-product/add-to-cart/variation.php file to your active theme's:
<?php
/**
* Single variation display
*
* This is a javascript-based template for single variations (see https://codex.wordpress.org/Javascript_Reference/wp.template).
* The values will be dynamically replaced after selecting attributes.
*
* #see https://docs.woocommerce.com/document/template-structure/
* #package WooCommerce/Templates
* #version 2.5.0
*/
defined( 'ABSPATH' ) || exit;
?>
<script type="text/template" id="tmpl-variation-template">
<div class="woocommerce-variation-description">{{{ data.variation.variation_description }}}</div>
<div class="woocommerce-variation-price">{{{ data.variation.price_html }}}</div>
<div class="woocommerce-variation-custom_field">{{{ data.variation.custom_field_html}}}</div>
<div class="woocommerce-variation-availability">{{{ data.variation.availability_html }}}</div>
</script>
<script type="text/template" id="tmpl-unavailable-variation-template">
<p><?php esc_html_e( 'Sorry, this product is unavailable. Please choose a different combination.', 'woocommerce' ); ?></p>
</script>
Tested and works.
Related: WooCommerce: Add/display Product or Variation custom field everywhere
Based on https://codex.wordpress.org/Javascript_Reference/wp.template and similar template engine like https://github.com/blueimp/JavaScript-Templates#evaluation, you need to build a template with evaluation.
In your case, it should be something like:
<div class="woocommerce-variation-custom_field">
<# if (data.variation.custom_field > 10) { #>
yes
<# } #>
</div>
Also, here https://lkwdwrd.com/wp-template-js-templates-wp you can find an example with if statement itself.
In the ecommerce store:
There are items displayed on Homepage and each of the items have an "Add to Cart" button underneath them. When this button is clicked, the item is added to cart. If this button is clicked again, the Quantity of the item that is already existing in cart, is incremented by 1. I believe this is the loop. So far, so good.
On the Single Product page, there is an "Add to Cart" button. When this button is clicked, the item gets added to cart. There is a Quantity input textbox as well that can be used to change the quantity. This is fine too.
THE ISSUE:
I need to differentiate between the "Add to Cart" button that was clicked within the loop (currently on Homepage, but can also be used on other pages such as Archive page, etc.) vs the "Add to Cart" button that was clicked on the Single Product page. Based on this differentiation, here is what I need to do:
If the "Add to Cart" button appearing within the loop was clicked, grab the Quantity of this item that is already existing in cart using the $cart_item_key, increment it by 1 and send this to a custom function that will do additional processing and save the details to cart again.
If the "Add to Cart" button appearing in the Single Product page was clicked, grab the Quantity of this item that is already existing in cart using the $cart_item_key, multiply it by 3 and send this to a custom function that will do additional processing and save the details to cart again.
In both the above cases, the Quantity is being changed, based on different logics and this Quantity needs to be sent to a custom function call.
WHAT I TRIED:
I tried the following code:
add_action('woocommerce_add_to_cart', 'custom_action_add_to_cart', 20, 6);
function custom_action_add_to_cart($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data)
{
$cart = WC()->cart->get_cart();
$product = wc_get_product($product_id);
// NEED TO RUN CUSTOM CODE HERE BASED ON THE CHECKS
if (add to cart within loop is clicked) {
// Get existing $quantity_from_cart from cart using $cart_item_key, but how????
$new_quantity = $quantity_from_cart + 1;
}
else if (add to cart on single product page is clicked) {
// Get existing $quantity_from_cart from cart using $cart_item_key, but how????
$new_quantity = $quantity_from_cart * 3;
}
// Need to send the $new_quantity along with the $cart_item_key to the custom function so that the data can be saved using $cart_item_key
my_custom_function($new_quantity, $cart_item_key);
}
function my_custom_function($new_quantity, $cart_item_key)
{
echo $new_quantity;
WC()->cart->cart_contents[$cart_item_key]['custom_quantity'] = $new_quantity;
WC()->cart->set_session();
}
The issue with the above code is that it if I don't have the if... else if... logic, then the code is executed regardless of where the "Add to Cart" button is located. In other words, whether I click the "Add to Cart" button that is located in the loop (Homepage, Archive page or any page that uses the loop) or I click the "Add to Cart" button located in the Single Product page, the above code gets executed in the absence of the if... else if... logic.
So, I want to run separate code when the "Add to Cart" button that is located in the loop is clicked (regardless of its location, whether Homepage, Archives, etc.) and run different code when the "Add to Cart" button that is located on the Single Product page is clicked. How can I achieve this?
Expecting something like this:
If button appearing inside the loop is clicked -> Do this.
If button appearing in Single Product page is clicked -> Do that.
you can use wp_get_referer or check_ajax_referer() for example:
function custom_action_add_to_cart($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data)
{
$cart = WC()->cart->get_cart();
$product = wc_get_product($product_id);
$referer = wp_get_referer();
// HOMEPAGE
if (strpos($referer ,'http://yourwebsite.com/') !== false) {
$new_quantity = $quantity_from_cart + 1;
}
//from some product page like http://yourwebsite.com/product/my-product-page
else if (strpos($referer ,'http://yourwebsite.com/product/') !== false) {
$new_quantity = $quantity_from_cart * 3;
}
// Need to send the $new_quantity along with the $cart_item_key to the custom function so that the data can be saved using $cart_item_key
my_custom_function($new_quantity, $cart_item_key);
}
Please refer: Wordpress Nonces related functions
You can try this way:
add_action('woocommerce_add_to_cart', 'custom_action_add_to_cart', 20, 6);
function custom_action_add_to_cart($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data) {
$cart = WC()->cart->get_cart();
$product = wc_get_product($product_id);
$referer = $_SERVER['HTTP_REFERER'];
$route = parse_url( $referer );
$path = $route['path'] ?? 'home' ;
$args = array_filter( ( explode('/', $path) ) );
if (in_array( 'product', $args) ) {
// Product Page
} elseif (in_array('product-category', $args)) {
// Product Category
} else {
// Default
}
}
But you need check your settings. Settings > Permalinks.
you can use is_product(),is_product_category() function
function custom_action_add_to_cart($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data)
{
$cart = WC()->cart->get_cart();
$product = wc_get_product($product_id);
if ( is_product() ) {
global $product;
$id = $product->get_id();
foreach ( WC()->cart->get_cart() as $cart_item ) {
if($cart_item['product_id'] == $id ){
$quantity_from_cart = $cart_item['quantity'];
break; // stop the loop if product is found
}
}
$new_quantity = $quantity_from_cart * 3;
}
else if (is_product_category()) {
$new_quantity = $quantity_from_cart + 1;
}
my_custom_function($new_quantity, $cart_item_key);
}
There are couple solutions I could think of. But here's one:
add_action( 'woocommerce_after_add_to_cart_button', 'rmg_woocommerce_after_add_to_cart_button' );
function rmg_woocommerce_after_add_to_cart_button() {
$button_location = 0;
// if (is_home() || is_front_page()) {
// // we're at the home page
// $button_location = 1;
// }
if (is_product()) {
// where at product page
$button_location = 2;
} else {
// pages other than product page
$button_location = 1;
}
echo '<input type="hidden" name="button-location" value="'. $button_location .'" />';
}
We could add an hidden input inside the form, that above code does it.
Then could check it's value like:
$button_location = $_REQUEST['button-location'];
if ($button_location && $button_location === 2) {
// add to cart button clicked at or came from product page..
$new_quantity = $quantity_from_cart + 1;
}
Please note that this is just an idea and not a complete solution... You need to take care of the ajax button.
On my magento product page I need to add a dynamic JavaScript array base on display upselling products on the product page. The goal is to change the images of the upselling products when the user change the color of the main product.
To achieve my goal I need a custom JavaScript array on every product page that give me information about crossselling product and the associated product image.
What is the best way to do this?
I try this
add a observer event in my config.xml
<controller_action_layout_load_before>
<observers>
<crossselling_product_view>
<type>singleton</type>
<class>XXXXXXXX_Crossselling_Model_Observer</class>
<method>productview</method>
</crossselling_product_view>
</observers>
</controller_action_layout_load_before>
add observer to add specific JS Code
<?php
class XXXXXXXX_Crossselling_Model_Observer {
public function productview(Varien_Event_Observer $observer) {
$product = Mage::registry('current_product');
//only on product page
if (!($product instanceof Mage_Catalog_Model_Product)) {
return;
}
$controller = $observer->getAction();
$layout = $controller->getLayout();
$block = $layout->createBlock('core/text');
$block->setText(
'<script type="text/javascript">
function main_pulsestorm_hellojavascript()
{
alert("Foo");
}
main_pulsestorm_hellojavascript();
</script>'
);
$layout->getBlock('head')->append($block);
}
}
My error:
Fatal error: Call to a member function append() on a non-object
What is my problem and is it the right way to add dynamic js code?
I would probably approach this from a different angle. Since you are only interested in interacting with data and output for the upsell block, you could change the behavior of just that block by observing its output and appending your extra JavaScript. For the purposes of brevity this answer assumes that you understand the basics of Magento extensions.
Observe the core_block_abstract_to_html_after event:
etc/config.xml
<core_block_abstract_to_html_after>
<observers>
<addCustomUpsellFormat>
<class>XXXXXXXX_Crossselling_Model_Observer</class>
<method>addCustomUpsellFormat</method>
</addCustomUpsellFormat>
</observers>
</core_block_abstract_to_html_after>
Act upon instances of Mage_Catalog_Block_Product_List_Upsell by appending the output of a new block that will read their data:
Model/Observer.php
public function addCustomUpsellFormat(Varien_Event_Observer $observer)
{
/* #var Mage_Core_Block_Abstract $block */
$block = $observer->getBlock();
if ($block instanceof Mage_Catalog_Block_Product_List_Upsell) {
/* #var Varien_Object $transport */
$transport = $observer->getTransport();
// Receive the standard output for the block.
$output = $transport->getHtml();
/* #var Mage_Core_Model_Layout $layout */
$layout = $block->getLayout();
$json = $layout->createBlock('core/template')
->setTemplate('catalog/product/list/upsell_json.phtml')
->setItems($block->getItems())
->toHtml();
// Append new JSON data to block output.
$transport->setHtml($output . $json);
}
return $this;
}
Create a template that interprets the upsell data and outputs it in your desired way, in my example above I created a template that could do something like this (my example creates a new template, so it should go into the base theme):
app/design/frontend/base/default/template/catalog/product/list/upsell_json.phtml
<?php
$_json = array(); // Add data in here to convert to JSON for output.
$_items = $this->getItems();
/* #var Mage_Catalog_Model_Product $_product */
foreach ($_items as $_product) {
$_json[$_product->getId()] = array(
'image' => (string)Mage::helper('catalog/image')->init($_product, 'image')
);
}
?>
<script type="text/javascript">var upsellData = <?php echo json_encode($_json) ?>;</script>
Use
$controller = $observer->getEvent()->getAction();
instead of
$controller = $observer->getAction();
I am new to CakePHP. I need to make a form with radio buttons and the last one is "other" where the user can type in an answer in a text box.
Is there any way FormHelper can do this that's built in?
One way I was going to do was create a radio list and a text field. When "other" is selected Javascript will show the text field. For this I don't understand how to use any other variables besides the fields in the database. How does one create a variable from a model that can be accessed from a view and the value returned for processing?
For the model I have:
class User extends AppModel {
/**
* Display field
*
* #var string
*/
public $displayField = 'title';
var $sourceOther = ' ';
var $passwordRepeat = ' ';
public function beforeSave($options = array()) {
if (isset($this->data[$this->alias]['password'])) {
$this->data[$this->alias]['password'] = sha1(
$this->data[$this->alias]['password']);
}
// $this->data[$this->alias]['created']= CakeTime::gmt();
// $this->data[$this->alias]['updated']= CakeTime::gmt();
$this->data[$this->alias]['username']= $this->data[$this->alias]['email'];
return true;
In the view I have
echo $this->Form->input('mobilePhone',array(
'label'=>'Mobile or fixed phone with no spaces'));
echo $this->Form->input('alternatePhone');
echo $this->Form->input('leadSource', array(
'options'=>array('Google'=>'Google','OnlineAd'=>'Online Ad',
'Printed Media'=>'Printed Media','LetterDrop'=>'Letter Drop',
'Other'=>'Other (specify text)'),
'empty'=>'(choose one)'));
echo $this->Form->input($this->sourceOther);
...but it doesn't like sourceOther, the variable in the model. How do I get data from the view (the text box) into the user model so beforeSave can do something with it?
Thanks.
Thanks.
Sorted it out after reading "Cake PHP Application Development". It works for Cake 2.x and 1.2 (as used in the book).
In your view put:
echo $this->Form->input('sourceOther');
Then in the model you can access your variable with:
$this->data['User']['sourceOther'];
For example, use it to save "other" text field in beforesave:
public function beforeSave($options = array()) {
if (isset($this->data[$this->alias]['password'])) {
$this->data[$this->alias]['password'] = sha1(
$this->data[$this->alias]['password']);
}
$this->data[$this->alias]['username'] = $this->data[$this->alias]['email'];
$this->data[$this->alias]['activation'] = md5(uniqid(rand(), true));
if ($this->data[$this->alias]['leadSource'] == 'Other') {
$this->data[$this->alias]['leadSource'] =
$this->data['User']['sourceOther'];
}
return true;
}
I am writing a code to use onchange in my application this is my code so far
.Phtml
<script type="text/javascript">
function submit()
{
$id = intval($_GET['id']);
$satellite = intval($_GET['satellite_id']);
if ($id == 0)
{
echo "Please select a Region";
}
else
{
$query = "select * from satellites where region_id = '".$id."'";
$query = mysql_query($query);
echo "<select name='satellite_id'><option value=''>-- select one --</option>";
while ($row = mysql_fetch_assoc($query))
{
echo "<option value='".$row['satellite_id']."'".($row['satellite_id']==$satellite?" selected":"").">".$row['satellite_name']."</option>";
}
echo "</select>";
//DisplayFormRow ("Satellite", FormDropDownBox ("satellite_id", $SatelliteARY, $Result['satellite_id']));
}
}
</script
//zend code Form
$region_name = new Zend_Form_Element_Select('region_name');
$region_name->setAttribs(array('style' => 'width: 150px;'));
$region_name ->setLabel('Region')
->onchange('this.form.submit();') //tried this code ->onchange('javascript:submit();')
->addMultiOption('--Select One--', '--Select One--');
$mdlRegions = new Model_Regions();
$regions = $mdlRegions->getRegions();
foreach ($regions as $region)
{
$region_name->addMultiOption($region->region_id, $region->region_name, $region->region_short_name);
}
//model
<?php
class Model_Regions extends Zend_Db_Table_Abstract
{
protected $_name = 'regions';
//protected $_name = 'smmedetails';
public function getregion($region_id)
{
$region_id = (int)$region_id;
$row = $this->fetchRow('region_id = ' . $region_id);
if (!$row) {
throw new Exception("Could not find row $region_id");
}
return $row->toArray();
}
public function smmedetails2region($region_name)
{
$data = array(
'region_name'=> $region_name
);
return $this->insert($data);
}
public function getRegions()
{
$select = $this->select();
return $this->fetchAll($select);
}
}
//controller
public function registerAction()
{
$this->view->headScript()->appendFile('/js/ui/jquery.ui.autocomplete.js');
$form = new Form_SmmeDetails();
$this->view->form = $form;
if ($this->getRequest()->isPost()) {
$formData = $this->getRequest()->getPost();
if ($form->isValid($formData)) {
$companyname = $form->getValue('companyname');
$companytradingname = $form->getValue('companytradingname');
$region_name = $form->getValue('region_name');
$satellite_name = $form->getValue('satellite_name');
$city = $form->getValue('city');
$companyaddress = $form->getValue('companyaddress');
$addresscode = $form->getValue('addresscode');
$companypostaladdress = $form->getValue('companypostaladdress');
$postalcode = $form->getValue('postalcode');
$companyphonenumber = $form->getValue('companyphonenumber');
$companyfaxnumber = $form->getValue('companyfaxnumber');
$companycellnumber = $form->getValue('companycellnumber');
$businessemailaddress = $form->getValue('businessemailaddress');
$businesswebsite = $form->getValue('businesswebsite');
$smmedetails = new Application_Model_DbTable_SmmeDetails();
$smmeid = $smmedetails ->smmedetailsSmmeDetails($companyname, $companytradingname, $region_name, $satellite_name, $city, $companyaddress, $addresscode, $companypostaladdress, $postalcode, $companyphonenumber, $companyfaxnumber,
$companycellnumber, $businessemailaddress, $businesswebsite);
// $region = new Application_Model_DbTable_Region();
//$region ->smmedetails2region($formData, $smmedetails->smmeid);
$this->_redirect('/admin/smme/register2/smmeid/'.$smmeid);
} else {
$form->populate($formData);
}
}
}
The code is suppose to view a hidden input select, called satellite when you select a feild option from regions, the satellite should view certain options based on the region selected. In short the region selected should correspond with what the user selected. eg Province is Gauteng, so cites would be, Johannseburg,Pretoria etc. Take note the region and satellite options are called from the database table according to they names and id. The code above keeps giving me and error Message: Method onchange does not exist. Was told not to use onchange method should I be using ajax and can I use javascript and sqlquery in the view or should I call it as an action? If so how? Here is a slight picture example.
Please be of help
Thanks in advance
I'd make a few suggestions to what you have there.
Firstly, for simplicity, I'd not use the onChange function, because I don't see it in the API, plus JavaScript or jQuery written in that way can become difficult to maintain and write properly. It is a lot simpler to instead include an external JavaScript file. By doing this, you can also test and debug the JavaScript separately, as well as reuse it.
Have a look at the excellent document for onChange, and getJson. I've used these and others and they're quite straight-forward. For testing, I recommend QUnit for starters. It makes testing a breeze.
Secondly, if you're using the Zend libraries for Model_Regions and $region_name, then I'd suggest using them instead of the direct mysql calls as well. This will allow you to build a good library which you can continue to expand as needed, plus it makes composing SQL quicker and safer.
For the controller, I'd suggest a RestController with a Restful Route. Here's an excellent tutorial.
I hope this helps you out with the problem. If you need anything more, let me know.
Thanks for emailing me about this.
The way I go about this is as follows:
Firstly I set up the form, and then an action in a controller.
Lets say getmajorgroupAction()
which in that action I would then disable layout, and just get the relevent results based on the id.
Then in the view file, loop through the
so the output from that call would be
<option value="1">1</option>
<option value="2">2</option>
etc
Personally I use jquery now, whereas the post you referenced when you emailed me, I was using another method.
trying to use something like this
jQuery(document).ready(function() {
jQuery("#division").change(function () {var division = jQuery("#division").val();
jQuery("#major_group").load("/module/getmajorgroup/", {division_id: division} );});
});
Hope that makes sense.
Thanks that was useful but i found a way to do it using this formula below, but everytime I click on the first select the while still in the session the second select appears all the time, eg if a person choose the wrong selection and re tried it brings up another field instead of fixing the field. I think its in a countinous loop . heres my script
<script type="text/javascript">
$(document).ready(function() {
$("#region_name").on('change', function () {
ajaxAddField();
}
);
}
);
// Retrieve new element's html from controller
function ajaxAddField()
{
$.ajax(
{
type: "POST",
url: '<?php echo $this->baseURL()?>/admin/ajax/get-cities/city/' + encodeURIComponent($('#region_name').val()),
success: function(newElement) {
// Insert new element before the Add button
//$(this).prev().remove().end().before('#city-label');
$("#city-label").before(newElement);
}
}
);
}
</script>