jQuery form validation after embedding Html with JS - javascript

I have a website developed within ASP.NET Core MVC (.NET6) + jQuery, Bootstrap. Due to some restrictions, some navigation pages must be embedded dynamically by non-typical way using Ajax request.
$.ajax({
url: link,
type: 'GET',
dataType: 'html',
headers: { 'X-Page-Request': 'true' },
success: function (data) {
var isFullPage = /<!DOCTYPE *html>/i.test(data);
if (!isFullPage) {
$("#contentContainer").empty().append($(data));
}
}
});
Some endpoints return partial views with already rendered HTML and JS code and this code embeds into pages after Ajax request using $("#contentContainer").empty().append($(data));
I need to validate the form and show validation outlines only after click on "Create" button, but validation is triggered even after a click on a bootstrap select element or "Cancel" button. I've already set all necessary options to the validator as default.
The thing is that if the code is originally on the page and doesn't integrate dynamically, form validation works as designed. But if I embed the same code using .append() and $.validator.unobtrusive.parse(), I have unexpected form validation after bootstrap select click or any button click.
Descried issues appear only in case when rendered HTML and JS code was added dynamically using .append(). As a result, elements with .btn class trigger form validation: all buttons, bootstrap select element etc. I need to prohibit this unexpected form validation and validate only using.valid().
Does anybody have any thoughts how to fix that? Thanks in advance!
P.S. I guess it's somehow related to the button element or .btn class.
Embedded code doesn't contain any special things except $.validator.unobtrusive.parse() and looks as usual.
<div id="userModal" class="modal fade" role="dialog" style="display: none;">
<div class="modal-dialog">
<div class="modal-content">
<div class="cl-modal-body modal-body">
<form class="form" id="user1Form">
<div class="row shift">
<div class="col-xs-12">
<div class="flex-align-center">
<label for="name" class="input-name-text-align-right input-name">* Name:</label>
<input for="name" class="form-control" id="userName" name="name" data-val="true" data-val-required="* This field is required." />
</div>
</div>
</div>
<div class="row shift">
<div class="col-xs-12">
<div class="flex-align-center">
<label for="countryId" class="input-name-text-align-right input-name">* Country:</label>
<select for="countryId" class="cl-select-form-control form-control" name="countryId" id="countryId1" data-val="true" data-val-required="* This field is required."></select>
</div>
</div>
</div>
</form>
</div>
<div class="cl-modal-footer">
<button type="button" class="btn cl-modal-button" data-dismiss="modal">Cancel</button>
<button type="button" id="userModalButton" class="btn btn-primary cl-modal-button">Save</button>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$(document).ready(function () {
$.validator.unobtrusive.parse("#userForm");
initCountries();
openUserModal();
});
...
$('#userModalButton').click(function (e) {
if ($("#userForm").valid()) {
...
}
});
...
</script>

Related

AJAX form submitting the wrong row from dynamically generated rows of data

I am currently reading data from a database and displaying the returned data in a table. One column contains the ID of each row, which I pass to a modal like this:
Edit
The modal gets data from another php file I included, using:
require('user_info.php');
The right data for each row is displayed on the modal, as I 'GET' the id passed into the modal, and query the database and display the returned info on a form on the modal. I have been careful to use classes in identifying the form elements, as I intend to submit the form using AJAX. Part of the form is:
<form method="POST" action="">
<div class="row form-group">
<label>User ID</label>
<div class="col-sm-12">
<input name="userid" type="text" class="form-control userid" value="<?php echo $prow['id'];?>">
</div>
<div class="col-md-6">
<label>Name</label>
<input name="name" type="text" class="form-control" value="<?php echo $prow['fullname'];?>">
</div>
<div class="col-md-6">
<label>Folder</label>
<input name="folder" type="text" class="form-control" value="<?php echo $prow['folder'];?>">
</div>
<input type="submit" class="btn form-control modify_user_info" value="Submit Modification">
</div>
The problem now is, no matter which row on the original table I edit and submit through a modal, it is the first row of the table that attempts to get edited. The modals display the right information based on the row selected, but submitting the form on the modal always returns the data on the first row to the php file handling the form submission.
Here's my javascript:
<script>
$(document).ready(function () {
$('.modify_user_info').click(function (e) {
e.preventDefault();
var userid = $('.userid').val();
var email = $('.email').val();
$.ajax
({
type: "POST",
url: "modify_user_info.php",
data: {
"userid": userid,
"email": email,
},
success: function (data) {
$('.result').html(data);
}
});
});
});
PS: Submitting the form without AJAX works fine.
Edit: I need to add that printing the id submitted by the form shows that it is the first row of the table that is submitted, not the selected row.
Change your href tag and modal like this
i hope you are using a foreach loop
then change your href tag and target modal like this
View
and your target modal as
<div style="" class="modal fade mymodal" id="user_id_<?php echo $row['id'];?>" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">

Show error message on Submit button if Radio Button is not clicked

I need to show an error message if No Radio Button is selected in the Model Form. I am getting Values into the radio form and now want to show a message that "Please select a Resume first" if no Resume is selected.
Following is the code for Model form in which I am showing the Radio Button:
<div class="modal fade" tabindex="-1" id="ResumeModal" role="dialog" ng-controller="topCtrl">
<div class="modal-dialog modal-sm">
<div class="modal-content ">
#using (Html.BeginForm("ApplyJob", "PostedJob", FormMethod.Post))
{
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
x
</button>
<h4 class="modal-title">Choose Your Resume</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-12">
<input type="hidden" name="PostedJobId" id="PostedJobById" value="#Model.PostedJobId" />
<input type="hidden" name="CreatedBy" id="CreatedBy" value="#Model.CreatedBy" />
#foreach (var item in NurseOneStop.WebSite.Models.ApplicationSession.CurrentUser.NurseResumeList)
{
<div class="col-md-12 lstCard">
<input type="hidden" name="CheckedResumeId" id="CheckedResumeId" />
<input type="radio" name="RBCheckedResume" style="height: 15px; width: 18px;" onchange="CheckedResume(#item.ResumeId)" /> <span>#item.ResumeName</span>
</div>
}
</div>
<span style="color:Red">{{msg}}</span>
#*<label id="lblMessage" style="color:red"></label>*#
</div>
</div>
<div class="modal-footer">
<span style="color:Red">{{msg}}</span>
<button id="btnSubmitResume" type="submit" class="btn btn-primary pull-right" ng-click="userAlertResumeSubmit()">
Submit
</button>
</div>
}
</div>
</div>
</div>
Below is the code for JavaScript:
<script type="text/javascript">
$(document).ready(function () {
$("#btnShowModal").click(function (){
$("#ResumeModal").modal('show');
});
});
function CheckedResume(id) {
$('#CheckedResumeId').val(id);
console.log($('#CheckedResumeId').val());
};
</script>
This is how I did it on a website recently. Please note, you should swap out the 'UIKit.notification' for something else if you are not using UIKit already on the website.
$('.btnSubmitResume').submit(function(e){
if ($("input[name=RBCheckedResume]:checked").length === 0) {
e.preventDefault();
UIkit.notification({
message: 'Please check at least one box to continue',
status: 'primary',
pos: 'top-right',
timeout: 5000
});
}
});
Also please note, you should not be using an ID within a for loop like id="CheckedResumeId". This will create multiple ID's of the same type and cause issues for you. I'd advise changing this to a class
ID attribute for an HTML element should be unique. In the code snippet which you've shared, duplicate hidden form elements with ID 'CheckedResumeId' will be created which will pollute the HTML DOM. You can take the element outside of foreach and check the code. Like Below
<input type="hidden" name="CheckedResumeId" id="CheckedResumeId" />
#foreach (var item in NurseOneStop.WebSite.Models.ApplicationSession.CurrentUser.NurseResumeList)
{
<div class="col-md-12 lstCard">
<input type="radio" name="RBCheckedResume" style="height: 15px; width: 18px;" onchange="CheckedResume(#item.ResumeId)" />
<span>#item.ResumeName</span>
</div>
}
Here goes the JS to check if radio button is clicked when executing the onsubmit function.
if($('#CheckedResumeId').val().trim() == "") {
//Give an error message to user saying that the radio button is not clicked.
}

Change form input field value with jquery within a bootstrap modal

I have a form within a bootstrap modal. I would like the input fields to display the past values that the user entered the first time they filled out the form, which I am retrieving from a cloudant database. I would like these input fields to be editable so that the user can resubmit the form with any changes they may have. However, I am stuck when trying to display the past information in the input fields. I can't find any reason why these value of the input fields are not being changed.
The javascript that adds my buttons to my boostrap list-group:
var loadIotPanel = function(iotsJSON)
{
for(var iot in iotsJSON)
{
var button = $('<button/>').text(iotsJSON[iot].appID).addClass('list-group-item iot').attr({name:iotsJSON[iot].appID, "aria-label": "Quick View IoT", "data-toggle": "modal", "data-target": "#quick-view-iot-modal", type: "button"});
$('#iot-list').append(button);
}
};
The html where my button will be placed within my list-group:
<div class="row">
<div class="col-lg-4 col-md-6 col-sm-12 col-sm-12 dash-col">
<button name="edit-iots" aria-label="Edit IoTs" data-toggle="modal" data-target="#edit-iots-modal" type="button" class="icon"><span class="glyphicon glyphicon-edit gray"></span></button>
<p class="fancy-font dash-item-title">Your IoTs</p>
<button name="add-iot" aria-label="Add IoT" data-toggle="modal" data-target="#connect-iot-modal" type="button" class="icon"><span class="glyphicon glyphicon-plus gray"></span></button>
<div class="list-group iot" id="iot-list"><!-- buttons will be placed here --></div>
</div>...
The modal that pops up when clicking a button:
<div class="modal fade" id="quick-view-iot-modal">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="quick-view-iot-h4"></h4>
</div>
<div class="modal-body">
<form id="edit-iot-form" method="post">
IoT Name: <br>
<input type="text" name="iot-name" class="iot-value" required><br>
Organization ID: <br>
<input type="text" name="org-id" class="iot-value" readonly required><br>
Authentication Method: <br>
<input type="text" name="auth-method" class="iot-value" value="apikey" readonly><br>
API Key: <br>
<input type="text" name="api-key" class="iot-value" readonly required><br>
Authentication Token: <br>
<input type="text" name="auth-token" class="iot-value" readonly required><br>
</form>
<button name="more" type="button" class="fancy-font page-button">More</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
The javascript that adds the content to modal. It is within a main method that is called when document is ready:
$('.iot').click(
function()
{
var iotName = event.target.name;
getIots(loadIotQuickView, iotName);
$('h4#quick-view-iot-h4.modal-title').text(event.target.name);
});
The getIots() function: (it includes parameter variable=null because I also use it in another part of code where the varaible parameter is not used. This method sends an ajax post to a servlet, which then responds with an array of iot objects)
var getIots = function(callback, variable=null)
{
var iotsJSON = null;
$.post("DashboardServlet", {loadIotPanel: "true"}, function(response)
{
iotsJSON = response;
callback(response, variable);
});
The loadIotQuickView() function: (This is where I believe I am getting problems)
var loadIotQuickView = function(iotsJSON, iotName)
{
var currentIoT = null;
for(var iot in iotsJSON)
{
if(iotsJSON[iot].appID = iotName)
currentIoT = iotsJSON[iot];
}
if(currentIoT == null)
return;
$('.iot-value[name="iot-name"]').attr("value",currentIoT.appId);
};
I've tried numerous jquery selectors but none of the input field values within the form will change. I've stepped through the code and all of my variables have the correct values that its just the last line that's not executing how I want. I am unsure if there is an issue with my jquery selector or if it is something else. Thanks in advance!
UPDATE:
I've tried the following selectors:
$('.iot-value[name="iot-name"]')
$('input[name="iot-name"]')
$('.iot-value')
$('#connect-iot-modal').find('input[name="iot-name"]')
I've also tried adding an id of "edit-iot-name" to my input field:
$('#edit-iot-name')
$('#connect-iot-modal #edit-iot-name')
But none of these have worked, which leads me to believe that it must not be an issue with my selector.
UPDATE:
I've also tried using .val(currentIoT.appID) with all of the previous selectors. Still not working.
I'm not sure why, but adding the id of the modal that my form is in, which is #quick-view-iot-modal, to my selector worked. However for some reason it only works when I use .val() and not when I use .attr(). So the final result is:
$('#quick-view-iot-modal #edit-iot-name').val(currentIoT.appID);
I'm not sure why it is required to add the id of the modal, and I'm not sure why it doesn't work like this:
$('#quick-view-iot-modal #edit-iot-name').attr("value",currentIoT.appID);
But it works! If anyone knows why it only works with this combination, please let me know!
try:
$('.iot-value[name="iot-name"]').val(currentIoT.appId);
Your selector is pretty weird as well. why not just refer to the input by name?
$('input[name="iot-name"]').val(currentIoT.appId);
In your code here:
$('.iot-value[name="iot-name"]')
"iot-name" is a string literal, and it will not evaluate to the value of your iot-name variable.
I'm guessing that you are looking to use the variable's value in your selector, which would look like this:
$('.iot-value[name="' + iot-name + '"]')
I have been struggling with this problem for 3 hours. The realisation that you must reference the object through the modal div is the winner.
I was trying to do 2 things:
populate the href in an <a> button on my modal
set the value of another field using an onChange()
so I end up with:
$("#modal-form #linkbtn").attr("href", url);
$('#modal-form #inputfield").val(newVal);
Thanks so much for this hint.
LISTEN!
i've got a good solution for all of you guys!
$("#exampleModal").modal("show");
$(function () {
$("#exampleModal #ticket_id").val("your_value_variable");
});
try this way after you load your modal show it then use DOM ready event then set your value to it input text and amazingly it works! this is the easiest and simplest way from me

Logging in via modal using AJAX and PHP

to be fair, I'm fairly new in the AJAX area (newbie to be more precise) and i think that i took quite a large bite entering that field.So, I'm struggling for a several days now trying to implement AJAX with my PHP script. Before you flag this question as duplicate please consider that I've tried every posted question from this site and not one solution pop out. That being said, here is what I want to achieve: I want to show some sort of message after PHP script was successful or unsuccessful, something like picture below:
If there was successful show me msg, and redirect me (after 2 sec) to admin site, and if not show me error!
So, here is code for modal form:
<div class="modal fade" id="test" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">test</h4>
</div>
<div class="modal-body">
<form id="myform" method="POST" role="form">
<div class="form-group">
<label for="user">User:</label>
<input name="user" type="text" class="form-control" placeholder="Unesi korisnika">
</div>
<div class="form-group">
<label for="pass">Password:</label>
<input name="pass" type="password" class="form-control" placeholder="Unesi lozinku">
</div>
<div id="error">
<div class="alert alert-danger"> <strong>Error, try again!</strong> </div>
</div>
<div id="thanks">
<div class="alert alert-success"> <strong>Logging in..</strong></div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" id="reset" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-success" id="submitForm">Login!</button>
</form>
</div>
Here is my javascript block of code: Here I tried loging in using my php script but nothing happens, it's only showing me #thanks div when I start typing
$('#test').on('hidden.bs.modal', function () {
$(this).removeData('bs.modal');
$(':input', '#myform').val("");
});
$("#thanks").hide();
$("#error").hide();
$("#myform").click(function (e) {
var url = "login.php";
$.ajax({
type: "POST",
url: url,
data: $('#myform').serialize(),
success:
$("#thanks").show(),
error: function () {
$("#error").show();
}
});
e.preventDefault();
});
Here is my PHP doLogin() function inside myAuth class:
static function doLogin() {
if(
!empty($_POST['user'])
&&
!empty($_POST['pass'])
) {
if(!session_id()) session_start();
// check and retrive user with sended pass
$user = self::_fetchUserWithPassDB();
// if user found log in
if($user) {
// security
$token = md5(rand(100000,999999));
// save token in session
$_SESSION["auth"] = $token;
// save user in session
$_SESSION["user"] = $user[0]["user"];
// save role in session
$_SESSION["role"] = $user[0]["role"];
// postavi validity and token in cookie, session in base
self::_setCookieSessionDBTokenValidity();
// redirect on admin.php
header( "refresh:2;url=admin.php" );
}
else {
header('Location:index.php');
}
if(!$user) {
header("refresh:1;url=index.php" );
}
} // od if POST
and finally here is my login.php
<?php
// login.php
require_once('init.php');
myAuth::doLogin();
?>
Is it problem in in doLogin() function or is there problem with javascript, I really don't know? If there is any help, when I use this script without AJAX it works normal without any problems.
Like this:
<form action="login.php" id="myform" method="POST" role="form">
....<!--rest of the modal form-->
UPDATE 1.
I've tried something like this, but it does not work. Also, I've removed redirect from doLogin () and added in AJAX call but without any luck
$("#myform").submit(function(e) {
var url = "login.php";
$.ajax({
type: "POST",
url: url,
data: $('#myform').serialize(),
success: function() {
$("#thanks").show(), setTimeout(function() {
window.location.href = "admin.php";
}, 2000);
},
error: function() {
$("#error").show();
}
});
e.preventDefault();
});
Try moving
<form id="myform" method="POST" role="form">
outside of
<div class="modal fade" id="test" role="dialog">
i.e.
<form id="myform" method="POST" role="form">
<div class="modal fade" id="test" role="dialog">
...
</div>
</form>
Currently, your HTML is not valid (the start of <form ... lies inside <div class="modal-body"> but the end of it is after the modal-body has ended. Your browser is probably cutting off the <form at the end of modal-body to follow valid HTML.

Issues getting CasperJS to upload image to file field - tried CasperJS fill() and PhantomJS uploadFile()

I'm trying to use CasperJS to upload images to a web-form.
My form looks something like this:
<form action="" method="POST" enctype="multipart/form-data" class="form-vertical">
...
<legend>Campaign Banner</legend>
<div class="control-group image-field ">
<label class="control-label">Now Large</label>
<div class="controls">
<div class="file-field"><input id="id_now_large_image" name="now_large_image" type="file"></div>
<div class="image-preview"></div>
<div class="clear"></div>
<span class="help-inline"></span>
</div>
</div>
<div class="control-group image-field ">
<label class="control-label">Now Medium</label>
<div class="controls">
<div class="file-field"><input id="id_now_medium_image" name="now_medium_image" type="file"></div>
<div class="image-preview"></div>
<div class="clear"></div>
<span class="help-inline"></span>
</div>
</div>
<div class="control-group image-field ">
<label class="control-label">Now Small</label>
<div class="controls">
<div class="file-field"><input id="id_thumbnail_image" name="thumbnail_image" type="file"></div>
<div class="image-preview now-small"></div>
<div class="clear"></div>
<span class="help-inline"></span>
</div>
</div>
The submit button looks like this:
<div class="form-actions">
<button type="submit" class="btn btn-small ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" role="button" aria-disabled="false"><span class="ui-button-text">Save changes</span></button>
</div>
I've put a Gist of the full HTML here: https://gist.github.com/victorhooi/8277035
First, I've tried using CasperJS's fill method:
this.fill('form.form-vertical', {
'now_large_image': '/Users/victor/Dropbox/CMT Test Resources/Test Banners/Default Banners/now_large.jpg',
}, false);
this.click(x('//*[#id="content-wrapper"]//button/span'));
I also did a this.capture(), and I saw that the file field had been filled in:
I'm not using the fill method's inbuilt submit, but I'm clicking on the submit button myself:
this.click(x('//*[#id="content-wrapper"]//button/span'));
I then do another capture, and I can see that the form has been submitted:
However, the image doesn't seem to have been uploaded at all.
I've also tried using PhantomJS's uploadFile() method:
this.page.uploadFile('input[name=now_large_image]', '/Users/victor/Dropbox/CMT Test Resources/Test Banners/Default Banners/now_large.jpg');
and then clicking on the submit button as well.
Same issue - the form field gets filled in - however, the image itself doesn't seem to get submitted.
Any ideas on how I can get the images to upload correctly here?
Since you are filling and submitting successfully, try a Wait command on the click.
casper.then(function() {
//+++ form fill here
//waits 1 sec
this.wait(1000, function() {
this.click(x('//*[#id="content-wrapper"]//button/span'));
});
});
Try this.
casper.thenOpen('about:blank', function(){
this.evaluate(function(){
var action = 'upload.php'
var html = '<form action="'+action+'" method="post" enctype="multipart/form-data">'
html += '<input type="file" name="files[]" multiple="multiple">'
html += '<button type="submit">Submit</button>'
html += '</form>'
document.write(html)
})
this.fill('form',{
'files[]': 'file.txt'
}, true)
this.waitFor(function(){
var uri = casper.evaluate(function(){
return document.documentURI
})
if ( 'about:blank' === uri ){
return false
}
return true
})
})

Categories