├── README.md
├── client.lua
├── config.lua
├── fxmanifest.lua
└── html
├── index.html
├── script.js
└── style.css
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Hi there, Im didAX19
4 |
5 |
6 | # QB Input Redesign
7 | - New modern design with redesigned inputs.
8 | - You can choose between dark or light modes in the configuration.
9 |
10 | # Preview
11 |
12 |
13 | # Support ?
14 | Welcome to our Discord server .
15 |
--------------------------------------------------------------------------------
/client.lua:
--------------------------------------------------------------------------------
1 | local properties = nil
2 |
3 | RegisterNUICallback("buttonSubmit", function(data, cb)
4 | SetNuiFocus(false)
5 | properties:resolve(data.data)
6 | properties = nil
7 | cb("ok")
8 | end)
9 |
10 | RegisterNUICallback("closeMenu", function(_, cb)
11 | SetNuiFocus(false)
12 | properties:resolve(nil)
13 | properties = nil
14 | cb("ok")
15 | end)
16 |
17 | local function ShowInput(data)
18 | Wait(150)
19 | if not data then return end
20 | if properties then return end
21 | properties = promise.new()
22 |
23 | SetNuiFocus(true, true)
24 | SendNUIMessage({
25 | action = "OPEN_MENU",
26 | data = data,
27 | darkMode = Config.darkMode
28 | })
29 |
30 | return Citizen.Await(properties)
31 | end
32 |
33 | exports("ShowInput", ShowInput)
--------------------------------------------------------------------------------
/config.lua:
--------------------------------------------------------------------------------
1 | Config = {}
2 |
3 | Config.darkMode = true
--------------------------------------------------------------------------------
/fxmanifest.lua:
--------------------------------------------------------------------------------
1 | fx_version 'cerulean'
2 | game 'gta5'
3 |
4 | description 'QB-Input Redesigned by didax19'
5 | version '0.0.1'
6 |
7 | client_scripts {
8 | 'client.lua',
9 | 'config.lua',
10 | }
11 |
12 | ui_page 'html/index.html'
13 |
14 | files {
15 | 'html/index.html',
16 | 'html/style.css',
17 | 'html/script.js'
18 | }
19 |
20 | lua54 'yes'
21 |
--------------------------------------------------------------------------------
/html/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | QB INPUT Redesigned by didax19
7 |
8 |
9 |
10 |
11 |
12 |
15 |
16 |
--------------------------------------------------------------------------------
/html/script.js:
--------------------------------------------------------------------------------
1 | let formInputs = {};
2 | let darkModeEnabled = true; // Set this variable to true for dark mode, false for default colors
3 |
4 | $(window).resize(function () {
5 | updateMainWrapperHeight();
6 | });
7 |
8 | const updateMainWrapperHeight = () => {
9 | const wrapper = $(".main-wrapper");
10 | const windowHeight = $(window).height();
11 | const wrapperTopOffset = wrapper.offset().top;
12 | const maxHeight = windowHeight - wrapperTopOffset;
13 | wrapper.css("max-height", maxHeight + "px");
14 | };
15 |
16 | const OpenMenu = (data, darkModeEnabled) => {
17 | if (data == null || data == "") {
18 | console.log("No data detected");
19 | return null;
20 | }
21 |
22 | let showContainer = () => {
23 | $(".background").fadeIn();
24 | $(".main-wrapper").addClass(darkModeEnabled ? "dark-mode" : "");
25 | $(".main-wrapper").fadeIn();
26 | };
27 |
28 | showContainer();
29 | updateMainWrapperHeight();
30 |
31 | let form = [
32 | "");
69 |
70 | $(".main-wrapper").html(form.join(" "));
71 |
72 | $("#qb-input-form").on("change", function (event) {
73 | if( $(event.target).attr("type") == 'checkbox' ) {
74 | const value = $(event.target).is(":checked") ? "true" : "false";
75 | formInputs[$(event.target).attr("value")] = value;
76 | }else{
77 | formInputs[$(event.target).attr("name")] = $(event.target).val();
78 | }
79 | });
80 |
81 | $("#qb-input-form").on("submit", async function (event) {
82 | if (event != null) {
83 | event.preventDefault();
84 | }
85 | await $.post(
86 | `https://${GetParentResourceName()}/buttonSubmit`,
87 | JSON.stringify({ data: formInputs })
88 | );
89 | CloseMenu();
90 | });
91 | };
92 |
93 | const renderTextInput = (item) => {
94 | const { text, name } = item;
95 | formInputs[name] = item.default ? item.default : "";
96 | const isRequired = item.isRequired == "true" || item.isRequired ? "required" : "";
97 | const defaultValue = item.default ? `value="${item.default}"` : ""
98 |
99 | return ` `;
100 | };
101 | const renderPasswordInput = (item) => {
102 | const { text, name } = item;
103 | formInputs[name] = item.default ? item.default : "";
104 | const isRequired = item.isRequired == "true" || item.isRequired ? "required" : "";
105 | const defaultValue = item.default ? `value="${item.default}"` : ""
106 |
107 | return ` `;
108 | };
109 | const renderNumberInput = (item) => {
110 | try {
111 | const { text, name } = item;
112 | formInputs[name] = item.default ? item.default : "";
113 | const isRequired = item.isRequired == "true" || item.isRequired ? "required" : "";
114 | const defaultValue = item.default ? `value="${item.default}"` : "";
115 |
116 | return ` `;
117 | } catch (err) {
118 | console.log(err);
119 | return "";
120 | }
121 | };
122 |
123 | const renderRadioInput = (item) => {
124 | const { options, name, text } = item;
125 | formInputs[name] = options[0].value;
126 |
127 | let div = `";
136 | return div;
137 | };
138 |
139 | const renderCheckboxInput = (item) => {
140 | const { options, name, text } = item;
141 |
142 |
143 | let div = `";
156 | return div;
157 | };
158 |
159 | const renderSelectInput = (item) => {
160 | const { options, name, text } = item;
161 | let div = `${text}
`;
162 |
163 | div += ``;
164 | formInputs[name] = options[0].value;
165 |
166 | options.forEach((option, index) => {
167 | const isDefaultValue = item.default == option.value
168 | div += `${option.text} `;
169 | if(isDefaultValue){ formInputs[name] = option.value }
170 | });
171 | div += " ";
172 | return div;
173 | };
174 |
175 | const CloseMenu = () => {
176 | $(`.main-wrapper`).fadeOut(0);
177 | $("#qb-input-form").remove();
178 | formInputs = {};
179 | };
180 |
181 | const CancelMenu = () => {
182 | $.post(`https://${GetParentResourceName()}/closeMenu`);
183 | return CloseMenu();
184 | };
185 |
186 | window.addEventListener("message", (event) => {
187 | const data = event.data;
188 | const info = data.data;
189 | const action = data.action;
190 | const darkModeEnabled = data.darkMode;
191 | switch (action) {
192 | case "OPEN_MENU":
193 | return OpenMenu(info, darkModeEnabled);
194 | case "CLOSE_MENU":
195 | return CloseMenu();
196 | default:
197 | return;
198 | }
199 | });
200 |
201 | document.onkeyup = function (event) {
202 | const charCode = event.key;
203 | if (charCode == "Escape") {
204 | CancelMenu();
205 | } else if (charCode == "Enter") {
206 | SubmitData();
207 | }
208 | };
209 |
210 | $(document).click(function (event) {
211 | var $target = $(event.target);
212 | if (
213 | !$target.closest(".main-wrapper").length &&
214 | $(".main-wrapper").is(":visible")
215 | ) {
216 | CancelMenu();
217 | }
218 | });
--------------------------------------------------------------------------------
/html/style.css:
--------------------------------------------------------------------------------
1 | @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@300;500&display=swap");
2 |
3 | :root {
4 | --primary-color: #f2f2f2;
5 | --secondary-color: #190A28;
6 | --accent-color: #D095FA;
7 | --input-hover: #D095FA;
8 | --text-color: #190A28;
9 | --select-bg: #A86DF9;
10 | --select-hover: #D095FA;
11 | --scrollbar-thumb: #D095FA;
12 | --scrollbar-color: #f7f7f7;
13 | }
14 |
15 | .dark-mode {
16 | --primary-color: #190A28;
17 | --secondary-color: #f2f2f2;
18 | --accent-color: #491085;
19 | --input-hover: #240842;
20 | --text-color: #ffffff;
21 | --select-bg: #A86DF9;
22 | --select-hover: #491085;
23 | --scrollbar-thumb: #6E19C8;
24 | --scrollbar-color: #240842;
25 | }
26 |
27 | * {
28 | padding: 0;
29 | margin: 0;
30 | font-family: "Poppins", sans-serif;
31 | font-weight: 300;
32 | }
33 |
34 | html,
35 | body {
36 | background: transparent;
37 | }
38 |
39 | .root-wrapper {
40 | width: 30vw;
41 | height: auto;
42 | top: 31.2%;
43 | left: 62.5%;
44 | transform: translate(-50%, -50%);
45 | position: absolute;
46 | background: transparent;
47 | opacity: .9;
48 | }
49 |
50 | .main-wrapper {
51 | margin: auto;
52 | margin-top: 64.2%;
53 | width: 300px;
54 | padding-bottom: 10px;
55 | border-radius: 9px;
56 | height: auto;
57 | position: relative;
58 | display: flex;
59 | flex-direction: column;
60 | }
61 |
62 | ::-webkit-scrollbar {
63 | width: 6px;
64 | }
65 |
66 | ::-webkit-scrollbar-track {
67 | background: var(--scrollbar-color);
68 | border-radius: 3px;
69 | }
70 |
71 | ::-webkit-scrollbar-thumb {
72 | background: var(--scrollbar-thumb);
73 | border-radius: 3px;
74 | }
75 |
76 | .heading {
77 | display: flex;
78 | justify-content: center;
79 | margin-bottom: 1.5vh;
80 | color: var(--secondary-color);
81 | background: linear-gradient(140deg, #D095FA 0%, #6E19C8 100%)!important;
82 | border-radius: 10px;
83 | font-size: 18px;
84 | font-weight: 500;
85 | padding: 10.5px;
86 | }
87 |
88 | .heading h1 {
89 | position: relative;
90 | }
91 |
92 | .inputs {
93 | max-height: 60vh;
94 | background: var(--primary-color);
95 | border-radius: 10px;
96 | overflow: auto;
97 | }
98 |
99 | input:last-of-type {
100 | border-radius: 0px 0px 10px 10px;
101 | }
102 |
103 | input:first-of-type {
104 | border-radius: 10px 10px 0px 0px;
105 | }
106 |
107 | input:only-of-type {
108 | border-radius: 10px 10px 10px 10px;
109 | }
110 |
111 | .divider {
112 | width: 100%;
113 | height: 1px;
114 | background-color: var(--accent-color);
115 | }
116 |
117 | .form {
118 | width: 100%;
119 | height: auto;
120 | min-height: 10%;
121 | max-height: 70%;
122 | margin: auto;
123 | display: flex;
124 | flex-direction: column;
125 | }
126 |
127 | .form label {
128 | margin-top: 24px;
129 | }
130 |
131 | .form-control[type="number"] {
132 | appearance: none;
133 | -webkit-appearance: none;
134 | }
135 |
136 | .form-control[type="text"],
137 | .form-control[type="number"],
138 | .form-control[type="password"] {
139 | border: none;
140 | font-size: 14px;
141 | padding: 5px 0px;
142 | height: 50px;
143 | text-align: center;
144 | background: transparent;
145 | background-color: transparent;
146 | width: 100%;
147 | color: var(--text-color);
148 | transition: background-color .25s ease-in;
149 | }
150 |
151 | .form-control[type="text"]:focus,
152 | .form-control[type="number"]:focus,
153 | .form-control[type="password"]:focus {
154 | outline: none;
155 | background-color: var(--input-hover);
156 | }
157 |
158 |
159 | input::-webkit-outer-spin-button,
160 | input::-webkit-inner-spin-button {
161 | -webkit-appearance: none;
162 | background: var(--select-bg) url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAKUlEQVQYlWNgwAT/sYhhKPiPT+F/LJgEsHv37v+EMGkmkuImoh2NoQAANlcun/q4OoYAAAAASUVORK5CYII=) no-repeat center center;
163 | width: 1.2em;
164 | height: 1.5rem;
165 | opacity: .5;
166 | border-radius: 5px;
167 | transition: opacity .25s ease-in;
168 | }
169 |
170 | input::-webkit-inner-spin-button:hover,
171 | input::-webkit-inner-spin-button:active{
172 | opacity: .8;
173 | }
174 |
175 |
176 | input[type=radio]{
177 | appearance: none;
178 | cursor: pointer;
179 | background-color: var(--input-hover);
180 | margin: 0;
181 | font: inherit;
182 | width: 1.15em;
183 | height: 1.15em;
184 | border: 0.15em solid var(--select-hover);
185 | border-radius: 50%;
186 | translate: -0.1em 0.15em;
187 | transition: all .35s ease;
188 | margin-left: .4vh;
189 | }
190 |
191 | input[type="radio"]:hover {
192 | transform: scale(1.1);
193 | background-color: var(--select-hover);
194 | }
195 |
196 | input[type="radio"]:checked {
197 | transform: scale(1);
198 | background-color: var(--select-bg);
199 | }
200 |
201 |
202 | input[type=checkbox] {
203 | visibility: hidden;
204 | }
205 |
206 | .checkmark {
207 | position: relative;
208 | top: 0;
209 | left: 0;
210 | height: 19px;
211 | width: 19px;
212 | background-color: var(--select-hover);
213 | border-radius: 5px;
214 | transition: all .2s ease-in;
215 | }
216 |
217 | .checklabel {
218 | display: flex;
219 | position: relative;
220 | cursor: pointer;
221 | }
222 |
223 | .checklabel:hover input~.checkmark {
224 | background-color: var(--select-bg);
225 | }
226 |
227 | .checklabel input:checked~.checkmark {
228 | background-color: var(--select-bg);
229 | }
230 |
231 | .checkmark:after {
232 | content: "";
233 | position: relative;
234 | display: block;
235 | opacity: 0;
236 | }
237 |
238 | .checklabel input:checked~.checkmark:after {
239 | opacity: 1;
240 | }
241 |
242 | .checklabel .checkmark:after {
243 | left: 6px;
244 | top: 2px;
245 | width: 4px;
246 | height: 8px;
247 | border: solid white;
248 | border-width: 0 3px 3px 0;
249 | -webkit-transform: rotate(45deg);
250 | -ms-transform: rotate(45deg);
251 | transform: rotate(45deg);
252 | transition: all .25s ease-in;
253 | }
254 |
255 |
256 | .form-input-group {
257 | padding-top: 5px;
258 | padding-bottom: 10px;
259 | padding: 5px;
260 | }
261 |
262 | .input-group {
263 | display: flex;
264 | flex-flow: row wrap;
265 | justify-content: space-evenly;
266 | }
267 |
268 | .input-group-chk {
269 | display: flex;
270 | flex-flow: column wrap;
271 | align-content: center;
272 | justify-content: center;
273 | }
274 |
275 | .input-group label {
276 | color: var(--text-color);
277 | }
278 |
279 | .input-group label:checked {
280 | color: var(--accent-color);
281 | }
282 |
283 | .form-group-title {
284 | font-size: 18px;
285 | font-weight: 400;
286 | width: 100%;
287 | text-align: center;
288 | color: var(--text-color);
289 | }
290 |
291 | .select-title {
292 | margin: 5px 0px;
293 | padding: 5px;
294 | text-align: center;
295 | font-size: 18px;
296 | font-weight: 400;
297 | color: var(--text-color);
298 | }
299 |
300 | .form-select {
301 | cursor: pointer;
302 | width: 100%;
303 | font-size: 14px;
304 | font-weight: 500;
305 | background: transparent;
306 | margin-top: 2.5px;
307 | margin-bottom: 10px;
308 | padding: 5px;
309 | border: none;
310 | outline: none;
311 | height: 50px;
312 | color: var(--text-color);
313 | transition: background-color .25s ease-in;
314 | }
315 |
316 | .form-select:hover {
317 | background-color: var(--input-hover);
318 | }
319 |
320 | .form-select > option {
321 | outline: none;
322 | border: none;
323 | cursor: pointer;
324 | background-color: var(--select-bg);
325 | color: var(--secondary-color);
326 | }
327 |
328 | .form-select > option:focus,
329 | .form-select > option:hover {
330 | background-color: var(--select-hover);
331 | }
332 |
333 |
334 | .form-select:active,
335 | .form-select:focus {
336 | width: 100%;
337 | margin-top: 2.5px;
338 | margin-bottom: 10px;
339 | padding: 5px;
340 | border: none;
341 | }
342 |
343 | .form-select:focus-visible {
344 | outline: none;
345 | }
346 |
347 | .input-group-chk label {
348 | color: var(--text-color);
349 | }
350 |
351 | ::placeholder {
352 | opacity: 65%;
353 | font-size: 14px;
354 | font-weight: 500;
355 | color: var(--text-color);
356 | }
357 |
358 | .btn {
359 | position: relative;
360 | display: flex;
361 | justify-content: center;
362 | align-items: center;
363 | width: 100%;
364 | height: 5vh;
365 | margin-top: .75vh;
366 | cursor: pointer;
367 | font-size: 2.5vh;
368 | background: var(--select-bg);
369 | color: var(--secondary-color);
370 | border: none;
371 | border-radius: 10px;
372 | font-weight: 400;
373 | text-overflow: ellipsis;
374 | white-space: nowrap;
375 | transition: color 0.1s linear, background-color 0.25s ease-in;
376 | }
377 |
378 | .btn:hover {
379 | background-color: var(--select-hover);
380 | }
--------------------------------------------------------------------------------