Приложения по сути одинаковые: берут с сайта данные, сохраняют в локальную базу и строят интерфейс по шаблонам используя данные из БД.
[spoiler]
Начнем с того, что этот функционал Битриксом на данный момент полностью не поддерживаается: нет библиотеки официальной, нет документации. Есть только м для Интернет Магазина в маркетплейсе - который делает простую разметку. И есть делать мобильные приложения (браузерные). Изначально все планировалось связать с выходом КП 10, однако затянулось.
Все же мне удалось получить их обещанную JS библиотеку для работы с сайтом ))
ВНИМАНИЕ: Код предоставляется как есть, совместимость дальнейшая не гарантируется.Структура проекта:
Клиентская часть
css
- template_styles.css - это наши стили для приложения
- jquery.mobile-1.0b1.min.css - это JQueryMObile
- app.js - это спионереная библиотека от Битрикса - немного доработанная
- map.js - это наш JS в котором мы управляем приложением
- jquery.mobile-1.0b1.min.js - это JQueryMObile
- jquery-1.5.2.min.js - это JQuery
- phonegap.0.9.6.min - это PhoneGap
- ajax-loader.png
- icons-18-black.png
- icons-18-white.png
- icons-36-black.png
- icons-36-white.png
- ... далее по необходимости
Серверная часть
на сайте куда нибудь ложим файл который будет отвечать на запросы клиентов. У меня /ajax/ocheredi.php
Листинги:
index.html
<!DOCTYPE html><html><head> <title>Очереди на границе</title> <link type="text/css" rel="stylesheet" href="css/jquery.mobile-1.0b1.min.css" /> <link rel="stylesheet" type="text/css" href="css/template_styles.css" /> <script type="text/javascript" src="js/jquery-1.5.2.min.js"></script> <script type="text/javascript" src="js/jquery.mobile-1.0b1.min.js"></script> <script type="text/javascript" src="js/phonegap.0.9.6.min.js"></script> <script type="text/javascript" src="js/app.js"></script> <script type="text/javascript" src="js/map.js"></script> <!--/убираем скролинк + ставим масштаб/--> <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0"/> </head> <body> <!--/Первая страничка, которую мы видим при запуске/--> <div data-role="page" data-theme="d" id="home" data-nobackbtn="true"> <div data-role="header" data-theme="c"> <div data-role="navbar" class="serv-navbar"> <ul> <li><a href="#" class="ui-btn-active" id="map" data-icon="custom">Очереди</a></li> <li><a href="#info" id="phone" data-icon="custom">Контакты</a></li> </ul> </div><!-- /navbar --> </div> <div data-role="content"> <div id="at_frm_bitrix"> <p><strong>Очереди в пунктах пропуска через Государственную границу Республики Беларусь</strong></p> <!--/Кнопка для старта синхронизации с сервером (id="refresh")/--> <a href="#" data-role="button" data-icon="refresh" id="refresh">Провести синхронизацию</a> <br class="clear" /> <!--/Тут список построим через JS (id="lisrSTDNKOPPR_SECTION")/--> <ul data-role="listview" id="lisrSTDNKOPPR_SECTION"></ul> </div> </div> </div> <!--/вторая страница - статическая/--> <div data-role="page" data-theme="d" id="info" data-nobackbtn="true"> <!--....--> </div> <!--/Это шаблоны - они изначально скрыты/--> <div style="display: none;"> <div data-role-bx="pageSTDNKOPPR" data-theme="d" data-nobackbtn="true"> <div data-role="header" data-theme="d"> <a href="#" rel="external" id="pageSTDNKOPPR_back" data-direction="reverse" data-role="button" data-icon="arrow-l">Назад</a> <h1 id="title"></h1> </div> <div data-role="content"> </div> </div> <div data-role-bx="pageSTDNKOPPRinfo" data-theme="d" data-nobackbtn="true"> <!--...--> </div> </div> </body></html> |
app.js
/////////////////////init///////////////////////////////
var stdnkDBName = 'stdnkTales1_3'; // название Вашей БД
var protocol = 'http://';
var defaultTransition = 'none'; // Как менять экраны - лучше пока вообще убрать
/********************************************************/
function OnLoadMobile()
{
//проверяем загрузилось ли Нативное приложение
document.addEventListener("deviceready", onDeviceReady, false);
// раскоменьтить если пробуем в обычном браузере т.е. не нужно нативное приложение
//onDeviceReady();
}
// настройки JQueryMobile
function OnMobileInit(){
$.mobile.ajaxEnabled = false;
$.mobile.hashListeningEnabled = false;
$.mobile.defaultPageTransition = defaultTransition;
$.mobile.defaultTransition = defaultTransition;
$.mobile.page.prototype.options.addBackBtn = false;
}
// лично я этим не пользовлся
function IsWebApp()
{
if(("standalone" in window.navigator) && !window.navigator.standalone)
{
return true;
}
else{
return false;
}
}
// в нативном приложении делается по другому
function isOnline()
{
if(navigator.userAgent.indexOf('iPhone')!=-1 || navigator.userAgent.indexOf('iPad')!=-1 || navigator.userAgent.indexOf('Android')!=-1)
return navigator.onLine;
return true;
}
function errorHandler(transaction, error)
{
alert(GetMessage('alertsave')+' '+error.message+' (Code '+error.code+')');
return true;
}
// вывод сообщений
function showProgress(title){
if(title)
{
$.mobile.pageLoading(false);
if(title.length>0){
//$('#loadingMessage').html(title);
$('div.ui-loader h1').html(title);
}else{
$('div.ui-loader h1').html('loading');
}
}
else
$.mobile.pageLoading(true);
}
////////////db//////////////////
var __DB = false;
function getDatabase(name)
{
if(__DB)
return __DB;
__DB = new BXDB();
__DB.open(name, '1.0', 10*1024*1024);
return __DB;
}
function BXDBResult(result)
{
this.__result = result;
}
// класс работы с БД
function BXDB()
{
var $this = this;
this.DB = null;
this.open = function (dbName, dbVer, dbSize)
{
$this.DB = window.openDatabase(dbName, dbVer, '', dbSize);
},
this.query = function (sqlQuery, arParams, fCallback, fOnError)
{
fCallback = fCallback || function (ob){};
fOnError = fOnError || function (tx, err){alert('Error:' + err.message + '\n' + sqlQuery)};
$this.DB.transaction(function(tx)
{
tx.executeSql(sqlQuery, arParams, function (transaction, result)
{
fCallback(new BXDBResult(result));
},
fOnError
);
}
);
}
this.queryArr = function (sqlQuery, arr, fCallback, fOnError)
{
fOnError = fOnError || function (tx, err){alert('Error:' + err.message + '\n' + sqlQuery)};
fCallback = fCallback || function (ob){};
$this.DB.transaction(function(tx)
{
for(var z in arr)
{
// console.log(sqlQuery + arr[z][0]);
tx.executeSql(sqlQuery, arr[z], function (){}, fOnError);
}
fCallback();
}
);
}
this.ReplaceTable = function (tableName, fields)
{
var ar1 = [], ar2 = [], data = [];
for(var i in fields)
{
ar1.push(i);
ar2.push('?');
data.push(fields[i]);
}
var str = 'INSERT OR REPLACE INTO '+tableName+'('+ar1.join(',')+') VALUES('+ar2.join(',')+')';
$this.query(str, data);
}
}
// обработчик запросов
function BXDBResult(dbRes)
{
var __cnt = 0;
var $this = this;
this.dbRes = dbRes;
this.Fetch = function ()
{
if(__cnt >= $this.dbRes.rows.length)
return false;
var o = $this.dbRes.rows.item(__cnt);
__cnt++;
if(o['_OBJ'])
return eval('(' + o['_OBJ'] + ')');
return o;
}
}
/////////////////bxmobile////////////
var bxmobile =
{
back: function ()
{
window.history.back();
}
}
/////////////////BXView////////////
// работа с шаблонами
var BXView = function(template)
{
var h = $(template).clone();
h.appendTo('body');
this.w = h;
this.$ = this.w;
this.id = '';
this.title = function (text)
{
var t = h.find("#title");
if(t.length<=0)
return;
t.html(text);
//$('title').html(text);
}
// поведение кнопки назад
this.backButton = function (title, url)
{
var bb = h.find("#backbtn"+this.id);
if(bb.length<=0)
return;
if(title)
{
bb.html(title);
if(url)
{
bb[0].onclick = '';
if(jQuery.isFunction(url))
//bb.click(url);
bb.live('vclick', url); // это новое в JQueryMobile Beta 1
else
bb.attr("href", url);
}
bb.show();
}
else
{
bb.hide();
}
}
// показать страницу
this.Show = function (effect)
{
effect = effect || defaultTransition;
var r = false;
if(effect.substring(0, 5)=="back-")
{
r = true;
effect = effect.substring(5);
}
$.mobile.changePage(this.w, effect, r, false);
}
// удалить страницу
this.Destroy = function ()
{
h.remove();
}
// установить контент в шаблон
this.setContent = function (content)
{
h.find('[data-role="content"]').html(content);
}
}
/////////////Mobile///////////////
// класс для синхронизации данных
_CBXMobile = function ()
{
var $this = this;
$this.UpdateSync = function (objName, fields)
{
var DB = getDatabase(stdnkDBName);
fields['OBJECT_ID'] = objName;
DB.ReplaceTable('CBXOSync', fields);
}
$this.UpdateSyncRows = function (objName, rows)
{
var str, cur = false, all = {};
for(var i=0; i < $this.syncData.length; i++)
{
if($this.syncData[i][0] == objName)
{
cur = eval('('+$this.syncData[i][1]['ROWS']+')');
break;
}
}
if(cur)
{
for(var i in cur)
all[i] = cur[i];
}
for(var i in rows)
{
if(rows[i] != 'DELETE')
all[i] = rows[i];
else
{
all[i] = null;
delete all[i];
}
}
$this.UpdateSync(objName, {'ROWS': JSON.stringify(all)});
}
$this.Sync = function (arObj, fNext, force)
{
$this.syncData = [];
for(var i=0; i<arObj.length; i++)
{
arObj[i].SyncData(force);
}
$this.AddSyncData = function (objName, data)
{
$this.syncData.push([objName, data]);
if(arObj.length == $this.syncData.length)
$this.SyncStart();
}
$this.SyncStart = function ()
{
var request = {'AJAX_CALL': 'Y'};
for(var i=0; i<$this.syncData.length; i++)
{
var objName = $this.syncData[i][0];
var obj = $this.syncData[i][1];
request['SYNC['+objName+'][LAST_SYNC]'] = obj['LAST_SYNC'] || '';
request['SYNC['+objName+'][CACHE_ID]'] = obj['CACHE_ID'] || '';
request['SYNC['+objName+'][ROWS]'] = obj['ROWS'] || '';
}
sslAjaxCall(
arResult['URL'],
request,
function(html)
{
if(html.length>10 && html.substring(0, 9) == 'arResult=')
{
var arResult;
eval(html);
//alert('2');
showProgress('Сохранение');
for(var i=0; i<arObj.length; i++)
{
if(i == arObj.length - 1)
arObj[i].UpdateDB(arResult['SYNC'][arObj[i].GetName()], function (){showProgress(false);fNext();});
else
arObj[i].UpdateDB(arResult['SYNC'][arObj[i].GetName()]);
}
}
else
{
alert(html);
showProgress(false);
}
},
function(e)
{
showProgress(false);
alert('Нет возможности открыть страницу: ' + arResult['URL'] + '. Попробуйте позже');
}
);
}
}
}
////////////Object/////////////
// класс объекта
CBXO = function (n, fields)
{
var $this = this;
this.__objectName = n;
this.__objectFields = {'ID': 'INTEGER', 'TIMESTAMP_X': 'TIME'};
fields = (fields || []);
for(var i in fields)
this.__objectFields[i] = fields[i];
var DB = getDatabase(stdnkDBName);
this.GetName = function ()
{
return $this.__objectName;
}
// метод готовит данные для запроса синхронизации на сервер
this.SyncData = function (force)
{
//if(force)
DB.query('CREATE TABLE IF NOT EXISTS CBXOSync(OBJECT_ID TEXT NOT NULL PRIMARY KEY, LAST_SYNC INTEGER, CACHE_ID TEXT, ROWS TEXT)');
DB.query('SELECT * FROM CBXOSync WHERE OBJECT_ID=?', [this.__objectName], function (dbRes)
{
var res;
if(res = dbRes.Fetch())
{
CBXMobile.AddSyncData($this.__objectName, res);
}
else
{
CBXMobile.AddSyncData($this.__objectName, {});
}
}
);
}
this.__createTable = function ()
{
var str = '', add;
for(var fName in $this.__objectFields)
{
if(fName == 'ID')
add = ' NOT NULL PRIMARY KEY';
else
add = '';
var fType = $this.__objectFields[fName];
switch(fType)
{
case 'INTEGER':
str += fName + ' INTEGER' + add + ', ';
break;
case 'TIME':
str += fName + ' INTEGER' + add + ', ';
break;
case 'REAL':
str += fName + ' REAL' + add + ', ';
break;
case 'TEXT':
str += fName + ' TEXT' + add + ', ';
break;
case 'BLOB':
str += fName + ' BLOB, ';
break;
}
}
str = 'CREATE TABLE IF NOT EXISTS '+$this.__objectName+'(' + str + ' _OBJ TEXT)';
return str;
}
this.UpdateDB = function (rows, fSucc)
{
// showProgress('Сохранение');
// return;
//debugger;
DB.query(this.__createTable());
var str1 = '', str2 = '';
for(var fName in this.__objectFields)
{
str1 += fName + ', ';
str2 += '?, ';
}
var str = 'INSERT OR REPLACE INTO ' + this.__objectName + '(' + str1 +'_OBJ) VALUES(' + str2 + '?)', arr = [], syncDataRow = {}, arDel = [];
for(var i in rows)
{
var row = rows[i], arFields = [];
if(row['__ACTION'] == 'DELETE')
{
syncDataRow[row['ID']] = 'DELETE';
arDel.push([row['ID']]);
}
else
{
syncDataRow[row['ID']] = row['TIMESTAMP_X'];
for(var fName in this.__objectFields)
arFields.push(row[fName]);
arFields.push(JSON.stringify(row));
arr.push(arFields);
}
}
CBXMobile.UpdateSyncRows($this.__objectName, syncDataRow);
if(arDel.length > 0)
DB.queryArr('DELETE FROM ' + $this.__objectName + ' WHERE ID=?', arDel);
DB.queryArr(str, arr, fSucc);
}
// получить список значений
this.GetList = function (fCallback, order, filter)
{
var arOrder = [], arFilter = [], arParams = [];
if(order)
{
for(var f in order)
{
if(!this.__objectFields[f])
continue;
arOrder.push(f + ' ' + (order[f]=='DESC'?'DESC':'ASC'));
}
}
if(filter)
{
for(var f in filter)
{
if(!this.__objectFields[f])
continue;
arFilter.push(f+'=?');
arParams.push(filter[f]);
}
}
DB.query('SELECT _OBJ FROM ' + $this.__objectName +
(arFilter.length>0 ? ' WHERE ' + arFilter.join(' AND ') : '')+
(arOrder.length>0 ? ' ORDER BY ' + arOrder.join(', ') : ''),
arParams, fCallback);
}
// получить список с фильтром WHERE IN
this.GetListIN = function (fCallback, order, filterField, filter)
{
var arOrder = [], arFilter = [], arParams = [];
if(order)
{
for(var f in order)
{
if(!this.__objectFields[f])
continue;
arOrder.push(f + ' ' + (order[f]=='DESC'?'DESC':'ASC'));
}
}
var q = "";
if(filter){
for (var i in filter){
q += (q == "" ? "" : ", ") + "?";
}
}
DB.query('SELECT _OBJ FROM ' + $this.__objectName +
(filter.length>0 ? ' WHERE ' + ' '+filterField+' IN ('+ q + ')': '')+
(arOrder.length>0 ? ' ORDER BY ' + arOrder.join(', ') : ''),
filter, fCallback);
}
// взять по ID
this.GetById = function (id, fCallback)
{
DB.query('SELECT _OBJ FROM ' + this.__objectName + ' WHERE ID=?', [id], fCallback);
}
this.Add = function (fields, fSucc)
{
DB.query(this.__createTable());
var str1 = '', str2 = '';
for(var fName in this.__objectFields)
{
str1 += fName + ', ';
str2 += '?, ';
}
var str = 'INSERT OR REPLACE INTO ' + this.__objectName + '(' + str1 +'_OBJ) VALUES(' + str2 + '?)', arr = [];
for(var i in fields)
{
var row = fields[i], arFields = [];
for(var fName in this.__objectFields)
arFields.push(row[fName]);
arFields.push(JSON.stringify(row));
arr.push(arFields);
}
DB.queryArr(str, arr, fSucc);
}
// обновить
this.Update = function (id, fields, fSucc)
{
var str1 = '', arr = [];
for(var i in fields)
{
var row = fields[i];
arr.push(row);
str1 += i + ' = ?, ';
}
arr.push(id);
arr.push(id);
var str = 'UPDATE ' + this.__objectName + ' SET ' + str1 +' ID = ? WHERE ID = ?';
DB.query(str, arr, fSucc);
}
// удалить по ID
this.Delete = function (id, fSucc)
{
var arr = [];
arr.push(id);
DB.query('DELETE FROM ' + this.GetName() + ' WHERE ID = ? ', arr ,fSucc);
}
// очистить все
this.Clear = function ()
{
DB.query('DELETE FROM ' + this.GetName() + '');
}
// cjplfnm nf,kbwe
this.createTable = function(){
DB.query(this.__createTable());
}
}
//////////////Ajax////////////////
function sslAjaxCall(url, data, success, error)
{
$.ajax({
'url': url,
'type': 'POST',
'timeout': 500000,
'data': data,
'success': success,
'error': error
});
}
//////////////Stack////////////////
var BXMStack = {
_stack: [],
push: function (el)
{
var l = this._stack.length;
this._stack[l] = el;
}
};
////////////////////////////////////////////
|
map.js
// инициализируем загрузку
$(document).ready(OnLoadMobile); // см в app.js
// инициализируем объекты
var STDNKOPPR_DATE, STDNKOPPR_SECTION, STDNKOPPR, STDNKOPPRinfo, STDNKOPPRochered = '';
var arResult, CBXMobile = '';
function onDeviceReady() {
///////////////init///////
// с чем мы будем синхронизироваться
arResult = ({'URL': 'http://site.by/ajax/ocheredi.php'});
CBXMobile = new _CBXMobile();
// создаем объекты
initObj();
$(document).bind('mobileinit', OnMobileInit);
// показываем нужные объекты
STDNKOPPR_DATE.Show();
STDNKOPPR_SECTION.Show();
// проверка доступности интернета
navigator.network.isReachable("site.by",
function(reachability){
var networkState = reachability.code || reachability;
if(networkState === NetworkStatus.NOT_REACHABLE){
$('#refresh').parent().append($('<p class="error">Нет доступа к mobile.gpk.gov.by</p>'));
$('#refresh').remove();
}
}, {});
// обработчики кликов по элементам
$('#refresh').live('vclick', UpdatePage);
$('#pageSTDNKOPPR_back').live('vclick', function(){
$.mobile.changePage($('#home'), defaultTransition);
});
$('#lisrSTDNKOPPR_SECTION li a').live('vclick', function(){
var param1, param2, param3;
param1 = $(this).attr('param1');
param2 = $(this).attr('param2');
param3 = $(this).attr('param3');
STDNKOPPR.Show(param1, param2, param3);
});
$('a.STDNKOPPRochered').live('vclick', function(){
//....
});
$('a.STDNKOPPRinfo').live('vclick', function(){
//....
});
}
// обновление данных с сайта
function UpdatePage () {
// трем созданные страницы
for(var fName in STDNKOPPR.page)
{
if (typeof STDNKOPPR.page[fName].Destroy == 'function'){
STDNKOPPR.page[fName].Destroy();
STDNKOPPR.page[fName] = false;
}
}
if (STDNKOPPRinfo.page.Destroy == 'function'){
STDNKOPPRinfo.page.Destroy();
STDNKOPPRinfo.page = false;
}
// синхронизируемся
showProgress('Начало синхронизации');
CBXMobile.Sync(new Array(STDNKOPPR_DATE, STDNKOPPR_SECTION, STDNKOPPR, STDNKOPPRinfo, STDNKOPPRochered), onUpdate, false);
return false;
}
// по результатам синхронизации
function onUpdate(){
STDNKOPPR_DATE.Show();
STDNKOPPR_SECTION.Show();
}
function initObj(){
///////////////objects////
// описываем объекты
/**************STDNKOPPR_DATE******************************************************/
STDNKOPPR_DATE = new CBXO(
'STDNKOPPR_DATE', {}
);
STDNKOPPR_DATE.createTable();
// создаем обработчик показа шаблона
STDNKOPPR_DATE.Show = function () {
var DATA;
this.GetList(function(result){
while(arItem = result.Fetch()){
DATA = new Date(arItem['TIMESTAMP_X']*1000);
}
if(DATA){
zeros = ['00', '0', '','',''];
date = new String(DATA.getDate());
month = new String(DATA.getMonth()+1);
year = new String(DATA.getFullYear());
hours = new String(DATA.getHours());
minutes = new String(DATA.getMinutes());
$('#refresh span.ui-btn-text').html('по состоянию на <br />'+
zeros[date.length]+date+'.'+
zeros[month.length]+month+'.'+
zeros[year.length]+year+' '+
zeros[hours.length]+hours+':'+
zeros[minutes.length]+minutes
);
}
}); }
/**************STDNKOPPR_SECTION******************************************************/
STDNKOPPR_SECTION = new CBXO(
'STDNKOPPR_SECTION', {
'NAME': 'TEXT',
'CODE': 'TEXT',
});
STDNKOPPR_SECTION.createTable();
STDNKOPPR_SECTION.Show = function () {
showProgress('Построение списка направлений');
// запрос к БД на получение данных
this.GetList(function(result){
var content = '';
var list = $('#lisrSTDNKOPPR_SECTION');
list.children('li').remove();
while(arItem = result.Fetch()){
list.append(
$(document.createElement('li')).html(
'<a rel="external" param1="'+arItem['CODE']+'" param2="'+arItem['ID']+'" param3="'+arItem['NAME']+'" href="#">'+arItem['NAME']+'</a>'
)
);
}
list.listview("destroy").listview();
showProgress(false);
});
return false;
}
/**************STDNKOPPR******************************************************/
STDNKOPPR = new CBXO(
'STDNKOPPR', {
'NAME': 'TEXT',
'CODE': 'TEXT',
'IBLOCK_SECTION_ID': 'INTEGER',
});
STDNKOPPR.createTable();
// будем делать много страниц
STDNKOPPR.page = [{}];
STDNKOPPR.Show = function (NaprCode, NaprID, title) {
if(this.page[NaprCode]){
this.page[NaprCode].Show();
}else{
this.page[NaprCode] = new BXView("[data-role-bx='pageSTDNKOPPR']");
this.page[NaprCode].id = NaprCode;
this.page[NaprCode].$.attr({
'id': NaprCode,
'data-role': 'page',
'data-url': NaprCode,
'data-role-bx': 'null'
});
this.page[NaprCode].title(title);
this.GetList(
function(result){
// после выборки
var list = $(document.createElement('ul')).attr({
'data-role': 'listview',
'data-split-icon': 'info',
'data-split-theme': 'd'
});
while(arItem = result.Fetch()){
list.append(
$(document.createElement('li')).html(
'<a rel="external" class="STDNKOPPRochered" param1="'+arItem['ID']+'" param2="'+NaprCode+'" param3="'+arItem['NAME']+'" param4="'+arItem['CODE']+'" href="#">'+arItem['NAME']+'</a>'+
'<a rel="external" class="STDNKOPPRinfo" param1="'+arItem['ID']+'" param2="'+NaprCode+'" param3="'+arItem['NAME']+'" href="#">Информация</a>'
)
);
}
// внести контент
STDNKOPPR.page[NaprCode].setContent(list);
// показать страницу
STDNKOPPR.page[NaprCode].Show();
},
// сортировка
{'NAME':'ASC'},
// фильтр
{'IBLOCK_SECTION_ID':NaprID}
);
}
return true;
}
/**************STDNKOPPRinfo******************************************************/
STDNKOPPRinfo = new CBXO(
'STDNKOPPRinfo', {
'DESC': 'TEXT',
'TEXT': 'TEXT',
'IT_PPR': 'INTEGER'
});
STDNKOPPRinfo.createTable();
STDNKOPPRinfo.page = false;
STDNKOPPRinfo.Show = function (PPRId, NaprCode, PPRName) {
//................................................................................
return true; }
/**************STDNKOPPRochered******************************************************/
STDNKOPPRochered = new CBXO(
'STDNKOPPRochered', {
'CODE': 'TEXT',
'NAME': 'TEXT',
'VALUE': 'INTEGER'
});
STDNKOPPRochered.createTable();
STDNKOPPRochered.page = false;
STDNKOPPRochered.Show = function (PPRId, NaprCode, PPRName, PPRCode) {
//................................................................................
return false;
}
} |
/ajax/ocheredi.php
<?define("STOP_STATISTICS", true);
require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
// обмен только в UTF-8
header('Content-Type: application/html; charset=utf-8');
if(CModule::IncludeModule("iblock")){
/*****************************************************/
if(!function_exists("__UnEscape"))
{
function __UnEscape(&$item, $key)
{
if(is_array($item))
array_walk($item, '__UnEscape');
else
{
if(strpos($item, "%u") !== false)
$item = $GLOBALS["APPLICATION"]->UnJSEscape($item);
}
}
}
if(!function_exists("_toUTF"))
{
function _toUTF($str)
{
return iconv("windows-1251", "utf-8", $str);
}
}
/*****************************************************/
array_walk($_REQUEST, '__UnEscape');
$arParams = array();
$arResult = array();
$arParams["IBLOCK_ID_OCHERED"] = 57;
$arParams["IBLOCK_ID_INFO"] = 43;
$content = '';
////////////////////////////////
if(isset($_REQUEST['AJAX_CALL']) && isset($_REQUEST['SYNC'])){
// пришел запрос на синхронизацию
foreach($_REQUEST['SYNC'] as $objName => $arInfoSYNC){switch($objName){
// перебираем объекты
case 'STDNKOPPRochered':
$arFilter = Array('IBLOCK_ID'=>$arParams["IBLOCK_ID_OCHERED"], 'ACTIVE'=>'Y');
$arSelect = array_merge($arParams["FIELD_CODE"], array(
"ID",
"IBLOCK_ID",
"NAME",
"PROPERTY_*",
));
$res = CIBlockElement::GetList(Array('ACTIVE_FROM' => 'DESC'), $arFilter, false, array('nTopCount' => 1), $arSelect);
$cnt = 0;
while($ob = $res->GetNextElement()){
$arFields = $ob->GetFields();
$arFields["PROPERTIES"] = $ob->GetProperties();
foreach($arFields['PROPERTIES'] as $num => $arInfo){
$arResult['SYNC']['STDNKOPPRochered'][$cnt] = array(
// поля объекта
'ID' => $cnt,
'NAME' => _toUTF($arInfo['NAME']),
'CODE' => $arInfo['CODE'],
'VALUE' => $arInfo['VALUE'],
'TIMESTAMP_X' => time()
);
$cnt ++;
}
}
break;
case 'STDNKOPPR_DATE':
//..............
break;
case 'STDNKOPPR_SECTION':
//............
break;
case 'STDNKOPPR':
//............
break;
case 'STDNKOPPRinfo':
//............
break;
default:
break;
}}
// ТУТ ВАЖНО возвращаем данные
echo 'arResult='.CUtil::PhpToJSObject($arResult);
}
require_once($_SERVER["DOCUMENT_ROOT"].BX_ROOT."/modules/main/include/epilog_after.php");
die();
}else{
ShowError("IBLOCK_MODULE_NOT_INSTALLED");
die();
}
?>
|
Итого:
1. Создайте простую HTML версию. Протестируйте ее работу - советую пользовать Chrome
2. Чуть измените код JS и подключите phoneGap
document.addEventListener("deviceready", onDeviceReady, false);
//onDeviceReady(); |
С удовольствием отвечу на вопросы