{"id":42653506,"url":"https://github.com/trevordevore/levurehelper-dataview","last_synced_at":"2026-01-29T07:44:36.258Z","repository":{"id":139967271,"uuid":"99969296","full_name":"trevordevore/levurehelper-dataview","owner":"trevordevore","description":"DataView helper for the Levure Application Framework","archived":false,"fork":false,"pushed_at":"2025-03-25T00:58:37.000Z","size":1076,"stargazers_count":4,"open_issues_count":1,"forks_count":6,"subscribers_count":5,"default_branch":"develop","last_synced_at":"2025-03-25T01:32:46.327Z","etag":null,"topics":["dataview","hacktoberfest","levure","levure-helper","livecode"],"latest_commit_sha":null,"homepage":"","language":"LiveCode Script","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/trevordevore.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-08-10T22:21:29.000Z","updated_at":"2025-03-25T00:58:40.000Z","dependencies_parsed_at":null,"dependency_job_id":"21b45a88-97f8-45c6-8443-8413dddb58ff","html_url":"https://github.com/trevordevore/levurehelper-dataview","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/trevordevore/levurehelper-dataview","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trevordevore%2Flevurehelper-dataview","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trevordevore%2Flevurehelper-dataview/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trevordevore%2Flevurehelper-dataview/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trevordevore%2Flevurehelper-dataview/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/trevordevore","download_url":"https://codeload.github.com/trevordevore/levurehelper-dataview/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trevordevore%2Flevurehelper-dataview/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28870645,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-29T07:35:32.468Z","status":"ssl_error","status_checked_at":"2026-01-29T07:33:31.463Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dataview","hacktoberfest","levure","levure-helper","livecode"],"created_at":"2026-01-29T07:44:35.129Z","updated_at":"2026-01-29T07:44:36.238Z","avatar_url":"https://github.com/trevordevore.png","language":"LiveCode Script","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DataView Helper\n\nA DataView displays rows of data. It is similar to a DataGrid form, a control available in the LiveCode IDE.\n\nLiveCode Version: 8.x or higher\n\nPlatforms: Tested on Windows, macOS, and iOS.\n\nA DataView is responsible for taking row data that your code provides and rendering it in a highly customizable way using row templates. Row data is an array of key=\u003evalue pairs. Out of the box you can assign a numerically indexed array of arrays with key=\u003evalue pairs to a DataView (see example below). But you can customize the data source any way you would like.\n\n## Demo\n\nThe DataView Demo application includes an example of using this helper:\n\nhttps://github.com/trevordevore/dataview_demo\n\n## Installation\n\n### Levure application\n\nIf your LiveCode application uses the Levure framework then the DataView can be added as a helper.\n\n1. Download the latest release of **Source Code.zip|tar.gz** from https://github.com/trevordevore/levurehelper-dataview/releases\n2. Unzip the contents, rename the resulting folder to **dataview**, and add the folder to the **./app/helpers** folder in your application folder.\n\n### non-Levure applications\n\nIf your LiveCode application is not using the Levure framework then you can use the **dataview_loader.livecodescript** file to load the necessary stacks into memory.\n\n1. Download the latest release of **Source Code.zip|tar.gz** from https://github.com/trevordevore/levurehelper-dataview/releases\n2. Unzip the contents, rename the resulting folder to **dataview**, and add the folder to your application folder.\n3. Using the property inspector, add the **dataview_behavior.livecodescript** stack file to the `mainstacks` property of your application stack.\n4. Now add all of the remaining stack files in the **dataview** folder to the `mainstacks` property of your application stack.\n5. In your application code start using the **\"DataView Assets Loader\"** stack and then remove it from memory.\n\n```\nstart using stack \"DataView Assets Loader\"\ndelete stack \"DataView Assets Loader\"\n```\n\n## Creating a DataView\n\nThe DataView helper includes two commands which can create DataView group controls in the LiveCode IDE:\n\n- `dvIdeCreateDataViewControl pName, pTargetCard, pBehavior`\n- `dvIdeCreateDataViewControlUsingDialog pTargetCard, pBehavior, pRowStyleTemplateGroupsA`\n\n`dvIdeCreateDataViewControl` will create a DataView with no additional input. The only required parameter is `pName` which will be the name of the group that is created. If `pTargetCard` is empty then the DataView group control will be added to the current card of the `topStack`. If you would like to assign a behavior to the DataView group control other than the \"DataView Behavior\" stack then pass a reference to it in `pBehavior`. For example, if you want to create a new DataView group control in the current card of the `topStack` that uses the DataView Array controller then you would make the following call:\n\n```\ndvIdeCreateDataViewControl \"My DataView\", empty, the long id of stack \"DataView Array Controller Behavior\"\n```\n\n`dvIdeCreateDataViewControlUsingDialog` will display a dialog with additional options. `pTargetCard` and `pBehavior` behave the same way as for `dvIdeCreateDataViewControl`.\n\nThe modal dialog that appears has a couple of additional options:\n\n- There is a field for entering a name for the DataView group control.\n- There is a checkbox for creating a row template in the *./templates* folder of your Levure application.\n- There is a filed where you can enter a comma-delimited list of row template styles you want to create. One row template group will be created for each style in the list.\n- There is a checkbox for specifying that you want to create a new behavior to assign to the DataView group control. This new behavior is used for your application specific code that you want to attach to the DataView. It will be saved as a script only stack in a \"behaviors\" folder sitting alongside the stack that the DataView is created in. The script only stack file will also be added to the `stackFiles` property of the stack.\n\nIf you pass in a value for `pBehavior` then `pBehavior` will be assigned as the behavior of the new behavior that is created. If you do not pass in `pBehavior` then the \"DataView Behavior\" stack will be assigned as the behavior of the new behavior.\n\n**Note:** If you plan on adding your application specific logic directly to the DataView group control script then you do not need to create an additional behavior script. Creating the additional behavior script is only necessary if you are using version control with your application or if prefer editing your LiveCode scripts in a separate text editor.\n\nHere is an example of creating a new DataView that uses the array controller and populating it with some test data. It is assumed that in the dialog you opted to create a row behavior. The row template that is created is coded to display a \"label\" key in each row.\n\n```\ndvIdeCreateDataViewControlUsingDialog empty, the long id of stack \"DataView Array Controller Behavior\"\n\nput \"Line 1\" into tA[1][\"label\"]\nput \"Line 2\" into tA[2][\"label\"]\nput \"Line 3\" into tA[3][\"label\"]\nput \"Line 4\" into tA[4][\"label\"]\n\nset the dvData of group \"My DataView\" to tA\n```\n\nIf you make changes to the row template group and want to see the change reflected in the DataView then issue the following calls:\n\n```\ndispatch \"ResetView\" to group \"My DataView\"\ndispatch \"RenderView\" to group \"My DataView\"\n```\n\n## Assigning data to a DataView\n\nTo test that a new DataView is working you can create a simple numerically indexed array and assign it to it's `dvData` property. The default row template displays a \"title\" key in a field so a simple test would look like this:\n\n```\nput \"Row 1\" into tDataA[1][\"title\"]\nput \"Row 2\" into tDataA[2][\"title\"]\nput \"Row 3\" into tDataA[3][\"title\"]\n\nset the dvData of group \"MyDataView\" to tDataA\n```\n\n## Customizing row templates\n\nEach row in a DataView is rendered using a row template. A row template is simply a `group` that contains all of the controls necessary to display the data for a row. The group has a behavior script assigned to it that contains all of the logic for displaying row data in the template and positioning the controls in the template.\n\n### Mapping row template groups to row styles\n\nEach row in a DataView has a style assigned to it. The default style is `default` and that is the only style that is supported if you are using the data controller behavior script assigned to a DataView by default. If you create a [custom data controller script](#Creating-a-custom-data-controller) then you can use style names of your choosing.\n\nEach style needs to be mapped to a group serving as a row template. You map a row template group to a row style through the `row style templates` property of a DataView. This property is an array whose keys are style names and values are a reference to a group control. Here is a simple example:\n\n```\nput the long id of group \"MyRowTemplate\" of stack \"MyRowTemplateStack\" \\\n    into tStyleTemplatesA[\"default\"]\nset the viewProp[\"row style templates\"] of group \"MyDataView\" to tStyleTemplatesA\n```\n\nAfter running the above code all rows in the \"MyDataView\" DataView would use the \"MyRowTemplate\" group as the row template.\n\nIf your DataView needs more than one row template than you can use multiple styles. For example:\n\n```\nput the long id of group \"HeadingTemplate\" of stack \"MyRowTemplateStack\" \\\n    into tStyleTemplatesA[\"heading\"]\nput the long id of group \"ParagraphTemplate\" of stack \"MyRowTemplateStack\" \\\n    into tStyleTemplatesA[\"paragraph\"]\nset the viewProp[\"row style templates\"] of group \"MoreComplexView\" to tStyleTemplatesA\n```\n\nAfter running the above code you could assign either the `heading` or `paragraph` style to each row in the \"MoreComplexView\" DataView and the appropriate row template group would be used.\n\n### Where do I store row template groups?\n\nRow templates should be stored in the `.app/templates` folder of a Levure project. Stacks in this folder are treated like a `ui` stack in that they are not loaded into memory at startup but will be loaded when the stack name is referenced in code.  What is different is that stacks in the `./app/template` folder will not be password protected which means their contents can be copied into a DataView in a standalone that is otherwise password protected.\n\nLike the `ui` folder, each folder in the `templates` folder contains one or more LiveCode stacks as well as the supporting behavior script files. Here is an example of a `./app/templates/my-row-template/` folder that stores the behavior in a script only stack:\n\n```\n./app/templates/my-row-template/my-row-template.livecode\n./app/templates/my-row-template/my-row-template-behavior.livecodescript\n```\n\nEach stack should have the following properties:\n\n1. The stack has one card.\n2. The card has one or more groups serving as a row template.\n3. Each group has a behavior assigned to it.\n4. If the behavior is stored in a script only stack then then assign the script only stack file to the `stackFiles` property of the stack the group is a part of.\n\n\n`InitializeTemplate`\n`FillInData pDataA, pRow`\n`LayoutControl pControlRect, pRow`\n`HideRowControl` # if cache is `none`\n`CleanupAfterControl`\n`ShowRowControl`\n`EditKey pKey`\n`PreOpenFieldEditor pEditor`\n\npDirection: next/previous\n`OpenNextFieldEditor pRow, pKey, pDirection, pActionTriggeredBy`\n`CloseFieldEditor pEditor, pRow, pKey, pEventTriggeredByEvent`\n`ExitFieldEditor pEditor, pRow, pKey, pEventTriggeredByEvent`\n\n`selectedRowChanged`\n`DataViewDidUpdateView`\n`HeightsForRows`\n\n`swipeRight`\n`swipeLeft`\n\n`DragReorderRows pTargetRows, pEffectiveDroppedAfterRow, pActualDroppedAfterRow`\n`PositionDropIndicator pBeingDroppedAfterRow`\n\n`HideDropIndicator`\n`ShowDropIndicator`\n\n## Creating a custom data controller\n\nA DataView doesn't have any internal knowledge of the data that it is displaying. Each time it displays a row it asks the outside world to provide the data for that row. When it needs to know how many total rows it should display it also asks the outside world. The code that provides that data can be thought of a data controller. The data controller script orchestrates moving data from a data source into a DataView and saving any changes made to data within the DataView back to the data source.\n\nThe DataView helper comes with a data controller script (`dataview_controller.livecodescript`) that is assigned as a behavior of a new DataView. This data controller script allows you to assign a numerically indexed array of data to the `dvData` property of the DataView. It will then handle feeding the data in that array to the DataView.\n\nFor more advanced cases you can remove this data controller script as the behavior and use your own data controller code. That code can reside in a different behavior script that you assign to the DataView or it might exist in another script in the message hierarchy – e.g. a `group` that the DataView is in or in the `card` or `stack` script. Regardless of where your data controller code is located, you will need to handle one message and two functions. The message is `DataForRow` and the functions are `NumberOfRows()` and `CacheKeyForRow()`. These handlers will be sent and called when you send the `RenderView` command to the DataView.\n\nLet's look at each in turn. In the example code for each handler assume that `sData` is a numerically indexed array.\n\n### DataForRow message\n\nThe `DataForRow` message is sent whenever the DataView needs data to associate with a row. It takes three parameters:\n\n```\nDataForRow pRow, @rDataA, @rTemplateStyle\n```\n\n- `pRow` is the number of the row that you should provide data for.\n- `rDataA` is an array that you populate with the data needed to display the row.\n- `rTemplateStyle` is the style to associate with the row. If you don't provide a value then `default` will be used.\n\nExample 1:\n\n```\ncommand DataForRow pRow, @rDataA, @rTemplateStyle\n  put sDataA[pRow] into rDataA\n  put \"default\" into rTemplateStyle\nend DataForRow\n```\n\nExample 2:\n\n```\ncommand DataForRow pRow, @rDataA, @rTemplateStyle\n  sqlquery_moveToRecord sQueryA, pRow\n  put sqlquery_currentRowToArray(sQueryA) into rDataA\n  put \"default\" into rTemplateStyle\nend DataForRow\n```\n\n### NumberOfRows function\n\nThe `NumberOfRows()` function must return the number of rows being displayed in the DataView.\n\nExample 1:\n\n```\nfunction NumberOfRows\n  return the number of elements of sDataA\nend NumberOfRows\n```\n\nExample 2:\n\n```\nfunction NumberOfRows\n  return sqlquery_get(sQueryA, \"number of records\")\nend NumberOfRows\n```\n\n### CacheKeyForRow function\n\nThe `CacheKeyForRow()` function must return a unique identifier for each row. If you don't define the `CacheKeyForRow()` function in the message path then the DataView will use the row number to uniquely identify each row. If your DataView is displaying a flat list of data that cannot be reordered and that never toggles the visibility of rows then there is nothing further that needs to be done.\n\nIf, however, the row that data in your data source is associated with can change between calls to `ResetView` then you must handle `CacheKeyForRow()` and return a unique identifier for the row. For example, the primary key column from a database table will be adequate in most cases. If your DataView is displaying records from multiple tables then the primary key might not be sufficient as the primary keys from two different tables aren't necessarily unique.\n\n```\nCacheKeyForRow pRow\n```\n\nExample 1:\n\n```\nfunction CacheKeyForRow pRow\n  return pRow\nend CacheKeyForRow\n```\n\nExample 2:\n\n```\nfunction CacheKeyForRow pRow\n  return sDataA[pRow][\"id\"]\nend CacheKeyForRow\n```\n\nExample 3:\n\n```\nfunction CacheKeyForRow pRow\n  return revDatabaseColumnNamed(sCursorId, \"id\")\nend CacheKeyForRow\n```\n\n## Specifying whether or not a row is selectable\n\nIf your DataView has rows that should not be selectable by the user then return false for the `dvCanSelect` property of the row template. The following script can be added to a row template behavior:\n\n```\ngetProp dvCanSelect\n  return false\nend dvCanSelect\n```\n\n## How caching works\n\n`lazy`, `eager`, `none`\n\n## Opening a field editor in a DataView\n\n1. Dispatch `EditKeyOfRow` to the DataView\n2. DataView dispatches `EditKey` to the row control.\n3. Call `CreateFieldEditorForField` and pass in the field to edit in the row control.\n\nPossible values for pEventThatTriggeredClose are `close control`,\n`closeField`, `exitField`, `returnInField`, `enterInField`, and `tabKey`.\n\n`close control` is sent when the user scrolls the row that is being edited out of view\nand caching is not turned on.\n\n## The `animate selections` property\n\nThe DataView can animate selections of rows that are not currently in view. You need to set the `viewProp[\"animate selections\"]` property to true and have the [animationEngine](https://github.com/derbrill/animationEngine) library in use.\n\n## The Drag Reordering API\n\nThe DataView has a built in API for drag reordering. To start a drag operation do the following:\n\n1. Define a `dragStart` handler in your instance of the DataView.\n2. In the handler set `the dvDragImageRow of me` to the first row that is being dragged. In most cases you can set the property to `item 1 of the dvHilitedRows of me` of the DataView.\n3. In the handler set `the dragData[\"private\"]` to a string that contains the necessary information for the drop. For example, line 1 of the string might be an identifier such as \"file nodes\" and line 2 would be `the dvHilitedRows of me`.\n4. In the handler set `the dvTrackDragReorder of me to true`\n\nAt this point you will see visual feedback. A snapshot of `the dvDragImageRow` will follow the mouse around and a drop indicator will show where the drop will occur.\n\n### ValidateRowDrop\n\nEach time `dragMove` is called, the DataView will calculate a proposed drop row and drop operation based on the position of the mouse. It will then dispatch `ValidateRowDrop` to the DataView and pass the following parameters:\n\n1. pDraggingInfoA: Array with `action` (the value of `dragAction`), `mouseH`, and `mouseV` keys. The `mouseH` and `mouseV` keys are the same parameters passed to `dragMove`.\n2. pProposedRow: The proposed row that the drop should occur on based on the mouse vertical position.\n3. pProposedDropOperation: The proposed drop operation based on the mouse vertical position. `on` or `above`.\n\n*Note:* If the drop will occur after the last row in the DataView then the proposed row will be the number of rows in the DataView + 1 and the proposed operation will be \"above\".\n\nThe `ValidateRowDrop` handler can accept any of the above parameters by reference (parameter name prefixed with `@`)\nand modify them. Modifying the proposed row and drop operation can be done if needed in order to redirect a drop.\n\nIf the drop should not occur over the proposed row then return `false` from `ValidateRowDrop`.\n\n### AcceptRowDrop\n\nWhen `dragDrop` is called as a result of the user \"dropping\" a row on the DataView your instance of the DataView will be notified with the `AcceptRowDrop` message. It will be sent the following parameters:\n\n1. pDraggingInfoA: Array with an `action` (the `dragAction`). In addition, if keys were added to the `pDraggingInfoA` array passed by reference to `ValidateRowDrop` the those keys will be present as well.\n2. pRow: The row that the drop occurred on.\n3. pDropOperation: The drop operation. `on` or `above`.\n\nThis handler is where you write your application specific logic that reorders the data in the data source and refreshes the DataView.\n\n### Customizing the row snapshot when setting the dvDragImageRow\n\nWhen the `dvDragImageRow` property is set a snapshot of the corresponding row control is taken and assigned to the `dragImage` property. Three messages are sent to the row control which allow you to customize the the snapshot that is taken - `PreDragImageSnapshot`, `CreateDragImageSnapshot`, and `PostDragImageSnapshot`.\n\n1. `PreDragImageSnapshot`: Make any customizations to the row control prior to the snapshot being taken. For example, you might hide controls in the row group control such as action menus and just leave a label field visible.\n2. `CreateDragImageSnapshot pTargetSnapshotImageId`: If your code handles this message (meaning your code defines he handler and does not pass it) then it is your responsibility to export a snapshot to image id `pTargetSnapshotImageId`. Example: `export snapshot from the target to image id pTargetSnapshotImageId as PNG`. If your code doesn't handle this message then a snapshot of the row control will be exported for you.\n3. In `PostDragImageSnapshot` you restore the row control to it's normal state.\n\nThese handlers will typically be defined in the row control behavior script or in the DataView instance script.\n\n### Customizing the drop indicator\n\nThe drop indicator (the line that shows you where the drop will occur) is determined by the `viewProp[\"drop indicator template\"]` custom property of the DataView. This property can be assigned the long id of a control (it will be converted to a rugged id when stored). If the property is empty then the drop indicator that is included with the DataView is used.\n\nIf you define your own control to use as a drop indicator then it needs a script with the following handler:\n\n```\ncommand PositionDropIndicator pDraggingInfoA, pRow, pDropOperation\n  # Resize the control...\nend PositionDropIndicator\n```\n\nBefore this handler is called, the control will be have it's width resized to the width of the DataView.\n\nThe default drop indicator template is a group with a script similar to the following:\n\n```\ncommand PositionDropIndicator pDraggingInfoA, pRow, pDropOperation\n  local tViewRect, tRect\n\n  put the rect of me into tViewRect\n\n  put the rect of graphic 1 of me into tRect\n  put item 1 of tViewRect into item 1 of tRect\n  put item 3 of tViewRect + 1 into item 3 of tRect\n  set the rect of graphic 1 of me to tRect\nend PositionDropIndicator\n```\n\n### Mobile and web support for drag reordering\n\nLimited drag reordering support has been implemented for mobile and web using\nmouse events and by showing the drag image within the dataview. The drag image\nif used only moves vertically in the view. These drag\noperations are only supported within the one dataview. To initiate a drag\nreorder on mobile you need to script the drag detection with a dataview\nscript such as:\n\n```\nlocal sDetectDrag = false\non mouseDown\n  if (the platform is \"web\" or the environment is \"mobile\") then\n    put true into sDetectDrag\n  end if\n\n  pass mouseDown\nend mouseDown\n\non mouseUp\n  if (the platform is \"web\" or the environment is \"mobile\") then\n    put false into sDetectDrag\n  end if\n\n  pass mouseUp\nend mouseUp\n\non mouseRelease\n  if (the platform is \"web\" or the environment is \"mobile\") then\n    put false into sDetectDrag\n  end if\n\n  pass mouseRelease\nend mouseRelease\n\non mouseMove \\\n    pMouseH, \\\n    pMouseV\n\n  if (the platform is \"web\" or the environment is \"mobile\") and \\\n      sDetectDrag and \\\n      _DragBegun(pMouseH, pMouseV) then\n    put false into sDetectDrag\n\n    /* Manually set the dragAction because the dragSource can not be used\n     * to detect a move */\n    set the dragAction to \"move\"\n    set the dragData[\"private\"] to the dvRow of the dvRowControl of the target\n    set the dvDragImageRow of me to the dragData[\"private\"]\n    set the dvTrackDragReorder of the dvControl of me to true\n  end if\n\n  pass mouseMove\nend mouseMove\n\nprivate function _DragBegun \\\n    pMouseH, \\\n    pMouseV\n\n  return abs(sqrt((clickH()  - pMouseH) ^ 2 \\\n      + (clickV() - pMouseV) ^ 2 )) \u003e= the dragDelta\nend _DragBegun\n```\n\nAdditional decoration of the drag image for web and mobile can be implemented\nsuch as:\n\n```\non PostDragImageSnapshot\n  if the platform is \"web\" or the environment is \"mobile\" then\n    set the blendLevel of image \"dvDragImage\" of me to 15\n    set the innerGlow[\"color\"] of image \"dvDragImage\" of me to \"0,0,255\"\n  end if\nend PostDragImageSnapshot\n```\n\n## A Note on Behaviors\n\nThis is mainly for folks who aren't using the Levure framework as they are more likely to run into the situation described below. Levure makes sure that behaviors are loaded into memory before any stacks try to load them.\n\nBehaviors are wonderful things. Except when they don't resolve properly. Then they are terrible things because they trick you into thinking they really did resolve properly. Here is what you need to know so you don't go down a troubleshooting rabbit hole and never come out.\n\nWhen the LiveCode engine finds a control which has its behavior property set it tries to resolve the behavior reference in order to find the script. If, for any reason, the engine cannot find the script that is referenced by the behavior property then the engine will silently move along as if nothing bad has happened. But something bad has happened. The behavior script wasn't loaded so any functionality that the behavior script provided will not work. When might something like this happen?\n\nIf you are storing your behaviors in script only stacks or a control in a stack that is not part of your main application then this might happen to you.\n\n### What should you do?\n\nA full-proof solution is to add each stack file that contains a behavior script to the `stackfiles` property of your main application stack. You can do this using the stack property inspector. By doing this the engine will always be able to track down the behavior when your application stack opens.\n\nBe aware that if you use `dvIdeCreateRowTemplates` to create row templates that a behavior will be stored in a script only stack. While this handler will assign the script only stack file to the `stackfiles` property of the stack that contains the row template, the script only stack file will not be assigned to the `stackfiles` property of your application stack. \n\nFor example, if your application stack 1) has a DataView in it and 2) you save the stack with row template groups loaded into the DataView then you must assign the row template behavior script only stack files to the `stackfiles` of your application stack. Otherwise when your application stack is loaded by the LiveCode engine it sees the row template groups, tries to resolve the behaviors assigned to them, can't find them, and you start wondering why your DataView is no longer functioning properly.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrevordevore%2Flevurehelper-dataview","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftrevordevore%2Flevurehelper-dataview","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrevordevore%2Flevurehelper-dataview/lists"}