Version Notes
Initial release
Download this release
Release Info
Developer | RocketWeb |
Extension | RocketWeb_CustomOptionValidator |
Version | 1.0.0 |
Comparing to | |
See all releases |
Version 1.0.0
- app/code/community/RocketWeb/All/Helper/Data.php +4 -0
- app/code/community/RocketWeb/All/Model/Feed.php +19 -0
- app/code/community/RocketWeb/All/Model/Observer.php +12 -0
- app/code/community/RocketWeb/All/etc/adminhtml.xml +23 -0
- app/code/community/RocketWeb/All/etc/config.xml +40 -0
- app/code/community/RocketWeb/All/etc/system.xml +42 -0
- app/code/community/RocketWeb/CustomOptionValidator/Block/Adminhtml/Validators.php +19 -0
- app/code/community/RocketWeb/CustomOptionValidator/Block/Rewrite/Adminhtml/Catalog/Product/Edit/Tab/Options/Option.php +23 -0
- app/code/community/RocketWeb/CustomOptionValidator/Helper/Data.php +4 -0
- app/code/community/RocketWeb/CustomOptionValidator/Model/Validator.php +6 -0
- app/code/community/RocketWeb/CustomOptionValidator/Model/Validator/List.php +6 -0
- app/code/community/RocketWeb/CustomOptionValidator/Model/Validator/Type.php +263 -0
- app/code/community/RocketWeb/CustomOptionValidator/etc/config.xml +49 -0
- app/code/community/RocketWeb/CustomOptionValidator/sql/rocketweb_cov_setup/mysql4-install-1.0.0.php +9 -0
- app/design/adminhtml/default/default/layout/rocketweb_cov.xml +19 -0
- app/design/adminhtml/default/default/template/catalog/product/edit/options/option.phtml +367 -0
- app/design/adminhtml/default/default/template/rocketweb_cov/adminhtml/validators.phtml +5 -0
- app/design/frontend/base/default/template/catalog/product/view/options/type/text.phtml +41 -0
- app/etc/modules/RocketWeb_All.xml +9 -0
- app/etc/modules/RocketWeb_CustomOptionValidator.xml +9 -0
- js/rocketweb/adminhtml/custom_option_validation.js +323 -0
- package.xml +18 -0
- skin/adminhtml/default/default/rocketweb/adminhtml/custom_option_validation.css +17 -0
app/code/community/RocketWeb/All/Helper/Data.php
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class RocketWeb_All_Helper_Data extends Mage_Core_Helper_Data {
|
3 |
+
|
4 |
+
}
|
app/code/community/RocketWeb/All/Model/Feed.php
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class RocketWeb_All_Model_Feed extends Mage_AdminNotification_Model_Feed {
|
3 |
+
public function getFeedUrl() {
|
4 |
+
$url = (Mage::getStoreConfigFlag(self::XML_USE_HTTPS_PATH) ? 'https://':'http://').'www.rocketweb.com/media/rss-notification.xml';
|
5 |
+
return $url;
|
6 |
+
}
|
7 |
+
|
8 |
+
|
9 |
+
public function getLastUpdate()
|
10 |
+
{
|
11 |
+
return Mage::app()->loadCache('rocketweb_notifications_lastcheck');
|
12 |
+
}
|
13 |
+
|
14 |
+
public function setLastUpdate()
|
15 |
+
{
|
16 |
+
Mage::app()->saveCache(time(), 'rocketweb_notifications_lastcheck');
|
17 |
+
return $this;
|
18 |
+
}
|
19 |
+
}
|
app/code/community/RocketWeb/All/Model/Observer.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class RocketWeb_All_Model_Observer {
|
3 |
+
public function updateNotifications($observer) {
|
4 |
+
if (Mage::getStoreConfig('rocketweb_all/general/enable_notifications')) {
|
5 |
+
try {
|
6 |
+
Mage::getModel('rocketweb_all/feed')->checkUpdate();
|
7 |
+
} catch (Exception $e) {
|
8 |
+
//silently ignore
|
9 |
+
}
|
10 |
+
}
|
11 |
+
}
|
12 |
+
}
|
app/code/community/RocketWeb/All/etc/adminhtml.xml
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<acl>
|
4 |
+
<resources>
|
5 |
+
<admin>
|
6 |
+
<children>
|
7 |
+
<system>
|
8 |
+
<children>
|
9 |
+
<config>
|
10 |
+
<children>
|
11 |
+
<rocketweb_all translate="title" module="rocketweb_all">
|
12 |
+
<title>RocketWeb All</title>
|
13 |
+
<sort_order>1006000</sort_order>
|
14 |
+
</rocketweb_all>
|
15 |
+
</children>
|
16 |
+
</config>
|
17 |
+
</children>
|
18 |
+
</system>
|
19 |
+
</children>
|
20 |
+
</admin>
|
21 |
+
</resources>
|
22 |
+
</acl>
|
23 |
+
</config>
|
app/code/community/RocketWeb/All/etc/config.xml
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<RocketWeb_All>
|
5 |
+
<version>1.0.0</version>
|
6 |
+
</RocketWeb_All>
|
7 |
+
</modules>
|
8 |
+
<global>
|
9 |
+
<helpers>
|
10 |
+
<rocketweb_all>
|
11 |
+
<class>RocketWeb_All_Helper</class>
|
12 |
+
</rocketweb_all>
|
13 |
+
</helpers>
|
14 |
+
<models>
|
15 |
+
<rocketweb_all>
|
16 |
+
<class>RocketWeb_All_Model</class>
|
17 |
+
</rocketweb_all>
|
18 |
+
</models>
|
19 |
+
</global>
|
20 |
+
<adminhtml>
|
21 |
+
<events>
|
22 |
+
<controller_action_predispatch>
|
23 |
+
<observers>
|
24 |
+
<rocketweb_all>
|
25 |
+
<type>singleton</type>
|
26 |
+
<class>rocketweb_all/observer</class>
|
27 |
+
<method>updateNotifications</method>
|
28 |
+
</rocketweb_all>
|
29 |
+
</observers>
|
30 |
+
</controller_action_predispatch>
|
31 |
+
</events>
|
32 |
+
</adminhtml>
|
33 |
+
<default>
|
34 |
+
<rocketweb_all>
|
35 |
+
<general>
|
36 |
+
<enable_notifications>1</enable_notifications>
|
37 |
+
</general>
|
38 |
+
</rocketweb_all>
|
39 |
+
</default>
|
40 |
+
</config>
|
app/code/community/RocketWeb/All/etc/system.xml
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<tabs>
|
4 |
+
<rocketweb_tab>
|
5 |
+
<label>Rocket Web Extensions</label>
|
6 |
+
<sort_order>1005001</sort_order>
|
7 |
+
</rocketweb_tab>
|
8 |
+
</tabs>
|
9 |
+
<sections>
|
10 |
+
<rocketweb_all translate="label" module="rocketweb_all">
|
11 |
+
<label>General</label>
|
12 |
+
<tab>rocketweb_tab</tab>
|
13 |
+
<frontend_type>text</frontend_type>
|
14 |
+
<sort_order>100</sort_order>
|
15 |
+
<show_in_default>1</show_in_default>
|
16 |
+
<show_in_website>1</show_in_website>
|
17 |
+
<show_in_store>1</show_in_store>
|
18 |
+
<groups>
|
19 |
+
<general translate="label">
|
20 |
+
<label>Settings</label>
|
21 |
+
<frontend_type>text</frontend_type>
|
22 |
+
<sort_order>10</sort_order>
|
23 |
+
<show_in_default>1</show_in_default>
|
24 |
+
<show_in_website>1</show_in_website>
|
25 |
+
<show_in_store>1</show_in_store>
|
26 |
+
<fields>
|
27 |
+
<enable_notifications translate="label comment">
|
28 |
+
<label>Enable notifications?</label>
|
29 |
+
<comment><![CDATA[]]></comment>
|
30 |
+
<frontend_type>select</frontend_type>
|
31 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
32 |
+
<sort_order>10</sort_order>
|
33 |
+
<show_in_default>1</show_in_default>
|
34 |
+
<show_in_website>1</show_in_website>
|
35 |
+
<show_in_store>1</show_in_store>
|
36 |
+
</enable_notifications>
|
37 |
+
</fields>
|
38 |
+
</general>
|
39 |
+
</groups>
|
40 |
+
</rocketweb_all>
|
41 |
+
</sections>
|
42 |
+
</config>
|
app/code/community/RocketWeb/CustomOptionValidator/Block/Adminhtml/Validators.php
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class RocketWeb_CustomOptionValidator_Block_Adminhtml_Validators extends Mage_Core_Block_Template {
|
3 |
+
public function getValidatorsInGroups() {
|
4 |
+
$ret = array();
|
5 |
+
|
6 |
+
$model = Mage::getModel('rocketweb_cov/validator_type');
|
7 |
+
$groups = $model->getGroups();
|
8 |
+
$items = $model->getTypes();
|
9 |
+
|
10 |
+
foreach($groups as $group) {
|
11 |
+
foreach($items as $key=>$data) {
|
12 |
+
if($group == $data['group']) {
|
13 |
+
$ret[$group][$key] = $data;
|
14 |
+
}
|
15 |
+
}
|
16 |
+
}
|
17 |
+
return json_encode($ret);
|
18 |
+
}
|
19 |
+
}
|
app/code/community/RocketWeb/CustomOptionValidator/Block/Rewrite/Adminhtml/Catalog/Product/Edit/Tab/Options/Option.php
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class RocketWeb_CustomOptionValidator_Block_Rewrite_Adminhtml_Catalog_Product_Edit_Tab_Options_Option
|
3 |
+
extends Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Options_Option {
|
4 |
+
|
5 |
+
public function getOptionValues()
|
6 |
+
{
|
7 |
+
parent::getOptionValues();
|
8 |
+
|
9 |
+
|
10 |
+
$optionsArr = array_reverse($this->getProduct()->getOptions(), true);
|
11 |
+
foreach ($optionsArr as $option) {
|
12 |
+
foreach($this->_values as &$value) {
|
13 |
+
if($value['id'] == $option->getOptionId()) {
|
14 |
+
$value['validators'] = $option->getValidators();
|
15 |
+
}
|
16 |
+
}
|
17 |
+
}
|
18 |
+
|
19 |
+
|
20 |
+
return $this->_values;
|
21 |
+
}
|
22 |
+
|
23 |
+
}
|
app/code/community/RocketWeb/CustomOptionValidator/Helper/Data.php
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class RocketWeb_CustomOptionValidator_Helper_Data extends Mage_Core_Helper_Data {
|
3 |
+
|
4 |
+
}
|
app/code/community/RocketWeb/CustomOptionValidator/Model/Validator.php
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class RocketWeb_CustomOptionValidator_Model_Validator {
|
3 |
+
private $_id = null;
|
4 |
+
private $_group = null;
|
5 |
+
|
6 |
+
}
|
app/code/community/RocketWeb/CustomOptionValidator/Model/Validator/List.php
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class RocketWeb_CustomOptionValidator_Model_Validator_List {
|
3 |
+
public function getAllValidators() {
|
4 |
+
|
5 |
+
}
|
6 |
+
}
|
app/code/community/RocketWeb/CustomOptionValidator/Model/Validator/Type.php
ADDED
@@ -0,0 +1,263 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class RocketWeb_CustomOptionValidator_Model_Validator_Type {
|
3 |
+
const GROUP_OTHER = 'Other';
|
4 |
+
const GROUP_COMMON = 'Common';
|
5 |
+
const GROUP_NUMBERS = 'Numbers';
|
6 |
+
const GROUP_LOCATION = 'Location/phone';
|
7 |
+
const GROUP_TEXT = 'Text';
|
8 |
+
const GROUP_CC_SSN = 'Credit Card Validation/SSN';
|
9 |
+
|
10 |
+
const TYPE_TEXT = 'field';
|
11 |
+
const TYPE_TEXT_AREA = 'area';
|
12 |
+
const TYPE_FILE = 'file';
|
13 |
+
const TYPE_DROP_DOWN = 'drop_down';
|
14 |
+
const TYPE_CHECKBOX = 'checkbox';
|
15 |
+
const TYPE_RADIO = 'radio';
|
16 |
+
const TYPE_MULTI = 'multiple';
|
17 |
+
const TYPE_DATE = 'date';
|
18 |
+
const TYPE_DATE_TIME = 'date_time';
|
19 |
+
const TYPE_TIME = 'time';
|
20 |
+
|
21 |
+
|
22 |
+
public function getGroups() {
|
23 |
+
return array(
|
24 |
+
self::GROUP_COMMON,
|
25 |
+
self::GROUP_TEXT,
|
26 |
+
self::GROUP_NUMBERS,
|
27 |
+
self::GROUP_LOCATION,
|
28 |
+
self::GROUP_CC_SSN,
|
29 |
+
self::GROUP_OTHER,
|
30 |
+
);
|
31 |
+
}
|
32 |
+
|
33 |
+
|
34 |
+
public function getTypes() {
|
35 |
+
return array(
|
36 |
+
'validate-no-html-tags' => array(
|
37 |
+
'group' => self::GROUP_OTHER,
|
38 |
+
'title' => 'No html tags',
|
39 |
+
'description' => '',
|
40 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
41 |
+
),
|
42 |
+
'validate-number' => array(
|
43 |
+
'group' => self::GROUP_NUMBERS,
|
44 |
+
'title' => 'Number',
|
45 |
+
'description' => '',
|
46 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
47 |
+
),
|
48 |
+
'validate-number-range' => array(
|
49 |
+
'group' => self::GROUP_NUMBERS,
|
50 |
+
'title' => 'Number in range',
|
51 |
+
'description' => '',
|
52 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
53 |
+
'extra' => array(
|
54 |
+
'combined_prefix' => 1,
|
55 |
+
'prefix' => 'number-range',
|
56 |
+
'elements' => array(
|
57 |
+
'n1' => array(
|
58 |
+
'prefix' => 'number-range',
|
59 |
+
'style' => 'width:30px',
|
60 |
+
'label' => 'Min:',
|
61 |
+
'required' => true
|
62 |
+
),
|
63 |
+
'n2' => array(
|
64 |
+
'prefix' => 'number-range',
|
65 |
+
'style' => 'width:30px',
|
66 |
+
'label' => 'Max:',
|
67 |
+
'required' => true
|
68 |
+
)
|
69 |
+
)
|
70 |
+
)
|
71 |
+
),
|
72 |
+
'validate-digits' => array(
|
73 |
+
'group' => self::GROUP_NUMBERS,
|
74 |
+
'title' => 'Digits',
|
75 |
+
'description' => '',
|
76 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
77 |
+
),
|
78 |
+
'validate-digits-range' => array(
|
79 |
+
'group' => self::GROUP_NUMBERS,
|
80 |
+
'title' => 'Digits range',
|
81 |
+
'description' => '',
|
82 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
83 |
+
'extra' => array(
|
84 |
+
'combined_prefix' => 1,
|
85 |
+
'prefix' => 'digits-range',
|
86 |
+
'elements' => array(
|
87 |
+
'n1' => array(
|
88 |
+
'prefix' => 'digits-range',
|
89 |
+
'style' => 'width:30px',
|
90 |
+
'label' => 'Min:',
|
91 |
+
'required' => true
|
92 |
+
),
|
93 |
+
'n2' => array(
|
94 |
+
'prefix' => 'digits-range',
|
95 |
+
'style' => 'width:30px',
|
96 |
+
'label' => 'Max:',
|
97 |
+
'required' => true
|
98 |
+
)
|
99 |
+
)
|
100 |
+
)
|
101 |
+
),
|
102 |
+
'validate-alpha' => array(
|
103 |
+
'group' => self::GROUP_TEXT,
|
104 |
+
'title' => 'Letters only',
|
105 |
+
'description' => 'Use letters only (a-z or A-Z) in this field',
|
106 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
107 |
+
),
|
108 |
+
'validate-code' => array(
|
109 |
+
'group' => self::GROUP_TEXT,
|
110 |
+
'title' => 'Code',
|
111 |
+
'description' => 'Use only letters (a-z), numbers (0-9) or underscore(_) in this field, first character should be a letter.',
|
112 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
113 |
+
),
|
114 |
+
'validate-alphanum' => array(
|
115 |
+
'group' => self::GROUP_TEXT,
|
116 |
+
'title' => 'Alphanumeric',
|
117 |
+
'description' => 'Use only letters (a-z or A-Z) or numbers (0-9) only in this field. No spaces or other characters are allowed.',
|
118 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
119 |
+
),
|
120 |
+
'validate-alphanum-with-spaces'=> array(
|
121 |
+
'group' => self::GROUP_TEXT,
|
122 |
+
'title' => 'Alphanumeric with spaces',
|
123 |
+
'description' => 'Use only letters (a-z or A-Z), numbers (0-9) or spaces only in this field.',
|
124 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
125 |
+
),
|
126 |
+
'validate-street' => array(
|
127 |
+
'group' => self::GROUP_LOCATION,
|
128 |
+
'title' => 'Street address',
|
129 |
+
'description' => 'Use only letters (a-z or A-Z) or numbers (0-9) or spaces and # only in this field.',
|
130 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
131 |
+
),
|
132 |
+
'validate-phoneStrict' => array(
|
133 |
+
'group' => self::GROUP_LOCATION,
|
134 |
+
'title' => 'Strict phone validation',
|
135 |
+
'description' => '',
|
136 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
137 |
+
),
|
138 |
+
'validate-phoneLax' => array(
|
139 |
+
'group' => self::GROUP_LOCATION,
|
140 |
+
'title' => 'Lax phone validation',
|
141 |
+
'description' => '',
|
142 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
143 |
+
),
|
144 |
+
'validate-fax' => array(
|
145 |
+
'group' => self::GROUP_LOCATION,
|
146 |
+
'title' => 'Fax',
|
147 |
+
'description' => '',
|
148 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
149 |
+
),
|
150 |
+
'validate-date' => array(
|
151 |
+
'group' => self::GROUP_COMMON,
|
152 |
+
'title' => 'Date',
|
153 |
+
'description' => '',
|
154 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
155 |
+
),
|
156 |
+
'validate-email' => array(
|
157 |
+
'group' => self::GROUP_COMMON,
|
158 |
+
'title' => 'E-mail',
|
159 |
+
'description' => '',
|
160 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
161 |
+
),
|
162 |
+
'validate-emailSender' => array(
|
163 |
+
'group' => self::GROUP_OTHER,
|
164 |
+
'title' => 'E-mail sender',
|
165 |
+
'description' => '',
|
166 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
167 |
+
),
|
168 |
+
'validate-password' => array(
|
169 |
+
'group' => self::GROUP_OTHER,
|
170 |
+
'title' => 'Password',
|
171 |
+
'description' => '6 or more characters, leading or trailing spaces will be ignored',
|
172 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
173 |
+
),
|
174 |
+
'validate-url' => array(
|
175 |
+
'group' => self::GROUP_OTHER,
|
176 |
+
'title' => 'Url',
|
177 |
+
'description' => 'valid URL, protocol is required (http://, https:// or ftp://)',
|
178 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
179 |
+
),
|
180 |
+
'validate-clean-url' => array(
|
181 |
+
'group' => self::GROUP_OTHER,
|
182 |
+
'title' => 'Clean url',
|
183 |
+
'description' => 'Valid URL, for example http://www.example.com or www.example.com',
|
184 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
185 |
+
),
|
186 |
+
'validate-ssn' => array(
|
187 |
+
'group' => self::GROUP_CC_SSN,
|
188 |
+
'title' => 'Social Security Number',
|
189 |
+
'description' => '',
|
190 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
191 |
+
),
|
192 |
+
'validate-zip' => array(
|
193 |
+
'group' => self::GROUP_LOCATION,
|
194 |
+
'title' => 'US zip code',
|
195 |
+
'description' => '',
|
196 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
197 |
+
),
|
198 |
+
'validate-zip-international' => array(
|
199 |
+
'group' => self::GROUP_LOCATION,
|
200 |
+
'title' => 'International zip code',
|
201 |
+
'description' => '',
|
202 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
203 |
+
),
|
204 |
+
'validate-not-negative-number' => array(
|
205 |
+
'group' => self::GROUP_NUMBERS,
|
206 |
+
'title' => 'Non-negative number',
|
207 |
+
'description' => 'zero or grater',
|
208 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
209 |
+
),
|
210 |
+
'validate-greater-than-zero' => array(
|
211 |
+
'group' => self::GROUP_NUMBERS,
|
212 |
+
'title' => 'Positive number',
|
213 |
+
'description' => '',
|
214 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
215 |
+
),
|
216 |
+
'validate-cc-number' => array(
|
217 |
+
'group' => self::GROUP_CC_SSN,
|
218 |
+
'title' => 'Credit Card number',
|
219 |
+
'description' => '',
|
220 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
221 |
+
),
|
222 |
+
'validate-cc-exp' => array(
|
223 |
+
'group' => self::GROUP_CC_SSN,
|
224 |
+
'title' => 'Credit Card expiration date',
|
225 |
+
'description' => '',
|
226 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
227 |
+
),
|
228 |
+
'validate-cc-cvn' => array(
|
229 |
+
'group' => self::GROUP_CC_SSN,
|
230 |
+
'title' => 'Credit Card verification number',
|
231 |
+
'description' => '',
|
232 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
233 |
+
),
|
234 |
+
'validate-length' => array(
|
235 |
+
'group' => self::GROUP_COMMON,
|
236 |
+
'title' => 'Required Length',
|
237 |
+
'description' => 'You can leave the min or max fields empty if you do not require a minimum/maximum',
|
238 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
239 |
+
'extra' => array(
|
240 |
+
'combined_prefix' => 0,
|
241 |
+
'elements' => array(
|
242 |
+
'n1' => array(
|
243 |
+
'style' => 'width:30px',
|
244 |
+
'label' => 'Min:',
|
245 |
+
'prefix' => 'minimum-length'
|
246 |
+
),
|
247 |
+
'n2' => array(
|
248 |
+
'style' => 'width:30px',
|
249 |
+
'label' => 'Max:',
|
250 |
+
'prefix' => 'maximum-length'
|
251 |
+
)
|
252 |
+
)
|
253 |
+
)
|
254 |
+
),
|
255 |
+
'validate-percents' => array(
|
256 |
+
'group' => self::GROUP_NUMBERS,
|
257 |
+
'title' => 'Percent value',
|
258 |
+
'description' => '',
|
259 |
+
'for_types' => array(self::TYPE_TEXT,self::TYPE_TEXT_AREA),
|
260 |
+
),
|
261 |
+
);
|
262 |
+
}
|
263 |
+
}
|
app/code/community/RocketWeb/CustomOptionValidator/etc/config.xml
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<RocketWeb_CustomOptionValidator>
|
5 |
+
<version>1.0.0</version>
|
6 |
+
</RocketWeb_CustomOptionValidator>
|
7 |
+
</modules>
|
8 |
+
<global>
|
9 |
+
<helpers>
|
10 |
+
<rocketweb_cov>
|
11 |
+
<class>RocketWeb_CustomOptionValidator_Helper</class>
|
12 |
+
</rocketweb_cov>
|
13 |
+
</helpers>
|
14 |
+
<models>
|
15 |
+
<rocketweb_cov>
|
16 |
+
<class>RocketWeb_CustomOptionValidator_Model</class>
|
17 |
+
</rocketweb_cov>
|
18 |
+
</models>
|
19 |
+
<blocks>
|
20 |
+
<rocketweb_cov>
|
21 |
+
<class>RocketWeb_CustomOptionValidator_Block</class>
|
22 |
+
</rocketweb_cov>
|
23 |
+
<adminhtml>
|
24 |
+
<rewrite>
|
25 |
+
<catalog_product_edit_tab_options_option>RocketWeb_CustomOptionValidator_Block_Rewrite_Adminhtml_Catalog_Product_Edit_Tab_Options_Option</catalog_product_edit_tab_options_option>
|
26 |
+
</rewrite>
|
27 |
+
</adminhtml>
|
28 |
+
</blocks>
|
29 |
+
<resources>
|
30 |
+
<rocketweb_cov_setup>
|
31 |
+
<setup>
|
32 |
+
<module>RocketWeb_CustomOptionValidator</module>
|
33 |
+
</setup>
|
34 |
+
<connection>
|
35 |
+
<use>core_setup</use>
|
36 |
+
</connection>
|
37 |
+
</rocketweb_cov_setup>
|
38 |
+
</resources>
|
39 |
+
</global>
|
40 |
+
<adminhtml>
|
41 |
+
<layout>
|
42 |
+
<updates>
|
43 |
+
<rocketweb_cov>
|
44 |
+
<file>rocketweb_cov.xml</file>
|
45 |
+
</rocketweb_cov>
|
46 |
+
</updates>
|
47 |
+
</layout>
|
48 |
+
</adminhtml>
|
49 |
+
</config>
|
app/code/community/RocketWeb/CustomOptionValidator/sql/rocketweb_cov_setup/mysql4-install-1.0.0.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
$installer = $this;
|
4 |
+
|
5 |
+
$installer->startSetup();
|
6 |
+
|
7 |
+
$installer->run("ALTER TABLE `{$this->getTable('catalog/product_option')}` ADD `validators` TEXT NOT NULL");
|
8 |
+
|
9 |
+
$installer->endSetup();
|
app/design/adminhtml/default/default/layout/rocketweb_cov.xml
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<layout>
|
2 |
+
<adminhtml_catalog_product_options>
|
3 |
+
<reference name="root">
|
4 |
+
<block type="rocketweb_cov/adminhtml_validators" name="rocketweb.cov.adminhtml_validators" template="rocketweb_cov/adminhtml/validators.phtml"/>
|
5 |
+
</reference>
|
6 |
+
</adminhtml_catalog_product_options>
|
7 |
+
<adminhtml_catalog_product_edit>
|
8 |
+
<reference name="head">
|
9 |
+
<action method="addCss"><name>rocketweb/adminhtml/custom_option_validation.css</name></action>
|
10 |
+
<action method="addJs"><script>rocketweb/adminhtml/custom_option_validation.js</script></action>
|
11 |
+
</reference>
|
12 |
+
</adminhtml_catalog_product_edit>
|
13 |
+
<adminhtml_catalog_product_new>
|
14 |
+
<reference name="head">
|
15 |
+
<action method="addCss"><name>rocketweb/adminhtml/custom_option_validation.css</name></action>
|
16 |
+
<action method="addJs"><script>rocketweb/adminhtml/custom_option_validation.js</script></action>
|
17 |
+
</reference>
|
18 |
+
</adminhtml_catalog_product_new>
|
19 |
+
</layout>
|
app/design/adminhtml/default/default/template/catalog/product/edit/options/option.phtml
ADDED
@@ -0,0 +1,367 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Magento
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Academic Free License (AFL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE_AFL.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/afl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to license@magentocommerce.com so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade Magento to newer
|
18 |
+
* versions in the future. If you wish to customize Magento for your
|
19 |
+
* needs please refer to http://www.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category design
|
22 |
+
* @package default_default
|
23 |
+
* @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
|
24 |
+
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
|
25 |
+
*/
|
26 |
+
?>
|
27 |
+
<?php echo $this->getTemplatesHtml() ?>
|
28 |
+
<script type="text/javascript">
|
29 |
+
//<![CDATA[
|
30 |
+
window.skinUrl = '<?php echo $this->getSkinUrl();?>';
|
31 |
+
|
32 |
+
var popupTemplate = '<div style="display:none" class="custom-option-validator-popup" id="validators_<?php echo $this->getFieldId() ?>_{{id}}">'+
|
33 |
+
'<div class="header">Configure Validators <a href="#" onclick="hideValidatorsPopup(\'validators_<?php echo $this->getFieldId() ?>_{{id}}\');return false;" class="close"></a></div>'+
|
34 |
+
'<div><dl class="popup-content accordion"></dl></div>'+
|
35 |
+
'<div class="buttons-set a-right">'+
|
36 |
+
'<button type="button" class="scalable" onclick="submitValidatorsPopup(\'validators_<?php echo $this->getFieldId() ?>_{{id}}\')"><span><span><span>OK</span></span></span></button>'+
|
37 |
+
'</div>'+
|
38 |
+
'<input type="hidden" id="custom_validators_<?php echo $this->getFieldId() ?>_{{id}}" name="product[options][{{id}}][validators]" value="{{validators}}"/>'+
|
39 |
+
'</div>';
|
40 |
+
|
41 |
+
var firstStepTemplate = '<div class="option-box" id="option_{{id}}">'+
|
42 |
+
'<table id="<?php echo $this->getFieldId() ?>_{{id}}" class="option-header" cellpadding="0" cellspacing="0">'+
|
43 |
+
'<input type="hidden" id="<?php echo $this->getFieldId() ?>_{{id}}_is_delete" name="<?php echo $this->getFieldName() ?>[{{id}}][is_delete]" value="" />'+
|
44 |
+
'<input type="hidden" id="<?php echo $this->getFieldId() ?>_{{id}}_previous_type" name="<?php echo $this->getFieldName() ?>[{{id}}][previous_type]" value="{{type}}" />'+
|
45 |
+
'<input type="hidden" id="<?php echo $this->getFieldId() ?>_{{id}}_previous_group" name="<?php echo $this->getFieldName() ?>[{{id}}][previous_group]" value="" />'+
|
46 |
+
'<input type="hidden" id="<?php echo $this->getFieldId() ?>_{{id}}_id" name="<?php echo $this->getFieldName() ?>[{{id}}][id]" value="{{id}}" />'+
|
47 |
+
'<input type="hidden" id="<?php echo $this->getFieldId() ?>_{{id}}_option_id" name="<?php echo $this->getFieldName() ?>[{{id}}][option_id]" value="{{option_id}}" />'+
|
48 |
+
'<thead>'+
|
49 |
+
'<tr>'+
|
50 |
+
'<th class="opt-title"><?php echo Mage::helper('catalog')->__('Title') ?> <span class="required">*</span></th>'+
|
51 |
+
'<th class="opt-type"><?php echo Mage::helper('catalog')->__('Input Type') ?> <span class="required">*</span></th>'+
|
52 |
+
'<th class="opt-req"><?php echo $this->jsQuoteEscape(Mage::helper('catalog')->__('Is Required')) ?></th>'+
|
53 |
+
'<th class="opt-order"><?php echo Mage::helper('catalog')->__('Sort Order') ?></th>'+
|
54 |
+
'<th class="opt-validate"> </th>'+
|
55 |
+
'<th class="a-right"><?php echo $this->jsQuoteEscape($this->getDeleteButtonHtml()) ?></th>'+
|
56 |
+
'</tr>'+
|
57 |
+
'</thead>'+
|
58 |
+
'<tr>'+
|
59 |
+
'<td><input type="text" class="required-entry input-text" id="<?php echo $this->getFieldId() ?>_{{id}}_title" name="<?php echo $this->getFieldName() ?>[{{id}}][title]" value="{{title}}">{{checkboxScopeTitle}}</td>'+
|
60 |
+
'<td><?php echo $this->getTypeSelectHtml() ?></td>'+
|
61 |
+
'<td class="opt-req"><?php echo $this->getRequireSelectHtml() ?></td>'+
|
62 |
+
'<td><input type="text" class="validate-zero-or-greater input-text" name="<?php echo $this->getFieldName() ?>[{{id}}][sort_order]" value="{{sort_order}}"></td>'+
|
63 |
+
'<td style="padding-left:10px;"><button style="display:none" id="product_option_{{id}}_type_cfg_button" onclick="window.rwvalidators.populateValidatorPopup(\'<?php echo $this->getFieldId() ?>_{{id}}\');showValidatorsPopup(\'validators_<?php echo $this->getFieldId() ?>_{{id}}\',100,100);return false;"><span><span><?php echo Mage::helper('catalog')->__('Configure Validators') ?></span></span></button>'+popupTemplate+'</td>'+
|
64 |
+
'<td> </td>'+
|
65 |
+
'</tr></table></div>';
|
66 |
+
|
67 |
+
var productOption = {
|
68 |
+
div : $('product_options_container_top'),
|
69 |
+
templateSyntax : /(^|.|\r|\n)({{(\w+)}})/,
|
70 |
+
templateText : firstStepTemplate,
|
71 |
+
itemCount : 1,
|
72 |
+
add : function(data) {
|
73 |
+
this.template = new Template(this.templateText, this.templateSyntax);
|
74 |
+
|
75 |
+
if(!data.id){
|
76 |
+
data = {};
|
77 |
+
data.id = this.itemCount;
|
78 |
+
data.type = '';
|
79 |
+
data.option_id = 0;
|
80 |
+
data.validators = '';
|
81 |
+
} else {
|
82 |
+
this.itemCount = data.item_count;
|
83 |
+
}
|
84 |
+
|
85 |
+
Element.insert(this.div, {'after':this.template.evaluate(data)});
|
86 |
+
|
87 |
+
//set selected type
|
88 |
+
if (data.type) {
|
89 |
+
$A($('<?php echo $this->getFieldId() ?>_'+data.id+'_type').options).each(function(option){
|
90 |
+
if (option.value==data.type) option.selected = true;
|
91 |
+
});
|
92 |
+
}
|
93 |
+
|
94 |
+
//set selected is_require
|
95 |
+
if (data.is_require) {
|
96 |
+
$A($('<?php echo $this->getFieldId() ?>_'+data.id+'_is_require').options).each(function(option){
|
97 |
+
if (option.value==data.is_require) option.selected = true;
|
98 |
+
});
|
99 |
+
}
|
100 |
+
|
101 |
+
if (data.checkboxScopeTitle) {
|
102 |
+
//set disabled
|
103 |
+
if ($('<?php echo $this->getFieldId() ?>_'+data.option_id+'_title') && data.scopeTitleDisabled) {
|
104 |
+
$('<?php echo $this->getFieldId() ?>_'+data.option_id+'_title').disable();
|
105 |
+
}
|
106 |
+
}
|
107 |
+
|
108 |
+
this.itemCount++;
|
109 |
+
this.bindRemoveButtons();
|
110 |
+
productOptionType.bindSelectInputType();
|
111 |
+
},
|
112 |
+
remove : function(event){
|
113 |
+
var element = $(Event.findElement(event, 'div'));
|
114 |
+
if(element){
|
115 |
+
$('product_'+element.readAttribute('id')+'_'+'is_delete').value = '1';
|
116 |
+
element.addClassName('no-display');
|
117 |
+
element.addClassName('ignore-validate');
|
118 |
+
element.hide();
|
119 |
+
}
|
120 |
+
},
|
121 |
+
bindRemoveButtons : function(){
|
122 |
+
var buttons = $$('div.product-custom-options .delete-product-option');
|
123 |
+
for(var i=0;i<buttons.length;i++){
|
124 |
+
if(!$(buttons[i]).binded){
|
125 |
+
$(buttons[i]).binded = true;
|
126 |
+
Event.observe(buttons[i], 'click', this.remove.bind(this));
|
127 |
+
}
|
128 |
+
}
|
129 |
+
var inputs = $$('div.product-custom-options button', 'div.product-custom-options input', 'div.product-custom-options select', 'div.product-custom-options textarea');
|
130 |
+
<?php if ($this->isReadonly()):?>
|
131 |
+
for (var i=0, l = inputs.length; i < l; i ++) {
|
132 |
+
inputs[i].disabled = true;
|
133 |
+
if (inputs[i].tagName.toLowerCase()=='button') {
|
134 |
+
inputs[i].addClassName('disabled');
|
135 |
+
}
|
136 |
+
}
|
137 |
+
<?php else: ?>
|
138 |
+
inputs.each(function(el) { Event.observe(el, 'change', el.setHasChanges.bind(el)); } )
|
139 |
+
<?php endif;?>
|
140 |
+
}
|
141 |
+
}
|
142 |
+
|
143 |
+
|
144 |
+
var productOptionType = {
|
145 |
+
templateSyntax : /(^|.|\r|\n)({{(\w+)}})/,
|
146 |
+
loadStepTwo : function(event){
|
147 |
+
var element = $(Event.findElement(event, 'select'));
|
148 |
+
|
149 |
+
var group = '';
|
150 |
+
var previousGroupElm = $(element.readAttribute('id').sub('_type', '_previous_group'));
|
151 |
+
|
152 |
+
switch(element.getValue()){
|
153 |
+
case 'field':
|
154 |
+
case 'area':
|
155 |
+
template = OptionTemplateText;
|
156 |
+
group = 'text';
|
157 |
+
break;
|
158 |
+
case 'file':
|
159 |
+
template = OptionTemplateFile;
|
160 |
+
group = 'file';
|
161 |
+
break;
|
162 |
+
case 'drop_down':
|
163 |
+
case 'radio':
|
164 |
+
case 'checkbox':
|
165 |
+
case 'multiple':
|
166 |
+
template = OptionTemplateSelect;
|
167 |
+
group = 'select';
|
168 |
+
break;
|
169 |
+
case 'date':
|
170 |
+
case 'date_time':
|
171 |
+
case 'time':
|
172 |
+
template = OptionTemplateDate;
|
173 |
+
group = 'date';
|
174 |
+
break;
|
175 |
+
default:
|
176 |
+
template = '';
|
177 |
+
group = 'unknown';
|
178 |
+
break;
|
179 |
+
}
|
180 |
+
|
181 |
+
if (previousGroupElm.getValue() != group) {
|
182 |
+
if ($(element.readAttribute('id')+'_'+previousGroupElm.getValue())) {
|
183 |
+
formElm = $(element.readAttribute('id')+'_'+previousGroupElm.getValue()).descendants();
|
184 |
+
formElm.each(function(elm){
|
185 |
+
if (elm.tagName == 'input' || elm.tagName == 'select') {
|
186 |
+
elm.name = '__delete__'+elm.readAttribute('name');
|
187 |
+
}
|
188 |
+
});
|
189 |
+
|
190 |
+
$(element.readAttribute('id')+'_'+previousGroupElm.getValue()).addClassName('no-display');
|
191 |
+
$(element.readAttribute('id')+'_'+previousGroupElm.getValue()).addClassName('ignore-validate');
|
192 |
+
$(element.readAttribute('id')+'_'+previousGroupElm.getValue()).hide();
|
193 |
+
}
|
194 |
+
|
195 |
+
previousGroupElm.value = group;
|
196 |
+
|
197 |
+
if ($(element.readAttribute('id')+'_'+group)) {
|
198 |
+
formElm = $(element.readAttribute('id')+'_'+group).descendants();
|
199 |
+
formElm.each(function(elm){
|
200 |
+
if (elm.match('input') || elm.match('select')) {
|
201 |
+
elm.name = elm.readAttribute('name').sub('__delete__', '');
|
202 |
+
}
|
203 |
+
});
|
204 |
+
$(element.readAttribute('id')+'_'+group).removeClassName('no-display');
|
205 |
+
$(element.readAttribute('id')+'_'+group).removeClassName('ignore-validate');
|
206 |
+
$(element.readAttribute('id')+'_'+group).show();
|
207 |
+
|
208 |
+
} else {
|
209 |
+
template = '<div id="'+element.readAttribute('id')+'_'+group+'" class="grid tier form-list">'+template+'</div><div id="'+element.readAttribute('id')+'_'+group+'_advice"></div';
|
210 |
+
this.secondTemplate = new Template(template, this.templateSyntax);
|
211 |
+
|
212 |
+
data = {};
|
213 |
+
if (!data.option_id) {
|
214 |
+
data = {};
|
215 |
+
data.option_id = $(element.readAttribute('id').sub('_type', '_id')).getValue();
|
216 |
+
}
|
217 |
+
|
218 |
+
Element.insert(element.readAttribute('id').sub('_type', ''), {'after':this.secondTemplate.evaluate(data)});
|
219 |
+
|
220 |
+
switch(element.getValue()){
|
221 |
+
case 'drop_down':
|
222 |
+
case 'radio':
|
223 |
+
case 'checkbox':
|
224 |
+
case 'multiple':
|
225 |
+
selectOptionType.bindAddButton();
|
226 |
+
break;
|
227 |
+
}
|
228 |
+
}
|
229 |
+
}
|
230 |
+
},
|
231 |
+
addDataToValues : function(data){
|
232 |
+
|
233 |
+
switch(data.type){
|
234 |
+
case 'field':
|
235 |
+
case 'area':
|
236 |
+
template = OptionTemplateText;
|
237 |
+
group = 'text';
|
238 |
+
break;
|
239 |
+
case 'file':
|
240 |
+
template = OptionTemplateFile;
|
241 |
+
group = 'file';
|
242 |
+
break;
|
243 |
+
case 'drop_down':
|
244 |
+
case 'radio':
|
245 |
+
case 'checkbox':
|
246 |
+
case 'multiple':
|
247 |
+
template = OptionTemplateSelect;
|
248 |
+
group = 'select';
|
249 |
+
break;
|
250 |
+
case 'date':
|
251 |
+
case 'date_time':
|
252 |
+
case 'time':
|
253 |
+
template = OptionTemplateDate;
|
254 |
+
group = 'date';
|
255 |
+
break;
|
256 |
+
}
|
257 |
+
|
258 |
+
$('<?php echo $this->getFieldId() ?>_'+data.id+'_previous_group').value = group;
|
259 |
+
|
260 |
+
template = '<div id="<?php echo $this->getFieldId() ?>_{{id}}_type_'+group+'" class="grid tier form-list">'+template+'</div><div id="<?php echo $this->getFieldId() ?>_{{id}}_type_'+group+'_advice"></div>';
|
261 |
+
|
262 |
+
this.secondTemplate = new Template(template, this.templateSyntax);
|
263 |
+
|
264 |
+
Element.insert($('<?php echo $this->getFieldId() ?>_'+data.option_id), {'after':this.secondTemplate.evaluate(data)});
|
265 |
+
|
266 |
+
if (data.checkboxScopePrice) {
|
267 |
+
//set disabled
|
268 |
+
if ($('<?php echo $this->getFieldId() ?>_'+data.option_id+'_price') && data.scopePriceDisabled) {
|
269 |
+
$('<?php echo $this->getFieldId() ?>_'+data.option_id+'_price').disable();
|
270 |
+
$('<?php echo $this->getFieldId() ?>_'+data.option_id+'_price_type').disable();
|
271 |
+
}
|
272 |
+
}
|
273 |
+
|
274 |
+
switch(data.type){
|
275 |
+
case 'drop_down':
|
276 |
+
case 'radio':
|
277 |
+
case 'checkbox':
|
278 |
+
case 'multiple':
|
279 |
+
data.optionValues.each(function(value) {
|
280 |
+
selectOptionType.add(value);
|
281 |
+
});
|
282 |
+
selectOptionType.bindAddButton();
|
283 |
+
break;
|
284 |
+
}
|
285 |
+
|
286 |
+
if (data.price_type) {
|
287 |
+
$A($('<?php echo $this->getFieldId() ?>_'+data.option_id+'_price_type').options).each(function(option){
|
288 |
+
if (option.value==data.price_type) option.selected = true;
|
289 |
+
});
|
290 |
+
}
|
291 |
+
|
292 |
+
showHideConfigureValidatorsButtons();
|
293 |
+
|
294 |
+
},
|
295 |
+
bindSelectInputType : function(){
|
296 |
+
var types = $$('.select-product-option-type');
|
297 |
+
for(var i=0;i<types.length;i++){
|
298 |
+
if(!$(types[i]).binded){
|
299 |
+
$(types[i]).binded = true;
|
300 |
+
Event.observe(types[i], 'change', function(event){
|
301 |
+
productOptionType.loadStepTwo(event);
|
302 |
+
showHideConfigureValidatorsButtons();
|
303 |
+
});
|
304 |
+
}
|
305 |
+
}
|
306 |
+
}
|
307 |
+
}
|
308 |
+
|
309 |
+
var productOptionScope = {
|
310 |
+
addScope : function(event){
|
311 |
+
var element = $(Event.element(event));
|
312 |
+
fieldToDisable = $(element.readAttribute('id').sub('_use_default', ''));
|
313 |
+
|
314 |
+
if (fieldToDisable.disabled) {
|
315 |
+
if (fieldToDisable.hasClassName('product-option-price')) {//need change to cheking value of element
|
316 |
+
$(fieldToDisable.readAttribute('id')+'_type').enable();
|
317 |
+
}
|
318 |
+
fieldToDisable.enable();
|
319 |
+
} else {
|
320 |
+
if (fieldToDisable.hasClassName('product-option-price')) {//need change to cheking value of element
|
321 |
+
$(fieldToDisable.readAttribute('id')+'_type').disable();
|
322 |
+
}
|
323 |
+
fieldToDisable.disable();
|
324 |
+
}
|
325 |
+
},
|
326 |
+
bindScopeCheckbox : function(){
|
327 |
+
var checkboxes = $$('.product-option-scope-checkbox');
|
328 |
+
for (var i=0;i<checkboxes.length;i++) {
|
329 |
+
if (!$(checkboxes[i]).binded) {
|
330 |
+
$(checkboxes[i]).binded = true;
|
331 |
+
Event.observe(checkboxes[i], 'click', this.addScope.bind(this));
|
332 |
+
}
|
333 |
+
}
|
334 |
+
}
|
335 |
+
}
|
336 |
+
|
337 |
+
if($('option_panel')){
|
338 |
+
$('option_panel').remove();
|
339 |
+
}
|
340 |
+
|
341 |
+
productOption.bindRemoveButtons();
|
342 |
+
|
343 |
+
if($('<?php echo $this->getAddButtonId() ?>')){
|
344 |
+
Event.observe('<?php echo $this->getAddButtonId() ?>', 'click', productOption.add.bind(productOption));
|
345 |
+
}
|
346 |
+
|
347 |
+
//validation for selected input type
|
348 |
+
Validation.addAllThese([
|
349 |
+
['required-option-select', <?php echo $this->helper('core')->jsonEncode(Mage::helper('catalog')->__('Select type of option')) ?>, function(v, elm) {
|
350 |
+
if (elm.getValue() == '') {
|
351 |
+
return false;
|
352 |
+
}
|
353 |
+
return true;
|
354 |
+
}]]);
|
355 |
+
|
356 |
+
//adding data to templates
|
357 |
+
<?php foreach ($this->getOptionValues() as $_value): ?>
|
358 |
+
productOption.add(<?php echo $_value->toJson() ?>);
|
359 |
+
productOptionType.addDataToValues(<?php echo $_value->toJson() ?>);
|
360 |
+
<?php endforeach; ?>
|
361 |
+
|
362 |
+
//bind scope checkboxes
|
363 |
+
productOptionScope.bindScopeCheckbox();
|
364 |
+
//]]>
|
365 |
+
</script>
|
366 |
+
|
367 |
+
<div><?php if (!$this->isReadonly()):?><input type="hidden" name="affect_product_custom_options" value="1" /><?php endif;?></div>
|
app/design/adminhtml/default/default/template/rocketweb_cov/adminhtml/validators.phtml
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div id="popup-window-mask" style="display:none;"></div>
|
2 |
+
<script type="text/javascript">
|
3 |
+
window.rwvalidators = new CustomOptionValidatorHolder(<?php echo $this->getValidatorsInGroups();?>);
|
4 |
+
</script>
|
5 |
+
|
app/design/frontend/base/default/template/catalog/product/view/options/type/text.phtml
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Magento
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Academic Free License (AFL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE_AFL.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/afl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to license@magentocommerce.com so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade Magento to newer
|
18 |
+
* versions in the future. If you wish to customize Magento for your
|
19 |
+
* needs please refer to http://www.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category design
|
22 |
+
* @package base_default
|
23 |
+
* @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
|
24 |
+
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
|
25 |
+
*/
|
26 |
+
?>
|
27 |
+
<?php $_option = $this->getOption(); ?>
|
28 |
+
<dt><label<?php if ($_option->getIsRequire()) echo ' class="required"' ?>><?php if ($_option->getIsRequire()) echo '<em>*</em>' ?><?php echo $this->htmlEscape($_option->getTitle()) ?></label>
|
29 |
+
<?php echo $this->getFormatedPrice() ?></dt>
|
30 |
+
<dd<?php if ($_option->decoratedIsLast){?> class="last"<?php }?>>
|
31 |
+
<div class="input-box">
|
32 |
+
<?php if ($_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_FIELD): ?>
|
33 |
+
<input type="text" onchange="opConfig.reloadPrice()" id="options_<?php echo $_option->getId() ?>_text" class="<?php echo $_option->getValidators()?> input-text<?php echo $_option->getIsRequire() ? ' required-entry' : '' ?> <?php echo $_option->getMaxCharacters() ? ' validate-length maximum-length-'.$_option->getMaxCharacters() : '' ?> product-custom-option" name="options[<?php echo $_option->getId() ?>]" value="<?php echo $this->escapeHtml($this->getDefaultValue()) ?>" />
|
34 |
+
<?php elseif ($_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_AREA): ?>
|
35 |
+
<textarea id="options_<?php echo $_option->getId() ?>_text" onchange="opConfig.reloadPrice()" class="<?php echo $_option->getValidators()?> <?php echo $_option->getIsRequire() ? ' required-entry' : '' ?> <?php echo $_option->getMaxCharacters() ? ' validate-length maximum-length-'.$_option->getMaxCharacters() : '' ?> product-custom-option" name="options[<?php echo $_option->getId() ?>]" rows="5" cols="25"><?php echo $this->escapeHtml($this->getDefaultValue()) ?></textarea>
|
36 |
+
<?php endif; ?>
|
37 |
+
<?php if ($_option->getMaxCharacters()): ?>
|
38 |
+
<p class="note"><?php echo Mage::helper('catalog')->__('Maximum number of characters:')?> <strong><?php echo $_option->getMaxCharacters() ?></strong></p>
|
39 |
+
<?php endif; ?>
|
40 |
+
</div>
|
41 |
+
</dd>
|
app/etc/modules/RocketWeb_All.xml
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<RocketWeb_All>
|
5 |
+
<active>true</active>
|
6 |
+
<codePool>community</codePool>
|
7 |
+
</RocketWeb_All>
|
8 |
+
</modules>
|
9 |
+
</config>
|
app/etc/modules/RocketWeb_CustomOptionValidator.xml
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<RocketWeb_CustomOptionValidator>
|
5 |
+
<active>true</active>
|
6 |
+
<codePool>community</codePool>
|
7 |
+
</RocketWeb_CustomOptionValidator>
|
8 |
+
</modules>
|
9 |
+
</config>
|
js/rocketweb/adminhtml/custom_option_validation.js
ADDED
@@ -0,0 +1,323 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
function showValidatorsPopup(id,limitX,limitY) {
|
2 |
+
element = $(id);
|
3 |
+
|
4 |
+
var elementDims = element.getDimensions();
|
5 |
+
var viewPort = document.viewport.getDimensions();
|
6 |
+
var offsets = document.viewport.getScrollOffsets();
|
7 |
+
var centerX = viewPort.width / 2 + offsets.left - elementDims.width / 2;
|
8 |
+
var centerY = viewPort.height / 2 + offsets.top - elementDims.height / 2;
|
9 |
+
if ( limitX && centerX < limitX )
|
10 |
+
{
|
11 |
+
centerX = parseInt(limitX);
|
12 |
+
}
|
13 |
+
if ( limitY && centerY < limitY )
|
14 |
+
{
|
15 |
+
centerY = parseInt(limitY);
|
16 |
+
}
|
17 |
+
|
18 |
+
|
19 |
+
element.setStyle( { position: 'absolute', top: Math.floor(centerY) + 'px', left: Math.floor(centerX) + 'px' } ).show();
|
20 |
+
$('popup-window-mask').onclick = function(){hideValidatorsPopup(id);}
|
21 |
+
$('popup-window-mask').setStyle({
|
22 |
+
height: $('html-body').getHeight() + 'px'
|
23 |
+
}).show();
|
24 |
+
|
25 |
+
}
|
26 |
+
|
27 |
+
|
28 |
+
function hideValidatorsPopup(id) {
|
29 |
+
$(id).hide();
|
30 |
+
$(id).down('.popup-content').update('');
|
31 |
+
$('popup-window-mask').hide();
|
32 |
+
}
|
33 |
+
|
34 |
+
function submitValidatorsPopup(id) {
|
35 |
+
if(window.rwvalidators.validate()) {
|
36 |
+
window.rwvalidators.serializeCustomOptions();
|
37 |
+
hideValidatorsPopup(id);
|
38 |
+
}
|
39 |
+
}
|
40 |
+
|
41 |
+
|
42 |
+
var CustomOptionValidator = Class.create({
|
43 |
+
initialize: function(id, options) {
|
44 |
+
this.id = id;
|
45 |
+
this.options = options;
|
46 |
+
},
|
47 |
+
getExtraFieldId: function(extra_field_id,extra_field_data) {
|
48 |
+
if(this.options.extra.combined_prefix) {
|
49 |
+
return this.id+'-extra-field-'+extra_field_id;
|
50 |
+
}
|
51 |
+
else {
|
52 |
+
return this.id+'-extra-field-'+extra_field_data.prefix;
|
53 |
+
}
|
54 |
+
},
|
55 |
+
getHtml: function(inputType) {
|
56 |
+
validForInputType = false;
|
57 |
+
for(k=0;k<this.options.for_types.length;k++) {
|
58 |
+
if(this.options.for_types[k] == inputType) {
|
59 |
+
validForInputType = true;
|
60 |
+
break;
|
61 |
+
}
|
62 |
+
}
|
63 |
+
|
64 |
+
if(validForInputType) {
|
65 |
+
html = new Element('div',{'class':'validator-container validator-'+this.id});
|
66 |
+
html.insert(new Element('input',{'type':'checkbox','name':'custom_validator[]','value':this.id,'id':this.id,'class':'validator-checkbox'}))
|
67 |
+
html.insert(new Element('label',{'for':this.id}).update(this.options.title));
|
68 |
+
|
69 |
+
if(this.options.extra) {
|
70 |
+
for(var extra_id in this.options.extra.elements) {
|
71 |
+
if(this.options.extra.elements.hasOwnProperty(extra_id)) {
|
72 |
+
label = new Element('label',{'class':'extra-field-label','for' : this.getExtraFieldId(extra_id,this.options.extra.elements[extra_id])}).update(this.options.extra.elements[extra_id].label);
|
73 |
+
element = new Element('input',{ 'type':'text',
|
74 |
+
'style':this.options.extra.elements[extra_id].style,
|
75 |
+
'class':this.getExtraFieldId(extra_id,this.options.extra.elements[extra_id])+' extra-field',
|
76 |
+
'id' : this.getExtraFieldId(extra_id,this.options.extra.elements[extra_id])
|
77 |
+
});
|
78 |
+
html.insert(label);
|
79 |
+
html.insert(element);
|
80 |
+
}
|
81 |
+
}
|
82 |
+
}
|
83 |
+
|
84 |
+
if(this.options.description) {
|
85 |
+
html.insert(new Element('p',{'class':'note'}).update(this.options.description))
|
86 |
+
}
|
87 |
+
return html;
|
88 |
+
}
|
89 |
+
else {
|
90 |
+
return '';
|
91 |
+
}
|
92 |
+
}
|
93 |
+
});
|
94 |
+
|
95 |
+
var CustomOptionValidatorGroup = Class.create({
|
96 |
+
initialize: function(group_name) {
|
97 |
+
this.group_name = group_name;
|
98 |
+
this.validators = new Array();
|
99 |
+
},
|
100 |
+
|
101 |
+
addValidator: function(validator) {
|
102 |
+
this.validators.push(validator);
|
103 |
+
},
|
104 |
+
getHtmlHeader: function(inputType) {
|
105 |
+
return new Element('dt',{'class':'validation-header'}).insert(new Element('a',{'href':'#'}).update(this.group_name));
|
106 |
+
return html;
|
107 |
+
},
|
108 |
+
getHtmlContent: function(inputType) {
|
109 |
+
content= new Element('dd');
|
110 |
+
validatorCount = 0;
|
111 |
+
for(j=0;j<this.validators.length;j++) {
|
112 |
+
validatorHtml = this.validators[j].getHtml(inputType);
|
113 |
+
if(validatorHtml) {
|
114 |
+
validatorCount++;
|
115 |
+
content.insert(validatorHtml);
|
116 |
+
}
|
117 |
+
}
|
118 |
+
if(validatorCount) {
|
119 |
+
return content;
|
120 |
+
}
|
121 |
+
else {
|
122 |
+
return '';
|
123 |
+
}
|
124 |
+
}
|
125 |
+
|
126 |
+
});
|
127 |
+
|
128 |
+
currentPopupId = '';
|
129 |
+
var CustomOptionValidatorHolder = Class.create({
|
130 |
+
initialize: function(validator_data) {
|
131 |
+
this.groups = new Array();
|
132 |
+
for(var group_name in validator_data) {
|
133 |
+
if(validator_data.hasOwnProperty(group_name)) {
|
134 |
+
group = new CustomOptionValidatorGroup(group_name);
|
135 |
+
|
136 |
+
for(var validator_id in validator_data[group_name]) {
|
137 |
+
if(validator_data[group_name].hasOwnProperty(validator_id)) {
|
138 |
+
validator = new CustomOptionValidator(validator_id, validator_data[group_name][validator_id]);
|
139 |
+
group.addValidator(validator);
|
140 |
+
}
|
141 |
+
}
|
142 |
+
|
143 |
+
this.groups.push(group);
|
144 |
+
}
|
145 |
+
}
|
146 |
+
},
|
147 |
+
|
148 |
+
populateValidatorPopup: function(id_part) {
|
149 |
+
this.id_part = id_part;
|
150 |
+
that = this;
|
151 |
+
currentPopupId = 'validators_'+id_part;
|
152 |
+
|
153 |
+
//create groups & checkboxes
|
154 |
+
validatorsDivContent = $(currentPopupId).down('.popup-content');
|
155 |
+
validatorsDivContent.update('');
|
156 |
+
inputType = $(id_part+'_type').options[$(id_part+'_type').selectedIndex].value;
|
157 |
+
|
158 |
+
hasContent = false;
|
159 |
+
for(i=0;i<this.groups.length;i++) {
|
160 |
+
content = this.groups[i].getHtmlContent(inputType);
|
161 |
+
if(content) {
|
162 |
+
hasContent = true;
|
163 |
+
validatorsDivContent.insert(this.groups[i].getHtmlHeader(inputType));
|
164 |
+
validatorsDivContent.insert(content);
|
165 |
+
}
|
166 |
+
}
|
167 |
+
if(hasContent) {
|
168 |
+
//listen to onclick events & populate the hidden field
|
169 |
+
|
170 |
+
accordion = new varienAccordion('validators_'+id_part, false);
|
171 |
+
|
172 |
+
//check selected values, populate extra fields & open accordions
|
173 |
+
|
174 |
+
selectedOptions = $('custom_validators_'+id_part).value.split(' ');
|
175 |
+
if(selectedOptions.length) {
|
176 |
+
for(i1=0;i1<selectedOptions.length;i1++) {
|
177 |
+
selectedOption = selectedOptions[i1];
|
178 |
+
$$('#validators_'+id_part+' .validator-checkbox').each(function(el){
|
179 |
+
if(el.value == selectedOption) {
|
180 |
+
el.checked = true;
|
181 |
+
validator = that.getValidatorForCheckboxId(el.id);
|
182 |
+
if(validator.options.extra) {
|
183 |
+
if(validator.options.extra.combined_prefix) {
|
184 |
+
prefix = validator.options.extra.prefix;
|
185 |
+
for(j1=0;j1<selectedOptions.length;j1++) {
|
186 |
+
if(selectedOptions[j1].indexOf(prefix) == 0) {
|
187 |
+
range = selectedOptions[j1].replace(prefix+'-','');
|
188 |
+
range = range.split('-');
|
189 |
+
currentPos = 0;
|
190 |
+
$$('#'+currentPopupId+' .validator-'+validator.id+' .extra-field').each(function(element){
|
191 |
+
element.value=range[currentPos];
|
192 |
+
currentPos++;
|
193 |
+
})
|
194 |
+
}
|
195 |
+
}
|
196 |
+
}
|
197 |
+
else {
|
198 |
+
for(var element_id in validator.options.extra.elements) {
|
199 |
+
if(validator.options.extra.elements.hasOwnProperty(element_id)) {
|
200 |
+
for(j1=0;j1<selectedOptions.length;j1++) {
|
201 |
+
if(selectedOptions[j1].indexOf(validator.options.extra.elements[element_id].prefix) != -1) {
|
202 |
+
elementValue = selectedOptions[j1].replace(validator.options.extra.elements[element_id].prefix+'-','');
|
203 |
+
$$('#'+currentPopupId+' #'+validator.getExtraFieldId(element_id,validator.options.extra.elements[element_id]))[0].value = elementValue;
|
204 |
+
}
|
205 |
+
}
|
206 |
+
}
|
207 |
+
}
|
208 |
+
}
|
209 |
+
}
|
210 |
+
|
211 |
+
accordion.showItem(el.up().up().previous());
|
212 |
+
}
|
213 |
+
});
|
214 |
+
}
|
215 |
+
}
|
216 |
+
|
217 |
+
|
218 |
+
}
|
219 |
+
else {
|
220 |
+
validatorsDivContent.insert(new Element('p',{'class':'no-validators'}).update('Validators are available only for text fields and text areas'));
|
221 |
+
}
|
222 |
+
|
223 |
+
|
224 |
+
},
|
225 |
+
|
226 |
+
getValidatorForCheckboxId: function(checkbox_id) {
|
227 |
+
for(i=0;i<this.groups.length;i++) {
|
228 |
+
for(j=0;j<this.groups[i].validators.length;j++) {
|
229 |
+
if(this.groups[i].validators[j].id == checkbox_id) {
|
230 |
+
return this.groups[i].validators[j];
|
231 |
+
}
|
232 |
+
}
|
233 |
+
}
|
234 |
+
} ,
|
235 |
+
|
236 |
+
validate: function() {
|
237 |
+
that = this;
|
238 |
+
hasErrors = false;
|
239 |
+
$$('#'+currentPopupId+' .validator-checkbox').each(function(el){
|
240 |
+
if(el.checked) {
|
241 |
+
validatorObject = that.getValidatorForCheckboxId(el.id);
|
242 |
+
if(validatorObject.options.extra) {
|
243 |
+
for(var extra_id in validatorObject.options.extra.elements) {
|
244 |
+
if(validatorObject.options.extra.elements.hasOwnProperty(extra_id)) {
|
245 |
+
extraFieldId = validatorObject.getExtraFieldId(extra_id,validatorObject.options.extra.elements[extra_id]);
|
246 |
+
extraFieldValue = parseInt($$('#'+currentPopupId+' #'+extraFieldId)[0].value);
|
247 |
+
$(extraFieldId).removeClassName('error-required');
|
248 |
+
if(validatorObject.options.extra.elements[extra_id].required && !extraFieldValue) {
|
249 |
+
$(extraFieldId).addClassName('error-required');
|
250 |
+
hasErrors = true;
|
251 |
+
}
|
252 |
+
}
|
253 |
+
}
|
254 |
+
}
|
255 |
+
}
|
256 |
+
})
|
257 |
+
if(hasErrors) {
|
258 |
+
alert("Please fill in all the required fields");
|
259 |
+
return false;
|
260 |
+
}
|
261 |
+
else {
|
262 |
+
return true;
|
263 |
+
}
|
264 |
+
},
|
265 |
+
|
266 |
+
serializeCustomOptions: function() {
|
267 |
+
that = this;
|
268 |
+
selectedOptions = '';
|
269 |
+
$$('#'+currentPopupId+' .validator-checkbox').each(function(el){
|
270 |
+
if(el.checked) {
|
271 |
+
selectedOptions+=el.value+' ';
|
272 |
+
|
273 |
+
//get extra values, if any
|
274 |
+
validatorObject = that.getValidatorForCheckboxId(el.id);
|
275 |
+
if(validatorObject.options.extra) {
|
276 |
+
value = '';
|
277 |
+
if(validatorObject.options.extra.combined_prefix) {
|
278 |
+
value = validatorObject.options.extra.prefix;
|
279 |
+
}
|
280 |
+
for(var extra_id in validatorObject.options.extra.elements) {
|
281 |
+
if(validatorObject.options.extra.elements.hasOwnProperty(extra_id)) {
|
282 |
+
extraFieldId = validatorObject.getExtraFieldId(extra_id,validatorObject.options.extra.elements[extra_id]);
|
283 |
+
extraFieldValue = parseInt($$('#'+currentPopupId+' #'+extraFieldId)[0].value);
|
284 |
+
if(validatorObject.options.extra.combined_prefix) {
|
285 |
+
if(isNaN(extraFieldValue)) {
|
286 |
+
extraFieldValue = 0;
|
287 |
+
}
|
288 |
+
value+='-'+extraFieldValue;
|
289 |
+
}
|
290 |
+
else {
|
291 |
+
if(!isNaN(extraFieldValue)) {
|
292 |
+
value = validatorObject.options.extra.elements[extra_id].prefix+'-'+extraFieldValue;
|
293 |
+
selectedOptions+=value+' ';
|
294 |
+
}
|
295 |
+
}
|
296 |
+
}
|
297 |
+
}
|
298 |
+
if(validatorObject.options.extra.combined_prefix) {
|
299 |
+
selectedOptions+=value+' ';
|
300 |
+
}
|
301 |
+
}
|
302 |
+
}
|
303 |
+
$('custom_validators_'+that.id_part).value = selectedOptions;
|
304 |
+
});
|
305 |
+
}
|
306 |
+
});
|
307 |
+
|
308 |
+
|
309 |
+
function showHideConfigureValidatorsButtons() {
|
310 |
+
$$('.select-product-option-type').each(function(el){
|
311 |
+
selectedOption = el.options[el.selectedIndex].value;
|
312 |
+
buttonId = el.id+'_cfg_button';
|
313 |
+
if(selectedOption == 'field' || selectedOption == 'area') {
|
314 |
+
$(buttonId).show();
|
315 |
+
}
|
316 |
+
else {
|
317 |
+
$(buttonId).hide();
|
318 |
+
}
|
319 |
+
});
|
320 |
+
}
|
321 |
+
|
322 |
+
|
323 |
+
|
package.xml
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<package>
|
3 |
+
<name>RocketWeb_CustomOptionValidator</name>
|
4 |
+
<version>1.0.0</version>
|
5 |
+
<stability>stable</stability>
|
6 |
+
<license uri="http://www.opensource.org/licenses/osl-3.0.php">OSL v3.0</license>
|
7 |
+
<channel>community</channel>
|
8 |
+
<extends/>
|
9 |
+
<summary>Add validation to custom product options</summary>
|
10 |
+
<description>This module brings the power of Magento's form validation to the custom product options</description>
|
11 |
+
<notes>Initial release</notes>
|
12 |
+
<authors><author><name>RocketWeb</name><user>rocketweb</user><email>dev@rocketweb.com</email></author></authors>
|
13 |
+
<date>2012-12-12</date>
|
14 |
+
<time>10:27:20</time>
|
15 |
+
<contents><target name="magecommunity"><dir name="RocketWeb"><dir name="CustomOptionValidator"><dir name="Block"><dir name="Adminhtml"><file name="Validators.php" hash="a7348ceed96b90cf6f1ef7ac11d0792b"/></dir><dir name="Rewrite"><dir name="Adminhtml"><dir name="Catalog"><dir name="Product"><dir name="Edit"><dir name="Tab"><dir name="Options"><file name="Option.php" hash="794d415489e3530637626d46bad2cd6e"/></dir></dir></dir></dir></dir></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="877e3b10b9b744d2d5c9a9fcb8844616"/></dir><dir name="Model"><dir name="Validator"><file name="List.php" hash="d17083cfc6094e8b25200d0144257f4e"/><file name="Type.php" hash="f2bbc9696d79d9ff7c487a8b134e071f"/></dir><file name="Validator.php" hash="4b48a10956b1c1ba2f4c7e3761c12213"/></dir><dir name="etc"><file name="config.xml" hash="5f7a4e6639c7f3f3dbb12f7db1219720"/></dir><dir name="sql"><dir name="rocketweb_cov_setup"><file name="mysql4-install-1.0.0.php" hash="fd2d5b23ed0339f12d07c67b99f0582c"/></dir></dir></dir><dir name="All"><dir name="Helper"><file name="Data.php" hash="e6dbd2a24db3d4d7861ef1c147c1fa76"/></dir><dir name="Model"><file name="Feed.php" hash="8e6a50942b3d1e5837a5ea989b9ef490"/><file name="Observer.php" hash="f6a9c8853b162372d9ed6c6bf7e3f86c"/></dir><dir name="etc"><file name="adminhtml.xml" hash="4fd75eb093ed58499256b0104018d523"/><file name="config.xml" hash="f0f72a5904f611a6c8e6d9c6cb074a5b"/><file name="system.xml" hash="90913e8ae8134bbe09c0f0a6552ff395"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="RocketWeb_CustomOptionValidator.xml" hash="f1ce6a52c27861a4d544f357c2e8dc84"/><file name="RocketWeb_All.xml" hash="b1c635dc428097a7fca6c9a1da0b7e04"/></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="rocketweb_cov.xml" hash="9ac2f2898b730b38fedc376e25d84adf"/></dir><dir name="template"><dir name="catalog"><dir name="product"><dir name="edit"><dir name="options"><file name="option.phtml" hash="d0c9f251ac43ad7ef2ee69dec9b2bcfa"/></dir></dir></dir></dir><dir name="rocketweb_cov"><dir name="adminhtml"><file name="validators.phtml" hash="2f356f2ba5d7076985f85155168dba70"/></dir></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="template"><dir name="catalog"><dir name="product"><dir name="view"><dir name="options"><dir name="type"><file name="text.phtml" hash="524b03911b5e9766923784ba1cacb2e0"/></dir></dir></dir></dir></dir></dir></dir></dir></dir></target><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="rocketweb"><dir name="adminhtml"><file name="custom_option_validation.css" hash="b68a2e4596cff3260ae614bc7c1060be"/></dir></dir></dir></dir></dir></target><target name="mageweb"><dir name="js"><dir name="rocketweb"><dir name="adminhtml"><file name="custom_option_validation.js" hash="5b6afe6a66c384ca2227a8c7ccf6c936"/></dir></dir></dir></target></contents>
|
16 |
+
<compatible/>
|
17 |
+
<dependencies><required><php><min>4.2.0</min><max>6.0.0</max></php></required></dependencies>
|
18 |
+
</package>
|
skin/adminhtml/default/default/rocketweb/adminhtml/custom_option_validation.css
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.custom-option-validator-popup {z-index:999;position:absolute;background-color:#FAFAFA;padding-bottom:10px;width:400px;border:1px solid #D6D6D6; }
|
2 |
+
.custom-option-validator-popup .header {background: #6F8992;padding: 2px 10px;color:white;text-align:left;font-weight:bold;}
|
3 |
+
.custom-option-validator-popup .popup-content {margin-bottom:20px;padding:10px;}
|
4 |
+
.custom-option-validator-popup .popup-content dt { color:white;font-weight:bold;}
|
5 |
+
.custom-option-validator-popup .popup-content dt a {display:block;width:100%;}
|
6 |
+
.custom-option-validator-popup .popup-content dd {padding-bottom:15px;}
|
7 |
+
.custom-option-validator-popup .popup-content dd .validator-container {padding-left:10px;padding-right:10px;}
|
8 |
+
.custom-option-validator-popup .popup-content dd .validator-container .validator-checkbox {margin-right:5px;}
|
9 |
+
.custom-option-validator-popup .popup-content dd .validator-container .note {font-size:10px;line-height:11px;}
|
10 |
+
.custom-option-validator-popup .popup-content .no-validators {padding:10px;padding-bottom:0px;}
|
11 |
+
.custom-option-validator-popup .popup-content .buttons-set {margin-bottom:0px;}
|
12 |
+
.custom-option-validator-popup .popup-content .extra-field-label {margin-left:10px;font-size:11px;margin-right:5px;}
|
13 |
+
.custom-option-validator-popup .popup-content .extra-field {font-size:11px;height:12px;line-height:12px;}
|
14 |
+
.custom-option-validator-popup .close {background: url('../../images/dashboard-close.gif') no-repeat;height:13px;width:13px;display:block;float:right;position:relative;top:2px;right:-7px;}
|
15 |
+
.custom-option-validator-popup .error-required {border: 1px solid red;}
|
16 |
+
|
17 |
+
|