This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| technical_discussions:click_to_connect_extra [2021/10/24 17:16] – [Introduction] admin | technical_discussions:click_to_connect_extra [2021/10/24 19:28] (current) – [Modify the Login Pages for the Extra Options] admin | ||
|---|---|---|---|
| Line 15: | Line 15: | ||
| ===== Files To Edit ===== | ===== Files To Edit ===== | ||
| + | ==== ExtJs side (Dynamic Details Applet) | ||
| + | * Locate the file pnlDynamicDetailClickToConnect.js. | ||
| + | * It is typically under /// | ||
| + | * We will define two combo boxes below **cmbReSupply** | ||
| + | <code javascript> | ||
| + | var cmbReSupplyP = Ext.create(' | ||
| + | fieldLabel | ||
| + | store : reSupply, | ||
| + | queryMode | ||
| + | displayField | ||
| + | valueField | ||
| + | name : ' | ||
| + | itemId | ||
| + | labelCls | ||
| + | allowBlank | ||
| + | forceSelection | ||
| + | value : 0 | ||
| + | }); | ||
| + | |||
| + | var cmbReSupplyDn = Ext.create(' | ||
| + | fieldLabel | ||
| + | store : reSupply, | ||
| + | queryMode | ||
| + | displayField | ||
| + | valueField | ||
| + | name : ' | ||
| + | itemId | ||
| + | labelCls | ||
| + | allowBlank | ||
| + | forceSelection | ||
| + | value : 0 | ||
| + | }); | ||
| + | </ | ||
| + | * Then we will add check boxes for these below the email checkbox | ||
| + | <code javascript> | ||
| + | { | ||
| + | xtype : ' | ||
| + | fieldLabel | ||
| + | itemId | ||
| + | name : ' | ||
| + | inputValue | ||
| + | checked | ||
| + | disabled | ||
| + | }, | ||
| + | cmbReSupplyP, | ||
| + | { | ||
| + | xtype : ' | ||
| + | fieldLabel | ||
| + | itemId | ||
| + | name : ' | ||
| + | inputValue | ||
| + | checked | ||
| + | disabled | ||
| + | }, | ||
| + | cmbReSupplyDn | ||
| + | </ | ||
| + | * You will notice that the items we added are disabled by default. | ||
| + | * We need to also modify the View Controller to include these new components when certain action are done. | ||
| + | * Locate the file vcDynamicDetailClickToConnect.js. | ||
| + | * It is typically under /// | ||
| + | * Compare the following with your original code. | ||
| + | <code javascript> | ||
| + | Ext.define(' | ||
| + | extend | ||
| + | alias : ' | ||
| + | control: { | ||
| + | '# | ||
| + | change: ' | ||
| + | }, | ||
| + | '# | ||
| + | change: | ||
| + | }, | ||
| + | '# | ||
| + | change: | ||
| + | }, | ||
| + | '# | ||
| + | change: | ||
| + | } | ||
| + | }, | ||
| + | chkClickToConnectChange: | ||
| + | var me = this; | ||
| + | var form = chk.up(' | ||
| + | var un = form.down('# | ||
| + | var sx = form.down('# | ||
| + | var cd = form.down('# | ||
| + | var co = form.down('# | ||
| + | var re = form.down('# | ||
| + | var rs = form.down('# | ||
| + | var rp = form.down('# | ||
| + | var rsp = form.down('# | ||
| + | var rdn = form.down('# | ||
| + | var rsdn = form.down('# | ||
| + | var value = chk.getValue(); | ||
| + | if(value){ | ||
| + | un.setDisabled(false); | ||
| + | sx.setDisabled(false); | ||
| + | cd.setDisabled(false); | ||
| + | co.setDisabled(false); | ||
| + | re.setDisabled(false); | ||
| + | rs.setDisabled(false); | ||
| + | rp.setDisabled(false); | ||
| + | rsp.setDisabled(false); | ||
| + | rdn.setDisabled(false); | ||
| + | rsdn.setDisabled(false); | ||
| + | }else{ | ||
| + | un.setDisabled(true); | ||
| + | sx.setDisabled(true); | ||
| + | cd.setDisabled(true); | ||
| + | co.setDisabled(true); | ||
| + | re.setDisabled(true); | ||
| + | rs.setDisabled(true); | ||
| + | rp.setDisabled(true); | ||
| + | rsp.setDisabled(true); | ||
| + | rdn.setDisabled(true); | ||
| + | rsdn.setDisabled(true); | ||
| + | } | ||
| + | }, | ||
| + | chkCtcRequireEmailChange: | ||
| + | var me = this; | ||
| + | var form = chk.up(' | ||
| + | var value = chk.getValue(); | ||
| + | var rs = form.down('# | ||
| + | if(value){ | ||
| + | rs.setDisabled(false); | ||
| + | }else{ | ||
| + | rs.setDisabled(true); | ||
| + | } | ||
| + | }, | ||
| + | chkCtcRequirePhoneChange: | ||
| + | var me = this; | ||
| + | var form = chk.up(' | ||
| + | var value = chk.getValue(); | ||
| + | var rs = form.down('# | ||
| + | if(value){ | ||
| + | rs.setDisabled(false); | ||
| + | }else{ | ||
| + | rs.setDisabled(true); | ||
| + | } | ||
| + | }, | ||
| + | chkCtcRequireDnChange: | ||
| + | var me = this; | ||
| + | var form = chk.up(' | ||
| + | var value = chk.getValue(); | ||
| + | var rs = form.down('# | ||
| + | if(value){ | ||
| + | rs.setDisabled(false); | ||
| + | }else{ | ||
| + | rs.setDisabled(true); | ||
| + | } | ||
| + | } | ||
| + | }); | ||
| + | </ | ||
| + | * Finally we need to add those extra fields to the grid displaying these items | ||
| + | * Locate the file gridDynamicDetailEmails.js. | ||
| + | * It is typically under /// | ||
| + | * See the following snippet | ||
| + | <code javascript> | ||
| + | { text: ' | ||
| + | { text: ' | ||
| + | { text: ' | ||
| + | { | ||
| + | text : ' | ||
| + | dataIndex | ||
| + | tdCls : ' | ||
| + | hidden | ||
| + | flex : 1, | ||
| + | stateId : ' | ||
| + | }, | ||
| + | </ | ||
| + | * Remember to run **Sencha Command** after these to generate the optimized JavaScript code. | ||
| + | * There is a dedicated Wiki Page in this site for it. | ||
| + | * Next we will see what we need to modify on the CakePHP3 App Side. | ||
| + | |||
| + | ==== CakePHP3 App Side ==== | ||
| + | * We need to add extra fields to the **dynamic_details** sql table inside the **rd** database. | ||
| + | * See the following SQL Patch snippet which add those fields if not present | ||
| + | <code sql> | ||
| + | if not exists (select * from information_schema.columns | ||
| + | where column_name = ' | ||
| + | alter table dynamic_details add column `ctc_require_phone` tinyint(1) NOT NULL DEFAULT ' | ||
| + | end if; | ||
| + | |||
| + | if not exists (select * from information_schema.columns | ||
| + | where column_name = ' | ||
| + | alter table dynamic_details add column `ctc_resupply_phone_interval` int(4) NOT NULL DEFAULT ' | ||
| + | end if; | ||
| + | |||
| + | if not exists (select * from information_schema.columns | ||
| + | where column_name = ' | ||
| + | alter table dynamic_details add column `ctc_require_dn` tinyint(1) NOT NULL DEFAULT ' | ||
| + | end if; | ||
| + | |||
| + | if not exists (select * from information_schema.columns | ||
| + | where column_name = ' | ||
| + | alter table dynamic_details add column `ctc_resupply_dn_interval` int(4) NOT NULL DEFAULT ' | ||
| + | end if; | ||
| + | </ | ||
| + | * We also need to add extra field to the **data_collectors** sql table inside the **rd** database. | ||
| + | * See the following SQL Patch snippet which add those fields if not present | ||
| + | <code sql> | ||
| + | if not exists (select * from information_schema.columns | ||
| + | where column_name = ' | ||
| + | alter table data_collectors add column `phone` varchar(36) NOT NULL DEFAULT ''; | ||
| + | end if; | ||
| + | |||
| + | if not exists (select * from information_schema.columns | ||
| + | where column_name = ' | ||
| + | alter table data_collectors add column `dn` varchar(36) NOT NULL DEFAULT ''; | ||
| + | end if; | ||
| + | </ | ||
| + | * After taking care of the database lets see what needs to be modified to the CakePHP 3 controllers | ||
| + | * Locate the file DynamicDetailsController.php. | ||
| + | * It is typically under /// | ||
| + | * There is not much that needs modification since CakePHP takes care of most things behind the scenes. | ||
| + | * Just locate the **editClickToConnect** method and modify **$check_items** | ||
| + | <code php> | ||
| + | $check_items = [ | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ]; | ||
| + | </ | ||
| + | * Locate the file DataCollectorsController.php. | ||
| + | * It is typically under /// | ||
| + | * We will modify the login page eventually to have various options displayed in the Pop-Up for Click-To-Connect so we need to modify the DataCollectorsController to only check the email field **IF PRESENT** | ||
| + | * See the following snippets | ||
| + | <code php> | ||
| + | public function addMac(){ | ||
| + | if ($this-> | ||
| + | if($this-> | ||
| + | if(!$this-> | ||
| + | return; | ||
| + | } | ||
| + | } | ||
| + | $dd = $this-> | ||
| + | </ | ||
| + | * And this one | ||
| + | <code php> | ||
| + | private function _addOrEdit($user, | ||
| + | |||
| + | //__ Authentication + Authorization __ | ||
| + | | ||
| + | $user_id | ||
| + | | ||
| + | if($this-> | ||
| + | if(!$this-> | ||
| + | return; | ||
| + | } | ||
| + | } | ||
| + | | ||
| + | $this-> | ||
| + | </ | ||
| + | * Also the **macCheck** method need to give feedback on those new methods in order so we can determine which fields must be shown in the Pop-Up | ||
| + | <code php> | ||
| + | public function macCheck(){ | ||
| + | |||
| + | $data = $this-> | ||
| + | $q_r = $this-> | ||
| + | | ||
| + | $data[' | ||
| + | |||
| + | if($q_r){ | ||
| + | |||
| + | //Once we found the Dynamic Login Page; We need to figure out if we need to ask for an email for this person | ||
| + | //For that we need to look for a combo **dynamic_detail_id** and **mac** | ||
| + | //IF found look at the modify timestamp and if it ' | ||
| + | //If not found ask for it (ctc_require_email == true) | ||
| + | //Else we set ctc_require_email == false since we found the combo and it has not expired yet | ||
| + | $dd_id | ||
| + | $dd_resuply_int = $q_r-> | ||
| + | $dd_resuply_intP = $q_r-> | ||
| + | $data[' | ||
| + | | ||
| + | if($q_r-> | ||
| + | $q_dd = $this-> | ||
| + | -> | ||
| + | -> | ||
| + | if($q_dd){ | ||
| + | if($dd_resuply_int > 0){ //This has an expiry date lets compare | ||
| + | | ||
| + | $expiry_time | ||
| + | $now = new FrozenTime(); | ||
| + | if($expiry_time < $now-> | ||
| + | //It already expired ask for a new one | ||
| + | $data[' | ||
| + | } | ||
| + | } | ||
| + | }else{ | ||
| + | $data[' | ||
| + | } | ||
| + | } | ||
| + | | ||
| + | if($q_r-> | ||
| + | $q_dd = $this-> | ||
| + | -> | ||
| + | -> | ||
| + | if($q_dd){ | ||
| + | if($dd_resuply_intP > 0){ //This has an expiry date lets compare | ||
| + | $expiry_time | ||
| + | $now = new FrozenTime(); | ||
| + | if($expiry_time < $now-> | ||
| + | //It already expired ask for a new one | ||
| + | $data[' | ||
| + | } | ||
| + | } | ||
| + | }else{ | ||
| + | $data[' | ||
| + | } | ||
| + | } | ||
| + | | ||
| + | if($q_r-> | ||
| + | $q_dd = $this-> | ||
| + | -> | ||
| + | -> | ||
| + | if($q_dd){ | ||
| + | if($dd_resuply_intP > 0){ //This has an expiry date lets compare | ||
| + | $expiry_time | ||
| + | $now = new FrozenTime(); | ||
| + | if($expiry_time < $now-> | ||
| + | //It already expired ask for a new one | ||
| + | $data[' | ||
| + | } | ||
| + | } | ||
| + | }else{ | ||
| + | $data[' | ||
| + | } | ||
| + | } | ||
| + | | ||
| + | } | ||
| + | | ||
| + | $this-> | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | )); | ||
| + | | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | * This brings us to the end of the CakePHP 3 modifications. | ||
| + | * The only remaining part is the login page themselves. | ||
| + | |||
| + | ==== Modify the Login Pages for the Extra Options ==== | ||
| + | * Locate the file rdConnect.js. | ||
| + | * It is typically under /// | ||
| + | * We need to add a flag to set if we created the pop-up window (**ctcFormDone**) | ||
| + | <code javascript> | ||
| + | cMinWidth | ||
| + | scrollHeight | ||
| + | |||
| + | var ctcFormDone | ||
| + | |||
| + | fDebug | ||
| + | if(cDebug){ | ||
| + | console.log(message) | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | </ | ||
| + | * Next we have to add some **OR** coonditions when the user click on the **Click To Connect** button | ||
| + | <code javascript> | ||
| + | var email_check = location.protocol+'//' | ||
| + | |||
| + | webix.ajax().timeout(3000).post( | ||
| + | email_check, | ||
| + | error : function(text, | ||
| + | console.log(" | ||
| + | }, | ||
| + | success : function(text, | ||
| + | if(data.json().success == true){ | ||
| + | if((data.json().data.ctc_require_email == true)||(data.json().data.ctc_require_phone == true)||(data.json().data.ctc_require_dn == true)){ | ||
| + | if(ctcFormDone == false){ //If not already done | ||
| + | buildClickToConnectForm(data.json().data); | ||
| + | } | ||
| + | showForm(" | ||
| + | }else{ | ||
| + | onBtnClickToConnectClick(); | ||
| + | } | ||
| + | }else{ | ||
| + | console.log(" | ||
| + | } | ||
| + | } | ||
| + | }); | ||
| + | </ | ||
| + | * Lets then see the function that is called **buildClickToConnectForm**. | ||
| + | * This is called only once. | ||
| + | * We also include validation rules for those fields. | ||
| + | <code javascript> | ||
| + | var buildClickToConnectForm = function(data){ | ||
| + | |||
| + | console.log(" | ||
| + | console.log(data); | ||
| + | var e1 = { | ||
| + | view : " | ||
| + | template | ||
| + | }; | ||
| + | var e2 = { view:" | ||
| + | var e3 = { view:" | ||
| + | var e4 = { view:" | ||
| + | var b1 = { view:" | ||
| + | if (this.getParentView().validate()){ //validate form | ||
| + | var button | ||
| + | var formData | ||
| + | var mac_address = getParameterByName(' | ||
| + | formData.append(" | ||
| + | | ||
| + | var values | ||
| + | console.log(values); | ||
| + | if(values.email){ | ||
| + | formData.append(" | ||
| + | } | ||
| + | if(values.phone){ | ||
| + | formData.append(" | ||
| + | } | ||
| + | if(values.dn){ | ||
| + | formData.append(" | ||
| + | } | ||
| + | | ||
| + | |||
| + | //We also add the following | ||
| + | var called | ||
| + | formData.append(" | ||
| + | |||
| + | var nasid = getParameterByName(' | ||
| + | formData.append(" | ||
| + | |||
| + | //This might not always be included | ||
| + | var ssid = getParameterByName(' | ||
| + | if(ssid !== '' | ||
| + | formData.append(" | ||
| + | } | ||
| + | | ||
| + | var add_mac | ||
| + | webix.ajax().timeout(3000).post( | ||
| + | add_mac, | ||
| + | formData, | ||
| + | { | ||
| + | error : function(text, | ||
| + | console.log(" | ||
| + | }, | ||
| + | success : function(text, | ||
| + | if(data.json().success == true){ | ||
| + | // | ||
| + | webix.message(" | ||
| + | button.getTopParentView().hide(); | ||
| + | onBtnClickToConnectClick(); | ||
| + | | ||
| + | }else{ | ||
| + | // | ||
| + | webix.message({ type:" | ||
| + | } | ||
| + | } | ||
| + | }); | ||
| + | | ||
| + | } | ||
| + | else | ||
| + | webix.message({ type:" | ||
| + | }}; | ||
| + | | ||
| + | var elements = [e1]; | ||
| + | var height | ||
| + | var rules = {}; | ||
| + | | ||
| + | if(data.ctc_require_email == true){ | ||
| + | elements.push(e2); | ||
| + | height = height+60; | ||
| + | rules.email = webix.rules.isEmail; | ||
| + | } | ||
| + | if(data.ctc_require_phone == true){ | ||
| + | elements.push(e3); | ||
| + | height | ||
| + | rules.phone = function(value){ | ||
| + | if (! / | ||
| + | webix.message(" | ||
| + | return false; | ||
| + | } | ||
| + | return true; | ||
| + | }; | ||
| + | } | ||
| + | if(data.ctc_require_dn == true){ | ||
| + | elements.push(e4); | ||
| + | height = height+60; | ||
| + | rules.dn = function(value){ | ||
| + | if (! / | ||
| + | webix.message(" | ||
| + | return false; | ||
| + | } | ||
| + | return true; | ||
| + | }; | ||
| + | } | ||
| + | elements.push(b1); | ||
| + | | ||
| + | frmEmail = { | ||
| + | view :" | ||
| + | borderless | ||
| + | elements | ||
| + | rules : | ||
| + | elementsConfig: | ||
| + | labelPosition:" | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | | ||
| + | view : " | ||
| + | id : " | ||
| + | head : false, | ||
| + | height | ||
| + | body : | ||
| + | }); | ||
| + | | ||
| + | ctcFormDone = true; | ||
| + | } | ||
| + | |||
| + | </ | ||
| + | * That brings us to the totality of the changes required. | ||
| + | * These login pages does not need any further optimization. (They are done using Webix) | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||