2

I'm making a fake horoscope website as a little project and am having some trouble with this last functionality. Currently, the user puts in their date and birthplace and some other info, then hitting the submit button calls a function which parses the date info and makes an alert pop up with a different paragraph depending on which astrological sign they are. This works fine, but isn't pretty.

Instead, I'd rather the submit button causes a modal to pop up and that same paragraph appears there (again, depending on what they'd changed the date input to).

I'm very new to HTML and JavaScript, so all of the "pass data into a modal" questions I've read have answers that just go over my head or don't seem to apply, as far as I can tell. Here's the HTML I have currently. I've cut out some of the extraneous inputs that don't actually do anything other than not allow submission until they're filled out and the paragraphs which are just long strings:

<body>
    <header>
    </header>
    <main>
        <div id="zodiacModal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 id="zodiacModalTitle" class="modal-title">Modal title</h5>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">&times;</span>
                        </button>
                    </div>
                    <div class="modal-body">
                        <p>Where I need the paragraph</p>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                    </div>
                </div>
            </div>
        </div>
        <form class="needs-validation" onsubmit="test(); return false;" novalidate>
            <div class="form-row">
                <div class="col-sm mb-3">
                    <label for="birthdate">Birthdate</label>
                    <input id="birthdate" class="form-control" type="date" value="2000-01-01" required>
                </div>
            </div>
            <div class="form-group">
                <div class="form-check">
                    <input id="terms" class="form-check-input" type="checkbox" value="" required>
                    <label class="form-check-label" for="terms">
                        I believe.
                    </label>
                    <div class="invalid-feedback">
                        You must believe before submitting.
                    </div>
                </div>
            </div>
            <button class="btn btn-primary" type="submit">Submit Form</button>
        </form>
    </main>
    <script>
        function test()
        {
            // Declare and initialize variables with strings for each sign here

            var date = document.querySelector("#birthdate").value.slice(5).split("-");
            var month = parseInt(date[0], 10), day = parseInt(date[1], 10);
            var signs = ["", capricorn, aquarius, pisces, aries, taurus, gemini, cancer, leo, virgo, libra, scorpio, saggitarius, capricorn];
            var days = [0, 20, 19, 20, 20, 21, 21, 22, 22, 23, 23, 22, 21];
            alert((day > days[month]) ? signs[month + 1] : signs[month]);
        }
    </script>

From the documentation, it looks like I need to change the submit button to something like this:

<button type="submit" class="btn btn-primary" data-toggle="modal" data-target="#zodiacModal">

TL;DR: I want to replace the alert that pops up on submitting the form (which has a different paragraph in the body depending on date input) with a modal that does the same thing. Any noob-friendly explanations of what I need to do here would be really appreciated.

dylosaur
  • 149
  • 2
  • 14
  • So that's means that you want to pass data through the body and modal? – Ahmed Ali Nov 06 '19 at 19:43
  • Sorry, I don't fully understand. I want to pass the paragraph that currently pops up as an alert (from the function `test()`) into the body of the modal and then have the modal pop up instead of the alert. This should happen when the user presses submit but ideally only after they've entered all the inputs, hence the `needs-validation`. It works currently as an alert, it just doesn't look very pretty. – dylosaur Nov 06 '19 at 19:51
  • so you want to alery when the user clicks on modal button – Ahmed Ali Nov 06 '19 at 19:52
  • 1
    No, I want to replace the alert with a modal that pops up instead. – dylosaur Nov 06 '19 at 19:59
  • Have you taken a look at simple angular modals? You can try using Angular Material. Check here for reference: https://material.angular.io/components/dialog/overview – Alvaro Carvalho Nov 06 '19 at 20:12
  • @AlvaroCarvalho I haven't, but I'm having trouble following the docs. Does this go into the HTML or JS? – dylosaur Nov 06 '19 at 20:23
  • @dylosaur done it ! check it simple way to do it, – Ahmed Ali Nov 06 '19 at 20:26
  • @dylosaur You'd have to install angular material using NPM or some other packet manager. Glad your problem was solved, though! – Alvaro Carvalho Nov 07 '19 at 14:27

2 Answers2

1

You can't pass data into HTML as you describe. What you can do is set the content of the <p> using Javascript. So in test() you could do something like this:

const text = day > days[month] ? signs[month + 1] : signs[month]

document.getElementById('modal-body').innerHTML = text

PS To use getElementById, add an id to the element in question. Otherwise you can use getQuerySelector if you want to stick to using a class. But generally it is better practice to use ids for getting elements by Javascript, since you might change the class to suit your CSS at a later time, and you don't want that to affect the script.

  • 1
    This seemed exactly like what I wanted to do, but unfortunately it's not working. I'm not sure why, but now hitting submit actually refreshes the page instead of bringing up the modal. I thought adding `return false` to the `onsubmit` would prevent that, but I must be missing something. – dylosaur Nov 06 '19 at 20:48
  • That's because the script doesn't call the modal, it's only changing the innerHTML of the `modal-body` element. The question was just about passing in data, so I only provided an answer for that. The answer you accepted uses jQuery to accomplish that; you could do a vanilla JS solution for that as well and not have to import jQuery. But that's for another question ;) – Jackson Holiday Wheeler Nov 06 '19 at 21:54
  • And to stop the page from refreshing, you need to do `e.preventDefault()`. Learn more here: https://stackoverflow.com/questions/19454310/stop-form-refreshing-page-on-submit – Jackson Holiday Wheeler Nov 06 '19 at 21:56
  • 1
    Thanks for the info. Yours was a lot simpler so I like that, so I'm going to try to get it to work. – dylosaur Nov 06 '19 at 23:50
  • Glad to hear it! If you want to use vanilla JS for opening the modal, use an event listener on the modal div. Hopefully that should be enough to go on, there is a lot of info on the web about event listeners ;) – Jackson Holiday Wheeler Nov 12 '19 at 08:52
1

As there is no method to pass variable via modal then , do like this as below,

$(".btn").click(function() {
  $(".modal-body p").text("inserted value");
  $("#myModal").modal();
  
});
<!DOCTYPE html>
<html lang="en">
<head>
  <title>Bootstrap Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
</head>
<body>

<div class="container">
  <h2>Modal Example</h2>
  <!-- Trigger the modal with a button -->
  <button type="button" class="btn btn-info btn-lg">Open Modal</button>

  <!-- Modal -->
  <div class="modal fade" id="myModal" role="dialog">
    <div class="modal-dialog">
    
      <!-- Modal content-->
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal">&times;</button>
          <h4 class="modal-title">Modal Header</h4>
        </div>
        <div class="modal-body">
          <p></p>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        </div>
      </div>
      
    </div>
  </div>
  
</div>

</body>
</html>
Ahmed Ali
  • 1,908
  • 14
  • 28
  • Would that go onto the end of `test()` or is that a totally separate script? How could I replace `"inserted value"` with the appropriate paragraph that `test()` chooses? – dylosaur Nov 06 '19 at 20:51
  • This actually worked! I missed that you'd added some scripts to the head. Why do those need to exist in the head and not before the closing body tag? – dylosaur Nov 06 '19 at 21:22
  • Changed the line in your script to `$(".modal-body p").text(test());` and it added in the appropriate paragraph depending on the date. Only one thing now: the form no longer shows the invalid feedback messages. Any idea why that is? – dylosaur Nov 06 '19 at 21:23