I am trying to parse a dynamically inserted form to add the jQuery unobtrusive validation.
I have the following AJAX function which is executed when the user is searching:
function search(el)
{
var $this = $(el);
var $form = $this.closest("form");
var url = $form.attr("action");
$results = $("#pnlSearchResults");
$.ajax({
type: "POST",
url: url,
data: $form.serialize()
})
.done(function(data){
$results.html('');
$results.html(data);
var $editForm = $results.find("form.edit-form");
$editForm.removeData("validator");
$editForm.removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse($editForm);
});
}
This inserts an editable form for the returned entity into a <div> on the page which looks like this. I have two fields which are required, but when I remove the values from those fields the "Required" validation does not fire. It only seems to occur when:
I delete the values.
Take the cursor away from the field.
Enter a new value.
Take the cursor away.
Then delete the new value.
How can I solve this so that the validation occurs when I delete the value the first time?
I found this question, which led me to an answer on this page.
(function ($) {
$.validator.unobtrusive.parseDynamicContent = function (selector) {
//use the normal unobstrusive.parse method
$.validator.unobtrusive.parse(selector);
//get the relevant form
var form = $(selector).first().closest('form');
//get the collections of unobstrusive validators, and jquery validators
//and compare the two
var unobtrusiveValidation = form.data('unobtrusiveValidation');
var validator = form.validate();
$.each(unobtrusiveValidation.options.rules, function (elname, elrules) {
if (validator.settings.rules[elname] == undefined) {
var args = {};
$.extend(args, elrules);
args.messages = unobtrusiveValidation.options.messages[elname];
//edit:use quoted strings for the name selector
$("[name='" + elname + "']").rules("add", args);
} else {
$.each(elrules, function (rulename, data) {
if (validator.settings.rules[elname][rulename] == undefined) {
var args = {};
args[rulename] = data;
args.messages = unobtrusiveValidation.options.messages[elname][rulename];
//edit:use quoted strings for the name selector
$("[name='" + elname + "']").rules("add", args);
}
});
}
});
}
})($);
Usage:
var html = "<input data-val='true' "+
"data-val-required='This field is required' " +
"name='inputFieldName' id='inputFieldId' type='text'/>";
$("form").append(html);
$.validator.unobtrusive.parseDynamicContent('form input:last');
Related
I am trying to make a facebook and twitter style mention system using jquery ajax php but i have a problem if i try to #mention more then one user. For example if i start to type something like the follow:
Hi #stack how are you.
The results showing #stack but if i try to mention another user like this:
Hi #stack how are you. i am #azzo
Then the results are nothing. What i am missing my ajax code anyone can help me please ?
I think there is a regex problem for search user_name. When i write some username after first one like #stack then the ajax request posting this:
f : smen
menFriend : #stack
posti : 102
But if i want to tag my other friend in the same text like this:
Hi #stack how are you. I am #a then ajax request looks like this:
f : smen
menFriend : #stack, #a
posti : 102
So what I'm saying is that apparently, ajax interrogates all the words that begin with #. It needs to do is interrogate the last #mention from database.
var timer = null;
var tagstart = /#/gi;
var tagword = /#(\w+)/gi;
$("body").delegate(".addComment", "keyup", function(e) {
var value = e.target.value;
var ID = e.target.id;
clearTimeout(timer);
timer = setTimeout(function() {
var contents = value;
var goWord = contents.match(tagstart);
var goname = contents.match(tagword);
var type = 'smen';
var data = 'f=' +type+ '&menFriend=' +goname +'&posti='+ID;
if (goWord.length > 0) {
if (goname.length > 0) {
$.ajax({
type: "POST",
url: requestUrl + "searchuser",
data: data,
cache: false,
beforeSend: function() {
// Do Something
},
success: function(response) {
if(response){
$(".menlist"+ID).show().html(response);
}else{
$(".menlist"+ID).hide().empty();
}
}
});
}
}
}, 500);
});
Also here is a php section for searching user from database:
$searchmUser = mysqli_real_escape_string($this->db,$searchmUser);
$searchmUser=str_replace("#","",$searchmUser);
$searchmUser=str_replace(" ","%",$searchmUser);
$sql_res=mysqli_query($this->db,"SELECT
user_name, user_id
FROM users WHERE
(user_name like '%$searchmUser%'
or user_fullname like '%$searchmUser%') ORDER BY user_id LIMIT 5") or die(mysqli_error($this->db));
while($row=mysqli_fetch_array($sql_res,MYSQLI_ASSOC)) {
// Store the result into array
$data[]=$row;
}
if(!empty($data)) {
// Store the result into array
return $data;
}
Looks like you're sending an array which is result of match you in AJAX request.
Though I cannot test it but you can use a lookahead in your regex and use 1st element from resulting array. Negative lookahead (?!.*#\w) is used to make sure we match last element only.
var timer = null;
var tagword = /#(\w+)(?!.*#\w)/;
$("body").delegate(".addComment", "keyup", function(e) {
var value = e.target.value;
var ID = e.target.id;
clearTimeout(timer);
timer = setTimeout(function() {
var contents = value;
var type = 'smen';
var goname = contents.match(tagword);
if (goname != undefined) {
var data = 'f=' +type+ '&menFriend=' +goname[1] +'&posti='+ID;
$.ajax({
type: "POST",
url: requestUrl + "searchuser",
data: data,
cache: false,
beforeSend: function() {
// Do Something
},
success: function(response) {
if(response){
$(".menlist"+ID).show().html(response);
} else {
$(".menlist"+ID).hide().empty();
}
}
});
}
}, 500);
});
I am trying to implement a functionality where a website admin can delete multiple content at once by checking the checkboxes and then clicking the SELECTED button as shown below.
That means I have to submit multiple forms at once and I looked up a workaround online but I can't seem to get it working. Upon clicking the SELECTED button, the deleteRecords() is called. The code's shown below:
function deleteRecords() {
//--- Creating array of selected rows ---
var arrayOfIDs;
arrayOfIDs = $('#table-style').find('[type="checkbox"]:checked').map(function(){
return $(this).closest('tr').find('td:nth-child(2)').text();
}).get();
//-- Declaring variables ---
var delFlagForm; //-- form
var action; //-- form action
var formID; //-- form id
var submitFormStr; //-- string of forms' id's
//--- Creating form for each row selected ---
for (var i = 0; i < arrayOfIDs.length; i++) {
delFlagForm = document.createElement("form"); //-- Creating form
action = "/delete_flag/" + arrayOfIDs[i]; //-- Creating action link
formID = 'form' + i; //-- Creating id (form0, form1, etc)
delFlagForm.setAttribute("id", formID); //-- Assigning id to form
delFlagForm.setAttribute("method", "post"); //-- Assigning method to form
delFlagForm.setAttribute("action", action); //-- Assigning action to form
//--- Creating string of forms' id's
if (i != 0) submitFormStr += ' #' + formID;
else submitFormStr = '#' + formID;
}
//--- Submiting forms at once ---
//-- For the table shown above, submitFormStr = "#form0 #form1"
$(submitFormStr).submit(); // = $('#form0 #form1').submit();
}
So apparently the code displayed above, should be submiting form0 and form1 thus deleting the selected records. But, for some reason, the forms aren't submitted and nothing happens at all.
Can you spot any error?
----------- EDIT - SOLUTION -----------
In order to solve this problem, I tried ignoring the requests by using AJAX and is working now. Here's what the new code looks like:
<script>
function deleteRecords() {
var arr;
arr = $('#table-style').find('[type="checkbox"]:checked').map(function(){
return $(this).closest('tr').find('td:nth-child(2)').text();
}).get();
var delFlagForm;
var action;
var formID;
var submitFormStr;
for (var i = 0; i < arr.length; i++) {
delFlagForm = document.createElement("form");
action = "/delete_flag/" + arr[i];
formID = 'form' + i;
delFlagForm.setAttribute("id", formID);
delFlagForm.setAttribute("method", "post");
delFlagForm.setAttribute("action", action);
ignoreRequest(delFlagForm);
}
}
function ignoreRequest(form) {
var formID = $('#' + form.id);
var action = form.action;
$.ajax({
type: "POST",
url: action, //action
data: formID,
success: function (data) {
location.reload();
},
error: function(jqXHR, text, error){
console.log(error);
}
});
return false;
}
</script>
It is not possible to submit multiple forms simultaneously. This is logical, since the default behavior when you submit a form is that the server's response is loaded as a new page.
Instead, I would recommend that you either change your HTML so that all of the values you need to submit are inside of a single form, or create an object that contains the values you want to submit, and send them to your server using AJAX (http://api.jquery.com/jquery.ajax/) instead.
I'm trying to execute a function that is bound to a form which stops the browser from submitting the form and checks that form for missing fields, and if there aren't any, it proceeds to submit the form via Ajax
The issue is, the page contains many very similar forms with identical fields, only with unique numbers after the ID for each form element. I want to pass that number to the function that is bound to the relevant form, however when I initialise any variable other than the 'event' variable, the form submits and ignores event.preventDefault(); AND/OR return false;
Here's a simple test:
http://jsfiddle.net/q3mae60g/
Here's the code:
JS:
$('#contact-form1').submit( submitForm("1") );
function submitForm(formId,event) {
var contactForm = $(this);
var forename = '#contact-forename' + formId;
var surname = '#contact-surname' + formId;
var email = '#contact-email' + formId;
var tel = '#contact-tel' + formId;
if ( !$(forename).val() || !$(surname).val() || !$(email).val() || !$(tel).val() ) {
$('.form-status').removeClass("current-status");
$('.contact-incomplete').addClass("current-status");
} else {
$('.form-status').removeClass("current-status");
$('.contact-sending').addClass("current-status");
$.ajax( {
url: contactForm.attr( 'action' ) + "?ajax=true",
type: contactForm.attr( 'method' ),
data: contactForm.serialize(),
success: submitFinished
} );
}
return false;
}
It seems like the problem lies in the attempt to pass a variable to the function.
.submit() need a function reference. What you are doing is calling a function that return the value false. It is like doing :
$('#contact-form1').submit( false );
Which does nothing.
What you can do is to pass an anonymous function that call your function. Something like that :
$('#contact-form1').submit( function(e){
e.preventDefault();
submitForm.call(this, "1", e);
});
I am working on a Plugin for WordPress and am having issues with the js code below executing the $.post.
The js is called, form validation takes place, the form inputs are serialized into post data correctly, the $.post just doesn't execute.
The form is being posted from the Admin, currently I can't get the .submit action to work so am using .click to execute the js function. This may be related to the issue, I am not sure... The form will load without submitting if I use the .submit action, versus using the .click action... never had this issue before and it is pretty frustrating to say the least.
Here is the code:
jQuery(document).ready(function($) {
$("#edit_member_submit").click( function() {
// define
var numbers = /^[0-9]+$/;
var referrer_id = $("#referrer_id").val();
// Validate fields START
if( !referrer_id.match(numbers) ) {
alert("Please enter a numeric value");
return false;
}
// Validate fields END
$("#ajax-loading-edit-member").css("visibility", "visible");
// Convert to name value pairs
// Define a data object to send to our PHP
$.fn.serializeObject = function() {
var arrayData, objectData;
arrayData = this.serializeArray();
objectData = {};
$.each(arrayData, function() {
var value;
if (this.value != null) {
value = this.value;
} else {
value = '';
}
if (objectData[this.name] != null) {
if (!objectData[this.name].push) {
objectData[this.name] = [objectData[this.name]];
}
objectData[this.name].push(value);
} else {
objectData[this.name] = value;
}
});
return objectData;
};
var data = $("#edit_member_form").serializeObject(); //the dynamic form elements.
//alert(JSON.stringify(data));
data.action = "edit_member_info"; //the action to call
data._ajax_nonce = custajaxobj.nonce; // This is the name of the nonce setup in the localize_script
// Define the URL for the AJAX to call
var url = custajaxobj.ajaxurl;
//alert( JSON.stringify( data ) );
//alert( JSON.stringify( url ) );
$.post(url, data, function(response) {
$("#ajax-loading-edit-member").css("visibility", "hidden");
alert(response);
});
return false;
});
});
Seems like the last section is having issues:
$.post(url, data, function(response) {
$("#ajax-loading-edit-member").css("visibility", "hidden");
alert(response);
});
$.post( "ajax/test.html", function( data ) {
$("#ajax-loading-edit-member").css("visibility", "hidden");
alert(data);
});
I have this HTML list
<ul id='usernameList'>
<li class='username'>John</li>
<li class='username'>Mark</li>
</ul>
and a form to add new names via AJAX, multiple add separated by commas. The response is a list with the names
[{name:David, newUser:yes}, {name:Sara, newUser:yes}, {name:Mark, newUser:no}]
I'm trying to insert this names sorted alphabetically in the list, like this example https://jsfiddle.net/VQu3S/7/
This is my AJAX submit
var form = $('#formUsername');
form.submit(function () {
$.ajax({
type: form.attr('method'),
url: form.attr('action'),
data: form.serialize(),
dataType: "json",
beforeSend: function () {
//
},
success: function (data) {
var listUsernames = $('#usernameList');
var numUsernames = listUsernames.children().length;
$.each(data, function(i, user) {
if(user.newUser == "yes"){
var htmlUser = "<li class='username'>" + user.name + "</li>";
var added = false;
$(".username", listUsernames).each(function(){
if ($(this).text() > user.name) {
$(htmlUser).insertBefore($(this));
added = true;
}
});
if(!added)
$(htmlUser).appendTo($(listUsernames));
}
// HERE I DO alert('numUsernames')
// I get the same number of users before sending form
// How can I update here the value of listUsernames and numUsernames?
});
}
});
return false;
});
My question is, how I can update the value of listUsernames and numUsernames after adding an item?
You just need to update numUsernames at that point.
Add this where your comments are:
numUsernames = listUsernames.children().length;
listUsernames already has the updated children, as it's a reference to the parent element.
Edit: Re: your comment below:
This should probably work:
$(".username", listUsernames).each(function(){
if ($(this).text() > user.name) {
$(htmlUser).insertBefore($(this));
added = true;
return false; // stop `.each` loop.
}
});
First you don't need a double jQuery wrapping:
$(htmlUser).appendTo($(listUsernames));
listUsernames is already a jQuery object, so try:
$(htmlUser).appendTo(listUsernames);
And after every adding, you can update the numUsernames variable with:
numUsernames = listUsernames.children().length;
but this is not necessary because you can always access listUsernames.children().length in the success handler.
I update your JSFiddle
var listUsernames = $('#usernameList');
var numUsernames = listUsernames.children().length;
var data = [{name:'David', newUser:'yes'}, {name:'Sara', newUser:'yes'}, {name:'Mark', newUser:'no'}]
$.each(data, function(i, user) {
if(user.newUser == "yes"){
var htmlUser = "<li class='username'>" + user.name + "</li>";
var added = false;
$(".ingredient", listUsernames).each(function(){
if ($(this).text() > user.name) {
$(htmlUser).insertBefore($(this));
added = true;
}
});
if(!added)
$(htmlUser).appendTo($(listUsernames));
}
// HERE I DO alert('numUsernames')
// I get the same number of users before sending form
// How can I update here the value of listUsernames and numUsernames?
});