4D v19 R6 and v19 R7 brought two interesting features to 4D for Mobile. Sessions and displaying web pages served by the 4D server in your native mobile app. But did you think about the possibilities you get when combining them both?
This blog post will show you one of these possibilities. We are going to see how to build a simple app that enables mobile users to place orders with their central purchasing office to consolidate their stock:
Feel free to try it yourself with the HDI above 🙂
PROJECT EDITOR SIDE
With this demo app, we are going to see how simple it is to :
- Add packs to a cart using a primary action and Session storage
- Visualize the cart using a preset open URL action
- Give the ability to remove packages from the cart
For that, we need to create two actions from the Action section :
Add To Cart action
First, create an “add To Cart” action, a simple action without any parameters. This action will allow you to send an action request from the mobile device and directly call the On Mobile App Action database method with the necessary context.
To create those actions, you just have to create a new basic action, remove parameters from the parameters bottom table, and select the Current entity scope (as we want to add a specific product to the cart).
open url preset action
We need to create an open URL preset action with a Table scope. Enter the 4D server path in the dedicated field. Let’s enter “/cart.shtml” for instance.
On the Mobile App Action database method
Then click on the Create button to create the On Mobile App Action database method. This will automatically create a Case with all your actions already filled in.
Then, add some code to your On Mobile App Action database method!
- First, we want to check if stock is left for the products we want to add to the cart.
- If so, add a product object as a collection item in the Session storage.
- If the product object already exists in the collection, we want to increment the quantity.
- Then when the product has been correctly added to the Session storage, we want to decrement the product stock in our database.
- Finally, we asked the app data to be reloaded.
#DECLARE($request : Object) : Object
var $productExist : Boolean
var $product; $response; $status : Object
var $mobileData : Collection
var $entity : 4D.Entity
$response:=New object
$action:=MobileAppServer.Action.new($request)
Case of
: ($request.action="addToCart")
If (Session.storage.mobileData=Null)
$mobileData:=New shared collection
Use (Session.storage)
Session.storage.mobileData:=$mobileData
End use
Else
$mobileData:=Session.storage.mobileData
End if
$entity:=ds[$request.context.dataClass]\
.query("ID = "+String($request.context.entity.primaryKey))\
.first()
// CHECK IF STOCK > 0
If ($entity.Stock>0)
If ($mobileData.length>0)
$product:=$mobileData.query("Name = :1"; $entity.Name).pop()
$productExist:=$product#Null
If ($productExist)
Use ($mobileData)
$product.Quantity:=$product.Quantity+1
$product.Price:=($entity.Price)*($product.Quantity)
End use
End if
End if
If (Not($productExist))
$product:=New shared object(\
"Name"; $entity.Name; \
"Picture"; $entity.Picture; \
"Quantity"; 1; \
"Price"; $entity.Price)
Use ($mobileData)
$mobileData.push($product)
End use
End if
$entity.Stock:=$entity.Stock-1
$status:=$entity.save()
If ($status.success)
$response.success:=True
$response.dataSynchro:=True
$response.statusText:="Well done 👍\n"\
+$entity.Name+" has been added to your cart!"
Else
$response.statusText:="Bad luck 🫤\n"\
+$entity.Name+" has not been added to your cart!"
End if
Else
// STOCK = 0
$response.dataSynchro:=True
$response.statusText:="Bad luck 👎\n"\
+"No more stock available for this product!"
End if
Else
// Unknown action
$response.statusText:="Unknown action: "+$request.action
End case
return $response
Then we want to visualize our cart on a web page accessible from our Stocks app screen and give the ability to remove products from the cart.
So let’s have a look at our cart web page…
WEB PAGE
We need to implement several things to display our cart to suit our needs :
- Get Session.storage.mobileData collection and display one item per table row using 4D tags:
<table id="products"> <tr> <th>Product</th> <th>Quantity</th> <th>Price</th> <th></th> </tr> <!--#4DEACH $product in Session.storage.mobileData--> <tr> <td> <!--#4DTEXT $product.Name--> </td> <td> <!--#4DTEXT $product.Quantity--> </td> <td> <!--#4DTEXT $product.Price--><b>$</b> </td> <td> <input type="button" value="Delete" onclick="RemoveRecord(this)"> </td> </tr> <!--#4DENDEACH--> </table>
- Add a javascript function to close the native app view from the webview and call it on the close button click :
<script> function closeFunc() { $4d.mobile.dismiss(); } </script>
- Add a javascript function to remove a table row (remove a product item from the product collection available in Session. storage) :
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> <script type="text/javascript"> function RemoveRecord(element) { var rowJavascript = element.parentNode.parentNode; var rowjQuery = $(element).closest("tr"); var request = $.ajax({ method: "POST", url: "4DACTION/deleteMethod", data: { index: rowJavascript.rowIndex - 1 } }); request.done(function(resultat) { window.location.reload(); }); } </script>
- Finally, we need to create a deleteMethod project method and call it in the RemoveRecord function after having retrieved the index to delete that will allow us to delete an element from the cart and from the Session.storage.mobileData collection:
ARRAY TEXT($var1; 0)
ARRAY TEXT($var2; 0)
WEB GET VARIABLES($var1; $var2)
$indexToRemove:=Find in array($var1; "index")
If ($indexToRemove>0)
$productIndex:=Num($var2{$indexToRemove})
Use (Session.storage.mobileData)
$mobileData:=Session.storage.mobileData
$mobileData.remove($productIndex)
End use
End if
What about Android?
As usual, to get the Android app, you just have to go back to the project editor, select the Android target and click the Build button! You build one single 4D mobile project to get iOS and Android apps. Remember?
Here is the final result on Android :
As you can see, using both the user session and the web pages served by 4D can cover some fascinating use cases!
It’s your turn; share yours with us on the forum! Looking forward to reading your scenario.