Skip to main content
A page is a screen of your own reached from a tab along the top of the map. While it is open the map is a blurred backdrop: it does not pan, its markers are hidden, and every click and key belongs to the page. Use a page for a list, a form or a summary that belongs next to the map: a job board, a garage, a property list. For a different map (other markers, another camera) use a view instead.

Calls

RegisterPage answers false when the page it was given cannot be drawn, which is also what happens to a page whose fields are of the wrong type: what the map cannot render it refuses rather than showing an empty screen. The reason is written to the console, so a refused page does not have to be guessed at. RemovePage answers whether there was a page of that id to remove. A page belongs to the resource that registered it. Registering your own id again replaces the first. Only that resource can update the page, set its content, register over it or remove it; the exports answer false to anyone else and say why in the console. OpenPage opens the menu on the page when it is closed, so a page can be reached from a command or a key of your own resource. It opens over the game without the map’s camera; pass true as the second argument to fly the camera up first. The camera comes up anyway once the player picks the Map tab.

Fields

The page

The document

A page is drawn like the settings screen, at its width, and each section is a titled column of rows. Two sections sit side by side; wide = true makes one take the full width. title is not drawn: the tab the player opened already names the page. subtitle is a line above the sections. The page is driven the way the settings screen is. The arrow keys move a cursor through everything that can be used, in reading order; left and right step a select, switch a toggle and move between a row’s actions; Enter presses a button, chooses a row or fires the action picked, and puts the caret in an input. A select steps through its options between two arrows, one action per step. Text, stats and disabled controls are passed over. A row of a list is { id, label, meta, icon, color, disabled, actions }. icon and color are a marker sprite and colour, drawn the way the legend draws them. actions is a list of { id, label, variant } shown at the end of the row. meta is text or a number. A variant that is not one of the three is ignored and the control is drawn as its default. A label too long for its row is cut with an ellipsis, on a tab, a row, a button and a select alike. A row has room for two short actions on a 1024-pixel-wide screen; with more, their labels are cut first. An item the map does not know is skipped, so a page written for a newer map still shows the rest of its content.

Embedding your own interface

The address must be https, and its host must be the NUI origin of a resource on this server: cfx-nui-<resource> and nothing more, so a registrable domain such as cfx-nui-x.example.com is not one: or a host listed whole in pageEmbedHosts in Menu. An address carrying a userinfo section (https://cfx-nui-x@example.com/) loads example.com and is refused, as is one whose host is percent-encoded or non-ASCII. Anything else is refused. The frame is sandboxed and is not same-origin with the map, so the embedded page cannot reach the map’s interface or its callbacks. It talks to its own resource, the way any NUI page does. Escape goes back from an embedded page as it does from any other, also after the player has clicked inside it.

What happens

The action table is { page, action, row, value }. The map holds no state of its own for a page: answer an action by sending the page back with SetPageContent. A toggle or a select shows the value you sent until you send another, and an input takes the value you send unless the player is typing in it. A view has the last word on which pages it hosts: a page its surface.pages does not list is neither drawn as a tab nor opened by OpenPage while that view is on screen. A page that is open when the view stops allowing it is closed. The page stays registered and comes back with the next view that allows it.

Errors

RegisterPage answers false and says why in the console when a page has no id, no label, or content that is neither a document nor an embeddable address. Nothing is registered: there is no half-registered page and no tab. An item the map does not understand is dropped from the page rather than refusing the whole of it, so a page written for a newer map still shows the rest of its content. An item of a kind in the table above that lacks a field it needs is dropped too, and the console says which kind, once per page. A section whose items is missing or empty is not drawn. An embed whose address does not pass the rule above is refused at registration, so it never reaches the interface. The interface applies the same rule again before it draws the frame, and shows “Embedded page refused” in place of the page if it ever disagrees. SetPageContent and RemovePage answer false for a page that is not registered.

Example