Form will not submit and gives error message - javascript

I have a form that contains clothing sizes. When a user selects a size, they are able to submit the form.
My issue is that the user is able to submit the form whether or not they have selected a size. The code is much more complicated but below is a break down of the form, with the add to bag button below.
<form>
<ul>
<li>
<ul>
<li class="size-value"></li>
<li class="size-value"></li>
<li class="size-value"></li>
<li class="size-value"></li>
</ul>
</li>
</ul>
</form>
<div class="mt10">
<input type="submit" class="modalAddToBagButton">
</div>
When a user selects a size, the class selected is added, so it would read class="size-value selected". This function is working fine. In my .js file I would like to add an if/else statement, where if an <li class="size-value"> has been given the class selected (the user has clicked this size), then the form will be submitted, however if NO <li> has the class selected, the form will throw an error message. Below is the section of my function that I believe I should add the if/else statement:
}).on('click', '.modalAddToBagButton', function(e) {
e.preventDefault();
// Add if/else statement here. if list items have a class selected, form can be submitted. if no list items have class selected, then display this error message.
$(this).closest("#dialog-addToBag").find('form').submit();
});
My question is: How do I write this if/else statement? I am not sure how to access the form and list items from my input button, since they are outside the div and are quite nested, and to listen for if any of the list items have been given the class selected so that the form can be submitted, and if not to throw an error message. Can anyone help with this?
UPDATE:
This function works in not submitting the form and displaying the error message when no size is selected, however even when a size is selected the error message still appears and the form will not submit. Can anyone figure out why?
.on('click', '.modalAddToBagButton', function(e) {
e.preventDefault();
var x = document.getElementsByClassName("es-value");
var i = x.length;
var selected = false;
while (i--) {
if (x[i].hasAttribute("selected")) {
selected = true;
}
}
if (selected == false) {
//Displays error
$("#errormessage").show();
} else {
$(this).closest("#dialog-addToBag").find('form').submit();
}
});

.on('click', '.modalAddToBagButton', function(e) {
e.preventDefault();
$form = $(this).closest("#dialog-addToBag").find('form');
if( $( ".size-value.selected" ).length ) { //ho
$form.submit();
} else {
$("#errormessage").show();
}
});
Try this one

How about
<div id="errorDiv"></div>
And inside your javascript function
}).on('click', '.modalAddToBagButton', function(e) {
e.preventDefault();
var x = document.getElementsByClassName("size-value");
var i = x.length;
var selected = false;
while(i--)
{
if (x[i].hasAttribute("selected"))
{
selected = true;
}
}
if(selected == false)
{
//Displays error
document.getElementById("errorDiv").innerHTML = "Please select a size.";
} else {
//Submit form
$(this).closest("#dialog-addToBag").find('form').submit();
}
});

This is how I would modify your HTML:
<form id="clothes-sizes">
<ul>
<li>
<ul>
<li class="size-value"></li>
<li class="size-value"></li>
<li class="size-value"></li>
<li class="size-value"></li>
</ul>
</li>
</ul>
<div class="mt10">
<input type="button" class="modalAddToBagButton">
</div>
</form>
And this is my jQuery that you can adapt, above I gave your form an id and using it in my jQuery below to locate it. I've also change the button type="button" and have moved it inside the <form>...</form> tag...
var form = $("#clothes-sizes");
var btn = form.find(".modalAddToBagButton");
btn
.unbind("click")
.bind("click", function ()
{
var selectedSizes = form.find("ul li.selected");
if (!selectedSizes.length)
{
alert("Please select a size.");
return false;
}
form.submit();
});

I modified your code a little bit :
$('.modalAddToBagButton').on('click', function(e) {
e.preventDefault();
var x = document.getElementsByClassName("size-value");
var i = x.length;
var selected = false;
while(i--) {
if (x[i].hasAttribute("selected")) {
selected = true;
}
}
console.log('selected: ',x[0].innerText);
if(selected == false) {
$("#errormessage").show();
} else {
$( "#dialog-addToBag").submit();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<form>
<ul>
<li>
<ul>
<li class="size-value">1</li>
<li class="size-value" selected>2</li>
<li class="size-value">3</li>
<li class="size-value">4</li>
</ul>
</li>
</ul>
</form>
<div class="mt10">
<input type="submit" class="modalAddToBagButton">
</div>
See if this helps.

Related

Why do my links on the search bar results not work when clicking on them?

JavaScript
window.addEventListener("onload", function(e){
document.querySelector('searchbar').addEventListener('click', search_album()) //adds a listener for the click event, which runs the function search_album()
document.querySelector('searchbar').addEventListener('blur', hide_results()) //adds a listener for the blur event, where the user loses focus from the input field, running the function hide_results()
});
function search_album() { //function to find the album via search bar
let input = document.getElementById('searchbar').value //input is the searchbar value
input = input.toLowerCase(); //turned into lowercase
let x = document.getElementsByClassName('albums'); // and x is the list of albums with the same class name
for (i = 0; i < x.length; i++){ //looping around for the number of albums in the list found in the php page
if (!x[i].innerHTML.toLowerCase().includes(input)) { //checking that the value entered is not found in the list of albums in the php page
//do not display the list of items that matches
}
else{
x[i].style.display = 'list-item'; //display the list of items that matches
}
}
}
function hide_results() { //function to run when the user click anywhere else in the page, not in the input field
let listItems = document.getElementById('list');
listItems.style.display = 'none'; //hide the results list
document.getElementById("searchbar").value = ""; //empty input field
}
HTML Code
<input id="searchbar" type="text" name="search" placeholder="Search Something..."
onkeyup="search_album()" onblur="hide_results()">
<ol id="list">
<li class="albums" id="#red">Red - Taylor Swift</li>
<li class="albums" id="#allartists">All Artists</li>
<li class="albums" id="#allalbums">All Albums of all Artists</li>
<li class="albums" id="#taylor">About Taylor Swift</li>
<li class="albums" id="#taylor">Taylor Swift Albums</li>
<li class="albums" id="#gigs">Upcoming GIGS</li>
</ol>
I was trying to make a searchbar so the user could enter any key and matching results would start to show up based on if the letter they entered is found in the word, hiding the results when the user clicks outside of the searchbar, showing the results again if inputting letters again, and allowing this process to repeat.

I want to include validation on certain fields. The validation should show messages only when a checkbox is checked

I want to include validation on certain fields. The validation should show messages only when a checkbox is checked. I am trying to achieve this in Angular
form.cshtml
<input type ="checkbox" ng-click = "mainControl.reportUpdates()">
<input type = "text" date-validator = "type.date">
<ul messages = "mainform['date'+$index].$error">
<li ng-message="required"> Required</li>
<li ng-message = "maxdatevalidator">Date cannot be greater than today
</li>
<ul>
App.js
_module.directive('dateValidator', ['$rootScope','$parse',function($rootscope,$parse)])
{
function maxDate(date)
{
var today = new Date();
if(date!=null)
return date>today
else
return true
}
return
{
require: 'ngModel',
link : function(scope,element,attrs,ctrl)
{
scope.$watch(attrs.ngModel,function(newValue,oldValue))
{
if(newValue!=oldValue)
{
var check_date=maxDate(newValue)
ctrl.setValidity('maxdatevalidator',check_date) ;
}
}
}
}
}
I would put an ng-show on the ul showing only when the checkbox is true.
First you'll need an ng-model for the checkbox:
<input type="checkbox" ng-click="mainControl.reportUpdates()" ng-model="reportUpdates">
Then you can add then ng-show to the ul:
<ul messages="mainform['date'+$index].$error" ng-show="reportUpdates">

Validate checkbox with AngularJs

Again i'm having trouble with checkboxes. I'm getting info from an API and showing like checkbox. The problem comes when i'm triying to add a validation. This is a part of my code:
(function() {
'use strict';
var fact = {
templateUrl: './app/components/fact.components.html',
controller: factCtrl
};
angular.module('fApp').component('odcFacturas', fact);
factCtrl.$inject = ["$scope", "couponApi"];
function factCtrl($scope, couponApi) {
var vm = this;
vm.clientOrder = null;
vm.all = false;
vm.sendData = function() {
vm.apiData = couponApi.get({
idOrder: vm.idOrder
}).$promise.then(function(data) {
for (var i = 0; i < data.Response.length; i++) {
data.Response[i].Select = vm.all;
}
vm.coupons = data.Response;
vm.combo = data.Response.length > 0;
});
}
Here i call the info, and the next part of my code check all the checkboxes:
vm.selectAll = function() {
for (var i = 0; i < vm.coupons.length; i++) {
vm.coupons[i].Select = vm.all;
}
if (vm.all == 0) {
alert("Select at least one coupon");
}
}
How can I trigger three validations with a submit button? I mean: what I want to do is validate three cases:
if the checkbox "select all checkboxes" is checked, submit
if there's no selected checkboxes, show the alert message
if there's at least one checkbox (or 'n' checkboxes) selected,
submit
On the HTML view i have this:
<div class ="container-fluid">
<div class="row">
<div class="col-md-6">
<div class="cbx input-group">
<div class="checkbox" name="imtesting" ng-show="$ctrl.coupons.length > 0">
<label><input type="checkbox"
ng-show="$ctrl.coupons.length > 0"
name="allCoupons"
ng-model="$ctrl.all"
ng-click="$ctrl.selectAll()"/>Select all coupons</label>
<ul>
<li ng-repeat="c in $ctrl.coupons">
<input type="checkbox"
name="couponBox"
ng-model="c.Select"
ng-click="$ctrl.result()"
required/>{{c.CodeCoupon}}
<br>
</li>
</ul>
<label class="label label-danger" ng-show="submitted == true && !ctrl.newTest()">Select at least one coupon</label>
</div>
</div>
</div>
</div>
Hope you can help me.
Thanx in advance.
You can use the Select property from each coupon object like
vm.canSubmit = function() {
for(var i = 0; i< vm.coupons.length; i++)
{
if (vm.coupons[i].Select) {
return true;
}
}
return false;
}
Redo the way you are handling your selectsAll function. When you are using angular there is a thing called scope.$apply that is actually running which tells the dom to update if the object or properties have changed. Sometimes if you use for loops the way you are using them it wont register a change.
Try this and it should work:
vm.selectAll = function()
{
vm.all = !vm.all;
vm.coupons.forEach(function(o){
o.Select = vm.all;
})
}
vm.submit = function(){
var checked = 0;
vm.coupons.forEach(function(o){
if(o.Select === true)
checked +=1;
})
if(vm.all || checked > 0){
//submit here
}
else if(checked === 0){
//error
}
}
This will work both ways. If checked it will check all and if unchecked it will uncheck all. That validation will work for all three scenarios.

AngularJS ng-repeat with checkbox and filter

I have ng-repeat list, and I need to filter that list with checkbox. In checkbox I have three value, ERROR, WARNING, SUCCESS. If I check ERROR, show only error, if I check ERROR and WARNING show error and warning, same with success. But problem is, when I check ERROR box, list show only data with error, but when I check WARNING, they show all data in list, not only ERROR and WARNING data. For better explanation here is
> http://jsfiddle.net/ADukg/12574/
It's because of your toggleFilter() function
$scope.toggleFilter= function(filterValues) {
if ($scope.filterValue == undefined) {
$scope.filterValue = filterValues;
} else {
delete $scope.filterValue;
}
};
What is does:
When there is no filter, set the selected filter
When there is a filter, delete the current filter
So when you check ERROR, it sets ERROR as filter, but when you then click WARNING too, it triggers the else, and removes the current selection.
When you change your else to:
else {
delete $scope.filterValue;
console.log($scope.filterValue);
}
You can see it logs undefined when selecting more than 1 filter.
Because there is no any solution for this, here is my code how I fix this.
<div class="nav">
<div ng-repeat="filter in filters" ng-class="{sel: selection.indexOf(filterValue) == selected}">
<span class="filters_ct_status"></span>
<div ng-repeat="filterValue in filter.lists" style="float:left; padding: 5px">
<input type="checkbox" value="{{filterValue}}" ng-model="checked" ng-checked="selection.indexOf(filterValue) > -1" ng-click="toggleSelection(filterValue)">
<img ng-if="filterValue == 'Success'" src="assets/img/success.png" alt="success"/>
<img ng-if="filterValue == 'Warning'" src="assets/img/warning.png" alt="warning"/>
<img ng-if="filterValue == 'Error'" src="assets/img/error.png" alt="Error"/>
</div>
</div>
</div>
<div class="table_bench_info logBox" style="overflow-y: auto; height: 250px;">
<div class="list" ng-repeat="list in lists">
<span ng-if="listaFiltera.indexOf(list.class) !== -1">{{list.description}}</span>
</div>
</div>
and there is controller
$scope.filterValue = [];
// toggle selection for a given employee by name
$scope.toggleSelection = function(valueFilter) {
var idx = $scope.filterValue.indexOf(valueFilter);
if (idx > -1) {
$scope.filterValue.splice(idx, 1);
if($scope.filterValue.length == 0){
return $scope.listaFiltera = ['Error','Warning','Success'];
}else{
$scope.listaFiltera = $scope.filterValue.map(function(x) {
return x;
});
}
} else {
$scope.filterValue.push(valueFilter);
$scope.listaFiltera = $scope.filterValue.map(function(x) {
return x;
});
}
};
$scope.filters = [
{
lists: ['Error','Warning','Success']
}
];
We need push checked checkboxes to the array. And splice unchecked checkboxes from the array. Also, we need to check $scope.filterValue.length if we want multiple filters.

Unobtrusive validation fails even before my javascript call to submit

I have an ASP.NET MVC application with a form defined as:
#using (Ajax.BeginForm("Identify", "Employee", new AjaxOptions()
{
HttpMethod = "POST",
OnSuccess = "Identify.OnSuccess(data, status, xhr)",
OnFailure = "Identify.OnFailure(xhr, status, error)"
}, new { id = "identifyForm"}))
{
<div id="employeeIdContainer">
#Html.LabelFor(m => m.IdEmployee) : <br/>
#Html.TextBoxFor(m => m.IdEmployee, new {#type = "number", #Id = "IdEmployee"})
<span class="validation">
#Html.ValidationMessageFor(m => m.IdEmployee)
</span>
</div>
<div id="pinContainer">
#Html.LabelFor(m => m.Pin) : <br/>
#Html.PasswordFor(m => m.Pin, new {#type = "number", #maxlength = "4", #Id = "Pin"})
<span class="validation">
#Html.ValidationMessageFor(m => m.Pin)
</span>
</div>
<div>
<input class="validate" type="submit" value="Submit" name="identifyButton"/>
</div>
<div id="keyboardContainer">
<ul id="keyboard">
<li class="number">1</li>
<li class="number">2</li>
<li class="number">3</li>
<li class="validate">Submit</li>
<li class="number line">4</li>
<li class="number">5</li>
<li class="number">6</li>
<li class="delete">Corriger</li>
<li class="number line">7</li>
<li class="number">8</li>
<li class="number">9</li>
<li class="number line hidden"></li>
<li class="number">0</li>
<li class="number hidden"></li>
</ul>
</div>
}
Inside the form I have a ul that I styled as a keyboard and this keyboard has an li that I want to use as a submit button, the one with the validate class. This isn't a regular submit button, but how do I submit the form in this case? I tried the following in javascript:
$("#keyboard li.validate").click(function () {
if ($("#identifyForm").valid()) {
$("#identifyForm").submit();
}
});
...but for some reason, before this javascript code is even called, the #Html.PasswordFor textbox gets erased and the validation kicks in saying that I need to enter a valid pin number (even when I just entered a valid one).
I have jQuery code that updates the EmployeeId and Pin number as the user types in the keyboard. I'm starting to think that the Unobtrusive validation mechanism does not see that these values have been updated and so it thinks that the Pin number is still empty. Here is the jQuery code if it helps:
var keyboard = $(function () {
var currentInput = $("#IdEmployee");
$("#Pin").on("focusin", function() {
currentInput = $("#Pin");
});
$("#IdEmployee").on("focusin", function() {
currentInput = $("#IdEmployee");
});
$('#keyboard li').click(function () {
var $this = $(this),
character = $this.html();
if ($this.hasClass('delete')) {
var html = currentInput.val();
currentInput.val(html.substr(0, html.length - 1));
return false;
}
currentInput.val(currentInput.val() + character);
});
$("#keyboard li.validate").click(function () {
if ($("#identifyForm").valid()) {
$("#identifyForm").submit();
}
});
$("#IdEmployee").focus();
});
Your $('#keyboard li').click(function () { is setting the current input to the text value of the associated li element.
In the case of <li class="validate">Submit</li> it is setting the value of the current numeric input to the value "Submit" which is not a valid number, so validation fails. And because its invalid, the contents are cleared (that is the default behavior of the HTML5 control)
You can make this work by modifying your script to
$('#keyboard li').click(function () {
var $this = $(this),
character = $this.html();
if ($this.hasClass('validate')) {
return;
} else if ($this.hasClass('delete')) {
var html = currentInput.val();
currentInput.val(html.substr(0, html.length - 1));
return false;
}
currentInput.val(currentInput.val() + character);
});
or modify the selector to exclude the li with class="validate" element
$('#keyboard li:not(.validate)') {
Side note: Its not necessary to add new { #Id = "IdEmployee"} to your controls. Your just overwriting the id attribute with the value that it already is.

Categories

Resources