Change attribute value for event only - javascript

I have this basic form:
jQuery(document).ready(function($) {
$('#btn').click(function() {
var form = document.getElementById('form');
form.setAttribute('action', 'export.php');
form.submit()
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form method="post" action="get.php" id="form">
<div>
<label for="date">From</label>
<input type="date" name="from-date" id="date" />
</div>
<div>
<label for="date">To</label>
<input type="date" name="to-date" id="date" />
</div>
<div>
<input type="checkbox" name="flags[new]" /> New
<input type="checkbox" name="flags[updated]" /> Updated
<input type="checkbox" name="flags[existing]" /> Existing
</div>
<div>
<input type="submit" />
</div>
<div>
<button type="button" id="btn">
<span>Export</span>
</button>
</div>
</form>
This works as (near) expected. However, I then clicked on the submit input and it tried going to export.php. For some reason my brain was telling me that this is incorrect behaviour, but I get that I've changed the attribute value within the DOM and thus, anything post-clicking the export button will render the attribute value (until I refresh).
I'm aware that I can do another event handler to reset the attribute value, but I feel like that's counter-intuitive, is there something in JS/jQuery that allows me to "toggle" an attribute for the event only? Or do I have to make-do with a hard reset?
TL;DR
Is there a way to temporarily set an attribute within an event?

Try something like this:
jQuery(document).ready(function($) {
$('#btn').click(function() {
let form = document.getElementById('form');
//Save the current attr
let currentAttr = form.getAttribute('action');
form.setAttribute('action', 'export.php');
form.submit();
//Reset the previous attr
form.setAttribute('action', currentAttr);
})
})
You actually save the current attr, submit the form and then set the attribute to the original one.
Hope it solved your issue!

Related

Is there a way to pass the value from a button to a form when the user clicks submit?

I am trying to get the value from 5 buttons, whichever the user selects, and then once they fill the form out, I want the button value that they selected to be shown on the "summary" screen.
Is there a way to get the value of the button, along with all the other form details, and then send all those details to a new screen that shows all the information the user has entered? Something like a confirmation screen to confirm all details before they send their enquiry.
What I've been trying:
Buttons:
<div class="card">
<h1 id="size">Select your size*</h1>
<ul class="size-list">
<li>
<button class="size-link" id="size-button" value="Small">
Small
</button>
</li>
<li>
<button class="size-link" id="size-button2" value="Medium">
Medium
</button>
</li>
<li>
<button class="size-link" id="size-button3" value="Large">
Large
</button>
</li>
<li>
<button class="size-link" id="size-button4" value="X Large">
X Large
</button>
</li>
<li>
<button class="size-link" id="size-button5" value="XX Large">
XX Large
</button>
</li>
</ul>
</div>
I want to get the value from each button above as well as all the information from the form below and send it to the "Summary" screen.
Form:
<form method="GET" action="final.html" id="myform" class="contact-form">
<label id="fullname">Full Name*</label> <br />
<input name="name" id="name" class="txt-form name" type="text" />
<label id="mail">Email*</label> <br />
<input name="email" id="email" class="txt-form email" type="email" />
<label id="cheap">Have you found this item cheaper on a competitor website?*</label>
<br />
<label>
<input id="radio1" type="radio" name="radio" value="Yes"> <label for="radio1">
<span><span></span></span>Yes</label>
<input id="radio2" type="radio" name="radio" value="No"> <label for="radio2">
<span><span></span></span>No</label> <br />
</label>
<div id="url">
<label>Competitor URL</label>
<input name="url_name" id="url-link" class="txt-form" type="url">
</div>
<label id="msg">Enquiry Message*
<span id="characters">(0/200)</span></label>
<textarea name="message" id="message" class="txt-form message" type="textarea"></textarea>
<p id="asterisk">
Fields marked with an *asterisk are compulsory
</p>
<input type="submit" class=" btn" id="submit" value="Submit your enquiry">
</form>
Summary Screen:
<div id="app" class="contact-main">
<form id="myform" class="contact-form"></form>
</div>
Javascript:
const urlName = new URL(location.href);
document.getElementById('app').innerHTML = `
<label>Full Name: </label> ${urlName.searchParams.get("name") || "N/A"}
<br /><br />
<label>Email:</label> ${urlName.searchParams.get("email") || "N/A"}<br /><br />
<label>Size of item selected:</label> ${urlName.searchParams.get("sizes") || "N/A"} <br /><br />
<label>Have you found this item cheaper on a competitor
website?
</label> ${urlName.searchParams.get("radio") || "N/A" } <br /><br />
<div>
<label>Competitor URL:</label> ${urlName.searchParams.get("url-link") || "N/A"} <br /><br />
</div>
<label id="msg">Enquiry Message:</label> <br/> "${urlName.searchParams.get("message") || "N/A"}" <br /><br />
`;
I am able to get everything from the form but the "Size of item selected". I know this is because I am trying to retrieve it from the url.searchPram, however the buttons are not included on the form so I am just wondering if there's any other way?
Regarding: "Is there a way to get the value of the button"
I assume you mean the value of the clicked button. Yes, there is a way, by setting up a click listener.
Rather than setting up a click listener for each button, you can set up just one on the parent that contains the buttons. To make things easy, set an id for the enclosing <ul>:
<ul class="size-list" id="size-list">
Then set a listener on that <ul>:
document.getElementById('size-list').addEventListener('click', evt => {
let clickedButton = evt.target;
let btnValue = clickedButton.value;
}
You now have the value of the clicked button.
Storing Button's Value into a Form Element
If you need to store that value into a form element, so that value is included when the form is submitted, this can also be done with a hidden input. Let's create one with an id and name of "size":
<form method="GET" action="final.html" id="myform" class="contact-form">
<input type="hidden" id="size" name="size" value="" />
</form>
Then, just a slight modification of the click handler will store the button's value into the hidden input:
document.getElementById('size-list').addEventListener('click', evt => {
let clickedButton = evt.target;
let btnValue = clickedButton.value;
document.getElementById('size').value = btnValue;
}
That's all, the "size" value will now be sent when the form is submitted.
SOLUTION:
Add a hidden input on your form for the data. Based on your HTML and JavaScript it would be:
<input type="hidden" id="sizes" name="sizes" value="Medium">
Notice that I added a value attribute of Medium just in case the user hits submit on the form without actually pressing on of the size buttons. You could remove this and add code in your JavaScript to check if sizes is empty/ missing.
Next you need to add a click event listener to each button that will call a function when they are clicked. The JavaScript way:
// Way 1 using older JS.
var buttons = document.querySelectorAll('.size-link');
for( var x = 0; x < buttons.length; x++ ){
buttons[x].addEventListener( 'click', recordButtonSize );
}
// Way 2 using newer JS without an arrow function.
var buttons = document.querySelectorAll('.size-link');
buttons.forEach( function( button ) {
button.addEventListener( 'click', recordButtonSize );
} );
Or directly in the HTML add an onclick to each button:
<button class="size-link" value="..." onclick="recordButtonSize">...</button>
Notice that I removed your ID's. You don't really need them regardless of which solution you choose to use, the JavaScript or HTML.
And now we make the recordButtonSize function that will copy the data from the pressed button over to the hidden input:
function recordButtonSize(){
// Get the element that was clicked on.
var elem = event.target || event.srcElemnt;
// Depending on browsers / where the user clicked we may not be on the button.
if( elem.nodeName != 'BUTTON' ){
elem = elem.closest('button');
}
// Now pull the value from the button and place in the hidden input.
document.getElementById('sizes').value = elem.value;
}
NOTES:
I don't know if button elements care allowed to have value attributes so you may need to switch that to a dataset.
This solution gets the size placed into an input on the form but DOES NOT submit the form. That isn't hard to add but I will leave it as an exercise for you to figure out.
This answer uses a mix of older and newer JavaScript which will work fine on any modern browser but IE 11. See here: closest

Show Text In A DIV On Blur Of Form Field

I have been searching this for over 5 hours now with no help lol.
I want to have a form field (text) that someone can type into. Either as they type or after the blur of the field I want that text to show in a div on the screen. Maybe this is not possible.
Here is the last piece of code I tried and of course it does not work.
<p>Headline Text:<br />
<input type="text" name="headline" value="$headline" onChange="document.getElementById('headline2').value=this.value" /></p>
<br />
<div id="headline2"></div>
In that code, anything typed into headline would appear in the <div id="headline2"></div> on blur.
Any help would be great.
You were not far!!!
A <div> doesn't have a value... But has inner HTML. ;)
Here it is on change:
<p>Headline Text:<br />
<input type="text" name="headline" value="$headline" onChange="document.getElementById('headline2').innerHTML=this.value" /></p>
<br />
<div id="headline2"></div>
And on keyup:
<p>Headline Text:<br />
<input type="text" name="headline" value="$headline" onKeyup="document.getElementById('headline2').innerHTML=this.value" /></p>
<br />
<div id="headline2"></div>
HTML:
<input>
<div id="target"></div>
Javascript:
var input = document.querySelector('input');
var target = document.querySelector('div')
input.addEventListener('blur', function() {
target.innerHTML = input.value
})
I recommend keeping your scripts separate from the markup, but if you so choose...
<input onblur="document.getElementById('target').innerHTML = this.value">
<div id="target"></div>
Form inputs have a value property, container elements such as divs have innerHTML. Try this instead:
<p>Headline Text:<br />
<input type="text" name="headline" value="$headline"
onChange="document.getElementById('headline2').innerHTML=this.value" />
</p>
<br />
<div id="headline2"></div>
<input type="text" id="text" onkeyup="getTextVal()">
<div id="showtext"></div>
<script>
function getTextVal(){
var val = document.getElementById('text').value;
var showText = document.getElementById('showtext');
showText.innerText = val;
}
</script>
See in jsfiddle link
This is very possible, and you were very close with your attempt. The problem is that a <div> element doesn't have a value, only innerHTML. Also, you're probably looking for onblur instead of onChange:
<p>Headline Text:<br />
<input type="text" name="headline" value="$headline" onblur="document.getElementById('headline2').innerHTML = this.value" /></p>
<br />
<div id="headline2"></div>
Just remember that with onblur, you have to actually click outside of the element for the changes to show. If you want it to change whenever the user types something, you're looking for onkeyup instead.
Hope this helps! :)

How do I write JavaScript that validates input across multiple forms?

I am attempting to write JavaScript that traverses multiple HTML forms, checks an input for a given value on edit, then enables/disables the submit button for that form based on the input value.
I have a very simple example script, which overrides the onclick function of checkboxes, to test the flow of my code.
<form>
<input type="checkbox" />
<input type="submit" disabled="disabled" />
</form>
<form>
<input type="checkbox" />
<input type="submit" disabled="disabled" />
</form>
<form>
<input type="checkbox" />
<input type="submit" disabled="disabled" />
</form>
<form>
<input type="checkbox" />
<input type="submit" disabled="disabled" />
</form>
<form>
<input type="checkbox" />
<input type="submit" disabled="disabled" />
</form>
<script type="text/javascript">
forms = document.getElementsByTagName("form");
for(i=0; i<forms.length; i++)
{
inputs = forms.item(i).getElementsByTagName("input");
inputs.item(0).onclick = function()
{
if(this.checked)
inputs.item(1).removeAttribute("disabled");
else
inputs.item(1).setAttribute("disabled","disabled");
}
}
</script>
What I expect to happen: the checkboxes change the value of the submit button in the same form.
What actually happens: all the checkboxes change the value of the submit button in the last form.
The actual code will be somewhat smarter, but I want to understand the flow of JavaScript code before progressing onto something more complex.
Thanks in advance!
Try something like this:
document.body.onchange = function(e) {
// this delegates all the way to the body - if you have a more specific
// container, prefer using that instead.
e = e || window.event;
var t = e.srcElement || e.target;
if( t.nodeName == "INPUT" && t.type == "checkbox") {
// may want to add a className to the checkboxes for more specificity
t.parentNode.getElementsByTagName('input')[1].disabled = !t.checked;
}
};
The reason you are seeing the behaviour you're getting is because inputs' value is not fixed, you are repeatedly re-assigning it to the next form's elements, ultimately resulting in the last one.

Input value hidden

I have this input:
<input id="tag1" type="text" name="tags" class="tags" value="#Model.list" />
and I want to get this input value in a hidden input, so I used this:
<input type="hidden" name="tag" value="tags" />
Instead of getting the true value of the first input, I only get the string "tags"! Can you please tell me how to obtain the true value of the first input in my hidden input? Thanks!
EDIT: Actually it's a submit page, the user enters tags in the #tag1 and when he clicks on submit I want to send these tags to my controller, that's why I'm using the hidden input...
My full code:
<form>
<p>
<input id="tag1" type="text" name="tags" class="tags" value="#Model.list" onblur="setValue()"; /></p>
<script>
$('#tag1').tagsInput({
// my parameters here
});
</script>
<style>
#wrapper {
margin: 20px;
}
</style>
<p>
<input type="submit" value="Create" />
<input type="hidden" name="taggg" id="tag2" />
<script type="text/javascript">
function setValue() {
document.getElementById("tag2").value = document.getElementById("tag1").value;
}
window.onload = setValue;
</script>
</p>
</form>
I don't understand why you would want to copy the value of one input field to another (albeit, hidden). But if that is what you want to do, try using the below code.
The function attached to the onblur event of the input field would set the value of the input field to the hidden field whenever it loses focus.
The window.onload = setValue will do the same on page load.
HTML
<input id="tag1" type="text" name="tags" class="tags" value="#Model.list" onblur="setValue();" />
<input type="hidden" name="tag" value="tags" id="tag1_hidden" /> <!-- Note the addition of an id attribute -->
JavaScript
function setValue() {
document.getElementById("tag1_hidden").value = document.getElementById("tag1").value;
}
window.onload = setValue;
Try this
<input id="tag1" type="text" name="tags" class="tags" value="#Model.list" />
<input type="hidden" name="tag" value="tags" id="tag2" />
Jquery:
$("#tag2").val($("#tag1").val());
or
$("#tag1").blur(function() {
$("#tag2").val($(this).val());
});
You can do like this (and you will need javascript for this).
Give a id to your hidden input also like:
<input type="hidden" id="hidden_input" name="tag" value="tags" />
and then use/paste this code when you need it:
var input_value = document.getElementById('tag1').value;
document.getElementById('hidden_input').value = input_value;

Change form action based on submit button

I have many forms like the following on the page. Now I want change the form action based on which submit button the user clicked (and of course submit the form)
<form action="/shop/products.php" data-ajax="false" method="post">
<div data-role="fieldcontain">
<input name="submit" class="obutn" type="submit" value="Order" />
<input name="submit" class="oEbutn" type="submit" value="Extras" />
</div>
</form>
I tried with
$(".obtn").click(function() {
$(this).parent().parent().attr("action", "/shop/products.php");
});
$(".oEbtn").click(function() {
$(this).parent().parent().attr("action", "/shop/extras.php");
});
but the form is always submited to products.php. Can you tell me what's wrong?
Instead of setting the action attribute on the form itself, consider setting formaction attribute on each individual input element.
Docs: http://www.w3.org/TR/html-markup/input.submit.html#input.submit.attrs.formaction
<form data-ajax="false" method="post">
<div data-role="fieldcontain">
<input formaction="/shop/products.php"
name="submit" class="obutn" type="submit" value="Order" />
<input formaction="/shop/extras.php"
name="submit" class="oEbutn" type="submit" value="Extras" />
</div>
</form>
There are two typos:
obtn instead of obutn
oEbtn instead of oEbutn
Another suggestion is to use closest("form") to get the form that contains the clicked button.
$(".obutn").click(function() {
$(this).closest("form").attr("action", "/shop/products.php");
});
$(".oEbutn").click(function() {
$(this).closest("form").attr("action", "/shop/extras.php");
});
$("form").on("submit", function () {
alert($(this).attr("action"));
});
JSFIDDLE
Capture the submit event and determine which button was clicked. From that, you can change the action of the form.
Here's a link on how to do that.
How can I get the button that caused the submit from the form submit event?
Also, don't give the form the action until the click happens at all, it is superfluous.
<form data-ajax="false" method="post">
<div data-role="fieldcontain">
<input name="submit" class="obutn" type="submit" value="Order" />
<input name="submit" class="oEbutn" type="submit" value="Extras" />
</div>
</form>
What if you try it out with a switch instead? Something like:
<input name="submit" id = "1" class="obutn" type="submit" value="Order" />
<input name="submit" id = "2" class="oEbutn" type="submit" value="Extras" />
And then in JavaScript we have:
//param: The Id attr of the button that was clicked
function postTo(id){
switch(id){
case 1: postProducts();
break;
case 2: postExtras();
break;
default: //Do something else
}
}
Just an idea. HavenĀ“t tested that yet, but maybe it could be helpful. I hope so.

Categories

Resources