D3 select: submit form dynamically? - javascript

I'm using D3. I have click-handling code for an input to stop form submission and do some validation. Then if validation succeeds, I want to submit the form.
How do I submit the form programmatically, using D3 selectors? form.submit() says the submit method does not exist. (I'm confident that form is the form element.)
I'm also trying form.dispatch('submit') but that does not work either:
import { select as $, event as d3_event } from "d3";
$(el).on("click", function() {
// prevent form submission
d3_event.stopPropagation();
d3_event.preventDefault();
// later, submit form?
var form = $(this.parentNode);
form.dispatch('submit');
}
My HTML:
<form method="post" action="myaction">
<button class="create-new btn popup"><i class="fa fa-external-link"></i> Submit</button>
</form>

I don't see a submit event in the predefined list of events for a d3 node. Here's an approach that fires the submit event by selecting the DOM node using node() function. (Btw I'm not using imports here)
d3.select('#submit').on('click', function() {
// prevent form submission
d3.event.stopPropagation();
d3.event.preventDefault();
// later, submit form?
var form = d3.select(this.parentNode).node();
form.submit();
})
<script src="https://d3js.org/d3.v4.js"></script>
<form id="myform" action="submit-form.php">
Search: <input type='text' name='query'>
Submit
</form>
Another approach I can think of as of now is define a custom event listener for submit and dispatch it which would still look for the DOM node in the listener function. (i.e. basically calling <form>'s built-in submit() function.

Related

Submit form with jquery which has multiple submit buttons without click trigger?

Imagine this :
<form id="form">
<input type="text">
<button type="submit" name="submit1" value="1">something1</button>
<button type="submit" name="submit2" value="2">something2</button>
<button type="submit" name="submit3" value="3">something3</button>
</form>
First of all when I write $('#form').submit() which submit value will be sent? the first one?
Second of all How can I submit the form without the click trigger event with the value I want? Is it possible at all? For example submitting the form with the 2 submit value.
The reason I want do this is to have confirmation popup with sweetalert before sending my form so here it is :
$('form').on('submit',function(e){
form = $(this);
e.preventDefault();
swal({'some dialog'},function(isConfirm)
{
if(isConfirm)
form.submit;
\\If I use the click trigger I will get stuck in here again.
})
});
There is an alternative - use the FormData You can create an instance of a FormData, add your html form, modify entries, and send it. Everything is under your control here then.
EDIT: Based on your edit, it seems you have the problem of resubmitting the form. You can handle it like this.
var form = document.querySelector('form');
form.addEventListener('submit', {
confirmed: false,
handleEvent: function (event) {
if (this.confirmed)
return;
event.preventDefault();
doconfirm((confirmed) => {
if (confirmed) {
this.confirmed = true;
form.submit();
}
})
}
}, false);
Or you can solve your problem by unbinding the submit handlers after validation and submit it again: $('form').off('submit').submit()
As #Scott Marcus explained, the value of named buttons will be submitted when the form is sent to the server. However in your case, this won't help because you want to perform some logic before submitting it to the server.
The issue is that jQuery has no way to determine which button was clicked because it doesn't provide the submit button values when you look at the form data via $.serialize(), and there is no easy cross-browser friendly way to check the button that triggered the $.submit() event without using click.
So, the only workaround would be to handle the click event of the 3 buttons and store some value that is checked before you submit the form as described in this answer: How can I get the button that caused the submit from the form submit event?
Example: http://codeply.com/go/Wj85swRyfX
Let's take your questions one at a time...
First of all when I write $('#form').submit() which submit value will
be sent? the first one?
When a form is submitted, ALL form elements that nave a NAME attribute will submit their value (even if the value is an empty string) to the form's ACTION destination. So, in your case, all 3 of your buttons have a name attribute and so all 3 buttons will submit their name/value pairs.
Usually, we don't put a name attribute on the submit button because we only want it to trigger the submit, not actually use it as a data container. And, we usually include only a single submit button under most circumstances.
Second of all How can I submit the form without the click trigger
event with the value I want? Is it possible at all? For example
submitting the form with the 2 submit value
You would use:
$('#form').submit()
to manually cause the submit, but you'd need to have an if() statement that has logic that determines which value is appropriate to submit. Instead of the value being stored in a button, you could use a hidden form field, like this:
<form id="form">
<input type="text">
<input type="hidden" name="hidden" value="">
<button type="submit">something3</button>
</form>
JavaScript:
$("#form").on("submit", function(evt){
// Stop the form submission process
evt.preventDefault();
// Logic that sets hidden input field to correct value:
if(condition1){
$("input[type=hidden]").attr("value", "1");
} else if(condition2) {
$("input[type=hidden]").attr("value","2");
} else {
$("input[type=hidden]").attr("value","3");
}
// Manually submit the form
$("#form").submit();
});
I suggest to use hidden input tag to make the logic clear.

jQuery one function not working as expected

I have the following jsp:
...
<script type="text/javascript">
$(function() {
// prevent multiple submissions
$('#saveCallListBtn').one("click", function() {
$('#callListForm').submit();
});
});
...
</script>
...
<form:form id="callListForm" commandName="callList" action="${contextPath}/calllist/save" method="POST" htmlEscape="true">
...
<td colspan="2" style="text-align: center">
<input id="saveCallListBtn" type="submit" value="Save" class="button-med"/>
</td>
...
</form:form>
The behavior I am looking for is to only all the form to be submitted once no matter how many times the save button is clicked. Using the jQuery .one function, I can get the above code to correctly work. As the form will submit multiple times if I click more than once.
The following code will work fine:
$('#saveCallListBtn').on("click", function() {
$(this).prop("disabled", true);
$('#callListForm').submit();
});
But I am interested to know what I am doing wrong with the .one function.
Note the type here:
<input id="saveCallListBtn" type="submit" value="Save" class="button-med"/>
A submit button in a form will submit the form, no JavaScript required. So when your handler is automatically removed, on the next click the default handling (submitting the form) occurs, courtesy of the browser.
The only reason you're not seeing the form submitted twice on first click, I suspect, is that the act of submitting the form begins the process of tearing down the page to make room for the result of the submission.
FWIW, I would suggest that you not have a click handler on the button, but rather a submit handler on the form that, if all is well and it's going to allow submission to occur, disables the button and sets a flag to prevent future form submission, since forms can be submitted in multiple ways. (On some forms, pressing Enter in a text field will do it, for instance.)
E.g.:
$("#callListForm").on("submit", function(e) {
var $btn = $("#saveCallListBtn");
var valid = !$btn.prop("disabled");
if (valid) {
// ...do any other validity checks you may want, set `valid` to false
// if problems encountered...
}
if (valid) {
$btn.prop("disabled", true);
} else {
e.preventDefault();
}
});
The jQuery one function will execute the event handler only once. However, the default behaviour of the element clicked will execute indefinitely.
Change the type of the button to button, such that it has no default behaviour:
<input id="saveCallListBtn" type="button" value="Save" class="button-med"/>

Calling javascript from appended elements

Just want to get a concept clear here.
suppose i have this html page:
<script>
function_1()
{
... posts a form via ajax
};
</script>
<body>
<div class='car'>
</div>
</body>
On an event I prepend() this form (which I get via ajax) to the above <div class='car'>
<form method='post'>
...
<button type='submit' value='post' />
</form>
The idea is to submit this form via ajax by calling the function_1 function on pressing the submit button.
Does this work? Because when I submit the form it is not calling the function_1, its just posting it via regular Http post.
When we append() or prepend() elements to DOM, do they have access to javascript right away?
Thank you
You are appending those form elements during run time, so you have to register events for it by using event-delegation. And by the way it is a submit button, so whenever you are clicking on it, it will simply invoke its default action, that is submitting the form. So you should use e.preventDefault() to prevent its default behaviour or you should need to change the type of that button from submit to button
Try,
<script>
$(document).ready(function(){
function function_1()
{
... posts a form via ajax
};
$(document).on("click", "input[type='submit']", function(e) {
e.preventDefault();
function_1()
});
});
</script>
You need to use a delegated event handler, for example:
$(document).on("submit", "#your-form-id", function(e) {
e.preventDefault();
// AJAX code
});
Then, the handler will be called on submit regardless of when the form is appended, as long as the form exists.

Where to add onsubmit to a form in Javascript

In my HTML I've got a form without an onsubmit event listener:
<form action="contact.php" method="post" id="contact">
...
<input type="submit" value="Send" />
</form>
As a result, the form is always posted whenever I click the "Send" button. However, I'd like to validate the input first, so I'd like to attach an event listener and intercept the post. This is how I attach the event listener to the form:
window.onload = function() {
function validate() {
return window.confirm("Confirm");
}
var form = document.getElementById("contact");
form.addEventListener("submit", validate);
}
While the event listener is being executed, if I go by above approach the form is always posted! However, if I make the validate() function global and use onsubmit="return validate();" in the <form> tag, then the form is only being submitted conditionally, as expected.
Why does this not work by adding the validate() function as above? It seems the false return value gets lost?
Modern event handling has a more complex API, it gives more flexibility but that comes at the cost of not being able to tie behaviour to a simple boolean result.
For your use case, you need to capture the event object:
function validate(ev) {
Then you can prevent the default action on it:
if (!confirm('Confirm')) {
ev.preventDefault();
}

Use submit event listener when form is submitted via inline JavaScript?

We have a script that tracks form submits by adding an event listener to the form. The problem is that one customer submits the form via a link using
Submit
which ignores the event listener. Here's a JSFiddle to demonstrate: http://jsfiddle.net/XhLkG/
As you can see the Submit button triggers the alert while the Submit link simply just submits the form and bypasses the event listener.
Is there a way to still trigger the event listener?
EDIT: We cannot change the markup since it's on our customer's homepage where they have embedded our script. Sorry if I didn't make it clear.
You can use this:
var form = document.getElementsByClassName('form');
form[0].addEventListener("submit", function(e) {
e.preventDefault();
alert('event');
});
form[0].childNodes[3].addEventListener("click", function(e) {
e.preventDefault();
alert('event');
});
instead of using the href try this
<form method="post" name="formname" class="form">
<input type="text" name="hello">
<a onclick="javascript:document.formname.submit();">Submit</a>
<input type="submit">
</form>
remove the href and replace it with onclick
try the following with jquery:
$("form").submit(function (e) {
e.preventDefault();
alert('event');
});
Reference here.

Categories