пятница, 1 ноября 2013 г.

JavaScript. AngularJS, или как облегчить жизнь

Если вы задались задачей написания динамически обновляемой HTML странички, то пред началом работы нужно решить, каким же образом это обновление будет происходить. Причем организовать все было бы неплохо так, чтобы посмотрев на свой код через несколько месяцев, вы не почувствовали себя в лабиринте без карты в руках.

Отличное решение - AngularJS.
Ссылочка: http://angularjs.org/

Этот фреймворк позволит:
  • легко настроить поведение элементов страницы
  • организовать связь элементов с сущностями, данные о которых они отображают
  • динамически обновлять страницу при изменении сущностей, без ее перезагрузки
  • отделить верстку от реализации поведения элементов страницы
  • минимизировать разметку страницы, задав общий вид представления объектов сущности
  • и многое другое
Например, вы разрабатываете сайт для жилищного агенства. С AngularJs, чтобы отобразить данные о множестве квартир на одной странице, вам нужно будет лишь написать шаблон на HTML для отображения данных одной квартиры, занести данные о множестве квартир в контейнер, и сказать HTML тегу - повторись для всех квартир в этом контейнере! И что самое главное, изменения данных в контейнере моментально отобразятся и на HTML страничке, а точнее в связанном с моделью теге.

Очень удобная штука. Сам я только начал с ней разбираться, в ней еще очень много интересного)

воскресенье, 6 октября 2013 г.

JavaScript. Dates. Даты. setMonth();

    Был у меня один случай. Необходимо было пробежать по значениям дат, начиная от n-го года, заканчивая k-м, с шагом в один месяц. В один прекрасный момент, задав начальный год тысяча-девятьсот-шестьдесят-какой-то все нафиг повисло.
    Реализовано это было следующим образом:

var startDate = new Date('1960-01-01');
var endDate   = new Date('2010-01-01');
for(var i = startDate; i < endDate; i = new Date(i.getFullYear(), i.getMonth() + 1, 0))
{
// Что-то происходит
}


    Оказалось, что в прекрасный промежуток годов от 1982 до 1986 (кажется, но суть не важна), конструктор new Date(year, month, day) устанавливал месяц, равный month - 1, если подавалась цифра 2! И так, в цикле бесконечно устанавливался месяц, равный 1.
Решил проблему используя метод setMonth();

for(var i = startDate; i < endDate; i.setMonth(i.getMonth() + 1))
{
// Что-то происходит
}

вторник, 27 августа 2013 г.

JavaScript. Dates. Даты. Часть 1

И так, друзья. Сегодня я расскажу вам про замечательный мир дат на JavaScript.

Заранее прилагаю первоисточник:
http://javascript.ru/Date

Вот основное, и то что пригодится:


Создание

dateObj = new Date()
dateObj = new Date(dateVal)
dateObj = new Date(year, month, date[, hours, minutes, seconds, ms] )



Аргументы

dateVal
  • Если параметр является числовым, то он интерпретируется как количество миллисекунд от 1-Янв-1970 00:00.
  • Если строкой, то она разбирается и интерпретируется как дата по стандартным правилам Date.parse.
year
Год в формате YYYY.
month
Месяц от 0 (Янв) до 11 (Дек).
date
День месяца от 1 до 31.
hours
Параметр должен быть указан, если указан параметр minutes. Устанавливает кол-во часов от 0 до 23.
minutes
Параметр должен быть указан, если указан параметр seconds. Устанавливает количество минут: от 0 до 59.
seconds
Параметр должен быть указан, если указан параметр ms. Устанавливает количество секунд: от 0 до 59.
ms
Количество миллисекунд: от 0 до 999.
Дата измеряется в миллисекундах, начиная от полуночи 01 января 1970 года GMT+0. День содержит 86,400,000 миллисекунд.
Объект Date ведет себя одинаково на всех платформах.
Date поддерживает как методы для работы в зоне UTC (GMT+0), так и методы для работы с местным временем.
Местное время - это то, которое установлено на компьютере, на котором выполняется яваскрипт.


Описание, примеры


Если конструктор запущен без аргументов, то возвращается текущая дата.

Пример: получить текущую дату
var today = new Date()
При вызове с одним аргументом - строкой, строка разбирается и интерпретируется как дата, так же, как и в методе Date.parse.

Пример: создать дату из строки
var date = new Date("21 May 1958 10:12"// используется редко
При объявлении с несколькими аргументами, отсутствующие аргументы автоматически считаются равными 0.

Пример: объявление даты с несколькими аргументами
01new Date(1)
02// Thu Jan 01 1970 03:00:00 GMT+0300 (Russian Standard Time)
03new Date(1,2)
04// Fri Mar 01 1901 00:00:00 GMT+0300 (Russian Standard Time)
05new Date(1,2,3)
06// Sun Mar 03 1901 00:00:00 GMT+0300 (Russian Standard Time)
07new Date(1,2,3,4)
08// Sun Mar 03 1901 04:00:00 GMT+0300 (Russian Standard Time)
09new Date(1,2,3,4,5)
10//Sun Mar 03 1901 04:05:00 GMT+0300 (Russian Standard Time)
11new Date(1,2,3,4,5,6)
12//Sun Mar 03 1901 04:05:06 GMT+0300 (Russian Standard Time)

пятница, 9 августа 2013 г.

JavaScript. Colors. Цвета.

Представляю вашему вниманию генератор шестнадцатиричных кодов html цветов. Возвращает что-то вроде "FFFFFF":

  function rgbToHex(R,G,B) {return toHex(R)+toHex(G)+toHex(B)}
  function toHex(n) 
  {
    n = parseInt(n,10);
    if (isNaN(n)) return "00";
    n = Math.max(0,Math.min(n,255));
    return "0123456789ABCDEF".charAt((n-n%16)/16)
      + "0123456789ABCDEF".charAt(n%16);
  }

Источник:
http://www.benknowscode.com

Firefix привередливый, и кушает это только так:
 #rgbToHex(7,9,8);
Chrome и так, и просто rgbToHex(7,9,8);

пятница, 2 августа 2013 г.

JavaScript. Библиотека визуализации графов Flot


Flot


Библиотека от Датских разработчиков, предоставляющая широкий инструментарий для визуализации графов посредством JavaScript и jQuery.

Ссылка на официальный сайт:
http://www.flotcharts.org/

Красиво, функционально, гибко и легко в использовании. На сайте приложено куча примеров, перебрав которые можно довольно быстро скомпоновать нужный вам вариант. Да и код библиотеки говорит сам за себя, не нужно никакой документации (Хотя она присутствует в полном объеме).

среда, 31 июля 2013 г.

Axapta. Parts

Рассмотрим гибкий инструмент, предусмотренный в системе Microsoft Dydamic AX, Parts. С его помощью можно легко помещать различную информацию из лабиринта связанных таблиц на форму, пользуясь объектами Query. Это и смотрится симпатично, и делается все в несколько перетаскиваний и кликов.

Допустим на Вашей форме присутствует Grid, отображающий записи в таблице FilmTable, и стоит задача отображать информацию о студии, которая выпустила выделенный фильм (Таблица SudioTable).

1) Создаем Query.
Для начала создадим объект Query, например, с названием StudioOfFilm, чтобы было понятно, для чего он собственно нужен. В нем необходимо создать Data Source для таблицы, откуда мы будем доставать информацию, то есть StudioTable.

Если нам нужно отображать еще и информацию о директоре студии, которая содержится в таблице DirectorsTable, то в датасорсе таблицы StudioTable нужно создать дочерний датасорс, назначить ему таблицу DirectorsTable и настроить в созданном датасорсе соответствующие Relations для связи с таблицей StudioTable. Например StudioTable_ds.DirectorName == DirectorsTable.Name. Но при этом необходимо учитывать условие, что поле Name в таблице DirectorsTable должно быть индексом.

We need to go deeper.

Замечание: Для группы Fields каждого датасорса нужно выставить свойство Dynamic в значение Yes.

2) Создаем InfoPart.
Вторым шагом будет создание InfoPart, которая будет определять, какую информацию из выбранных таблиц отображать, и каким образом. Называйте ее именем, созвучным с именем Вашего Query.

В значении свойства Query в InfoPart выберите созданный вами Query (StudioOfFilm), а затем в разметке вашей части (Layout) создайте группы для соответствующих таблиц. В них можно выбрать нужный датасорс и группу полей таблицы, которые следует отобразить. При необходимости можно создавать поля в ручную. (Есть возможность использования Display методов).

Дело почти сделано.

3) Создаем MenuItem.
Дело осталось за малым. Создаем MenuItem типа Display, задать ему Object типа Info Part (Наша InfoPart) и перетащить его в Parts нашей формы. FormPart будет создан автоматически. В нем нужно выбрать DataSource формы и Relation, по которой этот датасорс связан с главным датасорсом запроса Query.

Пурурум, все готово)

понедельник, 29 июля 2013 г.

WebGL. Загрузка текстур. Особенность Chrome

    Чтобы использовать текстуры в WebGL, их нужно для начала создать, а затем инициализировать. Делается это примерно так:

gl - объект типа WebGL Context

// Инициализация текстуры
function initTex(texture)
{
gl.bindTexture(gl.TEXTURE_2D,texture);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,texture.image);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR);
gl.bindTexture(gl.TEXTURE_2D, null);
}

// Создание текстуры
// Возвращает объект типа текстура
function createTex(image_name)
{
var image = new Image();
var texture = gl.createTexture();
image.src = image_name;
texture.image = image;
image.onload = function()
{
initTex(texture);
}
return texture;
}

// И собственно, как это потом выглядит в коде
texture[0] = createTex("pic/back_01.jpg");

Замечание!!!!
Вызов метода gl.createTexture(); обязательно должен производиться вне тела функции initTex();. Из-за такого в буферах начинали путаться текстуры, и общая картина смотрелась довольно забавно. Но одно дело забавно, а другое дело, что текстуры не на своих местах.

Google Chrome


С ним было много заморочек. Например:

При стандартных настройках безопасности у хрома нет возможности загрузки некоторых локальных ресурсов. По-этому, чтобы проверить работоспособность вашей программы на Хроме, разрабатывайте ее на сервере. В серьезных проектах это естественно будет так. Но вдруг вы просто решили потестить маленький примерчик, создали локальный html файл, и вдруг видите черный квадрат вместо текстуры. Это именно оно и есть.

Надеюсь, это кому-нибудь пригодится)))

среда, 24 июля 2013 г.

Axapta. Задание диапазона у DataSource

Существует как минимум два решения для этой проблемы. Нужное следует подбирать исходя из задачи.

1) Использование переменной для Range;
2) Обращение на прямую к DataSource.

Первый вариант удобен, если вам нужно задать статичный диапазон, который не будет изменяться во время работы с формой.

Второй вариант удобно использовать, если вы будете менять Range. Например, если вы хотите организовать возможность фильтрации датасорса.

Использование переменной Range

Для начала заведем переменную типа QueryBuildRange, которая будет отвечать за диапазон конкретного поля в датасорсе:

QueryBuildRange qbRange;

Ее нужно инициализировать следующим образом:

qbRange = 
(YourTable_ds.query().dataSourceTable(tableNum("YourTable")).findRange(fieldNum(YourTable, YourField)));
if  (qbRange == null) 
{
    qbRange = 
    YourTable_ds.query().dataSourceTable(tableNum("YourTable")).addRange(fieldNum(YourTable, YourField));
}

Затем нужно задать список значений нашему Range:

qbRange.value(strFmt('%1,%2,%3,%4,%5,%6',
                    queryValue(value1),
                    queryValue(value2),
                    queryValue(value3),
                    queryValue(value4),
                    queryValue(value5),
                    queryValue(value6)));

(Тип переменных value% должен совпадать с типом поля в таблице)

И  выполнить executeQuery у нашего DataSource.

Обращение на прямую к DataSource


В перегруженном executeQuery вашего DataSource сделайте примерно такое:

str s = strFmt('(RangeField != YourTable.OtherField)');
    this.query().dataSourceTable(tableNum(YourTable)).addRange(fieldNum(YourTable,RangeField)).value(s);
super();

воскресенье, 14 июля 2013 г.

Шпаргалка для всего

Одно милое существо скинула мне офигенную штуку) Офигенная шпоргалка для всего)
http://overapi.com/
Мило, и все в одном месте)