I need your help. I am trying to realize a live search. So whenever I switch from one TextBox to another, a form should be submitted, to update the URL and to pass the data to the controller. It works perfectly fine when I click the submit button but it does not work the way I want.
Here is my code:
Controller:
public ActionResult Index(string number, string caption)
{
//Fetch data from the database
return View();
}
View:
$(document).ready(function () {
$('#number').change(function () {
$('#filter').submit();
});
});
#using (Html.BeginForm("Index", "Home", FormMethod.Get, new { id = "filter" }))
{
<div class="row">
<div class="col-sm-2 checkbox">
Number:
</div>
<div class="col-sm-3">
#Html.TextBox("Number", "", new { #class = "form-control", type = "text", id = "number" })
</div>
</div>
<div class="row">
<div class="col-sm-2 checkbox">
Caption:
</div>
<div class="col-sm-3">
#Html.TextBox("Caption", "", new { #class = "form-control", type = "text", id = "caption" })
</div>
</div>
<div class="row">
<div class="col-sm-2 col-sm-offset-2">
<button type="submit" id="submit" class=" btn btn-block btn-primary">Search</button>
</div>
</div>
}
Output HTML:
<script>
$(document).ready(function () {
$('#number').change(function () {
$('#filter').submit();
});
});
</script>
<form action="/" id="filter" method="get"> <div class="row">
<div class="col-sm-2 checkbox">
Number:
</div>
<div class="col-sm-3">
<input class="form-control" id="number" name="Number" type="text" value="">
</div>
</div>
<div class="row">
<div class="col-sm-2 checkbox">
Caption:
</div>
<div class="col-sm-3">
<input class="form-control" id="caption" name="Caption" type="text" value="">
</div>
</div>
<div class="row">
<div class="col-sm-2 col-sm-offset-2">
<button type="submit" id="submit" class=" btn btn-block btn-primary">Search</button>
</div>
</div>
Browser Console:
Uncaught TypeError: elem[type] is not a function
at Object.trigger (http://localhost:49782/Scripts/jquery-1.8.2.js:2991:18)
at HTMLFormElement.<anonymous> (http://localhost:49782/Scripts/jquery-1.8.2.js:3618:17)
at Function.each (http://localhost:49782/Scripts/jquery-1.8.2.js:625:20)
at init.each (http://localhost:49782/Scripts/jquery-1.8.2.js:255:17)
at init.trigger (http://localhost:49782/Scripts/jquery-1.8.2.js:3617:15)
at init.jQuery.fn.(anonymous function) [as submit] (http://localhost:49782/Scripts/jquery-1.8.2.js:3671:9)
at HTMLInputElement.<anonymous> (http://localhost:49782/:63:26)
at HTMLInputElement.dispatch (http://localhost:49782/Scripts/jquery-1.8.2.js:3077:9)
at HTMLInputElement.eventHandle (http://localhost:49782/Scripts/jquery-1.8.2.js:2695:28)
Your JavaScript code is looking for the tag with ID #number. Because browsers mostly read the source code from the top to the bottom, the code will be evaluated well before the #number <input> is even declared. This means that jQuery will not find it and will therefore not attach the event. If you move the script after the HTML, or wrap it into document.ready, it will work as expected:
$(document).ready( function() {
$('#number').change(function () {
$('#filter').submit();
});
} );
//or simpler equivalent
$( function () { ... } );
This however will still not work as you want, because each time the input changes, the whole page will be posted back to the server, so user will have to wait for the entire page to reload after he tries to switch focus from one input to another. This is not very convenient and you would probably be better off changing the logic to use AJAX calls and dynamically update the search results. Although it is not a requirement, it is a nice to have and user-friendly approach :-) .
Update - solution to submit error
I have just found the solution for the error you get trying to submit. Your submit button's id is submit. This is not "wrong" per se, but it causes a problem trying to submit with jQuery. You see, because the button is inside your form, when jQuery returns the #filter form, when you try to use submit() on it, JavaScript finds your submit button in scope and thinks that you want to "call it" - hence you get the error, because you you cannot "call" an element. This might also happen if you use submit as the name of a button.
The best and easiest solution for you will be to change the id to something else:
<button type="submit" id="submitButton" class=" btn btn-block btn-primary">Search</button>
In modern browsers use the input event. This event will fire when the user is typing into a text field, pasting, undoing, basically anytime the value changed from one value to another.
$('#number').on('input', function() {
$('#filter').submit();
});
It's working fine for me I hope it also working for u
C# Code:
[HttpPost]
public ActionResult Index(string firstname)
{
return Json("Done");
}
Razor Code
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
var abc = document.getElementById('Number');
abc.onchange = (function () {
document.forms[0].submit();
});
});
</script>
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id= "filter" }))
{
<div class="row">
<div class="col-sm-2 checkbox">
Number:
</div>
<div class="col-sm-3">
#Html.TextBox("Number", "", new { #class = "form-control", type = "text", id = "Number" })
</div>
</div>
<div class="row">
<div class="col-sm-2 checkbox">
Caption:
</div>
<div class="col-sm-3">
#Html.TextBox("Caption", "", new { #class = "form-control", type = "text", id = "caption" })
</div>
</div>
<div class="row">
<div class="col-sm-2 col-sm-offset-2">
<button type="submit" id="submit1" class=" btn btn-block btn-primary">Search</button>
</div>
</div>
}
Do Not use submit as id or name of button it override the meaning of Java Script submit Method
Related
I'm learning javascript/jquery on the go, I'm trying to reload a form but keeping its js properties (required and masked inputs), code and pictures attached.
First image: Masked inputs works like a charm
Second image: The form its fully filled, still working
Third image: The form it reloaded, but no properties applied
The html form (minmized, just the first field)
<div class="card-body" id="clientsAddFormContainer">
<form method="post" action="main/clients/addController.php">
<div class="form-group row" id="clientRutDiv">
<div class="col-lg-6">
<div class="form-group" id="clientRutInnerDiv">
<label class="col-form-label" for="clientRut">RUT <span class="required">*</span></label>
<input type="text" name="clientRut" id="clientRut" class="form-control" placeholder="Ej. 11.111.111-1" required="" data-plugin-masked-input="" data-input-mask="99.999.999-*" autofocus>
</div>
</div>
</div>
</div>
</form>
<footer class="card-footer">
<div class="switch switch-sm switch-primary">
<input type="checkbox" name="wannaStay" id="wannaStay" data-plugin-ios-switch checked="checked" />
</div> Mantenerme en esta página
<button type="button" style="float: right;" class="btn btn-primary" onclick="realizaProceso();">Enviar</button>
</footer>
The JS for realizaProceso()
function realizaProceso(){
var validator =0;
validator += validateRequiredField('clientRut');
if(validator == 0){
var parametros = {
"clientRut" : document.getElementById('clientRut').value,
"tableName" : 'clients'
};
$.ajax({
data: parametros,
url: 'route/to/addController.php',
type: 'post',
success: function (respText) {
if(respText == 1){
if(document.getElementById('wannaStay').checked){
$("#clientsAddFormContainer").load(location.href + " #clientsAddFormContainer");
}else{
window.location = "linkToOtherLocation";
}
}else{
showNotyErrorMsg();
}
},
error: function () {
showNotyErrorMsg();
}
});
}else{
showNotyValidationErrorMsg();
}
}
So my JS check all fields are validated, then prepare the array, and wait for the php binary response, 1 means the data has been inserted to db, if wannaStay is checked reload the div "clientsAddFormContainer" but as I said, it loose the properties.
Please sorry for my grammar or any other related english trouble, not a native english speaker.
Ps. I've removed some code so it could go different than the images.
Thanks in advance!
EDIT!
The original code is
<div class="card-body" id="clientsAddFormContainer">
<form method="post" action="main/clients/addController.php">
</form>
</div>
one the js exec I got
<div class="card-body" id="clientsAddFormContainer">
<div class="card-body" id="clientsAddFormContainer">
<form method="post" action="main/clients/addController.php">
</form>
</div>
</div>
2nd EDIT
I found the answer in other stackoverflow question
I created the following HTML form inside a jqxWindow widget for a Laravel project:
<div id="provinceWindow">
<div id="provinceWindowHeader"></div>
<div id="provinceWindowContent">
<form id="provinceForm" method="POST" action="{{route('province.store')}}">
{{ csrf_field() }}
<input type="hidden" name="provinceId" id="provinceId" value=""/>
<div class="form-group row">
<div class="col-6"><label>English province name</label></div>
<div class="col-6"><input type="text" name="provinceNameEn" id="provinceNameEn" maxlength="20"/></div>
</div>
<div class="form-group row">
<div class="col-6"><label>Spanish province name</label></div>
<div class="col-6"><input type="text" name="provinceNameSp" id="provinceNameSp" maxlength="20"/></div>
</div>
<br/>
<div class="form-group row justify-content-center">
<input type="button" value="Submit" id="submitBtn" class="btn btn-sm col-3" />
<span class="spacer"></span>
<input type="button" value="Cancel" id="cancelBtn" class="btn btn-sm col-3" />
</div>
</form>
</div>
</div>
This is the javascript file:
$(document).ready(function () {
var datarow = null;
$.ajaxSetup({
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')}
});
//-----------------------------
// Window settings
//-----------------------------
$('#provinceWindow').jqxWindow({
autoOpen: false,
isModal: true,
width: 400,
height: 160,
resizable: false,
title: 'Province name',
cancelButton: $('#cancelBtn'),
initContent: function () {
$('#submitBtn').jqxButton();
$('#submitBtn').on('click', function () {
$('#provinceForm').submit();
});
}
}).css('top', '35%');
The file routes\web.php has only one resourse route defined for this page:
// Routes for province maintenance
Route::resource('province', 'provinceController');
Checking the available routes with php artisan route:list command, I get these:
Method URI Name Action
GET|HEAD / APP\Http\Controllers\homeController#index
GET|HEAD province province.index APP\Http\Controllers\provinceController#index
POST province province.store APP\Http\Controllers\provinceController#store
GET|HEAD province/create province.create APP\Http\Controllers\provinceController#create
GET|HEAD province/{province} province.show APP\Http\Controllers\provinceController#show
PUT|PATCH province/{province} province.update APP\Http\Controllers\provinceController#update
DELETE province/{province} province.destroy APP\Http\Controllers\provinceController#destroy
GET|HEAD province/{province}/edit province.edit APP\Http\Controllers\provinceController#edit
My controller action:
public function store(Request $request)
{
$fields = $request->all();
if ($request->provinceId == '') {
$province = new province($fields);
$validator = Validator::make($fields, $province->rules());
if ($validator->fails()) {
return redirect('')->withErrors($validator)->withInput();
}
else {
$province->save();
}
return view('province/index');
}
}
The form is shown on top of a jqxGrid widget, as a modal window, in order to capture the required information and perform the CRUD operations for the corresponding DB table.
The problem is, when I click the "Submit" button the window is closed and nothing else happens. The form is not posted to the indicated action and the data entered get lost.
It does not matter if I initialize the submitBtn inside the initContent or outside of it. The form is never posted.
I also tried the Close event of the jqxWindow to no avail.
If I take a look to the generated HTML it looks like this:
<form id="provinceForm" method="POST" action="http://mis:8080/province">
<input type="hidden" name="_token" value="Y9dF5PS7nUwFxHug8Ag6PHgcfR4xgxdC43KCGm07">
<input type="hidden" name="provinceId" id="provinceId" value="">
<div class="form-group row">
<div class="col-6">
<label>English province name</label>
</div>
<div class="col-6">
<input type="text" name="provinceNameEn" id="provinceNameEn" maxlength="20">
</div>
</div>
<div class="form-group row">
<div class="col-6">
<label>Spanish province name</label>
</div>
<div class="col-6">
<input type="text" name="provinceNameSp" id="provinceNameSp" maxlength="20">
</div>
</div>
<br>
<div class="form-group row justify-content-center">
<input type="button" value="Submit" id="submitBtn" class="btn btn-sm col-3 jqx-rc-all jqx-button jqx-widget jqx-fill-state-normal" role="button" aria-disabled="false">
<span class="spacer"></span>
<input type="button" value="Cancel" id="cancelBtn" class="btn btn-sm col-3">
</div>
</form>
Pressing the submit button takes me to the home page and nothing gets added to the DB table.
I guess the issue has something to do with Laravel routes because I get no errors.
What is missing or what is wrong with this approach?
Any light is appreciated.
Alright, because I erroneously added in my Model a validation, that was not needed, for a column (there was already a constraint defined at the DB table level), it was not possible to fulfill the validator when saving a new record. I commented that line in my Model and, that was it!
protected $rules = array(
'provinceNameEn' => 'required|alpha|max:20',
'provinceNameSp' => 'required|alpha|max:20'
//'deleted' => 'required|in:M,F' // This is already validated in a DB constraint.
);
I noticed the control was returned to my home page but without any message or error, but if you pay attention to my controller it was precisely the behavior programmed. However, there is no implementation to display the error messages, so I added dd($validator); before that return statement. There I read the message and finally found the solution.
I have a simple input params that are required. I want to disable my submit button until all the required fields are satisfied. Granted I am new to django, and the particular code I am working on is very old. As a result, post like this or this are not helping.
Current code that I am trying from one of the posts linked and including my own template
<script type="text/javascript">
$(document).ready(function() {
validate();
$('input').on('keyup', validate);
});
function validate() {
var inputsWithValues = 0;
// get all input fields except for type='submit'
var myInputs = $("input:not([type='submit'])");
myInputs.each(function(e) {
// if it has a value, increment the counter
if ($(this).val()) {
inputsWithValues += 1;
}
});
if (inputsWithValues == myInputs.length) {
$("input[type=submit]").prop("disabled", false);
} else {
$("input[type=submit]").prop("disabled", true);
}
}
$('#submit').on('click', function() {
var zip = $('#zip').val();
var email = $('#email').val();
var name = $('#name').val();
//if inputs are valid, take inputs and do something
});
<form class="form-horizontal" action="" method="get" id="dataform">
<div class="form-group">
<div class="container">
<div class="row">
<div class="col-md-offset-2 col-md-3">
<input class="col-md-12" id="zip" type="text" placeholder="Enter zip code" aria-required="true">
</div>
<div class="col-md-3">
<input class="col-md-12" id="name" type="text" placeholder="Enter last name" aria-required="true">
</div>
<div class="col-md-3">
<input class="col-md-12" id="email" type="email" placeholder="Enter email address" aria-required="true">
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="btn btn-primary" id="submit" type="submit">Submit</div>
</div>
</div>
</form>
any help on disabling my submit button until input fields are not validated/filled is much appreciated. Again, new to django and I am unable to use existing threads on said topic
From your current code, looks like your selector for the submit input is not actually getting the submit "button". Currently, your template defines the submit as a div and not an input, thus your selectors should be $("div[type=submit]") not $("input[type=submit]")
Better yet, just select by div id $('#submit')
Instead of targeting attributes, I was targeting props. Below is the fix for my particular issue.
if (inputsWithValues === 3) {
$("div[type=submit]").attr("disabled", false);
} else {
$("div[type=submit]").attr("disabled", 'disabled');
}
I think a more appropriate title is my private JavaScript Hell.
First off I am new to JavaScript. Never used it before this attempt.
Three or four weeks back when I first encountered this error I posted on ASP.Net forums and the good folks helped me out there. However after a full week of one hour a day concentrating on this issue I am no further advanced than I was three weeks ago even with their help. The issue seems to be either I am transcribing something incorrectly and I am blind (this wouldn't surprise me) or the error is specific to some aspect within my machine.
First the set up. I have a controller for jobs where I am wanting to cascade a drop down box content based on a preceeding selection. The two drop downs involved are Site and Waterbodys. The relevant part of the controller is:
public class JobsController : Controller
{
private readonly EVAContext _context;
public JobsController(EVAContext context)
{
_context = context;
}
// GET: Jobs/Create
public IActionResult Create()
{
ViewData["SiteID"] = new SelectList(_context.Sites, "SiteID", "SiteName");
ViewData["WaterBodyID"] = new SelectList(_context.WaterBodys, "WaterBodyID", "WBName");
ViewData["DepartmentID"] = new SelectList(_context.Departments, "DepartmentID", "iDepartment");
return View();
}
public IActionResult GetWaterBody(int siteID)
{
var waterBody = new List<WaterBody>();
waterBody = getWaterBodyFromDataBaseBySiteID(siteID);
return Json(waterBody);
}
public List<WaterBody> getWaterBodyFromDataBaseBySiteID(int siteID)
{
return _context.WaterBodys.ToList();
}
Within the associated view I have :
#model EVA.Models.Job
#{
ViewData["Title"] = "Add Job";
}
<h2>Add Job</h2>
<form asp-action="Create">
<div class="form-horizontal">
<hr />
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="OrderNumber" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="OrderNumber" class="form-control" />
<span asp-validation-for="OrderNumber" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="SiteID" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select asp-for="SiteID" class="form-control" asp-items="ViewBag.SiteID" id="site-target">
<option>---Select Site First---</option>
</select>
</div>
</div>
<div class="form-group">
<label asp-for="WaterBodyID" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select asp-for="WaterBodyID" class="form-control" asp-items="ViewBag.WaterBodyID" id="wb-target">
<option>---Select Site First---</option>
</select>
</div>
</div>
<div class="form-group">
<label asp-for="DepartmentID" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select asp-for="DepartmentID" class="form-control" asp-items="ViewBag.DepartmentID">
<option>---Select Department---</option>
</select>
</div>
</div>
<div class="form-group">
<label asp-for="JobNumber" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="JobNumber" class="form-control" value="1234" />
<span asp-validation-for="JobNumber" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="JobDescription" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="JobDescription" class="form-control" />
<span asp-validation-for="JobDescription" class="text-danger" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
<script>
$(document).ready(function () {
$("#site-target").on("change", function () {
$list = $("#wb-target");
$.ajax({
url: "Jobs/GetWaterBody",//Core0309 is my controller name
type: "GET",
data: { id: $("#site-target").val() }, //id of the site which is used to extract waterbodies
traditional: true,
success: function (result) {
$list.empty();
$.each(result, function (i, item) {
$list.append('<option value="' + item["WaterBodyID"] + '"> ' + item["WBName"] + ' </option>'); //Must be lowercase ,if not ,you will get value 'Undefined'
});
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest.status);
alert(textStatus);
},
//error: function () {
// alert("Danger!! Will Robertson Danger!!!!!!!!!!!");
// }
});
});
});
</script>
<!--<script src="~/js/WaterBody.js"></script>-->
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
I previously had Waterbody.js which was also returning the same 404 based error.
What is frustrating and has led me here is on the ASP.Net forum the people there have copied my code to their own machine and it is running without error I am told. Although they are using a different set of drop downs.
I am seriously feeling like I am bashing my head against the wall. I have tried every suggestion, spent hours looking at examples on line and making minor changes to try and find the culprit but nothing works.
I am left with these questions:
1: Is my JobController code correct? Have I inadvertently introduced a stuff up there?
2: Is the script correct? I added alerts at one stage and I keep getting the idea the error is in the url but don't know that.
3: Is there some reference or dependency I may be missing on my machine specifically?
4: Some other question I haven't considered as I am still too new to this?
Help please. I am at the point where I must get this working to be able to move on with the balance of the project. Thanks in advance. I honestly hope this is a silly thing I done.
Bit of an update...
I added some alerts and they are indicating the error is occurring on $.ajax line.
alert("Inside")
$list = $("#wb-target");
alert("aferlist")
$.ajax({
Afterlist is firing but the next alert "Ajax" doesn't fire.
I am using Ajax.Begin Form to post data on a form without refreshing whole page, I need to validate the textbox, if it has value then the data should be posted else validation message should be shown, but the problem is validation and posting data are both occurring at same time. If I do not add jquery.unobtrusive-ajax.js file then my partial view would is returning as separate white page but validation is working and form is not posting until the textbox has value, BUT if I add jquery.unobtrusive-ajax.js file on page, it is posting data whether textbox has value or not. What is wrong with the code, I am not getting this at all. Please help I have spent two days tried my possible solutions and still no success.
This is my Main View(Parent View) having PartialView
<div id="div_SearchPatient2">
#Html.Partial("SearchPatientPartial");
</div>
#Scripts.Render("~/bundles/jqueryval")
jqueryval is a bundle which has jquery.unobtrusive-ajax.js file.
<div>
#using (Ajax.BeginForm("Search", "Patient", new { },
new AjaxOptions
{
HttpMethod = "POST",
UpdateTargetId = "patientfound"
},
new
{
#name = "SearchPatientForm",
#id = "frmSearchPatient",
}
))
{
#Html.AntiForgeryToken()
<div class="form-title">
Enter MR Number to search patient
</div>
<div class="col-lg-4">
<div class="form-group">
<div class="col-lg-6">
<label class="control-label">MR Number</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="command" data-mask="999-99-99" placeholder="000-00-00" required data-bv-notempty="true" data-bv-notempty-message="MRNo. is required." />
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-4">
<input class="btn btn-darkorange" type="submit" value="Search" />
</div>
</div>
<div id="patientfound">
#Html.Partial("PatientFoundPartial")
</div>
}
</div>
Where patientfound is a div which will render details if found. I have given this in UpdateTargetId of AjaxBeginForm.
My Controller is returning PartialView
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Search(FormCollection collection, string id)
{
// some code to get data
return PartialView("PatientFoundPartial");
}
In the Ajax option write like this :
OnBegin = "return StartValidation();"
Now define a javascript function called StartValidation with this code :
function StartValidation(){ if($('fromid').validate()){return true;}return false;}