Статьи

Создание приложения для заказа пиццы Titanium Mobile: настройка формы заказа

Добро пожаловать в третий выпуск нашей серии, демонстрирующий создание приложения для заказа пиццы с помощью Titanium Mobile. В этом уроке мы создадим экран «Отправить ваш заказ».


Теперь, когда пользователь может выбирать и отменять начинки, нам нужно разрешить пользователю фактически отправлять заказ. Давайте начнем с изменения события click детали внутри toppings.js :

01
02
03
04
05
06
07
08
09
10
11
details.addEventListener(‘click’,function(e){
    var pizzaInfo = [];
    for (var i = 0; i < toppings.length; i++)
    {
        if (toppings[i].container != null)
        {
            pizzaInfo.push(toppings[i].title);
        }
    }
    Ti.App.fireEvent(‘details’,{crust:win.crust,path:win.path,toppings:pizzaInfo});
});

Теперь, когда вы нажмете кнопку «Подробности» в окне начинки, приведенный выше код будет перебирать наш гигантский массив начинки и проверять свойство container для каждого элемента массива. Если элемент не нулевой, он добавит его в наш временный массив, который называется pizzaInfo . После завершения цикла мы запустим новое пользовательское событие с именем details . Мы передадим три параметра этому событию:

  • Выбранная корочка.
  • Путь изображения к выбранной коре.
  • Выбранные начинки (то есть временный массив pizzaInfo ).

Нам нужно изменить наш файл main.js чтобы прослушать наше пользовательское событие, поэтому откройте этот файл. Вы также собираетесь добавить новый метод openDetails в код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
var win = Ti.UI.currentWindow;
 
//— Create the sub windows
var crusts = Ti.UI.createWindow();
var toppings = Ti.UI.createWindow();
var details = Ti.UI.createWindow();
 
//— We set the background here since this wont change
win.backgroundImage = ‘../images/bg_main.png’;
 
//— Include our clock
Ti.include(‘../includes/clock.js’);
 
//— This method will close the crusts/details window and open the toppings window
function openToppings(e)
{
    crusts.close();
 
    toppings.url = ‘toppings.js’;
    toppings.crust = e.crust;
    toppings.path = e.path;
    toppings.returnToppings = e.toppings;
     
    toppings.open();
}
 
//— The method will close the toppings window and open the crusts window
function openCrust(e)
{
    toppings.close();
    //— If the event has a crust property, that means the user hit cancel once in the toppings window
    if (e.crust)
    {
        crusts.crust = e.crust;
    }
    crusts.url = ‘crusts.js’;
    crusts.open();
}
 
//— This method will close the toppings window and open the details window
function openDetails(e)
{
    toppings.close();
     
    details.crust = e.crust;
    details.path = e.path;
    details.toppings = e.toppings;
    details.url = ‘details.js’;
     
    details.open();
}
 
//— Have our app listen for our custom events
Ti.App.addEventListener(‘toppings’,openToppings);
Ti.App.addEventListener(‘cancelToppings’,openCrust);
Ti.App.addEventListener(‘details’,openDetails);
 
openCrust({});

Хорошо, ваш файл main.js теперь должен соответствовать коду выше. В приведенном выше коде мы добавили новый прослушиватель событий внизу, который называется деталями, и когда приложение получает это событие, мы хотим вызвать метод openDetails . В методе openDetails мы сначала закрываем окно начинки. Затем мы устанавливаем некоторые свойства в окне сведений со значениями из события, которое мы передали в toppings.js . Мы также устанавливаем свойство URL на details.js и, наконец, вызываем метод open .


Нам нужно создать новый файл javascript с именем details.js и сохранить его в папке main_windows . В этом файле мы хотим добавить три текстовых поля:

  • имя
  • Адресная строка 1
  • Адресная строка 2

ПРИМЕЧАНИЕ. В реальном приложении у нас, очевидно, было бы больше полей, но для этого урока мы создали только три поля .

У нас также будет сводка пиццы, которую заказал пользователь, с помощью кнопки «Отправить заказ». Давайте начнем с интерфейса для этого:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
var win = Ti.UI.currentWindow;
var orderReq = Titanium.Network.createHTTPClient();
 
//— Name Text Field
var names = Titanium.UI.createTextField({
    color:’#336699′,
    top:100,
    left:10,
    width:300,
    height:40,
    hintText:’Name’,
    backgroundImage:’../images/textfield.png’,
    paddingLeft:8,
    paddingRight:8,
    keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
    returnKeyType:Titanium.UI.RETURNKEY_NEXT,
    suppressReturn:false
});
 
//— Address1 Text Field
var address1 = Titanium.UI.createTextField({
    color:’#336699′,
    top:140,
    left:10,
    width:300,
    height:40,
    hintText:’Address 1′,
    backgroundImage:’../images/textfield.png’,
    paddingLeft:8,
    paddingRight:8,
    keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
    returnKeyType:Titanium.UI.RETURNKEY_NEXT,
    suppressReturn:false
});
 
//— Address2 Text Field
var address2 = Titanium.UI.createTextField({
    color:’#336699′,
    top:180,
    left:10,
    width:300,
    height:40,
    hintText:’City, State, Zip Code’,
    backgroundImage:’../images/textfield.png’,
    paddingLeft:8,
    paddingRight:8,
    keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
    returnKeyType:Titanium.UI.RETURNKEY_DEFAULT
});
 
//— Listen for the next click on the key board
names.addEventListener(‘return’,function(){address1.focus();});
address1.addEventListener(‘return’,function(){address2.focus();});
 
win.add(names);
win.add(address1);
win.add(address2);
 
//— This method makes a nice formatted summary of the users order
function getFormattedPizza()
{
    var text = win.crust + ‘ pizza with:\n’;
    if (win.toppings.length == 0)
    {
        text += ‘&bull;
    }
    else
    {
        for (var i = 0; i < win.toppings.length; i++)
        {
            text += ‘&bull;
        }
    }
    return text;
}
 
//— Are formatted text field
var pizzaInfoText = Ti.UI.createLabel({
    text:getFormattedPizza(),
    font:{
        fontFamily:’Verdana’,
        fontSize:14
    },
    color:’#fff’,
    shadowColor:’#333′,
    shadowOffset:{x:1,y:1},
    textAlign:’left’,
    width:Ti.Platform.displayCaps.platformWidth,
    height:160,
    top:210,
    left:10
});
win.add(pizzaInfoText);
 
//— Order Button
var order = Ti.UI.createButton({
    width:137,
    height:75,
    backgroundImage:’../images/order.png’,
    top:385,
    left:165,
    opacity:0
});
 
//— Cancel Button
var cancel = Ti.UI.createButton({
    width:137,
    height:75,
    backgroundImage:’../images/cancel.png’,
    top:385,
    left:10,
    opacity:0
});
 
//— If android OS, use the image property instead of backgroundImage (Ti SDK bug)
if (Ti.Platform.osname == ‘android’)
{
    order.image = ‘../images/order.png’;
    cancel.image = ‘../images/cancel.png’;
}
win.add(order);
win.add(cancel);
 
//— Fade the order button in
order.animate({
    opacity:1,
    duration:500
});
 
//— Fade the cancel button in
cancel.animate({
    opacity:1,
    duration:500
});

Вышеупомянутый блок кода может выглядеть страшно, но на самом деле все довольно просто. Мы начнем с определения нашей переменной win а также нашей переменной orderReq . Переменная orderReq будет обрабатывать наш запрос в нашем PHP-файле, который мы рассмотрим в следующем уроке этой серии.

Затем мы определяем наши три текстовых поля и присваиваем им несколько простых свойств. Мы добавляем обработчик события return к текстовым полям, чтобы при нажатии клавиши «Далее» он переходил к следующему текстовому полю. Мы создаем ярлык с именем pizzaInfoText и устанавливаем его text свойство для нашего метода getFormattedPizza . Этот метод вернет отформатированный список нашей выбранной корки и начинки. Если пользователь не выбрал начинки, мы отобразим тип корочки и простую сырную пиццу. Мы также сделали наш заказ и отменили кнопки и потушили их. Теперь ваш интерфейс должен выглядеть так:


Итак, вы находитесь на экране отправки заказа и решаете, что хотите удалить грибы из списка. Ну, нет проблем! Приложению уже известны начинки, которые вы в данный момент выбрали, поэтому мы просто передадим этот временный массив обратно в toppings.js и перепроверим начинки. Сначала нам нужно добавить прослушиватель событий к нашей кнопке отмены. Прокрутите до конца вашего файла details.js и добавьте это:

1
2
3
4
//— Cancel button event.
cancel.addEventListener(‘click’,function(){
    Ti.App.fireEvent(‘cancelDetails’,{crust:win.crust,path:win.path,toppings:win.toppings});
});

Мы cancelDetails еще одно пользовательское событие, на этот раз называемое cancelDetails , и снова передаем три параметра:

  • Выбранная корочка.
  • Путь изображения к выбранной коре.
  • Выбранные начинки (то есть наш временный массив).

Давайте вернемся к main.js Нам нужно добавить новый слушатель событий. Добавьте следующее в конец наших слушателей событий.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Ti.App.addEventListener(‘cancelDetails’,openToppings);
</pre>
<p> Now we already have an <code>openToppings</code> method.
<pre name=»code» class=»javascript»>
//— This method will close the crusts/details window and open the toppings window
function openToppings(e)
{
    if (e.toppings)
    {
        details.close();
    }
    else
    {
        crusts.close();
    }
 
    toppings.url = ‘toppings.js’;
    toppings.crust = e.crust;
    toppings.path = e.path;
    toppings.returnToppings = e.toppings;
     
    toppings.open();
}

Итак, с помощью нашего модифицированного метода мы проверяем свойство toppings, связанное с событием. Если оно не равно нулю, мы хотим закрыть окно сведений. Если это ноль, мы хотим закрыть окно коры. Мы по-прежнему добавляем наши пользовательские свойства и затем открываем наше окно начинки.


Когда мы вернемся назад, мы хотим предварительно установить флажки начинки, которую мы выбрали ранее. Мы также хотим добавить начинки к пицце визуально. Откройте файл toppings.js и прокрутите вниз до метода createToppingsList . Разница между вашим текущим и тем, что приведена ниже, заключается в том, что если win.returnToppings не равен нулю, он будет перебирать наш больший массив toppings и сравнивать его с нашим временным массивом. Если они совпадают, перепроверьте флажок, добавьте визуальный элемент в корку и увеличьте количество добавок.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/*
This method creates the topping list.
*/
function createToppingsList()
{
    scrollView.opacity = 0;
    scrollView.top = 155;
    scrollView.height = 120;
    scrollView.contentWidth = Ti.Platform.displayCaps.platformWidth;
    scrollView.contentHeight = ‘auto’;
    scrollView.showVerticalScrollIndicator = true;
    win.add(scrollView);
 
    for (i = 0; i < toppings.length; i++)
    {
        //— The label
        var toppingLabel = Ti.UI.createLabel({
            text:toppings[i].title,
            font:{
                fontFamily:’Verdana’,
                fontWeight:’bold’,
                fontSize:14
            },
            color:’#fff’,
            shadowColor:’#333′,
            shadowOffset:{x:1,y:1},
            textAlign:’left’,
            width:Ti.Platform.displayCaps.platformWidth — 10,
            left:10
        });
         
        //— We add a custom property ‘selected’ to our checkbox view
        var checkbox = Ti.UI.createView({
            width:340,
            height:16,
            backgroundImage:’../images/checkbox_no.png’,
            selected:false,
            toppingID:i
        });
         
        //— if the user hits cancel in the details window, we go back and repopulate the list with previously checked toppings
        if (win.returnToppings)
        {
            for (j = 0; j < win.returnToppings.length; j++)
            {
                if (win.returnToppings[j] == toppings[i].title)
                {
                    var aTopping = Ti.UI.createView({
                        backgroundImage:toppings[i].path
                    });
                     
                    if (Ti.Platform.osname == ‘android’)
                    {
                        aTopping.image = toppings[i].path;
                    }
                    else
                    {
                        aTopping.opacity = 0;
                        aTopping.animate({
                            opacity:1,
                            duration:500
                        });
                    }
                    toppingsHolder.add(aTopping);
                    toppings[i].container = aTopping;
                    checkbox.backgroundImage = ‘../images/checkbox_yes.png’;
                    checkbox.selected = true;
                    numToppings += 1;
                }
            }
        }
         
        var toggler = Ti.UI.createView({
            width:Ti.Platform.displayCaps.platformWidth,
            height:20,
            top: i * 20
        });
         
        //— We use the singletap event rather than the click since its in a scroll view
        checkbox.addEventListener(‘singletap’,toppingListClick);
        toggler.add(toppingLabel);
        toggler.add(checkbox);
         
        scrollView.add(toggler);
    }
    scrollView.animate({
        opacity:1,
        duration:500
    });
}

В этом уроке мы создали экран «Submit Oder», который является последним экраном, который нам понадобится в этом уроке. Мы также добавили еще два пользовательских события в наше приложение, которые позволили нам переключаться между экранами «Choose Crust» и «Submit Order».

Следующая часть этой серии будет посвящена проверке подлинности формы, необходимой для обработки представлений, а затем отправке по электронной почте выбранного заказа вместе с отправленной информацией о клиенте (для отправки запроса потребуется веб-сервер с установленным почтовым клиентом и PHP). уведомление по электронной почте).