I have created a custom module on vTiger 6.5.
I have made an event handler for the module but I am wondering how I could perform some sort of validation on this field. So fat I have done this but I am unable to get it work, I have tested the handler just echoing a sting and it works fine.
Please see my code below. Thanks!
<?php
/*+***********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
*************************************************************************************/
# getModuleName : Returns the module name of the entity.
# getId : Returns id of the entity, this will return null if the id has not been saved yet.
# getData : Returns the fields of the entity as an array where the field name is the key and the fields value is the value.
# isNew : Returns true if new record is being created, false otherwise.
# 'vtiger.entity.beforesave.modifiable' : Setting values : $data->set('simple_field', 'value');
class isaHandler extends VTEventHandler {
function handleEvent($eventName, $entityData) {
global $adb;
$moduleName = $entityData->getModuleName();
if($moduleName=='isa'){
if($eventName == 'vtiger.entity.beforesave.modifiable') {}
if($eventName == 'vtiger.entity.beforesave') {
if('currentamount' > 20000){
echo "Please go back and enter less than 20000";
exit;
}
}
if($eventName == 'vtiger.entity.beforesave.final') {}
if($eventName == 'vtiger.entity.aftersave') {
}
}
}
}
?>
After doing some searching around and looking at other peoples event handlers I managed to solve this by changing:
if($eventName == 'vtiger.entity.beforesave') {
if('currentamount' > 20000){
echo "Please go back and enter less than 20000";
exit;
}
to
if($eventName == 'vtiger.entity.beforesave') {
$price = $entityData->get('currentamount');
if($price > 20000){
echo "Please go back and enter less than 20000";
exit;
}
Now I want to see if I can display the message and then give a link to go back to the entity module with all the fields still full.
In my opinion you should use the recordPreSave function.
It's allow you to display an information/error message before to save data on the database
Here is an example:
In your Edit.js:
donCache : {},
checkDon : function(details) {
// alert("checkOverlap");
var aDeferred = jQuery.Deferred();
var params = {
'module' : 'Affectations',
'action' : "checkAffectAmount",
'mode': 'CtrlAffectAmount',
'recordId' : details.don,
'montant' : details.montant
}
AppConnector.request(params).then(
function(data) {
if (data.success == true) {
// console.log(data.result);
var statut = data.result.statut;
var reste = data.result.reste;
if(statut == "error"){
aDeferred.reject(data);
}else {
aDeferred.resolve(data);
}
}
},
function(error,err){
aDeferred.reject();
}
);
return aDeferred.promise();
},
registerRecordPreSaveEvent : function(form) {
var thisInstance = this;
if (typeof form == 'undefined') {
form = this.getForm();
}
form.on(Vtiger_Edit_Js.recordPreSave, function(e, data) {
var check = false;
var recordId = jQuery('input[name="record"]').val();
if (!recordId || recordId) {
var montant_affectation = jQuery("input[name='affectations_montant']").val();
var don_id = jQuery("input[name='affectations_potentialid']").val();
var params = {};
if (!(check in thisInstance.donCache)) {
thisInstance.checkDon({
'montant' : montant_affectation,
'don': don_id
}).then(
function(data){
thisInstance.donCache[check] = data['success'];
form.submit();
},
function(data, err){
thisInstance.donCache[check] = data['success'];
var reste = data.result.reste;
var msg = app.vtranslate("<strong>Attention!</strong> La somme des affectations est supérieure de ")+ reste +app.vtranslate(" Euros au montant du don");
Vtiger_Helper_Js.showPnotify(msg);
delete thisInstance.donCache[check];
}
);
} else {
delete thisInstance.donCache[check];
return true;
}
e.preventDefault();
}
})
},
The PHP part in modules/isa/actions:
<?php
/***********************************
** DEBUT ALTAIR - JPR 15/06/2016 ***
***********************************/
class Affectations_checkAffectAmount_Action extends Vtiger_Action_Controller {
function __construct() {
$this->exposeMethod('CtrlAffectAmount');
}
public function checkPermission(Vtiger_Request $request) {
$moduleName = $request->getModule();
$moduleModel = Vtiger_Module_Model::getInstance($moduleName);
$userPrivilegesModel = Users_Privileges_Model::getCurrentUserPrivilegesModel();
$permission = $userPrivilegesModel->hasModulePermission($moduleModel->getId());
if(!$permission) {
throw new AppException('LBL_PERMISSION_DENIED');
}
}
public function process(Vtiger_Request $request) {
$mode = $request->getMode();
if(!empty($mode) && $this->isMethodExposed($mode)) {
$this->invokeExposedMethod($mode, $request);
return;
}
}
function CtrlAffectAmount(Vtiger_Request $request){
global $adb,$log;
$log->debug("ALTAIR CtrlAffectAmount OK");
$recordId = $request->get('recordId');
$montant = $request->get('montant');
// $query = $adb->pquery("SELECT SUM(unit_price) AS sommeaffectation FROM vtiger_products INNER JOIN vtiger_crmentity ON vtiger_products.productid = vtiger_crmentity.crmid WHERE don_affecte = ? AND vtiger_crmentity.deleted=0",array($recordId));
$query = $adb->pquery("SELECT SUM(affectations_montant) AS sommeaffectation FROM vtiger_affectations INNER JOIN vtiger_crmentity ON vtiger_affectations.affectationsid = vtiger_crmentity.crmid WHERE vtiger_affectations.affectations_potentialid = ? AND vtiger_crmentity.deleted=0",array($recordId));
$sommeAffectation = $adb->query_result($query,0,"sommeaffectation");
$query = $adb->pquery("SELECT amount FROM vtiger_potential INNER JOIN vtiger_crmentity ON vtiger_potential.potentialid = vtiger_crmentity.crmid WHERE potentialid = ? AND vtiger_crmentity.deleted = 0", array($recordId));
$montantDon = $adb->query_result($query,0,"amount");
if ( ($sommeAffectation + $montant) == $montantDon) {
$statut = "ok";
$reste = "";
} else if( ($sommeAffectation + $montant) > $montantDon) {
$statut = "error";
$reste = ($sommeAffectation + $montant) - $montantDon;
}
$value = array('statut'=>$statut, 'reste'=>$reste);
$response = new Vtiger_Response();
$response->setEmitType(Vtiger_Response::$EMIT_JSON);
$response->setResult($value);
$response->emit();
}
}
Oh. you have 1 invalid error here. please change:
if($eventName == 'vtiger.entity.beforesave') {
$currentAmount = $entityData->get('currentamount');
if($currentAmount > 20000){
echo "Please go back and enter less than 20000";
exit;
}
}
Related
I am not receiving the myStatus when retrieving it from the php login. I get p_id and full name but not the status. I am parsing it to separate out the & but keep getting a null result from login. section 6 and section 7 are the areas I think I am having issues can anyone help?
login AS3
package {
import flash.display.MovieClip;
import flash.text.*;
import flash.events.*;
import flash.ui.Keyboard;
import flash.net.*;
import MainDocument;
public class Login extends MovieClip {
public function Login() {
// constructor code
// modify existing text boxes
login_txt.tabEnabled = true;
login_txt.tabIndex = 1;
login_txt.border = true;
login_txt.borderColor = 0xAAAAAA;
login_txt.background = true;
login_txt.backgroundColor = 0xFFFFDD;
pwd_txt.tabEnabled = true;
pwd_txt.tabIndex = 2;
pwd_txt.border = true;
pwd_txt.borderColor = 0xAAAAAA;
pwd_txt.background = true;
pwd_txt.backgroundColor = 0xFFFFDD;
login_btn.tabEnabled = true;
login_btn.tabIndex = 3;
//add button event listeners
login_btn.addEventListener(MouseEvent.MOUSE_UP, doLogin);
login_close_btn.addEventListener(MouseEvent.MOUSE_UP, doClose);
addEventListener(KeyboardEvent.KEY_DOWN, onEnter);
} // end construtor
private function onEnter(e:KeyboardEvent):void{
// nothing yet
if(e.keyCode == Keyboard.ENTER){
trace("User presses keyboard ENTER key");
doLogin(null); // must be null to meet the need for a parameter
}// end if
}// end function
// SECTION 1 – This is a function we need for removing extra whitespace coming from CWP server
function trimWhitespace($string:String):String {
if ($string == null) {
return "";
} //end if
return $string.replace(/^\s+|\s+$/g, ""); // see regular expressions
} // end function
private function doLogin(e:MouseEvent):void{
//trace("User presses OK button");
// SECTION 2 – URL request variable declared with path to server script
var req:URLRequest=new URLRequest(MainDocument.localPath + "login.php");
req.method = URLRequestMethod.POST;
// SECTION 3 – Upload variables are named as URL variables
var vars:URLVariables=new URLVariables();
vars.login = login_txt.text;
vars.pwd = pwd_txt.text;
req.data = vars;
// SECTION 4 – The URL Loader class instance is set to perform the HTTP POST
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.VARIABLES;
loader.load(req);
// SECTION 5 – listeners are added for both the HTTP status and COMPLETE
loader.addEventListener(HTTPStatusEvent.HTTP_STATUS,onHTTPStatus);
loader.addEventListener(Event.COMPLETE, retrieveData);
// SECTION 6 – The complete handler function is embedded within the doLogin() function
function retrieveData(e:Event):void {
// For the CWP server we must parse our own incoming data
var rawString:String = trimWhitespace(unescape(e.target.data));
var stArray:Array = rawString.split("&"); //split on ampersand character
trace("retrieve data");
for(var i:uint; i<stArray.length; i++){
stArray[i] = trimWhitespace(stArray[i]);
var pair:Array = stArray[i].split("=");
pair[0] = trimWhitespace(pair[0]);
switch (pair[0]){
case "myStatus":
var ms:String = trimWhitespace(pair[1]); // status data value
break;
case "p_id":
var id:int = int(trimWhitespace(pair[1])); // player id
break;
case "fullname":
var fn:String = trimWhitespace(pair[1]); // fullname
break;
default: // this is all the other junk---> dump
//do nothing
} // end switch
} //end for
// SECTION 7 – A switch statement to deal with cases of myStatus
switch (ms){
case "NOTOK" :
MainDocument.doc.showMsg("There is a communication problem\nTry Again!");
break;
case "OK" :
if(fn != "INVALID"){
MainDocument.doc.showMsg("Welcome " + fn);
//MainDocument.player_id = id;
//MainDocument.player_name = fn;
MainDocument.doc.removeLogin();
MainDocument.doc.turnOffButton("both");
//MainDocument.doc.enable_chat_button();
//MainDocument.doc.activateConsole();
////////////////////////
// start game here
////////////////////////
}else{
MainDocument.doc.showMsg("Login or password is incorrect. Try again, or \nif you are not a member, please register");
MainDocument.doc.turnOnButton("register");
MainDocument.doc.turnOffButton("login");
}
break;
default:
//MainDocument.doc.showMsg("An unknown problem has occured");
} // end switch
} // end function
// SECTION 8 – Handler function for HTTP status – also embedded
function onHTTPStatus(event:HTTPStatusEvent):void {
//trace("HTTP response code " + event.status);
if(event.status!=200){
MainDocument.doc.showMsg("There is an I/O Error #" + event.status);
} // end if
} // end function
} // end function doLogin
private function doClose(e:MouseEvent):void{
// nothing yet
trace("User presses Close button");
MainDocument.doc.showMsg(""); // clears any message
MainDocument.doc.removeLogin();
MainDocument.doc.turnOnButton("both");
}// end function
}//end class
}// end package
login.php
<?php
require_once("settings.inc.php");
// Create vars and load with incoming POST data
$login = $_POST['login'];
if(!isset($login)){
$login = $_GET['login'];
}
$pwd = $_POST['pwd'];
if(!isset($pwd)){
$pwd = $_GET['pwd'];
}
//=========================================================================================
// MAIN
//=========================================================================================
if(!(isset($login) && isset($pwd))){
print "myStatus=NOTOK&dummy=dummy";
}else{
$query = "SELECT `p_id`,`p_name` FROM `player` WHERE `p_login`='$login' AND `p_pwd`='$pwd'";
$result = mysqli_query($link,$query);
$row = mysqli_fetch_row($result);
if($row[0] != null && $row[0] != ''){
$p_id = $row[0];
$fullname = trim($row[1]);
$myStatus = $row[2];
print "myStatus=OK&p_id=" . trim($p_id) . "&fullname=" . trim($fullname) . "&dummy=dummy";
}else{
$fullname = "INVALID";
print "myStatus=OK&fullname=" . trim($fullname) . "&dummy=dummy";
} //end else
} //end else
?>
I'm connecting hybrid app to the API of the web app to query certain data after search request by the user. I'm using Onsen UI to build the app.
The API code at the server side should return the merchant that the user searched for by it's name. The result should be only 1 merchant (restaurant name)
public function actionSearchMerchant()
{
if (!isset($this->data['merchant'])){
$this->msg=$this->t("Restaurant Name is required");
$this->output();
}
if (isset($_GET['debug'])){
dump($this->data);
}
if ( !empty($this->data['merchant'])){
$DbExt=new DbExt;
$DbExt->qry("SET SQL_BIG_SELECTS=1");
$total_records=0;
$data='';
$and="AND status='active' AND is_ready='2' ";
$services_filter='';
if (isset($this->data['services'])){
$services=!empty($this->data['services'])?explode(",",$this->data['services']):false;
if ($services!=false){
foreach ($services as $services_val) {
if(!empty($services_val)){
$services_filter.="'$services_val',";
}
}
$services_filter=substr($services_filter,0,-1);
if(!empty($services_filter)){
$and.=" AND service IN ($services_filter)";
}
}
}
$filter_cuisine='';
if (isset($this->data['cuisine_type'])){
$cuisine_type=!empty($this->data['cuisine_type'])?explode(",",$this->data['cuisine_type']):false;
if ($cuisine_type!=false){
$x=1;
foreach (array_filter($cuisine_type) as $cuisine_type_val) {
if ( $x==1){
$filter_cuisine.=" LIKE '%\"$cuisine_type_val\"%'";
} else $filter_cuisine.=" OR cuisine LIKE '%\"$cuisine_type_val\"%'";
$x++;
}
if (!empty($filter_cuisine)){
$and.=" AND (cuisine $filter_cuisine)";
}
}
}
$rname=$this->data['merchant'];
$stmt="SELECT * FROM
{{view_merchant}}
WHERE
restaurant_name LIKE '%\"$rname\"%'
SELECT a.*,count(*) as total_records FROM
{{view_merchant}} a
WHERE
restaurant_name LIKE '%\"$rname\"%'
$and
LIMIT 0,100
";
if (isset($_GET['debug'])){
dump($stmt);
}
if ( $res=$DbExt->rst($stmt)){
$stmtc="SELECT FOUND_ROWS() as total_records";
if ($resp=$DbExt->rst($stmtc)){
$total_records=$resp[0]['total_records'];
}
$this->code=1;
$this->msg=$this->t("Successful");
foreach ($res as $val) {
$minimum_order=getOption($val['merchant_id'],'merchant_minimum_order');
if(!empty($minimum_order)){
$minimum_order=displayPrice(getCurrencyCode(),prettyFormat($minimum_order));
}
$delivery_fee=getOption($val['merchant_id'],'merchant_delivery_charges');
if (!empty($delivery_fee)){
$delivery_fee=displayPrice(getCurrencyCode(),prettyFormat($delivery_fee));
}
/*check if mechant is open*/
$open=AddonMobileApp::isMerchantOpen($val['merchant_id']);
/*check if merchant is commission*/
$cod=AddonMobileApp::isCashAvailable($val['merchant_id']);
$online_payment='';
$tag='';
$tag_raw='';
if ($open==true){
$tag=$this->t("open");
$tag_raw='open';
if ( getOption( $val['merchant_id'] ,'merchant_close_store')=="yes"){
$tag=$this->t("close");
$tag_raw='close';
}
if (getOption( $val['merchant_id'] ,'merchant_preorder')==1){
$tag=$this->t("pre-order");
$tag_raw='pre-order';
}
} else {
$tag=$this->t("close");
$tag_raw='close';
if (getOption( $val['merchant_id'] ,'merchant_preorder')==1){
$tag=$this->t("pre-order");
$tag_raw='pre-order';
}
}
$data[]=array(
'merchant_id'=>$val['merchant_id'],
'restaurant_name'=>$val['restaurant_name'],
'address'=>$val['street']." ".$val['city']." ".$val['state']." ".$val['post_code'],
'ratings'=>Yii::app()->functions->getRatings($val['merchant_id']),
'cuisine'=>AddonMobileApp::prettyCuisineList($val['cuisine']),
'delivery_fee'=>$delivery_fee,
'minimum_order'=>$minimum_order,
'delivery_est'=>getOption($val['merchant_id'],'merchant_delivery_estimation'),
'is_open'=>$tag,
'tag_raw'=>$tag_raw,
'payment_options'=>array(
'cod'=>$cod,
'online'=>$online_payment
),
'logo'=>AddonMobileApp::getMerchantLogo($val['merchant_id']),
'offers'=>AddonMobileApp::getMerchantOffers($val['merchant_id'])
);
}
$this->details=array(
'total'=>$total_records,
'data'=>$data
);
} else $this->msg=$this->t("No restaurant found");
} else $this->msg=$this->t("Error has occurred failed restaurant info");
} else $this->msg=$this->t("Restaurant Name is required");
$this->output();
}
Basically I'm sending a parameter names "merchant" from the app that the API should get and search a table into the database called "view_merchant" column "restaurant_name" and compare the name requested by the one in the database then return it back to the app as found.
EDIT I added the JS function
var search_restaurant;
var search_cuisine;
var search_food;
$("#r").val( getStorage("search_restaurant") );
$("#c").val( getStorage("search_cuisine") );
$("#f").val( getStorage("search_food") );
function searchMerchantName()
{
var r = $('#r').val();
/*clear all storage*/
setStorage("search_restaurant",r);
removeStorage('merchant_id');
removeStorage('shipping_address');
removeStorage('merchant_id');
removeStorage('transaction_type');
removeStorage('merchant_logo');
removeStorage('order_total');
removeStorage('merchant_name');
removeStorage('total_w_tax');
removeStorage('currency_code');
removeStorage('paymet_desc');
removeStorage('order_id');
removeStorage('order_total_raw');
removeStorage('cart_currency_symbol');
removeStorage('paypal_card_fee');
if(r!=""){
var options = {
merchant:r,
closeMenu:true,
animation: 'slide'
};
menu.setMainPage('searchMerchants.html',options);
} else{
onsenAlert( getTrans('Restaurant Name is required','merchant_is_required') );
}
}
function searchCuisine()
{
var c = $('#c').val();
/*clear all storage*/
setStorage("search_cuisine",c);
removeStorage('merchant_id');
removeStorage('shipping_address');
removeStorage('merchant_id');
removeStorage('transaction_type');
removeStorage('merchant_logo');
removeStorage('order_total');
removeStorage('merchant_name');
removeStorage('total_w_tax');
removeStorage('currency_code');
removeStorage('paymet_desc');
removeStorage('order_id');
removeStorage('order_total_raw');
removeStorage('cart_currency_symbol');
removeStorage('paypal_card_fee');
if(c!=""){
var options = {
cuisine:c,
closeMenu:true,
animation: 'slide'
};
menu.setMainPage('searchCuisine.html',options);
} else{
onsenAlert( getTrans('Cuisine Type is required','cuisine_is_required') );
}
}
function searchFood()
{
var f = $('#f').val();
/*clear all storage*/
setStorage("search_food",f);
removeStorage('merchant_id');
removeStorage('shipping_address');
removeStorage('merchant_id');
removeStorage('transaction_type');
removeStorage('merchant_logo');
removeStorage('order_total');
removeStorage('merchant_name');
removeStorage('total_w_tax');
removeStorage('currency_code');
removeStorage('paymet_desc');
removeStorage('order_id');
removeStorage('order_total_raw');
removeStorage('cart_currency_symbol');
removeStorage('paypal_card_fee');
if(f!=""){
var options = {
foodname:f,
closeMenu:true,
animation: 'slide'
};
menu.setMainPage('searchFood.html',options);
} else{
onsenAlert( getTrans('Food Name is required','foodname_is_required') );
}
}
case "searchmerchant-page":
$("#search-text").html( getStorage("search_restaurant") );
callAjax("searchmerchant","merchant="+ getStorage("search_restaurant") );
break;
case "searchcuisine-page":
$("#search-text").html( getStorage("search_cuisine") );
callAjax("searchcuisine","cuisine="+ getStorage("search_cuisine") );
break;
case "searchfood-page":
$("#search-text").html( getStorage("search_food") );
callAjax("searchfood","foodname="+ getStorage("search_food") );
break;
case "page-home":
geoComplete();
search_address=getStorage("search_address");
if (typeof search_address === "undefined" || search_address==null || search_address=="" ) {
} else {
setTimeout('$("#s").val(search_address)', 1000);
}
translatePage();
$("#s").attr("placeholder", getTrans('Street Address,City,State','home_search_placeholder') );
//Added for Restaurant Name Search
search_restaurant=getStorage("search_restaurant");
if (typeof search_restaurant === "undefined" || search_restaurant==null || search_restaurant=="" ) {
} else {
setTimeout('$("#r").val(search_restaurant)', 1000);
}
translatePage();
$("#r").attr("placeholder", getTrans('Restaurant Name','restaurant_search_placeholder') );
//Added for Cuisine Type
search_cuisine=getStorage("search_cuisine");
if (typeof search_cuisine === "undefined" || search_cuisine==null || search_cuisine=="" ) {
} else {
setTimeout('$("#c").val(search_cuisine)', 1000);
}
translatePage();
$("#c").attr("placeholder", getTrans('Cuisine Type','cuisine_search_placeholder') );
//Added for Food Type
search_food=getStorage("search_food");
if (typeof search_food === "undefined" || search_food==null || search_food=="" ) {
} else {
setTimeout('$("#f").val(search_food)', 1000);
}
translatePage();
$("#f").attr("placeholder", getTrans('Food Name','food_search_placeholder') );
break;
function searchResultCallBack(address)
{
search_address=address;
}
function searchMerchantsCallBack(merchant)
{
search_restaurant=merchant;
}
function searchCuisineCallBack(cuisine)
{
search_cuisine=cuisine;
}
function searchFoodCallBack(foodname)
{
search_food=foodname;
}
Your SQL statement will be:
SELECT * FROM view_merchant WHERE lower(restaurant_name)=?
You will want to toLowerCase() your passed value $this->data['merchant'] so you are finding the restaurant regardless of casing. The only issue is that this will return multiple records if there are ones with the same name.
I have a SQL view in phpmyadmin which has a is used to populate data in a table created using jquery jtable. The issue is quite bizarre as only one column's data which is being pulled by the view isn't being displayed and all of the others are being displayed without an issue. There is also no issue when I edit the fields and I can see the changes I made in phpmyadmin. How do I get the Successful column to display ? All help is greatly appreciated.
Screenshot of the table
js which handles creation of the table
function getLessonsLearnedResponseChildTable(ContainerID) {
var table = {
title: '',
width: '5%',
sorting: false,
edit: false,
create: false,
display: function(data) {
//create an image to be used to open child table
var $img = $('<img src="' + config.base_url + 'assets/images/expand_row-small.png" title="View Responses" style="height:30px;width:30px;cursor:pointer;" height="30" width="30"/>');
$img.click(function() {
$('#' + ContainerID).jtable('openChildTable',
$img.closest('tr'),
{
title: data.record.event,// + ' - Response Plans'
actions: {
listAction: config.base_url + "data_fetch/responses/" + data.record.risk_id,
deleteAction: config.base_url + 'data_fetch/delete_response/',
updateAction: config.base_url + 'data_fetch/edit_response/'
},
messages: defaultResponseMessages,
fields: LessonsLearnedResponseFields
}, function(data) {//opened handler
data.childTable.jtable('load');
});
});
//return image to show on row
return $img;
}
};
return table;
}
Controller method for the listAction:
function responses($risk_id = null, $offset = 0, $limit = 100, $order_by = 'response_id', $direction = 'ASC') {
$confirm_member = $this->User_model->confirm_member(true, false);
if (!$confirm_member['success']) {
$this->print_jtable_error(self::ERROR_NOT_LOGGED_IN);
return;
}
$user_id = $_SESSION['user_id'];
$this->load->model('Response_model');
$responses = $this->Response_model->get_all($risk_id, $user_id, $limit, $offset, $order_by, $direction);
if ($responses == false) {
$this->print_jtable_error(self::ERROR_NO_ACCESS_PERMISSION);
return;
} else {
return $this->print_jtable_result($responses);
}
}
get_all method in Response Model
/*
* Retrieves all responses associated with the risk
*/
public function get_all($risk_id, $user_id, $limit = null, $offset = 0, $order_by = null, $direction = 'ASC') {
//load risk model to check if user can read from project
$this->load->model('Risk_model');
if ($this->Risk_model->initialize($risk_id, $user_id) == false) {
return false;
}
if ($limit !== null && $limit != 0) {
$this->db->limit($limit, $offset);
}
if ($order_by !== null) {
$this->db->order_by($order_by, $direction);
}
$query = $this->db->select('SQL_CALC_FOUND_ROWS *', false)->from('view_responses')->where('risk_id', $risk_id)->get();
$data = $query->result_array();
$this->load->model('Task_model');
foreach ($data as &$response)
$response['WBS'] = $this->Task_model->normalize_WBS($response['WBS']);
$data['num_rows'] = $this->db->
query('SELECT FOUND_ROWS()', false)->row(0)->{'FOUND_ROWS()'};
return $data;
}
Screenshot of the sql view
successful is received but not displayed
http://imgur.com/MqCVAGm
I've been able to solve the problem. It was an issue with spelling. I had a missing c in successful coming from the SQL view and now its working fine.
I have a tree login page as my first page in a survey. The issue is that , if the user does not select any node and clicks on the next button he is redirected to the same page . The problem is that he does not get any error message .
I want the user to get an error message 'Please select a group'
Please look into the below code which does this action
(P.S check the Display() function )
Correct me where I am going wrong
<?php
/**
* File: TreeLoginWidget.php
*
*
* Purpose: display tree page.
*
* Dependents: none
*
* Dependencies: SurveyItem
*
* Classes:
* 1. PinWidget
*
* Interface/public functions:
*
* Notes: ???
*
* Todo: none
*
**/
class DisplayTreeLoginWidget extends DisplayItem
{
function DisplayTreeLoginWidget(& $sourceObj)
{
// debug
if( $pDebugTraceFlag == _ID_FLAG_ON ) GDebugTraceFunc( __CLASS__." :: ".__FUNCTION__ );
$this->node = 0;
$surveywidget = getDataFromSession("surveywidget");
DisplayItem::DisplayItem();
$_SESSION["profile"]["rootNode"]=0;
if($_GET["nodeId"]) {
setDataToSession("postVar","");
}
$this->sourceObj =& $sourceObj;
}
/**
* Purpose: display pin page label text
*
* Input Params: none
*
* Output Params: none
*
* Return Value: none
*
* Notes:
*/
function display()
{
global $skin_path,$skin,$path;
setDataToSession("skipPage", 0);
setDataToSession('HideSave&Resume',0);
$currentPageNumber = currentPageNumber();
if($currentPageNumber!=1) {
setDataToSession('HideSave&Resume',1);
}
echo "<script type=\"text/javascript\" src=\"".$path."../lib/java/commonFuncs.js\"></script>";
// include the header
include_once ("../lib/include/path.inc.php");
include_once ("../lib/include/jshelper.php");
include_once("display/tree.inc.php");
include_once("display/commonTreeLayout.php");
include_once ("../lib/include/commonTreeCode.php");
setUpTreeAppProperty();
$postVar = getDataFromSession("postVar");
if(is_array($postVar)) {
$_POST = $postVar;
}
if($this->sourceObj->displayType == "expanded") {
$postVar["Expand_All"] = "Expand All";
$this->sourceObj->displayType = "";
}
if($this->sourceObj->levelShowing != "") {
setDataToSession("levelShowing",$this->sourceObj->levelShowing);
}
setUpElist($postVar, $_GET);
$verifiedStartingNode = getTreeStartingNode();
/** $matchedIdArr contains matched nodeIds or empty if no matches found/no search performed */
$matchedIdArr = doSearch($verifiedStartingNode, $postVar);
$eList = getEList();
$Tree = new TreeWithRadioButton($this->sourceObj);
$Tree->reSetupElist();
$startingNode = &$Tree->nodesArr[$verifiedStartingNode];
echo "<div class=\"body2 IE6trans\">";
displaySearchTable();
if(!$postVar["searchSubmit"]) {
$matchedIdArr = array(getDataFromSession("data,node_id"));
}
displayTree('Search Organization Structure', '', '', $startingNode, $eList, $matchedIdArr, $maxDepth, get_path_prefix(),$this->sourceObj->_errorMsg,$this->sourceObj->_prompt);
echo "<script type=\"text/javascript\">";
echo "$(document).ready(function () { $('input[name=\"wildText\"]').keyup(function(event){ if(event.keyCode == 13){ $('input[name=\"searchSubmit\"]').click(); } }); });";
echo "</script>";
echo "</div>";
}
/**
* Purpose: storing error message to _errorMsg
*
* Input Params: none
*
* Output Params: none
*
* Return Value: Boolean - true or false
*
* Notes:
*/
function validate()
{
// debug
if( $pDebugTraceFlag == _ID_FLAG_ON ) GDebugTraceFunc( __CLASS__." :: ".__FUNCTION__ );
$surveywidget = getDataFromSession('surveywidget');
$this->getPostData();
$this->sourceObj->_errorMsg = "";
$lastVisitedWidgetOid_Tree = getDataFromSession("lastVisitedWidgetOid_Tree");
setDataToSession("lastVisitedWidgetOid" , $lastVisitedWidgetOid_Tree);
setLoginUserLanguage($this->node);
$operations = ((strcmp($this->operation,getText2($surveywidget->saveResumeButtonText)) == 0)||
(strcmp($this->operation,getText2($surveywidget->backButtonText)) == 0)||
(strcmp($this->operation,getText2($surveywidget->nextButtonText)) == 0));
if(($operations) && ($this->node != "")) {
setDataToSession("data,node_id",$this->node);
// used to track the node id assigned to this pin when more than one login is used
setDataToSession("tree_login,node_id",$this->node);
setDataToSession("tree_login_before_saveresume,node_id",$this->node);
//Custom -
$oids = getListOfOidAndNodes(Array($this->node));
$_SESSION["conditionNodeList"] = $oids;
//End Custom
if(!getDataFromSession('multiLoginIndex')) {
$multiLoginIndex = 1;
} else {
$multiLoginIndex = getDataFromSession('multiLoginIndex');
}
$multiLoginIndex++;
setDataToSession("multiLoginIndex",$multiLoginIndex);
$this->sourceObj->_errorMsg = "";
} else if(($operations) && ($this->node == "")){
$this->sourceObj->_errorMsg = "Please select a group";
return false;
} else {
return false;
}
if($this->node == "") {
$this->node = 0;
}
// user click save&resume before visiting login page, we are redirecting to login page, That time user enter invalid node_id we are mainting save&resume flag to 1 for displaying submitbutton(it act like as save&resume)
if(getDataFromSession('save&resumeflag') == 1) {
setDataToSession('save&resumeloginpage',1);
}
return true;
}
/**
* Purpose: get post data
*
* Input Params: none
*
* Output Params: none
*
* Return Value: none
*
* Notes:
*/
function getPostData()
{
// debug
if( $pDebugTraceFlag == _ID_FLAG_ON ) GDebugTraceFunc( __CLASS__." :: ".__FUNCTION__ );
$postVar["exactText"] = (empty($_REQUEST["exactText"])==1) ?"" :stripslashes($_REQUEST["exactText"]);
$postVar["wildText"] = (empty($_REQUEST["wildText"])==1) ?"" :stripslashes($_REQUEST["wildText"]);
$postVar["searchSubmit"] = (empty($_REQUEST["searchSubmit"])==1) ?"" :$_REQUEST["searchSubmit"];
$postVar["Collapse_All"] = (empty($_REQUEST["Collapse_All"])==1) ?"" :$_REQUEST["Collapse_All"];
$postVar["idText"] = (empty($_REQUEST["idText"])==1) ?"" :$_REQUEST["idText"];
$postVar["node"] = (empty($_REQUEST["node"])==1) ?"" :$_REQUEST["node"];
$this->node = ($_REQUEST["node"] == "") ?"" :$_REQUEST["node"];
$this->operation = (empty($_REQUEST["Operation"])==1) ?"" :$_REQUEST["Operation"];
if($postVar["Collapse_All"]) {
$postVar["wildText"] = "";
}
setDataToSession('postVar',$postVar);
setDataToSession('Operation',$this->operation);
setDataToSession('node',$this->node);
}
}
?>
Your code is long, and I didn't read it.
But the typical way to do this is to pass a url parameter, and if the parameter exists print it out as a message.
Basically, how would I make an auto-updating mysql query result animated using jquery? I would want it to look like a newsfeed that is animated and slides down when a result it added? How difficuilt would this be to achieve and what would I use to do it?
Thanks,
Cameron
First you need some JS, PHP and HTML skill.
JAVASCRIPT:
function create_ajax()
{
try
{
ajaxRequest = new XMLHttpRequest();
}
catch (e)
{
try
{
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
try
{
ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e)
{
return false;
}
}
}
return ajaxRequest;
}
You need this function in your HTML file, to start the message service:
function StartUp()
{
/** Jquery **/
setTimeout(function() {$('#message').fadeOut('fast');}, 5000);
UserLogService();
}
This function helps to connect to PHP:
function MessageService()
{
setTimeout('MessageService()', 60000);
var ajaxRequest;
ajaxRequest=create_ajax();
ajaxRequest.onreadystatechange =
function()
{
if(ajaxRequest.readyState == 4)
{
message = ajaxRequest.responseText.split(';');
if (message[0])
{
headMessageDisplay(message[0], message[1]);
setTimeout('headMessageNoDisplay()', 30000);
}
}
}
ajaxRequest.open("GET", "xxx.php", true);
ajaxRequest.send(null);
}
In your PHP get the messages:
if ($msg)
{
$this->Show($msg);
exit();
}
PHP: This shows the message from PHP:
private function Show($msg = null)
{
for ($i = 0; $i < count($msg); $i++)
{
$error = $this->html;
$error = str_replace('{MESSAGE}', $msg[$i], $error);
$error = str_replace('{TYPE}', error, $error);
$error = str_replace('{DISPLAY}', 'block', $error);
$this->message .= $error;
}
print $this->message;
}
This makes the message itself:
$r = $_REQUEST["sql"]->Query("SELECT m.id, m.message, t.name as type FROM db_table_message m JOIN db_table_messagetype t ON (t.id = m.type) WHERE m.processing = '0' AND m.user_id = '".$_REQUEST["user"]->Id."'
AND m.date != '0000-00-00 00:00:00' AND m.date <= DATE_SUB(NOW(), INTERVAL -1 MINUTE) LIMIT 1");
$a = $_REQUEST["sql"]->GetRecord($r, 0);
if (!$a["id"])
{
$r = $_REQUEST["sql"]->Query("SELECT m.id, m.message, t.name as type FROM db_table_message m JOIN db_table_messagetype t ON (t.id = m.type) WHERE date = '0000-00-00 00:00:00' AND m.processing = '0' AND m.user_id = '".$_REQUEST["user"]->Id."' LIMIT 1");
$a = $_REQUEST["sql"]->GetRecord($r, 0);
}
if ($a["id"])
{
$_REQUEST["sql"]->Query("UPDATE db_table_message SET processing = '1' WHERE id = '$a[id]'");
}
else
{
$r = $_REQUEST["sql"]->Query("SELECT m.id, m.message, t.name as type FROM db_table_message m JOIN db_table_messagetype t ON (t.id = m.type) WHERE m.user_id = '0' LIMIT 1");
$a = $_REQUEST["sql"]->GetRecord($r, 0);
}
$this->Show($a["message"], $a["type"]);
}
private function Show($message = null, $type = null)
{
if ((!$message) || (!$type)) return false;
switch($type)
{
case "information":
$type = information;
break;
case "warning":
$type = warning;
break;
case "error":
$type = error;
break;
}
print "$message;$type";
Use a PHP Class to get the message from the database... There are many things needed to do this. I nearly forgot to get the old messages from the database on page load by php.
Then, if everything works, add:
ANIMATION
$("selector").fadeIn(slow);
If you want to do the animation with jQuery. :) The animation itself is the last thing you have to worry about. :)
I'll throw my oar in here although this is a similar solution to Dae except using jQuery templates and JSON. I don't work with php myself but creating JSON doesn't seem too difficult with json_encode()
jsFiddle Example
Broadly:
Create a PHP page that returns the results of the MySQL query.
Periodically load() that page with Javascript from the containing page.
Update the contents of the containing element if a difference is found.
Here's a very brief outline. Initially, let's get the results.
// results.php
$sql = "SELECT * FROM `tbl` LIMIT 10 ORDER BY date_created DESC";
if(!$query = mysql_query($sql))
trigger_error(mysql_error());
while($result = mysql_fetch_assoc($query))
print_r($result);
Then make a page to show them.
// index.html
<script type="text/javascript">
function loadResults() {
$('#results').fadeTo('fast' , 0).load('results.php').fadeTo('fast' , 1);
}
$(document).ready(function() {
loadResults();
var interval = self.setInterval(loadResults(), 10000);
});
</script>
<div id="results"></div>
Untested.