B4J Tutorial [BANano] Creating an Online Store Website / WebApp

Ola

Download

NB: Open and run the project in the Library folder to have the latest library version.

We attempted to create a News App using BANano. Now we will attempt an online store. Only the basics are being covered here and nothing extensive. What we want to achieve is something like this..

We are using VueX, a global data store for VueJS and Vuetify. We have a navigation bar for the store and cart, some featured products and some functionality.

onlinestore.png


We need products to sell, so lets define these as list.

B4X:
Sub Build_Products
    Products.Initialize
    Products.add(CreateMap("image": "./assets/product-1.jpg", "name": "Nintendo Switch", "price": 299.99))
    Products.Add(CreateMap("image": "./assets/product-2.jpg", "name": "Gameboy Mug", "price": 19.99))
    Products.Add(CreateMap("image": "./assets/product-3.jpg", "name": "Family Computer", "price": 70))
    Products.add(CreateMap("image": "./assets/product-4.jpg", "name": "Jeopardy Game", "price": 30))
    Products.Add(CreateMap("image": "./assets/product-5.jpg", "name": "Game Cube", "price": 99.99))
    Products.Add(CreateMap("image": "./assets/product-6.jpg", "name": "Gameboy Color", "price": 45))
    ' try and use vuex for the data store
    MyApp.SetDataVuex("products", Products)
 
    Prices = MyApp.newlist
    Prices.AddAll(Array("Any","Under R25", "R25 to R100", "R100 to R500", "Over R500"))
    MyApp.SetDataVuex("prices", Prices)
End Sub

We will show 3 products at a time. Thus we define a vertical product layout so that we can loop and show each product in a column. We create our layout for the products we want to see. We want the image, the price, a header and add to cart functionality showing..

product.png


Each product is created using a card layout. We bind the product image with :product.image, on the product name, we also create another binding with {{ product.name }}

On the price we do the same thing with R {{ product.price }}

Like I said, we want to show 3 products at a time, so we create a row with a column (that loops) with a v-for directive.

(product, i) in $store.state.products.slice(0, 3)

We are using routers for the pages and thus, when one selects the Store on the navbar, the address bar should be

1592837182577.png


For the cart, it will be,

1592837234862.png


As noted, there is no hamburger on the navbar, this is hidden and should be shown on small devices only..

1592837318524.png


This is a wrap of this repo

#To be continued...
 
Last edited:

swamisantosh

Member
Licensed User
Longtime User
Ola

NB: Source Code Coming Soon.

We attempted to create a News App using BANano. Now we will attempt an online store. Only the basics are being covered here and nothing extensive. What we want to achieve is something like this..

We are using VueX, a global data store for VueJS and Vuetify. We have a navigation bar for the store and cart, some featured products and some functionality.

View attachment 96048

We need products to sell, so lets define these as list.

B4X:
Sub Build_Products
    Products.Initialize
    Products.add(CreateMap("image": "./assets/product-1.jpg", "name": "Nintendo Switch", "price": 299.99))
    Products.Add(CreateMap("image": "./assets/product-2.jpg", "name": "Gameboy Mug", "price": 19.99))
    Products.Add(CreateMap("image": "./assets/product-3.jpg", "name": "Family Computer", "price": 70))
    Products.add(CreateMap("image": "./assets/product-4.jpg", "name": "Jeopardy Game", "price": 30))
    Products.Add(CreateMap("image": "./assets/product-5.jpg", "name": "Game Cube", "price": 99.99))
    Products.Add(CreateMap("image": "./assets/product-6.jpg", "name": "Gameboy Color", "price": 45))
    ' try and use vuex for the data store
    MyApp.SetDataVuex("products", Products)
   
    Prices = MyApp.newlist
    Prices.AddAll(Array("Any","Under R25", "R25 to R100", "R100 to R500", "Over R500"))
    MyApp.SetDataVuex("prices", Prices)
End Sub

We will show 3 products at a time. Thus we define a vertical product layout so that we can loop and show each product in a column. We create our layout for the products we want to see. We want the image, the price, a header and add to cart functionality showing..

View attachment 96049

Each product is created using a card layout. We bind the product image with :product.image, on the product name, we also create another binding with {{ product.name }}

On the price we do the same thing with R {{ product.price }}

Like I said, we want to show 3 products at a time, so we create a row with a column (that loops) with a v-for directive.

(product, i) in $store.state.products.slice(0, 3)

We are using routers for the pages and thus, when one selects the Store on the navbar, the address bar should be

View attachment 96050

For the cart, it will be,

View attachment 96051

As noted, there is no hamburger on the navbar, this is hidden and should be shown on small devices only..

View attachment 96052


#To be continued...
In the near future we will be populating
Build_Products from Database Tables, rather than static variables.
 

Mashiane

Expert
Licensed User
Longtime User
The Store page is more or less like the featured products page. We list all the products in the store and one can also add products to a cart.

We create a row with 2 columns. One for the sidebar that shows prices and the others to show the products from the store.

store.png


In the previous example, we only showed 3 products using the .slice(0,3) call of the product. For this we exclude all of that.

For the second column, we create a "productdisplay" layout and this has a placeholder inside it where we will load the products.

productdisplay.png


The ppdiv view shows "Products" and under that is just the row and column to show each product. We establish the loop inside the column using

B4X:
product in $store.state.products

in the v-for attribute.

We then consolidate all of this into a single layout HTML that we will feed to our router HTML..

B4X:
'load the store layout and get its html from the placeholder
    'add the vertical display
    BANano.LoadLayout("#productdisplayplaceholder", "ProductDisplay")
    BANano.LoadLayout("#verticalproductplaceholder", "VerticalProduct1")
    BANano.LoadLayout("#sidebarplaceholder", "storesidebar")

In Summary..

1. We load the store layout - This has a sidebar for the radio group to select prices and the other column to show products.

B4X:
BANano.LoadLayout("#placeholder", "store")


store1.png


2. We then load the sidebar - This helps us choose the price ranges. This has been designed in such a way that for small devices, one uses an expansion panel / accordion whilst on large devices it appears like above.

B4X:
BANano.LoadLayout("#sidebarplaceholder", "storesidebar")

3. We then load the product display layout on r1c2. Inside that we will load the products.

B4X:
BANano.LoadLayout("#productdisplayplaceholder", "ProductDisplay")

We created a clone of the layout for the VerticalProduct layout that was used in the home page of the store, we load it inside product display.

B4X:
BANano.LoadLayout("#verticalproductplaceholder", "VerticalProduct1")

We need to the the complete built up HTML for this page. This is all now available on the #placeholder element. We will feed this to the template of the router.

B4X:
'get element by id
    placeholderEL.Initialize("#placeholder")
    'get the html of the placeholder
    Template = placeholderEL.GetHTML
    'empty the placeholder
    placeholderEL.Empty
    'set the router template
    Store.SetTemplate(Template)

That concludes building the HTML template for the store page and when we navigate to that page, the router will show our own defined HTML we created here.

Ta!

#To be continued.
 

Attachments

  • sidebar.png
    sidebar.png
    28.5 KB · Views: 279

Mashiane

Expert
Licensed User
Longtime User

Mashiane

Expert
Licensed User
Longtime User
For the prices, we create a list with the values... These we save to the global state using VueX

B4X:
Dim prices As List = MyApp.newlist
    prices.addall(Array("Any", "Under R25", "R25 to R100", "R100 to R500", "Over R500"))
    MyApp.SetDataVuex("prices", prices)

On our layout, we drag and drop a VRadio control and then specify some bindings for it. These are specified in the Key, Label, VFor properties

BVMPrices.gif
 

Mashiane

Expert
Licensed User
Longtime User
Adding to Cart

BVMAddToCart.gif


When adding a product to a cart, we need to read the existing cart, if the product already exists, we will increment the quantity for that product. This also happens for the Store page. The next part is to show the actual cart.

BVMAddToCartStore.gif




B4X:
'add an item to the cart
Sub addItemToCart(payload As Map)
    'get the quantity to add
    Dim qty As Int = payload.Get("quantity")
    'get the product to add
    Dim product As String = payload.get("product")
    'get the cart
    Dim cart As Map = MyApp.GetDataVuex("cart")
    'do we have the product in the cart
    If cart.Containskey(product) Then
        'we have the product, increment by 1
        Dim oldproduct As Map = cart.get(product)
        Dim oldqty As Int = oldproduct.get("quantity")
        oldqty = BANano.parseInt(oldqty) + 1
        oldproduct.put("quantity", oldqty)
        'update the cart
        cart.Put(product, oldproduct)
    Else
        Dim newproduct As Map = CreateMap()
        newproduct.put("quantity", qty)
        cart.Put(product, newproduct)
    End If
    'update the state
    MyApp.SetDataVuex("cart", cart)
    'show snackbar
    Dim msnack As Map = MyApp.GetDataVuex("snackbar")
    msnack.put("show", True)
    msnack.put("message", $"Success! '${product}' added to the cart."$)
    MyApp.SetDataVuex("snackbar", msnack)
End Sub
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
In closing...

Here we ensure that the cart has our selected products and showing the total amount due.

In this example, we select items from the store for our cart, these are added to the cart and summed.

BVMCart.gif


We can then add other functionality like shipping address and checkout. That wont be covered for this tut though.

Ta!

PS: Updated source code on first post!
 
Top