Rock Mobile Docs
App Factory
  • Welcome 👋
  • 📱Getting Started
    • Building Your First App
      • Creating An App
      • App Configuration
      • Adding Content
      • Deploying Your App
    • Lexicon
  • 🧱Essentials
    • Animations
    • Blocks
      • CMS
        • Content
        • Content Channel Item View
        • Content Collection View
        • Daily Challenge Entry
        • Hero
        • Lava Item List
        • Login
          • Using Auth0
          • Using Entra
        • Profile Details
        • Register
        • Structured Content View
        • Workflow Entry
      • Check-in
        • Check-in
      • Communication
        • Communication Entry
        • Communication List Subscribe
        • Communication View
        • SMS Conversation List
        • SMS Conversation
      • Connection
        • Add Connection Request
        • Connection Type List
        • Connection Opportunity List
        • Connection Request List
        • Connection Request Detail
      • Core
        • Attribute Values
        • Notes
        • Search
        • Smart Search
        • Quick Note
        • My Notes
      • CRM
        • Group Members
        • Person Profile
      • Events
        • Live Experience Occurrences
        • Live Experience
        • Calendar Event Item Occurrence View
        • Calendar Event List
        • Calendar View
        • Event Item Occurrence List By Audience Lava
      • Finance
        • Giving
        • Scheduled Transaction List
        • Transaction Detail
        • Transaction List
      • Groups
        • Group Attendance Entry
        • Group Edit
        • Group Finder
        • Group Member Edit
        • Group Member List
        • Group Member View
        • Group Registration
        • Group View
        • Schedule Preference
        • Schedule Sign Up
        • Schedule Toolbox
        • Schedule Unavailability
      • Prayer
        • Answer To Prayer
        • My Prayer Requests
        • Prayer Card View
        • Prayer Request Details
        • Prayer Session
        • Prayer Session Setup
      • Reminders
        • Reminder Edit
        • Reminder List
        • Reminder Dashboard
      • Security
        • Onboard Person
    • Codex
      • Application Strategy
      • XAML Styling
      • Resources
      • Documentation
    • Commands
      • Communication Commands
      • Navigation Commands
      • Media Commands
      • Utility Commands
    • Controls
      • Behaviors
        • Event To Command Behavior
        • Touch Behavior
      • Content Controls
        • Activity Indicator
        • Application Info
        • Avatar
        • Bible Audio
        • Bible Browser
        • Bible Reader
        • Campus Context Picker
          • Camera Code Reader
        • Cards
          • Block Card
          • Contained Card
          • Inline Card
          • Elements of a Card
          • Masks
          • Styling Cards With CSS
        • Context Menu
        • Countdown
        • Cover Sheet
        • Divider
        • Expander
        • Field Container
        • Flip View
        • Following Icon
        • Geo Boundary View
        • HTML
        • Icon
        • Icon Button
        • Image
        • Interaction
        • Items Collection
        • Login Status
        • Login Status Photo
        • Lottie View
        • Markdown
        • Media Player
          • Legacy
        • Notification Box
        • Paragraph Text
        • QR Code
        • Ratio View
        • Redirect
        • Responsive Column
        • Responsive Layout
        • Scroll View
        • Segment Picker
        • Styled Border
        • Styled View
        • Tag
        • Toggle Button
        • Web View
      • Developer Controls
        • Execute Command
        • Bible Book And Chapter Picker
        • Command Reference
        • Field Stack
        • Media Cast Button
        • Media Progress Bar
        • Parameter
        • Scan Code
        • Validator
        • Volume Control
        • Zone
      • Effects
        • Blur Effect
        • Safe Area Padding Effect
      • Form Fields
        • Attribute Value Editor
        • Address
        • Campus Picker
        • Check Box
        • Check Box List
        • Currency Box
        • Date Picker
        • Email Box
        • Literal
        • Marital Status Picker
        • Multi Picker
        • Number Box
        • Phone Number Box
        • Picker
        • Text Box
        • Text Editor
      • XAML Extensions
        • Boolean Value Converter
        • From Json
        • Inverse Boolean Converter
        • Nullable Guid Converter
        • On Device Platform
        • On Device Type
        • Palette Color
        • Seconds To Time String Converter
    • Field Types
    • Lava
      • Context in Lava
    • Performance
    • Tips and Tricks
      • Custom Site Attributes
      • Migrating to .NET MAUI (V6)
      • Page Anchors
    • Troubleshooting
    • Advanced Topics
      • Dynamic Content
      • Deep Linking
  • 🎨Styling
    • Introduction
    • Style Guide
      • Walkthrough
      • Colors
      • Typography
      • Utilities
      • Shell Components
      • Migrating
    • Legacy
      • Colors
      • Borders
        • Border Color
        • Border Radius
        • Border Width
      • Text
        • Background Color
        • Text Size
        • Alignment
        • Color
        • Line Height
        • Weights & Styles
      • iOS Shadows
      • Styling Components
        • Tags
        • Bible
        • Button
        • Form Fields
        • Modals
      • Custom CSS
  • 👨‍💻Developers
    • Fundamentals
    • Core & Shell Dependencies
    • Custom Blocks
    • OS Version Requirements
  • 🏭App Factory
    • Overview
    • Android Keystore
    • App Store Product Page
    • Developer Accounts
    • Image Resources
    • In-App Giving
    • Publishing Requirements
    • Push Notifications
    • Rock Logins
    • Shell Update Requirements
Powered by GitBook

Resources

  • Release Notes
  • Community Chat
  • Ask Chip

Documentation

  • Rock Manuals
  • Lava

⚙️ Powered by Rock RMS

On this page
Export as PDF
  1. Developers

Custom Blocks

Okay, maybe all of this still isn't quite enough for what you need. Or maybe it works, but you are building such complicated entity commands and SQL queries in Lava that it's just not performant enough. Maybe you are just far more familiar with C# so you'd rather go that way. Possibly you want to build a plugin that provides a new block type with some settings for the admin to configure and then it magically does what it does.

Let's start with the most basic block configuration:

[DisplayName( "My Custom Block" )]
[Category( "Rock Solid Church > Mobile" )]
[Description( "A custom block to do magical things." )]
[IconCssClass( "fa fa-square" )]
public class MyCustomBlock : RockMobileBlockType
{
    #region IRockMobileBlockType Implementation

    int IRockMobileBlockType.RequiredMobileAbiVersion => 1;

    string IRockMobileBlockType.MobileBlockType => "Rock.Mobile.Blocks.Content";

    object IRockMobileBlockType.GetMobileConfigurationValues()
    {
        string content = "<Label Text=\"Hello World\" />";

        return new Rock.Mobile.Common.Blocks.Content.Configuration
        {
            Content = content
        }
    }

    #endregion
}

So here is what we got. We are specifying that in order for this block to render, the mobile app needs to support ABI version 1. Next we are specifying the CLR class name on the mobile app that will handle the rendering, we are going to use the Rock.Mobile.Blocks.Content block so that we can update things. This block will render a simple text label that says Hello World.

But that is rather boring. Instead, lets have it render out something a bit more expressive.

object IRockMobileBlockType.GetMobileConfigurationValues()
{
    string content = @"
<StackLayout>
    <Rock:FormGroup Title=""Search"">
        <Rock:FormField>
            <Rock:TextBox x:Name=""SearchTerm"" />
        </Rock:FormField>
    </Rock:FormGroup>

    <Button Text=""Search"" StyleClass=""btn, btn-primary"" Command=""{Binding Callback}"">
        <Button.CommandParameter>
            <Rock:CallbackParameters Name="":Search"">
                <Rock:Parameter Name=""Term"" Value=""{Binding Source={x:Reference SearchTerm}, Path=Text}"" />
            </Rock:CallbackParameters>
        </Button.CommandParameter>
    </Button>
</StackLayout>
";

    return new Rock.Mobile.Common.Blocks.Content.Configuration
    {
        Content = content
    }
}

If you look very carefully, you'll notice that we prefixed the action command Search with a :. Here is the difference. Without the : prefix, the mobile block will call a single method:

[BlockAction]
public string GetCallbackContent( string command, Dictionary<string, object> parameters)

That is perfectly fine and you can do it that way if you want. However, with the : prefix then it calls a method named for the Name and passes the parameters as actual method parameters. So in our case, our search method would be:

[BlockAction]
public string Search( string term )

Either will achieve the same result, but the latter form might be easier to read in your code - especially if you have multiple commands being handled. The return type of these methods is a simple string that contains the XAML code used to render the UI. Let's use the latter form and build our search results:

[BlockAction]
public object Search( string term )
{
    var searchClient = IndexContainer.GetActiveComponent();
    var searchEntities = new List<int> { EntityTypeCache.Get( SystemGuid.EntityType.GROUP.AsGuid() ) };
    var results = searchClient.Search( term,
        SearchType.Wildcard,
        searchEntities,
        "GroupTypeName^Serving Team",
        5,
        0,
        out int totalResults );

    var sb = new StringBuilder();
    sb.AppendLine( "<StackLayout>" );
    foreach ( var result in results )
    {
        var button = $@"
    <Button Text=""{result.DocumentName}""
            StyleClass=""btn, btn-primary""
            Command=""{{Binding Callback}}"">
        <Button.CommandParameter>
            <Rock:CallbackParameters Name="":ShowGroup"">
                <Rock:Parameter Name=""GroupId"" Value=""{result.Id}"" />
            </Rock:CallbackParameters>
        </Button.CommandParameter>
    </Button>";
        sb.AppendLine( button );
    }
    sb.AppendLine( "</StackLayout>" );

    return new Rock.Mobile.Common.Blocks.Content.CallbackResponse
    {
        Content = sb.ToString()
    };
}

So we use the Universal Search component to get a list of all matching serving team groups. Then we loop over those results and build a stack layout of buttons. Each button will trigger the :ShowGroup command with a different GroupId value. A handler for such a command might look like:

[BlockAction]
public object ShowGroup( int groupId )
{
    return new Rock.Mobile.Common.Blocks.Content.CallbackResponse
    {
        Content = "<Rock:NotificationBox NotificationType=""Error"" Text=""Not Implemented"" />"
    };
}

This is a simple handler that just displays a notification on the screen stating it hasn't been implemented yet. Obviously you will want to have to actually do something. For example, you might have it display some information about the group and then display two buttons: Cancel and Join.

Dynamic Initial Content

What we described above will leave you with a block whose initial content is static, that is it never changes unless the admin deploys a new application bundle. That might work for you, but you probably want to change that content based on query string parameters and such. Let's modify our block so that it instructs the mobile application to be dynamic.

[DisplayName( "My Custom Block" )]
[Category( "Rock Solid Church > Mobile" )]
[Description( "A custom block to do magical things." )]
[IconCssClass( "fa fa-square" )]
public class MyCustomBlock : RockMobileBlockType
{
    #region IRockMobileBlockType Implementation

    int IRockMobileBlockType.RequiredMobileAbiVersion => 1;

    string IRockMobileBlockType.MobileBlockType => "Rock.Mobile.Blocks.Content";

    object IRockMobileBlockType.GetMobileConfigurationValues()
    {
        return new Rock.Mobile.Common.Blocks.Content.Configuration
        {
            Content = null,
            DynamicContent = true
        }
    }

    #endregion

    [BlockAction]
    public object GetInitialContent()
    {
        return new Rock.Mobile.Common.Blocks.Content.CallbackResponse
        {
            Content = "<Label Text=\"Hello World\" />"
        };
    }
}

Last updated 8 months ago

👨‍💻