Which button was clicked without using Javascript? - html

There is a html code
<form>
<button type="submit" name="button-name" value="btn1">button1</button>
<button type="submit" name="button-name" value="btn2">button2</button>
</form>
Is there any way to determine which button was clicked on a server side? I'd like not to use javascript and not to replace them with input.
That's funny but I have nil in params["button-name"]

This would work if you are working with PHP on the server side.
if(isset($_GET['button-name']))
echo $_GET['button-name'];

You should be able to check the value of the button-name parameter on the server side to determine which button was clicked. In decent browsers it will be the value of the value attribute, but in IE you will receive the inner html of each button.
So for example, if I clicked the first button and was using Java on the server side:
In IE
String param = reqeust.getParameter("button-name");
System.out.println(param); // Prints button1
In Firefox
String param = reqeust.getParameter("button-name");
System.out.println(param); // Prints btn1

If you were to use PHP, this would work (assuming you use GET instead of POST):
if((isset($_GET['button-name'])) && ($_GET['button-name'] === 'btn1' || $_GET['button-name'] === 'btn2')){
}

Related

What is the HTML <dialog> tag used for and when to use it?

The way I've understood it, the tag is used to open and close content like a popup alert. What I fail to understand is what advantages the tag has compared to just using a "div" and styling it with css and adding functionality to it with js. It also seems counter intuitive to manipulate the "open" property in order to show/hide the content instead of using display:none/block; with css.
I also don't understand exactly which scenarios would be considered a dialog box. Is a form login box a dialogbox? What about a popup telling you to disable adblock? Are all popups that can be hidden considered dialog boxes?
The traditional, hacky way to create a dialog, via designing a div via CSS only seems to be intuitive for you because you are used to it. However, you need to implement every functionality related to it, such as:
opening it
closing it
Also, in the future, this will be enhanced by standard functionalities, so, while it's not urgent for already existent code, but when you write code, especially when you start a project, it makes sense to start using it. Let's see an example from [Mozilla's page][1]:
var updateButton = document.getElementById('updateDetails');
var favDialog = document.getElementById('favDialog');
var outputBox = document.querySelector('output');
var selectEl = document.querySelector('select');
var confirmBtn = document.getElementById('confirmBtn');
// "Update details" button opens the <dialog> modally
updateButton.addEventListener('click', function onOpen() {
if (typeof favDialog.showModal === "function") {
favDialog.showModal();
} else {
alert("The <dialog> API is not supported by this browser");
}
});
// "Favorite animal" input sets the value of the submit button
selectEl.addEventListener('change', function onSelect(e) {
confirmBtn.value = selectEl.value;
});
// "Confirm" button of form triggers "close" on dialog because of [method="dialog"]
favDialog.addEventListener('close', function onClose() {
outputBox.value = favDialog.returnValue + " button clicked - " + (new Date()).toString();
});
<!-- Simple pop-up dialog box containing a form -->
<dialog id="favDialog">
<form method="dialog">
<p><label>Favorite animal:
<select>
<option></option>
<option>Brine shrimp</option>
<option>Red panda</option>
<option>Spider monkey</option>
</select>
</label></p>
<menu>
<button value="cancel">Cancel</button>
<button id="confirmBtn" value="default">Confirm</button>
</menu>
</form>
</dialog>
<menu>
<button id="updateDetails">Update details</button>
</menu>
<output aria-live="polite"></output>
However, at the time of this writing (February the 3rd, 2022), this is not supported in all browsers, so it is perfectly feasible to avoid using it for now, until it will become supported everywhere.
[1]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog

multiple form generated jquery doesn't submit

I'm building a website (e-commerce like) with Django.
At some point I display a list of items and for each item there is a form with submit button Order and Quantity picker.
I've implemented filter function that delete the html code of my items list and rebuild it with the matching items with jquery.
The new forms generated by this function do nothing when the submit button is clicked
Here is a part of the code I use in my function (I use an ajax call to generate a json of matching items and then I display them in the table list) :
$.each(code_json, function(index, value){
var string = "<tr id="+ value.material +"><td>"+ value.manufNo +"</td><form method='POST' action='/add_to_cart/"+value.material+"/"+ value.node+"/{{language}}'><td><input type='submit' class='btn' value='Commander' style='color:blue;'></td><td><input id='qty' type='number' name='qty' class='form-control' value='1'></td></form></tr>";
$("#header").after(string);
});
I know that usually with Django you have to add {% csrf_token %} for each form. However it throw an error page usually when missing and here it doesn't show anything
Edit : I tried to bind an onclick event on the submit button dynamically created. In this I did a $.post in jquery to simulate the submit of the form but nothing happend
$(document).on('click', '.btnStandard', function(event) {
console.log($(this).attr('id'));
$.post('/add_to_cart/'+$(this).attr('id'),
{
qty: $("#qty"+$(this).attr('id')).val()
},function(data,status,xhr){
alert("Data : "+data+", status: "+status+", xhr: "+xhr);
});
It print in console $(this).attr('id') but it doesn't do anything else
Thank you for your help
It doesn't explain why I have this problem but I found a workaround to solve my problem.
Instead of dynamically generate forms, I generate them with template and then I hide them all. Later, I make those I need visible when I need thanks to css.

AngularJS - bind ng-model with button click

I've got an irritating problem with data binding using ng-model and button.
The principle of operation of my site:
My HTML site displays a list of projects (loaded from external .json file).
Each row has a button named Edit which displays a modal containing some <input type="text" filled with relevant data about project (like project.name, project.date etc.)
Initial value of input is equal to object data (text-input called Name will contain project.name etc.)
Object is modified only if you click Save button and confirm the operation (confirm(sometext) is okay).
Closing the modal, not clicking the button or pressing cancel on confirmation box should prevent data from being updated.
Editing input (let's say that project.name is "Project2" and I modify it by adding 3 numbers resulting in "Project2137"), closing modal and opening it again should result in "Project2" text inside input (because object wasn't modified, only input)
So far I understand that single text input should look like this
<input type="text" id="editName" class="form-control" ng-model = "project.name">
Using ng-model means that they are binded. That's what I know. However editing input means that object is updated as soon as I enter some data.
I tried to fiddle with ng-model-options but I didn't find any possible solutions.
I tried to do it programmatically as well using
<input type="text" id="editName" class="form-control" value = {{project.name}}>
....
<button type="button" class="btn pull-right btn-primary btn-md" ng-click="edit(project)" data-dismiss="modal" >Save</button>
And function:
$rootScope.edit = function(project)
{
if(confirm("Are you sure to save changes?"))
{
project.name = angular.element(document.getElementById('editName')).val();
// ...and so on with other properties
This solution is kinda close to what I wanted to achieve (object is updated only on confirm), but I faced another problem: input loads data from object only once at the beginning instead of each time the modal is opened which is against rule #5
Is there any way to fix this using either ng-model bind or custom function? Or maybe there is some other, easier way?
--EDIT--
Here I don't have any problem with saving the data using a button, everything works well and clicking Save is reflected in a projects list. (well until I hit a F5 key).
The problem is that input text is not properly binded to project and that's what I want to fix.
Sample data (pseudocode)
project1.name = "Proj1"
project2.name = "Proj2"
I click an Edit button on row #1
Text input displays "Proj1". Everything is fine.
I change input by adding some random characters like "Proj1pezxde1"
Text input is now "Proj1pezxde1"
I do not click Save button.
I close the modal.
Project summary still displays "Proj1". Okay.
I click an edit button on first row
10. Text input is "Proj1pezxde1" even though I didn't modify an object.
Text input should read data from object again (each time I open this modal) and thus display "Proj1"
That's the problem I want to fix. Sorry for being a little bit inaccurate.
You can create a copy of the project object in modal controller and use this object to bind with the input element of the modal
$scope.copyProj = angular.copy($scope.project);
Assign the copy object properties to project only when save is clicked.
As per my understanding after reading the provided descriptions, you have a list of projects, which is being used as in an repeater and you want to bind each projects data to a Text box and a Button.
Have you tried initializing your Projects object following way?
$scope.projects = [
{ 'name': 'proj1', 'id': '1' },
{ 'name': 'proj2', 'id': '2' }
];
Then you can do something like below to show your data
<div ng-repeat="project in projects">
<div>
<input type="text" class="form-control" ng-model = "project.name">
<button type="button" class="btn pull-right btn-primary btn-md" ng-click="edit(project)" data-dismiss="modal" >Save</button>
</div>
</div>
The simplest way to do this in my opinion is using a second object that is a copy of the project, and after confirmation applying the changes to the original project object.
For example, a simple "pseudo code" of a controller:
function MyCtrl($scope) {
$scope.projects = [...];
$scope.currentProject = null;
$scope.edit = function(project) {
$scope.currentProject = angular.copy(project); // This will create a copy so the changes in $scope.currentProject will not reflect.
// Open dialog with input bound to $scope.currentProject
if (confirm) {
// Assign all properties from currentProject to project
angular.extend(project, $scope.currentProject);
}
}
}
So , as I understand from your question , you need to update the project data only if it is saved. To do that you can maintain a copy of the actual object which get updated only it is saved like below :
Here we are using angular.copy(), which does a deep copy of the source object.
$scope.original = {name : "xyz"};
$scope.project = angular.copy(original);
//Call this when the user confirms to save , here we are replacing the
//original copy with the latest object that needs to be saved.
$scope.save = function () {
$scope.original = angular.copy($scope.project);
}
//Call this when closing the modal or clicking cancel or when losing
//focus, this will reset the changes to the original copy.
$scope.reset = function () {
$scope.project = angular.copy(original);
}

HTML nav menu/form list that redirects on button click

Here is what I'm trying to do, and I feel as though maybe I'm overthinking it. I can easily make a dropdown nav list, but what I need is to combine two different dropdown lists to give a user options, then when they click the button it will send them to a page that corresponds with their choices.
For example, dropdown list one: What type of advice do you need?
-Career
-Relationships
-Health
droplist two: What layout do you want?
-Quick and Dirty
-Standard
-In-depth
Then I just need to program in the link to every combination of these pages. How do program in the correct redirects depending on the selections?
Assuming you have a pair of drop-down menus like this:
<form method="post">
<p>What type of advice do you need?
<br><select id="s1">
<option>Career</option>
<option>Relationships</option>
<option>Health</option>
</select>
<p>What layout do you want?
<br><select id="s2">
<option>Quick and Dirty</option>
<option>Standard</option>
<option>In-depth</option>
</select>
<input type="button" onclick="send(this.form)" value="Send"/>
</form>
The button at the end of the form, when clicked calls a function that will redirect to the page you want comparing the items selected in each menu. The function should receive a reference to the form (passed in this.form), get the selected indexes and text (or values, if you use them in each option) and test them in a condicional branch:
function send(form) {
var s1 = document.getElementById("s1");
var s2 = document.getElementById("s2");
var choice1 = s1.options[s1.selectedIndex].text;
var choice2 = s2.options[s2.selectedIndex].text;
if (choice1 == "Career" && choice2 == "Quick and Dirty") {
location.href = "http://quickdirtycareers.com";
} else if (choice1 == "Career" && choice2 == "Standard") {
location.href = "http://standardcareers.com";
} else {
location.href = "http://careers.stackoverflow.com";
}
}
Here's a Fiddle with a working sample: http://jsfiddle.net/helderdarocha/TNZ9A/
(There are many other ways to do it, adding CSS, dynamic selection, focus, etc. It's easier to add these enhancements using JQuery.)

Manually Triggering Form Validation using jQuery

I have a form with several different fieldsets. I have some jQuery that displays the field sets to the users one at a time. For browsers that support HTML5 validation, I'd love to make use of it. However, I need to do it on my terms. I'm using JQuery.
When a user clicks a JS Link to move to the next fieldset, I need the validation to happen on the current fieldset and block the user from moving forward if there is issues.
Ideally, as the user loses focus on an element, validation will occur.
Currently have novalidate going and using jQuery. Would prefer to use the native method. :)
TL;DR: Not caring about old browsers? Use form.reportValidity().
Need legacy browser support? Read on.
It actually is possible to trigger validation manually.
I'll use plain JavaScript in my answer to improve reusability, no jQuery is needed.
Assume the following HTML form:
<form>
<input required>
<button type="button">Trigger validation</button>
</form>
And let's grab our UI elements in JavaScript:
var form = document.querySelector('form')
var triggerButton = document.querySelector('button')
Don't need support for legacy browsers like Internet Explorer? This is for you.
All modern browsers support the reportValidity() method on form elements.
triggerButton.onclick = function () {
form.reportValidity()
}
That's it, we're done. Also, here's a simple CodePen using this approach.
Approach for older browsers
Below is a detailed explanation how reportValidity() can be emulated in older browsers.
However, you don't need to copy&paste those code blocks into your project yourself — there is a ponyfill/polyfill readily available for you.
Where reportValidity() is not supported, we need to trick the browser a little bit. So, what will we do?
Check validity of the form by calling form.checkValidity(). This will tell us if the form is valid, but not show the validation UI.
If the form is invalid, we create a temporary submit button and trigger a click on it. Since the form is not valid, we know it won't actually submit, however, it will show validation hints to the user. We'll remove the temporary submit button immedtiately, so it will never be visible to the user.
If the form is valid, we don't need to interfere at all and let the user proceed.
In code:
triggerButton.onclick = function () {
// Form is invalid!
if (!form.checkValidity()) {
// Create the temporary button, click and remove it
var tmpSubmit = document.createElement('button')
form.appendChild(tmpSubmit)
tmpSubmit.click()
form.removeChild(tmpSubmit)
} else {
// Form is valid, let the user proceed or do whatever we need to
}
}
This code will work in pretty much any common browser (I've tested it successfully down to IE11).
Here's a working CodePen example.
You can't trigger the native validation UI (see edit below), but you can easily take advantage of the validation API on arbitrary input elements:
$('input').blur(function(event) {
event.target.checkValidity();
}).bind('invalid', function(event) {
setTimeout(function() { $(event.target).focus();}, 50);
});
The first event fires checkValidity on every input element as soon as it loses focus, if the element is invalid then the corresponding event will be fired and trapped by the second event handler. This one sets the focus back to the element, but that could be quite annoying, I assume you have a better solution for notifying about the errors. Here's a working example of my code above.
EDIT: All modern browsers support the reportValidity() method for native HTML5 validation, per this answer.
In some extent, You CAN trigger HTML5 form validation and show hints to user without submitting the form!
Two button, one for validate, one for submit
Set a onclick listener on the validate button to set a global flag(say justValidate) to indicate this click is intended to check the validation of the form.
And set a onclick listener on the submit button to set the justValidate flag to false.
Then in the onsubmit handler of the form, you check the flag justValidate to decide the returning value and invoke the preventDefault() to stop the form to submit. As you know, the HTML5 form validation(and the GUI hint to user) is preformed before the onsubmit event, and even if the form is VALID you can stop the form submit by returning false or invoke preventDefault().
And, in HTML5 you have a method to check the form's validation: the form.checkValidity(), then in you can know if the form is validate or not in your code.
OK, here is the demo:
http://jsbin.com/buvuku/2/edit
var field = $("#field")
field.keyup(function(ev){
if(field[0].value.length < 10) {
field[0].setCustomValidity("characters less than 10")
}else if (field[0].value.length === 10) {
field[0].setCustomValidity("characters equal to 10")
}else if (field[0].value.length > 10 && field[0].value.length < 20) {
field[0].setCustomValidity("characters greater than 10 and less than 20")
}else if(field[0].validity.typeMismatch) {
field[0].setCustomValidity("wrong email message")
}else {
field[0].setCustomValidity("") // no more errors
}
field[0].reportValidity()
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="email" id="field">
Somewhat easy to make add or remove HTML5 validation to fieldsets.
$('form').each(function(){
// CLEAR OUT ALL THE HTML5 REQUIRED ATTRS
$(this).find('.required').attr('required', false);
// ADD THEM BACK TO THE CURRENT FIELDSET
// I'M JUST USING A CLASS TO IDENTIFY REQUIRED FIELDS
$(this).find('fieldset.current .required').attr('required', true);
$(this).submit(function(){
var current = $(this).find('fieldset.current')
var next = $(current).next()
// MOVE THE CURRENT MARKER
$(current).removeClass('current');
$(next).addClass('current');
// ADD THE REQUIRED TAGS TO THE NEXT PART
// NO NEED TO REMOVE THE OLD ONES
// SINCE THEY SHOULD BE FILLED OUT CORRECTLY
$(next).find('.required').attr('required', true);
});
});
I seem to find the trick:
Just remove the form target attribute, then use a submit button to validate the form and show hints, check if form valid via JavaScript, and then post whatever. The following code works for me:
<form>
<input name="foo" required>
<button id="submit">Submit</button>
</form>
<script>
$('#submit').click( function(e){
var isValid = true;
$('form input').map(function() {
isValid &= this.validity['valid'] ;
}) ;
if (isValid) {
console.log('valid!');
// post something..
} else
console.log('not valid!');
});
</script>
Html Code:
<form class="validateDontSubmit">
....
<button style="dislay:none">submit</button>
</form>
<button class="outside"></button>
javascript( using Jquery):
<script type="text/javascript">
$(document).on('submit','.validateDontSubmit',function (e) {
//prevent the form from doing a submit
e.preventDefault();
return false;
})
$(document).ready(function(){
// using button outside trigger click
$('.outside').click(function() {
$('.validateDontSubmit button').trigger('click');
});
});
</script>
Hope this will help you
For input field
<input id="PrimaryPhNumber" type="text" name="mobile" required
pattern="^[789]\d{9}$" minlenght="10" maxLength="10" placeholder="Eg: 9444400000"
class="inputBoxCss"/>
$('#PrimaryPhNumber').keyup(function (e) {
console.log(e)
let field=$(this)
if(Number(field.val()).toString()=="NaN"){
field.val('');
field.focus();
field[0].setCustomValidity('Please enter a valid phone number');
field[0].reportValidity()
$(":focus").css("border", "2px solid red");
}
})
$('#id').get(0).reportValidity();
This will trigger the input with ID specified. Use ".classname" for classes.
When there is a very complex (especially asynchronous) validation process, there is a simple workaround:
<form id="form1">
<input type="button" onclick="javascript:submitIfVeryComplexValidationIsOk()" />
<input type="submit" id="form1_submit_hidden" style="display:none" />
</form>
...
<script>
function submitIfVeryComplexValidationIsOk() {
var form1 = document.forms['form1']
if (!form1.checkValidity()) {
$("#form1_submit_hidden").click()
return
}
if (checkForVeryComplexValidation() === 'Ok') {
form1.submit()
} else {
alert('form is invalid')
}
}
</script>
Another way to resolve this problem:
$('input').oninvalid(function (event, errorMessage) {
event.target.focus();
});