I’m having trouble getting my script to update the UI with Lua data. I’ve handled the JavaScript part to the best of my ability as I’m reacquainting myself with frontend development. My friend and I are collaborating on an RZ script—I’ve handled the frontend UI, and he’s tackled the Lua. We’re attempting to pass Lua data to the JavaScript for UI updates, but it seems like something’s faulty. So i was able to do everything but trying to handle the data for the top 4 players which is not updating i setup console logs and I’m still confused.
enter image description here enter image description here
I tried many ways but still not work this is my current js
function clearText(ids) {
ids.forEach(function(id) {
$('#' + id).text('');
});
}
window.addEventListener('message', function(event) {
const type = event.data.type;
const playerData = event.data.PlayerData;
const zonedata = event.data.zonedata;
updateUI(playerData, zonedata);
});
function updateUI(playerData, zonedata) {
// Get UI elements
const leaderElement = document.getElementById("leader");
const leaderKillsElement = document.getElementById("leaderkills");
const killStreakNameElement = document.getElementById("killstreakname");
const killStreakNumberElement = document.getElementById("killstreaknumber");
const rewardOnKillElement = document.getElementById("rewardonkill");
const totalKillsElement = document.getElementById("totalkills");
const killsElement = document.getElementById("kills");
const deathsElement = document.getElementById("deaths");
const top1NameElement = document.getElementById("top1name");
const player1KillsElement = document.getElementById("player1kills");
const top2NameElement = document.getElementById("top2name");
const player2KillsElement = document.getElementById("player2kills");
const top3NameElement = document.getElementById("top3name");
const player3KillsElement = document.getElementById("player3kills");
const top4NameElement = document.getElementById("top4name");
const player4KillsElement = document.getElementById("player4kills");
// Update UI elements based on received data
if (zonedata) {
leaderElement.textContent = zonedata && typeof zonedata.leader !== 'undefined' && zonedata.leader !== null ? zonedata.leader : '';
leaderKillsElement.textContent = zonedata && typeof zonedata.leaderkills !== 'undefined' ? zonedata.leaderkills : '';
killStreakNameElement.textContent = zonedata && typeof zonedata.killStreakName !== 'undefined' ? zonedata.killStreakName : '';
killStreakNumberElement.textContent = zonedata && typeof zonedata.killStreakNumber !== 'undefined' ? zonedata.killStreakNumber : '';
rewardOnKillElement.textContent = '$ ' + (zonedata && typeof zonedata.rewardOnKill !== 'undefined' ? zonedata.rewardOnKill : '');
totalKillsElement.textContent = zonedata && typeof zonedata.totalKillsToWin !== 'undefined' ? zonedata.totalKillsToWin : '';
// Update other UI elements from zonedata as needed
}
if (playerData) {
killsElement.textContent = playerData && typeof playerData.kills !== 'undefined' ? playerData.kills : '';
deathsElement.textContent = playerData && typeof playerData.deaths !== 'undefined' ? playerData.deaths : '';
// Update other UI elements from playerData as needed
}
// Update top players if available
console.log('Received top players:', zonedata?.topplayers);
if (zonedata?.topplayers?.length >= 4) {
for (let i = 0; i < 4; i++) {
const nameElement = document.getElementById(`top${i}name`);
const killsElement = document.getElementById(`player${i}kills`);
if (zonedata.topplayers[i]) {
nameElement.textContent = zonedata.topplayers[i].name || '';
killsElement.textContent = zonedata.topplayers[i].kills || '';
}
}
}
}
$(document).ready(function() {
window.addEventListener('message', function(event) {
console.log('Message received:', event.data); // Log the received message
console.log('Message data:', JSON.stringify(event.data)); // Log the received data as JSON string
if (typeof event.data.zonedata !== 'undefined') {
console.log('Type of zonedata:', typeof event.data.zonedata); // Log the type of zonedata
// Check if zonedata is a string and parse it
if (typeof event.data.zonedata === 'string') {
console.log('zonedata is a string, parsing...');
try {
const zonedata = JSON.parse(event.data.zonedata);
// Now zonedata is an object, you can proceed to use it
updateUI(event.data.playerData, zonedata);
} catch (error) {
console.error('Error parsing zonedata:', error);
}
} else {
updateUI(event.data.playerData, event.data.zonedata);
}
}
if (event.data.type === 'updateUI') {
console.log('Updating UI with data:', event.data); // Log the received data
updateUI(event.data.message);
} else if (event.data.type === 'showUI') {
console.log('Showing UI');
$(".container").fadeIn('fast');
} else if (event.data.type === 'hideUI') {
console.log('Hiding UI');
$(".container").fadeOut('fast');
} else {
console.log('Unknown message type:', event.data.type);
}
});
`
and here is my server.lua
function SetupZoneData()
for k,v in pairs(Config.RedZones) do
ZoneData[k] = {
routingbucket = v.routingbucket,
totalKillsToWin = Config.DeafultKillsToWin,
Players = {},
leader = 'None',
killStreakName = 'None',
killStreakNumber = 0,
rewardOnKill = Config.KillRewardMoney,
topplayers = {}
}
end
print(json.encode(ZoneData))
end
SetupZoneData()
Citizen.CreateThread(function()
while true do
-- Loop through each zone
for zoneName, zoneData in pairs(ZoneData) do
if ZoneData[zoneName].Players then
-- Sort players by kills
local sortedPlayers = {}
for playerId, stats in pairs(ZoneData[zoneName].Players) do
table.insert(sortedPlayers, { playerId = stats.source, kills = stats.kills, deaths = stats.deaths, killstreak = stats.killstreak, zonename = stats.zonename })
end
table.sort(sortedPlayers, function(a, b)
return a.kills > b.kills
end)
-- Update top 4 players in topplayers field
local topPlayers = {}
for i = 1, 4 do
if sortedPlayers[i] then
local playerId = sortedPlayers[i].playerId
local playerName = GetPlayerName(playerId)
local playerKills = sortedPlayers[i].kills
table.insert(topPlayers, { name = playerName, kills = playerKills })
end
end
print('Top Players for Zone ' .. zoneName .. ': ' .. json.encode(topPlayers))
-- Find player with the highest kill streak
local highestKillStreak = 0
local playerWithHighestStreak = nil
for _, player in ipairs(PlayerData) do
if player.killstreak > highestKillStreak then
highestKillStreak = player.killstreak
playerWithHighestStreak = player.source
end
end
-- Set ZoneData with highest kill streak player
if playerWithHighestStreak then
ZoneData[zoneName].killStreakName = GetPlayerName(playerWithHighestStreak)
ZoneData[zoneName].killStreakNumber = highestKillStreak
else
ZoneData[zoneName].killStreakName = 'None'
ZoneData[zoneName].killStreakNumber = 0
end
-- Update ZoneData with top players
ZoneData[zoneName].topplayers = topPlayers
print(json.encode(topPlayers))
-- Update clients with the latest player and zone data
for _, data in pairs(PlayerData) do
TriggerClientEvent('mtf-redzone:Client:RequestZoneSync', data.source, json.encode(ZoneData[zonename].Players[data.source]), json.encode(ZoneData[zoneName]))
end
end
end
-- Sleep for a minute before updating again (adjust as needed)
Citizen.Wait(1000)
end
end)
and here is the client.lua
local ActiveZones = {}
local InActiveZone = false
local display = false
function SetDisplay(bool)
display = bool
if bool then
SendNUIMessage({
type = "showUI",
-- PlayerData = PlayerData,
-- zonedata = zonedata,
status = bool,
})
else
SendNUIMessage({
type = "hideUI",
status = bool,
})
end
end
function UpdateUIThread(zonedata, playerData)
while InActiveZone do
Wait(500)
SendNUIMessage({
type = "updateUI",
PlayerData = playerData,
zonedata = zonedata,
})
end
end
-- [ Zone / Blip Creation ] --
Citizen.CreateThread(function()
for k,v in pairs(Config.RedZones) do
ActiveZones[k] = lib.zones.sphere({
coords = v.coords,
radius = v.zonesize,
debug = Config.Debug,
onEnter = function(self)
TriggerServerEvent('mtf-redzone:Server:EnterZone', v.routingbucket, k)
InActiveZone = true
if Config.DisableInventory then exports.ox_inventory:weaponWheel(true) end
GiveWeaponToPed(PlayerPedId(), v.issueweapon, 99999, false, true)
SetDisplay(true)
end,
onExit = function(self)
TriggerServerEvent('mtf-redzone:Server:LeftZone', v.routingbucket, k)
RemoveAllPedWeapons(PlayerPedId())
-- RemoveWeaponFromPed(PlayerPedId(), v.issueweapon)
InActiveZone = false
if Config.DisableInventory then exports.ox_inventory:weaponWheel(false) end
SetDisplay(false)
end,
})
if Config.ShowZoneRadius then
local radius = AddBlipForRadius(v.coords, v.blipradius)
SetBlipSprite(radius, 1)
SetBlipColour(radius, 1)
SetBlipAlpha(radius, 65)
end
end
end)
RegisterNetEvent('mtf-redzone:SetCurrentWeapon', function()
SetCurrentPedWeapon(PlayerPedId(), GetHashKey('weapon_pistol'), true)
end)
RegisterNetEvent('mtf-redzone:Client:RequestZoneSync', function(playerData, zoneData)
print('Received zone data:', json.encode(zoneData)) -- Check the received data
print('Received player data:', json.encode(playerData)) -- Check the received data
-- Further processing, if needed
UpdateUIThread(zoneData, playerData) -- Pass the zone data to the UI update function
end)
RegisterNetEvent('mtf-redzone:client:DeathHandler', function(nearestPoint)
local player = PlayerPedId()
DoScreenFadeOut(1000)
Wait(1000)
SetEntityCoords(PlayerPedId(), nearestPoint.x, nearestPoint.y, nearestPoint.z)
Wait(2500) -- Wait for the player to be teleported
SetEntityMaxHealth(player, 200)
SetEntityHealth(player, 200)
ClearPedBloodDamage(player)
SetPlayerSprint(PlayerId(), true)
-- qb-ambulancejob specific events to revive player
TriggerEvent('hospital:client:Revive')
DoScreenFadeIn(1000)
end)
AddEventHandler('onResourceStop', function()
-- for k,v in pairs(Config.RedZones) do
-- RemoveBlip(k)
-- lib.zones.remove(k)
-- end
end)
and here is the html for the top 4 players that i waant updated with the lua data
<h2>TOP 4</h2>
</div>
<div class="red-zone">
<div class="red-card left-card">
<span class="badge">1
</span >
<p id="top1name">Josh</p>
</div>
<div class="red-card right-card">
<i class="icon skull-icon"></i>
<span id="player1kills">30</span>
</div>
</div>
<div class="red-zone">
<div class="red-card left-card">
<span class="badge">2
</span>
<p id="top2name">Vinny</p>
</div>
<div class="red-card right-card">
<i class="icon skull-icon"></i>
<span id="player2kills">10</span>
</div>
</div>
<div class="red-zone">
<div class="red-card left-card">
<span class="badge">3
</span>
<p id="top3name">llyty</p>
</div>
<div class="red-card right-card">
<i class="icon skull-icon"></i>
<span id="player3kills">9</span>
</div>
</div>
<div class="red-zone">
<div class="red-card left-card">
<span class="badge">4
</span>
<p id="top4name">Bob</p>
</div>
<div class="red-card right-card">
<i class="icon skull-icon"></i>
<span id="player4kills">5</span>
</div>
</div>
<div>