How to check AngularJs form field on Cancel button? - javascript

I have a Cancel button on a form. When a user clicks on the Cancel button I have three scenarios.
If the user has entered values in any field and, without saving, clicks on the cancel button I am alerting "all data will be lost" and redirecting it to home page
If the user has not entered any values in form fields and clicks on cancel I don't want to display the message "all the data will be lost". It will be a different message and redirect it to home because he did not enter any information, so I want to display a different message.
Once form is saved and now we are in edit Mode without changing any
existing values how to implement second scenario, No value is
changed if user clicks on cancel don't want to display the message
"all the data will be lost".
How to check the second scenario if no values were entered in the
form fields and on handleCancel display a different message?
How to check third scenario in edit Mode if existing values are not changed then click on cancel behavior should be similar to second scenario ?
main.html
<div class="col-md-8">
<input type="text" class="form-control" id="processOwnerRes"
ng-model="challengesDTO.challengeResponseWrk"
name="processOwnerRes" readonly="readonly" >
</div>
<div class="panel-footer">
<button class="btn btn-default" type="button" ng-click="handleCancel()">Cancel</button>
<div class="pull-right">
<button class="btn btn-primary"
ng-disabled="processChallengeForm.$invalid"
ng-class="{disableSaveCls:processChallengeForm.$invalid}"
ng-click="submit()" >Save
</button>
</div>
</div>
ctrl.js
$scope.handleCancel = function () {
if($rootScope.status !== 'view') {
$scope.messageText = $rootScope.alertMessages['common.cancelConfirmMessage'];
$scope.confirmationWin.open().center();
$scope.yesCallback = $scope.cancelPRT;
} else { $scope.redirectToProcessScreen(); }
};

You can use the properties $pristine or $dirty to check if the user has already interacted with the form.
https://docs.angularjs.org/api/ng/type/form.FormController
Something like this:
$scope.handleCancel = function () {
if($rootScope.status !== 'view') {
if($scope.processChallengeForm.$dirty){
$scope.messageText = $rootScope.alertMessages['common.cancelConfirmMessage'];
$scope.confirmationWin.open().center();
$scope.yesCallback = $scope.cancelPRT;
}
} else { $scope.redirectToProcessScreen(); }
};

Related

Validate a form element without/before submitting the form with JavaScript

I have an HTML form that has its elements displayed in various Bootstrap modals. The first modal has a text box input that and a "Next" button to open the next modal. When the "next" button is pressed. I want to check if the text box is empty, and trigger a validation message. The form does not get submitted until the very end. Everything I've tried has not worked so far.
Javascript/jQuery code
$("#add_assistant_next").click(function () {
var textInput = document.getElementById('add_assistant_user');
var text = textInput.value;
if (text === "") {
textInput.setCustomValidity('Please fill out this field.');
textInput.checkValidity();
var form = $('#form_add_assistant');
form.find(':submit').click();
} else {
textInput.setCustomValidity('');
}
});
HTML
<form name="add_assistant" method="post" id="form_add_assistant">
<div class="modal-body">
<div class="step">
<span class="fas fa-arrow-right choose-arrow mr-1"></span>1. Choose a user to add
</div>
<div class="pl-3 pt-1">
<div>
<input type="text" id="add_assistant_user" name="add_assistant[user]" required="required" placeholder="UCInetID or UCI email address" class="mr-0 form-control" />
<button type="button" id="add_assistant_next" name="add_assistant[next]" data-toggle="modal" data-target="#add-user-modal" class="btn btn-outline-secondary btn">Look up user</button>
</div>
<input type="hidden" name="user_search_route" value="/courseSpace/20900/listAssistantEnrollment">
</div>
</div>
... form continues in other modals
Your JS code is probably fighting with Bootstrap for control of that button. To get around that, and have your validation, you could try modifying your code to have a middle step / temporary button to help with validation first before actually submitting. So something like this:
Javascript/jQuery code
$("#my_temp_button").click(function () {
var textInput = document.getElementById('add_assistant_user');
var text = textInput.value;
// Might also want to handle null and undefined cases?
if (text === "" || text === undefined || text === null) {
// I'm assuming if it's empty, it doesn't pass validation,
// so we just display this warning and wait for the user to fix it:
textInput.setCustomValidity('Please fill out this field.');
} else {
// it's not empty so validate:
if (textInput.checkValidity()) {
// it passed validation, so ok to submit.
// call the real button:
$('#add_assistant_next').click();
// do you need this?
var form = $('#form_add_assistant');
form.find(':submit').click();
} else {
// it failed validation, so display another error?
textInput.setCustomValidity('Try again.');
}
}
});
HTML:
<form name="add_assistant" method="post" id="form_add_assistant">
<div class="modal-body">
<div class="step">
<span class="fas fa-arrow-right choose-arrow mr-1"></span>1. Choose a user to add
</div>
<div class="pl-3 pt-1">
<div>
<input type="text" id="add_assistant_user" name="add_assistant[user]" required="required" placeholder="UCInetID or UCI email address" class="mr-0 form-control" />
<!-- Feel free to change the id name. This is the button the user sees. It's only purpose is to give your function above full control to it and prevent Bootstrap from touching it and jumping to the next modal without having the user fix the validation failure first: -->
<button type="button" id="my_temp_button" class="btn btn-outline-secondary btn">Look up user</button>
<!-- Hide the real button from the user: -->
<div style="display:none">
<button type="button" id="add_assistant_next" name="add_assistant[next]" data-toggle="modal" data-target="#add-user-modal" class="btn btn-outline-secondary btn">Look up user</button>
</div>
</div>
<input type="hidden" name="user_search_route" value="/courseSpace/20900/listAssistantEnrollment">
</div>
</div>
...
Have you tried adding a trap for the submit event itself?
$('#form_add_assistant').submit(function(evt){
//do your validation here
if (validation fails){
return false; // OR, alternatively, `evt.preventDefault()`
}
//form submission will continue if not returned false
});
References:
https://api.jquery.com/submit/
How to conduct manual form validation via jQuery .submit()

Input Box Values Disappear on Button Click

I am just starting out with JQuery for asp.net core mvc.
I have a section of a page comprising a list of items linked to the main subject. When an 'edit' button is clicked against one of the list items, a hidden section (fieldset) is displayed and populated with the values of that list item. Other inputs on the page are disabled and the user can edit the item. All works fine.
However, when finished editing, the user clicks a 'submit' button (within the previously hidden fieldset) and the idea is to submit the edited data via ajax and, if accepted, to update the list. Ajax, etc. is not (yet) the problem.
When the user clicks the 'submit' button (coded as type="button"), the values in the edited section appear to have been cleared and are returned as spaces or nulls. It only seems to apply to this fieldset, as (disabled) values from the remainder of the document can be retrieved (just for testing purposes).
Can anyone tell me what is going on here and how to preserve these edited values, please?
#**** Drop-down section for editing Admissions ****#
<fieldset id="AdmissionsEditFieldset" class="app-edit-main-fieldset" hidden>
<legend id="AdmissionsEditLegend" class="app-edit-fieldset-legend">Editing Admission</legend>
<div class="row">
<div class="col-sm-12" style="padding-left: 5%; padding-right: 5%">
<div class="form-group">
<strong><label>Institution:</label></strong>
<span class="app-label-to-input-sep">
<input id="admId" name="aId" type="text" class="form-input app-can-disable" asp-for="Admission.Id" hidden />
<select id="admPlace" name="aPlace" type="text" class="app-can-disable" asp-items="Model.PlaceOfDetentionDd" asp-for="Admission.PlaceId"></select>
</span>
<strong><label class="app-input-fld-sep">Date Admitted:</label></strong>
<span class="app-label-to-input-sep">
<input id="admDate" name="aDate" type="text" class="form-input app-can-disable" asp-for="Admission.DateAdmitted" style="width: 5%" />
</span>
<strong><label class="app-input-fld-sep">Sequence:</label></strong>
<span class="app-label-to-input-sep app-can-disable">
<input id="admSeq" name="aSeq" type="text" class="form-input" asp-for="Admission.Seq" style="width: 5%" />
</span>
<span>
<button id="admSubmitBtn" class="btn btn-sm btn-primary app-adm-edit-btn" type="button">Submit</button>
<button id="admCancelBtn" type="button" class="btn btn-sm btn-danger app-button-to-button-sep">Cancel</button>
</span>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12" style="padding-left: 5%; padding-right: 5%">
</div>
</div>
And this is the JavaScript/JQuery
$(document).ready(function () {
$('.app-adm-edit-btn').click(function (event) {
//*** Prevent default button actions
event.preventDefault();
// btn has format 'editN[N...]'
var btn = event.target.id;
var sid = btn.substring(4);
//*** Un-hide the editing drop-down
$('#AdmissionsEditFieldset').removeAttr('hidden');
//*** Copy values from the relevent line in the table to the editing drop-down
$('#admId').val($('#ident' + sid).text());
$('#admPlace').val($('#placeN' + sid).text());
$('#admDate').val($('#dateAdm' + sid).text());
$('#admSeq').val($('#seq' + sid).text());
//*** Set the section legend
$('#AdmissionsEditLegend').text('Editing an Admission');
//*** Disable other sections
DisableFieldsets(); // Works OK - makes no difference if commented out
//*** Focus the first input box
$('#admPlace').focus();
}); // $('.app-adm-edit-btn').click
/*----------------------------------------------------------------------------------
Admissions Submit button click handler
----------------------------------------------------------------------------------*/
$('#admSubmitBtn').click(function (event) {
//*** Prevent default button actions
event.preventDefault();
// Just to verify nothing wrong with JSON.stringify
var id = $('#admId').val();
var placeId = $('#admPlace').val();
var seq = $('#admSeq').val();
var dateAdmitted = $('#admDate').val();
var court = $('#Court').val();
// Not integrated, so that I can display the values
var jsn = JSON.stringify({
Id: $('#admId').val(),
PlaceId: $('#admPlace').val(),
Seq: $('#admSeq').val(),
DateAdmitted: $('#admDate').val()
});
$.ajax({
url: "api/EditAdmissionApi",
method: "POST",
contentType: "application/json",
data: jsn,
success: function (data) {
alert("Ajax Success"); //TODO
}
});
alert(jsn);
//TODO
});
/*------------------------------------------------------------------------
Admissions Cancel button click handler
--------------------------------------------------------------------------*/
$('#admCancelBtn').click(function (event) {
//*** Prevent default button actions
event.preventDefault();
});
}); // $(document).ready
/*===========================================================================
Helper Functions
===========================================================================*/
/*---------------------------------------------------------------------------
DisableFieldsets Helper function to disable fieldsets while input of linked
items takes place
---------------------------------------------------------------------------*/
function DisableFieldsets() {
DoDisableFieldsets('#MainFieldset');
DoDisableFieldsets('#AdmissionsFieldset');
DoDisableFieldsets('#ChildrenFieldset');
DoDisableFieldsets('#SubmitButtonsNonFieldset');
}
function DoDisableFieldsets(id) {
var xId = $(id);
$('.app-can-disable', xId).attr('disabled', 'disabled');
$(xId).addClass('app-disabled-background');
}
Yes it does and many thanks for the suggestion, mj.
Trying to see why and testing alternatives brought me to the real issue, however. I have to confess that it was one of those stupidities that you can stare at for hours without seeing. Still I will confess, in case it helps anyone else.
I had given the Edit buttons in the list a 'dummy' class name to make selection easier. Then I had inadvertently copied and adapted the button html to be the Submit button following edit, without deleting the class. So both the Edit and Submit button handlers seemed to be called, which was causing havoc (I have not yet worked out why this was not just producing the unedited text in the second handler - but life's too short). So a dumb question on my part - sorry for wasting everyone's time.
The construct $('#admId').val($('#ident' + sid).text()); works fine now.

Form data object is not formed on first click when validation fails; only on second click

I'm using a pretty simple form to submit something to our API. I added some form validation using a directive called Angular UI Form Validation. I'm just submitting an object with 2 properties; 'id', and 'points'. I'm running into a strange issue that I've been having a lot of trouble solving and hope I can get some help here.
The form validation works fine. If I enter a value into the input field that doesn't pass, you can't submit the form and a message beneath the input saying why appears. However, if I then remove the incorrect input and put in a correct input, the message is still there. If I click on the submit button, the message disappears. If I click the submit button again, it submits. I've noticed, however, that if I just press the enter key it submits right away.
I threw some console.log's in there, and it looks like the problem is that a formData object isn't created on the first click; only on the second. Here is the html:
<form name="pointsField">
<p><input type="number" ng-model="formData.points"
validation-only-numbers="true"
validation-field-required="{message:'Points value is required.',value:true}"
min="0"/></p>
<p><button class="btn btn-success" type="button" ng-click="updatePoints(pointsField)" ng-disabled="loading">
<span ng-if="loading"><i class="fa fa-circle-o-notch fa-la fa-spin"></i></span>Update Points
</button></p>
</form>
And here is the Javascript (keep in mind that the formData object is created when the controller is initialized, and it is just an empty object):
$scope.updatePoints = function(formData) {
console.log('formData ', formData);
$scope.$broadcast('runCustomValidations');
if(formData.$invalid){
return;
}
var pointsObject = {
"id": $scope.userId,
"points": $scope.formData.points
};
$scope.loading = true;
User.updateUserPoints(pointsObject).then(function(response) {
if(response.success) {
Notification.now.success(response.message);
$scope.loading = false;
} else {
Notification.now.error(response.message);
$scope.loading = false;
}
}, function(reason) {
Notification.now.error(reason.message);
$scope.loading = false;
});
};
If anyone can help me out I'd be eternally grateful. Thank you!
try adding novalidate in your form tag if this does not work dont use angular ui Form validation just use below format to validate .
<form name="pointsField" novalidate>
<input type="text" id="username" name="username" placeholder="Email Address"
ng-model="user.username" autocomplete="off" required >
<span class="text-danger" ng-show="pointsField.username.$dirty && pointsField.username.$invalid">
<span ng-show="pointsField.username.$error.required">Email Address is required</span>
</span>
<button type="submit" class="submit center" ng-disabled="pointsField.$invalid || dataLoading ">
<form>

AJAX and submit button on form interaction

I'm creating a simple website and a html page on it which contains a table that shows products. I load this table using AJAX and it work properly. Here is a screenshot:
Under the table I have buttons which perform CRUD operations using AJAX.
They communicate to a php script on a server outside of my domain using GET method.
When I click on Add product it opens a form with a button that whose onclick event calls a function which adds a product using AJAX. But, when I click, the whole page reloads and the product is not added. If I put the value that says wheter the call is async to false, it works as intended and the product is added to the table, however that is not the point of AJAX.
This is my code for adding a product(delete and update are almost the same).
<div id="addProductPopup">
<div id="popupContact">
<form id="form" method="post" name="form">
<img id="close" src="/servis/Resursi/Slike/close.png" onclick ="hide('addProductPopup');">
<h2>Dodavanje proizvoda</h2>
<hr>
<input id="name" name="naziv" placeholder="Naziv proizvoda" type="text" required>
<input id="kolicina" name="kolicina" placeholder="Količina proizvoda" type="text" required>
<input id="url" name="url" placeholder="URL slike" type="text" required>
<input type="submit" value="Pošalji" class="popupButtons" onclick="addProduct()">
</form>
</div>
When I click on submit this function is called:
function addProduct(){
var isValid = true;
var url = "http://zamger.etf.unsa.ba/wt/proizvodi.php?brindexa=16390";
var amount = document.form.kolicina.value;
var naziv = document.form.naziv.value;
var slikaurl = document.form.url.value;
var validity = validateFields(naziv, slikaurl, amount);
if(!validity) return false;
var product = {
naziv: naziv,
kolicina: amount,
slika: slikaurl
};
var requestObject = new XMLHttpRequest();
requestObject.onreadystatechange = function(event) {
if (requestObject.readyState == 4 && requestObject.status == 200)
{
loadProducts();
event.preventDefault();
}
}
requestObject.open("POST", url, true);
requestObject.setRequestHeader("Content-type","application/x-www-form-urlencoded");
requestObject.send("akcija=dodavanje" + "&brindexa=16390&proizvod=" + JSON.stringify(product));
}
It is because you are not preventing the default action of the submit button click.
You can return false from an event handler to prevent the default action of an event so
<input type="submit" value="Pošalji" class="popupButtons" onclick="addProduct(); return false;">
But since you have a form with a submit button, I think it will be better to use the submit event handler like
<form id="form" method="post" name="form" onsubmit="addProduct(); return false;">
....
<input type="submit" value="Pošalji" class="popupButtons">
Your problem is that your submit button still executes a real submit. You could change your addProducts method. The method have to return false to prevent the real submit.
Submit button performs default Submit action for HTML code.
Try to change Submit tag into Button tag. Or after AddProduct() in OnClick JS Action put
return false;
Simple Change put input type="button" instead of tpye="submit"
<input type="button" value="Pošalji" class="popupButtons" onclick="addProduct()">

required attribute on textbox in html doesn't work

I have a popover with a form inside. And It is already out and ready for submission, here is the code for the popover
<div id="popover-head" class="hide">Add new subject</div>
<div id="popover-content" class="hide">
<form class="form-inline" id="pop-form" method="POST" action="../admin/module_add_subject.do">
<div class="form-group">
<!-- This input is what i'm talking about -->
<input type="text" name="subjectName" id="subject-name" required="required" pattern="^[\S\s]{3,25}[A-z]+$" title="Only accept alphabet characters and length is minimum of 3 and max of 25 " placeholder="Subject name.."/>
<button class="btn btn-primary" type="button" id="add-subject" ><i class="icon-white icon-ok"></i></button>
</div>
<p></p>
<p style="color:red" id="error-message"></p>
</form>
</div>
The input above I'm sure the regex is working. When I change the button to submitthe required is working perfectly fine but when I change it back to button then it is not working again.
The reason why my submit button is a type="button" because of this code:
$(document).on('click', '#add-subject', function(e) {
$.post('../admin/module_check_subject.do', { subjectName: $('#subject-name').val() },
function( data ) {
// if data from the database is empty string
if( $.trim( data ).length != 0 ) {
// hide pop-over
$('#popover').popover('hide');
// submit form
$('#pop-form').submit();
} else {
$('#error-message').text('Subject already exist.' );
}
}
})
.fail( function () {
bootbox.alert('Failed to check, please try again later.');
});
});
What I'm doing is on submit i'll check out first in my database if the input text in the textbox exist in the database, then if the text exist the database stop the submission of the form and display error at the p tag
By the form submission algorithm, validation is not performed when a form is submitted using the submit() method. The idea is, more or less, that when you submit a form with a script, your script should also carry out any checks deemed necessary.
Within your script, you can call the checkValidity() method to carry out the normal validation that would be performed if the form were submitted with a submit button. Note that it performs static validation only.

Categories