Unobtrusive validation fails even before my javascript call to submit - javascript

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.

Related

how to get an array post values

In my script, I have input fields which are added dynamically. I have to get all input values using php but the problem in that $_POST['poids'] give me just the first value of input array, so just the first element of the array poids. This is my code:
$(function() {
var max_fields = 10;
var $wrapper = $(".container1");
var add_button = $(".add_form_field");
$(add_button).click(function(e) {
e.preventDefault();
const vals = $("> .item input[name^=poids]", $wrapper).map(function() {
return +this.value
}).get()
const val = vals.length === 0 ? 0 : vals.reduce((a, b) => a + b);
if ($("> .item", $wrapper).length < max_fields && val < 100) {
const $form_colis = $(".item").first().clone();
$form_colis.find("input").val("");
$wrapper.append($form_colis); //add input box
} else {
var err_msg = 'limit riched';
//alert(err_msg);
window.alert(err_msg);
}
});
$wrapper.on("click", ".delete", function(e) {
e.preventDefault();
$(this).parent('div').remove();
})
});
<div class="container1" style="min-height:200px">
<button class="add_form_field">Add New Field ✚</button>
<form method="post" action="postForm.php">
<div class="item">
<input type="text" placeholder="Poids" name="poids[]">
<input type="text" placeholder="Longueur" name="longueurs[]">
<input type="text" placeholder="Largeur" name="largeurs[]">
<input type="text" placeholder="Hauteur" name="hauteurs[]">
Delete
</div>
<button type="submit" name="" class="btn btn-danger btn-responsive "> Send </button></center>
</a>
</form>
</div>
to get post (postForm.php):
$poids = $_POST['poids'];
foreach($poids as $poid) {
echo " -->" .$poid;
}
I hope that you undestand what I mean.
Thank you in advance
The problem is that you're appending the div with the new input fields to $wrapper, but that's outside the form. You need to put it inside the form.
Change
$wrapper.append($form_colis); //add input box
to
$('.item', $wrapper).last().after($form_colis); //add input box
I'm no PHP expert, but by just browsing the code provided, it seems you're just searching for inputs with a name value of poids.
const vals = $("> .item input[name^=poids]",$wrapper).map(function() { return +this.value }).get()
Then when you create a bew input, you do not append poids to the input name.
const $form_colis = $(".item").first().clone();
$form_colis.find("input").val("");
$wrapper.append($form_colis);
Therefore, you will only find one with your method, and that's this one:
<input type="text" placeholder="Poids" name="poids[]">
So to solve this, inside the $form_colis method, add poids to it I do believe.

I am trying to make a checklist where I can click on the button attributed to each "task" and the single line is removed when it is clicked.

Like the question says. I have been able to rid the entire list with a click of a single button (not what I want), I have been able to click a button and rid just the button but not the text - this is what is giving me the biggest issue.
Any help would be greatly greatly appreciated.
//create the initial todocount variable
var toDoCount = 0;
window.onload = function() {
//user clicked on the add button in the to-do field add that text into the to-do text
$('#add-to-do').on('click', function(event) {
event.preventDefault();
//assign variable to the value entered into the textbox
var value = document.getElementById('to-do').value;
//test value
console.log(value);
var todoitem = $("#to-dos");
todoitem.attr("item-");
//prepend values into the html and add checkmark, checkbox, and line break to make list
var linebreak = "<br/>";
var todoclose = $("<button>");
todoclose.attr("data-to-do", toDoCount);
todoclose.addClass("checkbox");
todoclose.text("☑");
//prepend values to html
$("#to-dos").prepend(linebreak);
$("#to-dos").prepend(value);
$("#to-dos").prepend(todoclose);
toDoCount++;
//to remove item from checklist
$(document.body).on("click", ".checkbox", function() {
var toDoNumber = $(this).attr("data-to-do");
$("#to-dos").remove();
});
});
HTML below
<div class ="col-4">
<!-- To Do List -->
<form onsubmit= "return false;">
<span id = "todo-item" type = "text">
<h4>Add your Agenda Here</h4>
<input id ="to-do" type = "text">
<input id ="add-to-do" value = "Add Item" type = "submit">
</span>
</form>
<div id="to-dos"></div>
</div>
This should work.
//create the initial todocount variable
var toDoCount = 0;
$(function() {
//user clicked on the add button in the to-do field add that text into the to-do text
$('#add-to-do').on('click', function(event) {
event.preventDefault();
//assign variable to the value entered into the textbox
var value = document.getElementById('to-do').value;
//test value
console.log(value);
var todoitem = $("#to-dos");
todoitem.attr("item-");
//prepend values into the html and add checkmark, checkbox, and line break to make list
var linebreak = "<br/>";
var todoclose = $("<button>");
todoclose.attr("data-to-do", toDoCount);
todoclose.addClass("checkbox");
todoclose.text("☑");
//prepend values to html
$("<div/>", {
"class": "to-do-item"
})
.append([todoclose, value, linebreak])
.appendTo($("#to-dos"));
toDoCount++;
//to remove item from checklist
$(document.body).on("click", ".to-do-item", function() {
var toDoNumber = $('.checkbox', this).attr("data-to-do");
$(this).remove();
});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col-4">
<!-- To Do List -->
<form onsubmit="return false;">
<span id="todo-item" type="text">
<h4>Add your Agenda Here</h4>
<input id ="to-do" type = "text">
<input id ="add-to-do" value = "Add Item" type = "submit">
</span>
</form>
<div id="to-dos"></div>
</div>
I found the root issue to be related to how you remove the item. If it is based on the button click, then $(this).remove() simply removes the button.
Consider the following code.
$(function() {
function makeTask(todo) {
var c = $("#to-dos .todo-item").length + 1;
console.log(c, todo);
var item = $("<div>", {
class: "todo-item",
id: "todo-item-" + c
});
$("<button>", {
class: "checkbox todo-item-close",
id: "todo-item-close-" + c
}).html("☑").click(function(e) {
console.log("Remove", $(this).parent().attr("id"));
$(this).parent().remove();
}).appendTo(item);
item.append(todo);
return item;
}
$('form').submit(function(e) {
e.preventDefault();
var task = makeTask($("#to-do").val());
task.appendTo("#to-dos");
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col-4">
<!-- To Do List -->
<form>
<h4>Add your Agenda Here</h4>
<input id="to-do" type="text" />
<input id="add-to-do" value="Add Item" type="submit" />
</form>
<div id="to-dos"></div>
</div>
Here we add the button and assign a click event to that button. Since the button is inside the <div> we need to traverse to the parent element and then remove the entire element.
Since it is in a form, and many users may try to submit the data with Enter, I prefer to use .submit() callback.
Hope that helps.

Form will not submit and gives error message

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.

Form submit programmatically does not invoke inner function

I have the following autocomplete functions. The form gets autosubmitted when a one of suggested values is clicked:
var submitAutocompleteForm = function (event, ui) {
var $input = $(this);
$input.val(ui.item.value);
var $form = $input.parents("form:first");
$form.submit();
};
var createAutoComplete = function () {
var $input = $(this);
var options = {
source: $input.attr("data-source-autocomplete"),
select: submitAutocompleteForm,
};
$input.autocomplete(options);
};
$("input[data-source-autocomplete]").each(createAutoComplete);
This works just fine. The form has this additional hidden input:
<input id="autocomplete" name="autocomplete" type="hidden" value="False" />
Now, I want change submitAutocompleteForm function to change this input's value to true upon submit:
$form.submit(function (e) {
$(this).children('#autocomplete').val(true);
});
but this inner function is never invoked. Even tried with a simple alert inside, this also never gets invoked.
What am I doing wrong?
EDIT:
Html code:
#using (Ajax.BeginForm("LoadBook", new { id = Model.CollectionId }, new AjaxOptions
{
HttpMethod = "POST",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "bookDetailsPlaceHolder",
OnComplete = "animateBookLoad"
}))
{
#Html.Hidden("autocomplete", false)
<div class="form-horizontal">
<div class="form-group form-custom">
<div class="col-md-12">
#Html.TextBox("bookDetails", null, new { #class = "form-control pull-left", #placeholder = "Szukaj tytułu", data_source_autocomplete = Url.Action("Autocomplete") })
<span class="input-group-btn">
<button id="addCopySearchBtn" class="btn btn-default" type="submit">
<span class="glyphicon glyphicon-search"></span>
</button>
</span>
</div>
</div>
</div>
}
<div id="bookDetailsPlaceHolder" style="display:none">
</div>
Also, I noticed that when I manually hit the submit button, the inner function gets invoked... So it seems to me that $form.submit() submits the form (obviously) but the $form.submit(function () { } actually gets invoked when the form is being submitted.
I'll try to specify whan I need:
I need the submitAutocompleteForm function to submit the value in TextBox, but also to change the hidden input's value. I cannot write something like $('#form").on('submit', function () { } as I do not want input's value to be changed when user manually submits the form.
$form.submit(function (e) {
e.preventDefault();
$(this).children('#autocomplete').val(true);
});
This stops the form from sending which means the function below will be able to manipulate the form elements. However this means you do have to AJAX the form data via JavaScript or submit the form again.

How can I populate an input field with a .val()?

I'm trying to edit list items that I have and I want to set the text of the parent section to the form field with .val(). I also want to remove it from the local storage as well, problem is I have no idea how to do this and it doesn't seem to be to popular online because I can't find it anywhere.
This is how I'm bringing in the data through the input form:
function addTodo(form) {
var input = $(form).find('input[name="todo"]').first();
if (input) {
var todo = input.val();
if (Modernizr.localstorage) {
var todo_list = {};
if (localStorage.todos) {
todo_list = JSON.parse(localStorage.todos);
}
var id = +new Date;
todo_list[id] = {
name: todo,
completed: false
};
localStorage.todos = JSON.stringify(todo_list);
drawTodos();
}
input.val('');
}
if ( jQuery.fn.validate ) {
$(form).validate().resetForm();
}
}
How would I select a list item that I've added so that it will end up back in the input feild so I can edit it?
<section>
<h1>List</h1>
</section>
<section id="todo_list">
<header>
<form>
<input type="text" name="todo" placeholder="What do you need to do?" />
<input type="submit" name="add_todo" value="Add To List" />
</form>
</header>
</section>
I have some html generating in a loop within the jquery:
<section class="todo_item" id="item' + id + '"><span id="complete" class="colour complete">Complete</span><span id="incomplete" class="colour incomplete">Incomplete</span><span class="content editable" id="done">' + todo.name + '</span><img src="img/delete.png" /></section>
Why don't you attach a handler to the span that has editable class?
Something like this:
$(document).ready(function () {
$(".content.editable").click(function () {
$("input[name='todo']").val($(this).text());
});
});
Please note, IDs must be unique. It is an error to assign the same ids: 'done', 'incomplete', 'complete' to several sections.

Categories

Resources