Many-to-many and One-to-many in Prisma

I am trying to make a database with the structure:

model Game {
  id          Int        @id @default(autoincrement())
  createdAt   DateTime   @default(now())
  lobbyName   String
  authorId    String     @default(cuid())
  author      User       @relation(fields: [authorId], references: [id])
  maxPlayers  Int        @default(20)
  defaultTime Int        @default(1800000)
  players     User[]     @relation(fields: [playerIds], references: [id])
  gameStarted Boolean    @default(false)
  gameEnded   Boolean    @default(false)
}


model Game {
  id          Int        @id @default(autoincrement())
  createdAt   DateTime   @default(now())
  lobbyName   String
  authorId    String     @default(cuid())
  author      User       @relation(fields: [authorId], references: [id])
  maxPlayers  Int        @default(20)
  defaultTime Int        @default(1800000)
  players     User[]     @relation(fields: [playerIds], references: [id])
  gameStarted Boolean    @default(false)
  gameEnded   Boolean    @default(false)
}

Essentially, I am trying to have the host saved as a user. Then also keep track of all the users that are in the game. This will be useful for a leaderboard I am planning to implement.

I keep getting this error:

Error validating model "Game": Ambiguous relation detected. The fields `author` and `players` in mod
el `Game` both refer to `User`. Please provide different relation names for them by adding `@relation(<name
>).

There are a few ways around this. I could make a host model, that simply has the user nested within it, but that seems like a weird solution.

Help would be appreciated.

Saw something similar here, but I could not respond. Data modeling in Prisma with relations

Trouble adding Open Dyslexic to my wordpress theme files

I am attempting to build a wordpress theme. For various reasons I am trying to incorporate accessibility instantly. One of the ways I am doing this is by giving the user option to choose fonts but I am struggling to get Open Dyslexic to even register on my web theme.

I have tried putting the font face directly in the style.css to check that isn’t the problem, even attempted to add !important at the end of any css font-family code.

What am I doing wrong?

**style.css / fonts.css **

@font-face {
    font-family: 'Open Dyslexic';
    src: url('<?php echo get_template_directory_uri(); ?> /fonts/opendyslexic/compiled/OpenDyslexic-Regular.woff2') format('woff2'),
         url('<?php echo get_template_directory_uri(); ?> /fonts/opendyslexic/compiled/OpenDyslexic-Regular.woff') format('woff');
    font-weight: normal;
    font-style: normal;
}

/* Open Dyslexic Bold */
@font-face {
    font-family: 'Open Dyslexic';
    src: url('<?php echo get_template_directory_uri(); ?>/fonts/opendyslexic/compiled/OpenDyslexic-Bold.woff2') format('woff2'),
         url('<?php echo get_template_directory_uri(); ?>/fonts/opendyslexic/compiled/OpenDyslexic-Bold.woff') format('woff');
    font-weight: bold;
    font-style: normal;
}

/* Open Dyslexic Italic */
@font-face {
    font-family: 'Open Dyslexic';
    src: url("<?php echo get_template_directory_uri(); ?>/fonts/opendyslexic/compiled/OpenDyslexic-Italic.woff2") format('woff2'),
         url('<?php echo get_template_directory_uri(); ?>/fonts/opendyslexic/compiled/OpenDyslexic-Italic.woff') format('woff');
    font-weight: normal;
    font-style: italic;
}

/* Open Dyslexic Bold Italic */
@font-face {
    font-family: 'Open Dyslexic';
    src: url('<?php echo get_template_directory_uri(); ?> /fonts/opendyslexic/compiled/OpenDyslexic-BoldItalic.woff2') format('woff2'),
         url('<?php echo get_template_directory_uri(); ?> /fonts/opendyslexic/compiled/OpenDyslexic-BoldItalic.woff') format('woff');
    font-weight: bold;
    font-style: italic;
}

customizer.php

/* Open Dyslexic Regular */
@font-face {
    font-family: 'Open Dyslexic';
    src: url('<?php echo get_template_directory_uri(); ?>/fonts/opendyslexic/compiled/OpenDyslexic-Regular.woff2') format('woff2'),
         url('<?php echo get_template_directory_uri(); ?>/fonts/opendyslexic/compiled/OpenDyslexic-Regular.woff') format('woff');
    font-weight: normal;
    font-style: normal;
}

/* Open Dyslexic Bold */
@font-face {
    font-family: 'Open Dyslexic';
    src: url('<?php echo get_template_directory_uri(); ?>/fonts/opendyslexic/compiled/OpenDyslexic-Bold.woff2') format('woff2'),
         url('<?php echo get_template_directory_uri(); ?>/fonts/opendyslexic/compiled/OpenDyslexic-Bold.woff') format('woff');
    font-weight: bold;
    font-style: normal;
}

/* Open Dyslexic Italic */
@font-face {
    font-family: 'Open Dyslexic';
    src: url('<?php echo get_template_directory_uri(); ?>/fonts/opendyslexic/compiled/OpenDyslexic-Italic.woff2') format('woff2'),
         url('<?php echo get_template_directory_uri(); ?>/fonts/opendyslexic/compiled/OpenDyslexic-Italic.woff') format('woff');
    font-weight: normal;
    font-style: italic;
}

/* Open Dyslexic Bold Italic */
@font-face {
    font-family: 'Open Dyslexic';
    src: url('<?php echo get_template_directory_uri(); ?>/fonts/opendyslexic/compiled/OpenDyslexic-BoldItalic.woff2') format('woff2'),
         url('<?php echo get_template_directory_uri(); ?>/fonts/opendyslexic/compiled/OpenDyslexic-BoldItalic.woff') format('woff');
    font-weight: bold;
    font-style: italic;
}

functions.php

<?php
// Theme setup
function themename_theme_setup() {
    // Support for post thumbnails (featured image)
    add_theme_support('post-thumbnails');
    
    // Support for custom logo
    add_theme_support('custom-logo');
    
    // Register Navigation Menus
    register_nav_menus(array(
        'main' => __('Main Menu', 'themename'),
        'social' => __('Social Menu', 'themename')
    ));
    
    // Add customizer options
    require get_template_directory() . '/customizer.php';
}
add_action('after_setup_theme', 'themename_theme_setup');

// Enqueue Styles and Scripts
function themename_enqueue_scripts() {
    // Enqueue the main theme stylesheet (style.css)
    wp_enqueue_style('themename-style', get_stylesheet_uri());

    // Enqueue Nightmode Script
    wp_enqueue_script('nightmode', get_template_directory_uri() . '/js/nightmode.js', array(), null, true);

    
    // Enqueue Google Fonts
    wp_enqueue_style('google-fonts', 'https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&family=Charm&family=Merryweather&family=Courier+New&family=Times+New+Roman&display=swap', false);

    // Enqueue Open Dyslexic font from Font Library (via CDN)
     wp_enqueue_style('open-dyslexic', get_template_directory_uri() . '/css/fonts.css', null);
}
add_action('wp_enqueue_scripts', 'themename_enqueue_scripts');

// Register Sidebar
function themename_register_sidebar() {
    register_sidebar(array(
        'name'          => 'Main Sidebar',
        'id'            => 'main-sidebar',
        'before_widget' => '<section id="%1$s" class="widget %2$s">',
        'after_widget'  => '</section>',
        'before_title'  => '<h2 class="widget-title">',
        'after_title'   => '</h2>',
    ));
}
add_action('widgets_init', 'themename_register_sidebar');

// Function to dynamically add CSS based on customizer settings
function themename_dynamic_styles() {
    ?>
    <style type="text/css">
        /* Body Background Color */
        body {
            background-color: <?php echo esc_attr(get_theme_mod('body_background_color', '#ffffff')); ?>;
            color: <?php echo esc_attr(get_theme_mod('font_color', '#333333')); ?>;
            font-family: <?php echo esc_attr(get_theme_mod('paragraph_font', 'Arial')); ?>, sans-serif;
        }

        /* Header Background Color */
        header {
            background-color: <?php echo esc_attr(get_theme_mod('header_background_color', '#f4a261')); ?>;
            color: <?php echo esc_attr(get_theme_mod('font_color', '#333333')); ?>;
        }

        /* Footer Background Color */
        footer {
            background-color: <?php echo esc_attr(get_theme_mod('footer_background_color', '#f8f8f8')); ?>;
            color: <?php echo esc_attr(get_theme_mod('font_color', '#333333')); ?>;
        }

        /* Sidebar Background Color */
        #sidebar {
            background-color: <?php echo esc_attr(get_theme_mod('sidebar_background_color', '#f1f1f1')); ?>;
        }

        /* Links Background Color */
        a {
            background-color: <?php echo esc_attr(get_theme_mod('links_background_color', '#0073e6')); ?>;
        }

        /* Night Mode Styles */
        <?php if (get_theme_mod('night_mode_toggle', 'off') == 'on') : ?>
            body.nightmode {
                background-color: #000080 !important;
                color: #f0f0f0 !important;
            }
            body.nightmode header,
            body.nightmode footer {
                background-color: #000000 !important;
                color: #f0f0f0 !important;
            }
            body.nightmode #sidebar {
                background-color: #6a0dad !important;
            }
        <?php endif; ?>

        /* Typography */
        body {
            font-family: <?php echo esc_attr(get_theme_mod('paragraph_font', 'Arial')); ?>, sans-serif;
        }
        h1, h2, h3, h4, h5, h6 {
            font-family: <?php echo esc_attr(get_theme_mod('heading_font', 'Poppins')); ?>, sans-serif;
        }
    </style>
    <?php
}
add_action('wp_head', 'themename_dynamic_styles');

I was expecting the theme to display open dyslexic font when font-family: "Open Dyslexic" !important is used. Tried to see if it was an enqueueing error by placing it in the style.css which works. double checked the pathway.

How to disable Waypoints when horizontal scrolling?

I’m using waypoints.js with the Sticky shortcut: http://imakewebthings.com/waypoints/shortcuts/sticky-elements/

It’s working great when I scroll vertically, but if I also scroll horizontally, then my elements stay stuck in their fixed position instead of scrolling horizontally.

Here’s what I have:

.board-header.stuck {
   position: fixed;
   z-index: 100;
   top: 32px;
}


var sticky = new Waypoint.Sticky({
   element: $('.board-header'),
   offset: 32
});

Before Horiz. scroll

enter image description here

After Horiz. scroll

enter image description here

How can I disable Waypoints when horizontal scrolling, or use fixed positioning for vertical scroll & relative when horizontal scroll?

Reset the scroll position to its last state when navigating back to it

I have a React Native App that shows cars ( a bit like AutoTrader). Each car is represented like this:
enter image description here

A simple square box that has details about a car. There are multiple of these on the screen and if you scroll down you can keep on browsing more and more cars.

If you click on a car you will be taken to another screen where you can see more details about the car.

Now the problem…

Once you have finished looking at that car, you will go back to browse more cars. The annoying thing that happens now is that I am taken straight back to the top of the page. This is not a good user experience and I want to be able to keep that inital state so that I can use it when I come back to view all the cars.

The state that I keep is the Offset of the last position on the screen before the user clicks on a specific car. I used this event from the FlashList:

          onMomentumScrollEnd={(event) => {
            handleSetYOffset(event);
          }}

  const [yOffset, setYOffset] = useAtom(yOffestAtom);

  const handleSetYOffset = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
    setYOffset(Math.floor(e.nativeEvent.contentOffset.y));
  };

I am using Jatoi as my state persistant libary. I am able to now store the offset of the last position.

Next I can do one of two things.
One:
Use a useEffect like such:

  useEffect(() => {
    if (hasUserClickedOnAListing === 0) {
      return;
    }
    // User has come after going to another page
    if (scrollViewRef.current) {
      // Perform the scroll action with the current yOffset
      scrollViewRef.current.scrollToOffset({
        offset: yOffset,
        animated: true
      });

      // Reset the flag after the scroll action
      setHasUserClickedOnAListing(0);
    }
  }, [hasUserClickedOnAListingAtom, yOffestAtom]);

I only set the offset if the user has visited the next page and hence I have the “setHasUserClickedOnAListing” set function which will tell me if the user has gone there. I set it to 2 (I set it to this number just for testing purposes so I know the user has visited the next page) if it has visited then next page. That way if I return to the previous page I can check to see if the page after it was visited. Then I can set the scroll position straight away i.e when the component re-mounts. The reason I implemented this design pattern was because I was getting constant re-renders of my useEffect as I had passed the yOffset as on of its dependencies (as you can see in the useEffect). Therefore, whenever I would scroll it would automatically take me back up to the previous yOffset value. Perhaps this design wasn’t the best with using the number 2 and other things perhaps you folks have seen but I just to test out this idea I had

2nd way:
Use the onLoad event on the FlashList. This is what I did:

          onLoad={(e) => {
            if (hasUserClickedOnAListing === 0) {
              return;
            }
            if (scrollViewRef.current) {
              scrollViewRef.current.scrollToOffset({
                offset: yOffset,
                animated: true
              });
              setHasUserClickedOnAListing(0);
            }
          }}

This is quite self explanatory…

The issue that I get, which is very quite an annoying issue, is that sometimes the offset will be very accurate but then other times it will be completely off! That is the annoying part as I can’t put my finger on one particular issue. I tried to use multiple methods such as setTimeout but I can’t get a consistent result which is good.

I did notice one thing which is that the inaccurate offset happens when I scroll down. I don’t know if that is the cause for it and if it is how to fix it.

P.S. I use a react memo function component.

I would appreciate any help!

fillTable function not always working correctly – how to make it more reliable?

I’m using a JavaScript function to fill an HTML table based on data fetched from a given URL (in JSON format). It works sometimes, but other times the table stays empty or the data doesn’t display as expected.

Here is the function:

function fillTable(tablehead, tablebody, url) {
    return new Promise((resolve, reject) => {
        $(`#${tablehead}`).html('');
        $(`#${tablebody}`).html('');
        xhr = new XMLHttpRequest();
        xhr.open('GET', url, true);
        xhr.send();
        xhr.onreadystatechange = function() {
            var tabla = JSON.parse(xhr.responseText);
            if (xhr.readyState == 4 && xhr.status == 200) {
                if (url.search("/mozi") != -1) {
                    xhr = new XMLHttpRequest();
                    xhr.open('GET', '/get_moziid_count', true);
                    xhr.send();
                    xhr.onreadystatechange = function() {
                        if (xhr.readyState == 4 && xhr.status == 200) {
                            var moziidcount = JSON.parse(xhr.responseText);
                            var fejlec = '<tr>';
                            for (var key in tabla[0]) {
                                fejlec += `<th>` + key + '</th>';
                            }
                            fejlec += '</tr>';
                            var sorok = '';
                            for (var i = 0; i < tabla.length; i++) {
                                let szam = moziidcount.filter(m => m.moziid == tabla[i].id);
                                sorok += `<tr title="Number of screenings: ${szam.length > 0 ? szam[0].count : 0}">`
                                for (var k in tabla[i]) {
                                    sorok += '<td>' + tabla[i][k] + '</td>';
                                }
                                sorok += '</tr>';
                            }
                            $(`#${tablehead}`).html(fejlec);
                            $(`#${tablebody}`).html(sorok);
                            resolve();
                        }
                    }
                } else {
                    var fejlec = '<tr>';
                    for (var key in tabla[0]) {
                        fejlec += `<th>` + key + '</th>';
                    }
                    fejlec += '</tr>';
                    var sorok = '';
                    for (var i = 0; i < tabla.length; i++) {
                        sorok += `<tr>`;
                        for (var k in tabla[i]) {
                            sorok += '<td>' + tabla[i][k] + '</td>';
                        }
                        sorok += '</tr>';
                    }
                    $(`#${tablehead}`).html(fejlec);
                    $(`#${tablebody}`).html(sorok);
                    resolve();
                }
            }
        };
    });
}

Problems I’m facing:

Sometimes the table remains empty.

The line tabla = JSON.parse(xhr.responseText); is called before readyState === 4, which throws an error if the response hasn’t arrived yet.

The second inner xhr.onreadystatechange may be overwriting the first one.

I’m not sure if nesting multiple XMLHttpRequests like this is causing race conditions or unreliable behavior.

What I’m looking for:

How can I make this function more reliable?

Is there a better, more modern way to handle this (like using fetch with async/await)?

What’s the recommended way to manage nested asynchronous requests like this?

Any help or improvements would be much appreciated. Thanks in advance!

How to exclude items when analyzing memory leak in Chrome’s Memory panel?

I suspect there’s a memory leak on my web page.

Following online tutorials, I took two memory snapshots in Incognito Mode at different times. Here are the results:

screenshot of memory snapshot

It shows that memory increased from 84.9MB to 133MB, mainly due to (Compiled Code), (CSSAnimation), and (KeyframeEffect). I have three questions:

  1. Why doesn’t the sum of ‘Size Delta’ on the right equal 133MB – 84.9MB = 48.1MB?

  2. (CSSAnimation) and (KeyframeEffect) are retained because of InspectorOverlayHost. After researching, it seems InspectorOverlayHost is related to DevTools and not the real cause of my page’s memory leak. How can I exclude this interference to find the root cause?

enter image description here

  1. What is (Compiled Code), and why does it keep growing?

I’m still confused about using DevTools to analyze memory leaks. Any help would be greatly appreciated.

requests_html html.render() works on Ubuntu laptop but not on headless Raspberry Pi

I’ve written a program that uses requests_html to fetch, render Javascript, and then pick specific bits (using CSS selectors) out of certain web pages. It works on my Ubuntu laptop but not on the headless Raspberry Pi (where I want to run it as a cron job). I’ve done some tests in REPL and found this discrepancy:

laptop in idle3, python 3.11.0:

s = requests_html.HTMLSession()
r = s.get(url)
h = r.html
len(h.html)
342318
h.render()
len(h.html)
461598

That’s what I expected — the javascript adds the content that I want to the page.

Pi (over ssh in python 3.11.2)

>>> s = requests_html.HTMLSession()
>>> r = s.get(url)
>>> h = r.html
>>> len(h.html)
341539
>>> h.render()
>>> len(h.html)
339279

That’s obviously not right!

I would be grateful for any ideas on how to fix this.

Resolve a range specification with worksheet name in Excel JS API?

Given these legal Excel range specifications as strings:

  1. SheetName!A1
  2. 'Sheet Name'!A1
  3. 'Sheet!Name'!A1
  4. 'Sheet''Name'!A1
  5. '''Sheet Name'''!A1
  6. 'Sheet''!Name'!A1

is there a way to get a Range object using the Excel JavaScript API without manually parsing the string?


The documentation page Get a range using the Excel JavaScript API only shows examples using Excel.Worksheet.getRange(), requiring one to get the worksheet (by name) first.

The API reference for Excel.Range does not link to methods that return it, nor show a constructor that would allow building it from the address. In fact the main example on that page shows using the sheet name as a string and the range name to first get the worksheet and then get the range from that.

I was hoping there was a getRange() method on the Workbook class, but there isn’t.

Manually parsing an address to look for a sheet name is messy. I’m not even sure if this covers every edge case:

function sheetNameFromAddress(addr) {
  const match = addr.match(/^(?:'((?:[^']|'')+)'|([^'![]*/\?:]+))!/);
  if (!match) return;
  const quoted = match[1];
  const unquoted = match[2];
  return quoted ? quoted.replace(/''/g, "'") : unquoted;
}

how can I stop quill from replacing the html element that i create with it’s own svg element?

Quill replaces the img element in the button with it’s own svg.

<button data-tippy-content="Add Image" class="neeche-wale-buttons ql-image" id="add-img-btn"><img
                    src="images/add-image.png" alt=""></button>

I tried some solutions but they didn’t work.
sorry but below text is just to increase character count.
countcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcountcount

Click event of checkbox fired twice

There are a few labels, every label contents checkbox and image. Labels are linked to checkboxes like this:

<label for="check1">
    <input type="checkbox" id="check1" class="some_checkboxes">
    <img>image</img>
</label>
<label for="check2">
    <input type="checkbox" id="check2" class="some_checkboxes">
    <img>image</img>
</label>
<label for="check3">
    <input type="checkbox" id="check3" class="some_checkboxes">
    <img>image</img>
</label>

Each label has its own Listener assigned to it, whose task is to create a button if the checkbox is checked and to remove the button if the checkbox is not checked.

Each created button is also assigned its own Listener, which, when clicked, should remove the mark from its checkbox. Unfortunately, here the program does not behave as expected.

The click event on the checkbox is called twice, so it always remains enabled. Moreover, nodeName, target and currentTarget in both triggers show INPUT. stopPropagation() does not help.

Undesirable behavior is observed only in Chromium-based browsers and is not observed in FireFox.

chbx = document.querySelectorAll('.some_checkboxes');

for (let i = 0; i < chbx.length; ++i) {
    chbx[i].addEventListener("click", genB);
}

function genB(event) {
    alert(event.target.id + " " + event.target.checked);
    if (event.target.checked) {
        let bt_r = createButton('buttonr');
        event.target.parentNode.insertBefore(bt_r, event.target.nextSibling);
        bt_r.style.cssText  = "top: 50vh; left: 50vw";
        addBL(bt_r, event);
    } else {
        event.target.nextSibling.remove();
    }
}
function addBL(button, event){
    let event_checkbox = event.target.id;
    button.onclick = function() {
        document.getElementById(event_checkbox).click();
    }
}
function createButton(buttonClass){
    let button = document.createElement('button');
    button.setAttribute('type', 'button');
    button.classList.add(buttonClass, 'btn');
    return button;
}

First click (on image in label) create button and this is ok, popup messange says “check1 true” and this is ok. After pressing button there is two popup messenge: first is “check1 false” and second is “check1 true”.

Need help in toggeling animation with CSS Web Animations API

I am trying to toggle an animation on an element using the CSS Web Animations API (WAAPI). Specifically, I want the animation to transition smoothly between two states on each button click — essentially playing forward on the first click, then reversing on the second, and so on.

I’ve set up my keyframes and options correctly, and the animation runs fine the first time, but from the second toggle onward, the animation becomes jittery and visually “janky”.

!Important!
I also want the box to get the end of animation styles.

I want the animation to respond correctly even when the user clicks the button rapidly, ensuring that it reverses immediately from its current state without any delay or visual glitches.

Here is a link to code pen where I was replicated the issue:
https://codepen.io/mab141211/pen/VYYoOjw

const keyframes = [
  { border: '2px solid red', width: '200px', backgroundColor: 'blue', offset: 0, },
  { border: '6px solid green', width: '250px', backgroundColor: 'purple', offset: 1, },
];

// Options
const options = {
  duration: 200,
  easing: 'ease-in',
  fill: 'both',
};

let isPlayingForward = true;

const animation = box.animate(keyframes, options);
animation.pause();

button.addEventListener('click', () => {
  if (isPlayingForward) {
    animation.play();
  } else {
    animation.reverse();
  }
  
  isPlayingForward = !isPlayingForward;
});```

jQuery Validation not working with custom validation attributes since upgrade to .NET Core

Recently upgraded to .NET Core, and at the start the validation attributes were not rendering the required data-attributes which we have since resolved. The markup is now correct. The problem lies with getting jQuery Validation (via jQuery Validation Unobtrusive) to recognise the custom validation.

This is the input markup for reference:

<input class="control--input valid" data-val="true" data-val-acceptedtermsandconditions="Please read and accept our terms and conditions." data-val-required="HasAcceptedTermsAndConditions-Required" id="BankDetails_HasAcceptedTermsAndConditions" name="BankDetails.HasAcceptedTermsAndConditions" type="checkbox" value="true" autocomplete="off" aria-describedby="BankDetails.HasAcceptedTermsAndConditions-error">

1. This is called globally when the DOM is loaded:

$.validator.setDefaults({
    ignore: ':hidden:not(.do-not-ignore)',
    onsubmit: false,
    // any other default options and/or rules
});

2. This is then called on a specific page load. I know you may wonder why not a simple [Required] for a checkbox, it’s because @Html.CheckBoxFor() renders 2 checkboxes. One for the true value, one for the false value (which is hidden), either way, [Required] will always be successfully validated as true because one of both values will be submitted. We need to explicitly check for true:

$.validator.addMethod(`acceptedtermsandconditions`, (value, element) => {
        if ((element as HTMLInputElement).checked) {
            return true;
        }

        return false;
    });
    $.validator.unobtrusive.adapters.add(`acceptedtermsandconditions`, function setValidation(options: any) {
        options.rules.acceptedtermsandconditions = true;
        options.messages.acceptedtermsandconditions = options.message;
    });

3. This is called when the form is revealed $.validator.unobtrusive.parse(formElement);

4. This is called on form submission if ($(formElement).valid())

All the standard default validation methods like [Required], or [RegEx] work. The custom ones don’t even fire.

I’m at a loss as I believe I’m following the correct order.

Alur pembuatan sistem aplikasi web [closed]

Saat membuat sistem aplikasi web kira kira alur tahapan nya apa aja ya seperti pembuatan flowchart, use case diagram dll. Kira kira apa aja ya alurnya supaya saya lebih mudah dalam membuat sebuah aplikasi yang kompleks, karena akhir-akhir ini saya membuat aplikasi tanpa membuat rancangan seperti activity, use case dll, saya ngerasa bikin lama dalam pembuatan aplikasinya

Saya dapat mengetahui hal hal yang saya tanyakan