Class: JoyUssdEngine::PaginateMenu

Inherits:
Menu
  • Object
show all
Defined in:
lib/joy_ussd_engine/paginate_menu.rb

Instance Attribute Summary collapse

Attributes inherited from Menu

#context, #current_client_state, #error_text, #errors, #field_error, #field_name, #menu_error, #menu_items, #menu_text, #previous_client_state, #previous_menu, #skip_save

Instance Method Summary collapse

Methods inherited from Menu

#after_render, #allow_validation, #before_show_menu, #do_validation, #get_previous_state, #is_last_menu, #is_numeric, #joy_release, #joy_response, #on_error, #on_validate, #raise_error, #remove_error_field, #render_field_error, #render_menu_error, #run, #save_field_value, #save_state, #set_previous_state

Constructor Details

#initialize(context) ⇒ PaginateMenu

Returns a new instance of PaginateMenu.



21
22
23
24
25
26
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 21

def initialize(context)
    super(context)
    @items_per_page = 5
    @back_key = '0'
    @next_key = '#'
end

Instance Attribute Details

#back_keyObject (readonly)

To paginate a menu you just call the ‘paginate` method and to display a paginated menu you call the `show_menu` method and pass the values returned from the `paginate` method. To get a item the user selects from the menu just use the `get_selected_item` method EXAMPLE: my_items = paginate show_menu(my_items) selected_item = get_selected_item



19
20
21
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 19

def back_key
  @back_key
end

#current_pageObject (readonly)

To paginate a menu you just call the ‘paginate` method and to display a paginated menu you call the `show_menu` method and pass the values returned from the `paginate` method. To get a item the user selects from the menu just use the `get_selected_item` method EXAMPLE: my_items = paginate show_menu(my_items) selected_item = get_selected_item



19
20
21
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 19

def current_page
  @current_page
end

#items_per_pageObject (readonly)

To paginate a menu you just call the ‘paginate` method and to display a paginated menu you call the `show_menu` method and pass the values returned from the `paginate` method. To get a item the user selects from the menu just use the `get_selected_item` method EXAMPLE: my_items = paginate show_menu(my_items) selected_item = get_selected_item



19
20
21
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 19

def items_per_page
  @items_per_page
end

#next_keyObject (readonly)

To paginate a menu you just call the ‘paginate` method and to display a paginated menu you call the `show_menu` method and pass the values returned from the `paginate` method. To get a item the user selects from the menu just use the `get_selected_item` method EXAMPLE: my_items = paginate show_menu(my_items) selected_item = get_selected_item



19
20
21
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 19

def next_key
  @next_key
end

#paginating_errorObject (readonly)

To paginate a menu you just call the ‘paginate` method and to display a paginated menu you call the `show_menu` method and pass the values returned from the `paginate` method. To get a item the user selects from the menu just use the `get_selected_item` method EXAMPLE: my_items = paginate show_menu(my_items) selected_item = get_selected_item



19
20
21
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 19

def paginating_error
  @paginating_error
end

#paginating_itemsObject (readonly)

To paginate a menu you just call the ‘paginate` method and to display a paginated menu you call the `show_menu` method and pass the values returned from the `paginate` method. To get a item the user selects from the menu just use the `get_selected_item` method EXAMPLE: my_items = paginate show_menu(my_items) selected_item = get_selected_item



19
20
21
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 19

def paginating_items
  @paginating_items
end

#paginating_items_selectorObject (readonly)

To paginate a menu you just call the ‘paginate` method and to display a paginated menu you call the `show_menu` method and pass the values returned from the `paginate` method. To get a item the user selects from the menu just use the `get_selected_item` method EXAMPLE: my_items = paginate show_menu(my_items) selected_item = get_selected_item



19
20
21
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 19

def paginating_items_selector
  @paginating_items_selector
end

Instance Method Details

#before_paginateObject



148
149
150
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 148

def before_paginate
   @paginating_error = check_input_errors?
end

#before_renderObject



152
153
154
155
156
157
158
159
160
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 152

def before_render
    # To use pagination in a particular menu we need to follow the other of execution in the before_render method
    # 
    # 1. {my_items = paginate} - first you have to execute the `paginate` method and cache the value
    # 2. {show_menu(my_items)} - then you pass the cached value returned from the `paginate` method 
    # and save in some data in some variable you will use in the `render` method to render the page.
    # 3. {get_selected_item if has_selected?} - we use this to `get_selected_item` to return the item
    # the user selected and we do so by checking if the user has selected an item with the `has_selected?` method
end

#can_go_back?Boolean

Returns:

  • (Boolean)


95
96
97
98
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 95

def can_go_back?
    !@context.get_state[:"#{@field_name}_paginate"].blank? &&
    (@context.params[:message] == @back_key) && !is_first_page(get_previous_page)
end

#can_load_more?Boolean

Returns:

  • (Boolean)


90
91
92
93
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 90

def can_load_more?
    !@context.get_state[:"#{@field_name}_paginate"].blank? &&
    (@context.params[:message] == @next_key) && !is_last_page(get_previous_page, @context.get_state[:"#{@field_name}_paginated_list_size"])
end

#can_paginate?Boolean

Returns:

  • (Boolean)


86
87
88
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 86

def can_paginate?
    @context.get_state[:"#{@field_name}_paginate_initiation"] == 'exists'
end

#check_input_errors?Boolean

Returns:

  • (Boolean)


133
134
135
136
137
138
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 133

def check_input_errors?
   @errors = (!can_load_more? && @context.params[:message] == @next_key) || (!can_go_back? && @context.params[:message] == @back_key)

   @error_text = "Sorry invalid input" if @errors
   @errors
end

#executeObject



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 177

def execute
    save_field_value
    do_validation
    before_render
    return render_menu_error[:data] if @paginating_error || @menu_error
    if allow_validation
        return render_previous if @previous_menu.field_error
    end
    response = render
    response = response.blank? ? joy_response(@current_client_state) : response
    after_render
    save_state(response[:ClientState]) if response[:ClientState] != "EndJoyUssdEngine"
    @context.reset_state if response[:ClientState] == "EndJoyUssdEngine" 
    response[:data].blank? ? response : response[:data]
end

#get_current_pageObject



126
127
128
129
130
131
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 126

def get_current_page
    return 1 unless !@context.get_state[:"#{@field_name}_paginate"].blank?
    return load_prev_page if can_go_back?
    return load_next_page if can_load_more?
    @current_page
end

#get_previous_pageObject



122
123
124
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 122

def get_previous_page
    can_paginate? ? @context.get_state[:"#{@field_name}_paginate"] : 1
end

#get_selected_item(error_message = "Sorry wrong option selected") ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 100

def get_selected_item(error_message = "Sorry wrong option selected")

    selected_item = nil
    check_input = is_numeric(@context.params[:message]) && @context.params[:message].to_i != 0
    if check_input 
        selected_item = @paginating_items[@context.params[:message].to_i - 1]
    end
    

    @paginating_error = selected_item.blank?
    @error_text = error_message if @paginating_error
    selected_item
end

#has_selected?Boolean

Returns:

  • (Boolean)


82
83
84
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 82

def has_selected?
    can_paginate? &&  ((@context.params[:message] != @next_key) && (@context.params[:message] != @back_key))
end

#is_first_page(page_number) ⇒ Object



144
145
146
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 144

def is_first_page(page_number)
    page_number.present? ? page_number == 1 : true
end

#is_last_page(page_number, page_items_size) ⇒ Object



140
141
142
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 140

def is_last_page(page_number, page_items_size)
    (((page_number - 1) * 5) + page_items_size) >= @paginating_items.count
end

#load_menu(menu_to_load) ⇒ Object



71
72
73
74
75
76
77
78
79
80
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 71

def load_menu(menu_to_load)
    return render_menu_error[:data] if @menu_error
    next_menu = menu_to_load.to_s
    if has_selected?
        @context.set_state({"#{@field_name}_paginate_initiation".to_sym =>  nil})
        set_previous_state 
        @context.current_menu = @current_client_state = next_menu
        @context.load_from_paginate_menu(next_menu) 
    end
end

#load_next_pageObject



114
115
116
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 114

def load_next_page
    (@context.get_state[:"#{@field_name}_paginate"].to_i + 1)
end

#load_prev_pageObject



118
119
120
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 118

def load_prev_page
    (@context.get_state[:"#{@field_name}_paginate"].to_i - 1)
end

#paginateObject



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 28

def paginate 

    before_paginate
    return [] if @paginating_error
    
    @current_page = get_current_page
    
    paginated_items = @paginating_items.to_a.paginate(page: @current_page, per_page: @items_per_page)

    is_first_render = @context.get_state[:"#{@field_name}_paginate_initiation"].blank?

    @context.set_state({"#{@field_name}_paginate".to_sym => @current_page, "#{@field_name}_paginated_list_size".to_sym => paginated_items.length, "#{@field_name}_list_size".to_sym => paginated_items.length, "#{@field_name}_paginate_initiation".to_sym => is_first_render ? "is_new" : "exists"})

    paginated_items
end

#renderObject



162
163
164
165
166
167
168
169
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 162

def render
    # Paginating menu's render method calls the `load_menu` method to load a particular menu
    # This can come from a selected paginating item
    # load_menu(menu_name)

    # Paginating menus also terminates the session with a `joy_release` method to end the ussd_application
    # joy_release(@error_message - optional)
end

#render_previousObject



171
172
173
174
175
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 171

def render_previous
    @context.current_menu = @previous_menu.current_client_state = @previous_client_state
    @context.set_state({"#{@field_name}_paginate_initiation".to_sym =>  nil})
    @previous_menu.render_field_error
end

#show_menu(items = [], title: '', key: '') ⇒ Object



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
# File 'lib/joy_ussd_engine/paginate_menu.rb', line 44

def show_menu(items=[], title: '', key: '')

    return if has_selected?
    
    @errors = true if @paginating_error || items.blank?
    return @error_text if @paginating_error
    return raise_error("Sorry something went wrong!") if items.blank?

    more_menu = !is_last_page(@current_page, items.length)
    back_menu = !is_first_page(@current_page) 

    item_number = (@current_page - 1) * @items_per_page

    tmp_menu = []
    
    first_option = item_number
    items.each do |m|
      tmp_menu << "#{first_option+=1}. #{key.blank? ? m : m[:"#{key}"]}"
    end

    tmp_menu << "#{back_key}. Back" if back_menu
    tmp_menu << "#{next_key}. Next" if more_menu
    text = tmp_menu.join("\n")
    text = "#{title}\n#{text}" unless title.blank?
    text
end