I am validating fields through Laravel Request and able to show validation messages for normal fields. But when it comes to the attributes having array, like below code I am not able to show validation message.
HTML Code:
{!! Form::text('mobile_no[]', null, ['class'=>'form-control', 'id'=>'mobile_no[]', 'placeholder'=>'Enter Mobile Number']) !!}
{!! Form::text('mobile_no[]', null, ['class'=>'form-control', 'id'=>'mobile_no[]', 'placeholder'=>'Enter Mobile Number']) !!}
{!! Form::text('mobile_no[]', null, ['class'=>'form-control', 'id'=>'mobile_no[]', 'placeholder'=>'Enter Mobile Number']) !!}
AJAX Code:
(function ($) {
$('.add-form').on('submit', function (e) {
e.preventDefault();
var formObj = $(this);
var formUrl = formObj.attr('action');
$.each(formObj.find('input, select, textarea'), function (i, field) {
var element = $(`input[name="${field.name}"]`).removeClass('is-invalid').parent();
element.find('label.error-field').remove();
})
if (window.FormData !== undefined) {
var formData = new FormData(formObj[0]);
$.ajax({
url: formUrl,
type: 'POST',
data: formData,
dataType: 'JSON',
mimeType: 'multipart/form-data',
contentType: false,
cache: false,
processData: false,
beforeSend: function (xhr, opts) {
// progress bar show
},
success: function (data, textStatus, jqXHR) {
//// progress bar hide
alert('Record added successfully');
window.location.href = base_url + data.data;
//console.log('DATA :: ', data);
},
error: function (data, textStatus, jqXHR) {
//// progress bar hide
if (data.responseJSON.errors) {
$.each(data.responseJSON.errors, function (key, value) {
var element = $('[name=' + key + ']', formObj);
element.addClass('is-invalid').after(`<label for=${key} class="error-field">${value[0]}</label>`);
});
}
},
});
}
});
})(jQuery)
You should do console.log(data.responseJSON.errors) to see exactly what errors are getting returned, but normally when trying to access item.* validation errors you need to access it on the front end via items.1, items.2
Related
I'm trying to remove an object from an ObservableArray after an ajax-call. It works with the '.pop' function, but not when I'm using the custom knockout.js '.remove'-function.
If I move the call to the '.remove' function outside the ajax-complete function, '.remove' does work. But I would really rather have it inside the '.complete'.
Can anyone spot what I'm doing wrong?
This doesn't work:
self.removeItem = function(data) {
$.ajax({
type: 'POST',
url:'/echo/js/?js=hello%20world!',
dataType: 'json',
contentType: 'application/json',
data: null
}).complete(function (item,data) {
self.Items.remove(data);
});
};
I made a jsfiddle to demonstrate: http://jsfiddle.net/6oe6dn7n/1/
My view-model looks like so:
var data = {
Name: "Test",
Items: ["One", "Two", "Three"]
};
function ViewModel(data) {
var self = this;
self.Items = ko.observableArray(ko.utils.arrayMap(data.Items,
function(item) {
return { value: ko.observable(item) };
}));
self.removeItem = function(data) {
$.ajax({
type: 'POST',
url:'/echo/js/?js=hello%20world!',
dataType: 'json',
contentType: 'application/json',
data: null
}).complete(function (item,data) {
// This doesn't affect the observableArray.
// 'self.Items.pop(data) does, however.
self.Items.remove(data);
});
};
}
And my HTML looks like so:
<div>
<table>
<tbody data-bind="template: { name: 'itemTemplate', foreach: Items }"></tbody>
</table>
</div>
<script type="text/html" id="itemTemplate">
<tr>
<td>
<input data-bind="value: value" />
Remove Item
</td>
</tr>
</script>
You have replaced "data" variable object in the context of response handler:
was:
self.removeItem = function(data) { // <- data
$.ajax({
type: 'POST',
url:'/echo/js/?js=hello%20world!',
dataType: 'json',
contentType: 'application/json',
data: null
}).complete(function (item, data) { // <- another data overrides upper data
// This doesn't affect the observableArray.
// 'self.Items.pop(data) does, however.
self.Items.remove(data); // <- what data to use???
});
};
changed:
self.removeItem = function(data) {
$.ajax({
type: 'POST',
url:'/echo/js/?js=hello%20world!',
dataType: 'json',
contentType: 'application/json',
data: null
}).complete(function (item, data1) { // another data - data1
// This doesn't affect the observableArray.
// 'self.Items.pop(data) does, however.
self.Items.remove(data);
});
};
I've updated the fiddle, it works for me - at least removes items.
You need to use the data variable that is passed into removeItem. Instead you override it, by using the textStatus variable of the complete callback. Like so:
self.removeItem = function(data) {
$.ajax({
type: 'POST',
url:'/echo/js/?js=hello%20world!',
dataType: 'json',
contentType: 'application/json',
data: null
}).complete(function (item) {
self.Items.remove(data);
});
};
The reason self.Items.pop(data) worked is because .pop doesn't actually take any parameters. So the data you passed in is never used, and the call is just popping the array. The second parameter in the complete callback method is by default a textStatus response.
From the documentation:
http://api.jquery.com/jQuery.ajax/
complete
Type: Function( jqXHR jqXHR, String textStatus )
A function to be called when the request finishes (after success and error callbacks are executed). The function gets passed two arguments: The jqXHR (in jQuery 1.4.x, XMLHTTPRequest) object and a string categorizing the status of the request ("success", "notmodified", "nocontent", "error", "timeout", "abort", or "parsererror").
I am using AJAX to load (and subsequently refresh) a JS datatable (v1.10.0). I don't think I'm doing this properly because while I can get the initial table to load, subsequent AJAX requests do not update the table.
I've tried various combinations of the .clear(), .draw() and .rows.add() JS Datatables methods, but nothing seems to work.
jquery code below:
$(document).ready(function() {
$('#results').html('<table id="table-output" class="display" cellspacing="0" width="100%"></table>');
var table_config = {
"bDestroy": true,
"paging": false,
"language": {
"zeroRecords": "No results found",
"processing": "<div align='center'><img src='/static/ajax-loader.gif'></div>",
"loadingRecords": "<div align='center'><img src='/static/ajax-loader.gif'></div>"
}
};
$("form").submit(function(e) {
e.preventDefault();
var form_data = JSON.stringify($(this).serializeArray());
$.ajax({
type: 'POST',
url: /the_url,
data: form_data,
contentType: 'application/json',
dataType: 'json',
success: function(response) {
table_config.data = response.data;
table_config.columns = response.columns;
$('#table-output').dataTable(table_config);
}
});
});
});
I figured it out. Modifying the success function as follows works:
success: function(response) {
$('#results').html('<table id="table-output" class="display" cellspacing="0" width="100%"></table>');
table_config.columns = response.columns;
var table = $('#table-output').DataTable(table_config);
table.clear();
table.rows.add(response.data);
table.draw();
}
You can try :
var table1 = $('#youtblename').DataTable();
var pathp = "/server_processing_pie.php";
tablel.clear();
tablel.draw();
tablel.ajax.url(pathp).load();
I need to upload image with ajax call. But POST field with image always is empty. Part of my form:
<div class="col-lg-6">
<?php echo CHtml::activeFileField($model, 'logo'); ?>
<?php echo CHtml::textField('test', 'test'); ?>
<?php echo CHtml::submitButton('Upload'); ?>
<?php echo CHtml::ajaxSubmitButton('Upload ajax', '#');?>
</div>
If i click submitButton, then i have both test and logo fields - image uploaded.
And if i click ajaxSubmitButton, then i have only test field, logo is empty. What is the solution?
PS: i need non-extension solution.
You cannot upload files with ajaxSubmitButton by default. Use simple submit or some uploader.
If you want to upload image via ajax, here's example:
<?php echo CHtml::link('Upload ajax', '#', array("onclick"=>"js:upload_file(this)"));?>
In your js:
function upload_file(){
var fd = new FormData();
var e = document.getElementById("Model_logo");
fd.append( "Model[logo]", $(e)[0].files[0]);
$.ajax({
url: 'upload',
type: 'POST',
cache: false,
data: fd,
processData: false,
contentType: false,
success: function (data) {
},
error: function () {
alert("ERROR in upload");
}
});
}
Change Model to your model name and this will work. Also now you can append any data to FormData and it will be passed in $_POST and your file in $_FILES.
Be carefull, this way doesn't work on ie7 and ie8 as i remember.
Based on ineersa's answer, I made some improvements:
<?php echo CHtml::link('Upload ajax', '#', array("onclick"=>"upload_file()")); ?>
In your js:
function upload_file(){
var fd = new FormData($('#model-form')[0]);
$.ajax({
url: 'upload',
type: 'POST',
cache: false,
data: fd,
processData: false,
contentType: false,
success: function (data) {
},
error: function () {
alert("ERROR in upload");
}
});
}
This way you don't have to append each form field manually. All form data will be read automatically (including files). Just make sure that #model-form is changed according to your form id.
A way you don't need to call $.ajax(...) by yourself.
$(document).on('ajaxBeforeSend', 'form.my-form', function (event, jqXHR, settings) {
if ((settings.url.indexOf("js_skip") == -1) && $("form.my-form input[type=file]")[0].files.length) {
jqXHR.abort();
settings.cache = false;
settings.contentType = false;
settings.processData = false;
settings.data = new FormData(this);
settings.url = settings.url + "&js_skip=1";
jqXHR = $.ajax(settings);
}
});
This works
#Html.DropDownListFor(model => Model.Assessment.Interviewer, Model.SiteListing)
This does not
<div class="resident-relationship">#Html.DropDownListFor(m => Model.HouseholdMembersListing.ElementAt(i).Relationship, Model.ResidentTypeListing, new { #class = "t150"})</div>
How does one correct use #HTML.DropdownListFor to bind to a List<anything> so that on POST to the controller it will have the value? I have this on a page where there can be many residents in the household. I have other bindings like name and age and they work well. But on the Relationship I need to have the drop down list.
var ddlStates = '#dropdownlistId'
$.ajax({
cache:false,
type: "GET",
url: "#(Url.Action("GetStatesByCountryId", "Country"))",
data: "countryId=" + selectedItem + "&addEmptyStateIfRequired=true",
success: function (data) {
ddlStates.html('');
$.each(data, function(id, option) {
if( option.name=="Maharashtra")
{
ddlStates.append($('<option></option>').val(76).html(option.name));
}
});
},
error:function (xhr, ajaxOptions, thrownError){
alert('Failed to retrieve states.');
statesProgress.hide();
}
});
I need to get string array or list with ajax and Action, this is my Implementation:
This is my html Dom of view of Index action in AccessMenuController:
<div class="RoleAccess">
<select name="RoleDropDown">
<option value="0">Select Role</option>
<option value="61AD3FD9-C080-4BB1-8012-2A25309B0AAF">AdminRole</option>
<option value="8A330699-57E1-4FDB-8C8E-99FFDE299AC5">Role2</option>
<option value="004E39C2-4FFC-4353-A06E-30AC887619EF">Role3</option>
</select>
</div>
My Controller:
namespace MyProject.Areas.GlobalAccess.Controllers {
public class AccessMenuController : Controller {
public ActionResult Index() { return View();}
[HttpPost]
public JsonResult RoleDropDownChanged(string roleId) {
Guid RoleId = new Guid(roleId);
//Some implement
List<string> actions = new List<string>();
for(int i = 0; i <= 10; i++)
actions.Add(i.ToString());
return Json(actions.ToArray(), JsonRequestBehavior.AllowGet);
}
}
}
and the script:
$(document).ready(function () {
//Handle Checks of Actions by RoleName Changed
$('div.RoleAccess select').change(function () {
RoleChangeHandler();
});
function RoleChangeHandler() {
$.ajax({
url: '#Url.Action("RoleDropDownChanged")',
type: 'POST',
data: { 'roleId': '61AD3FD9-C080-4BB1-8012-2A25309B0AAF' },
dataType: 'json',
processData: false,
contentType: 'application/json; charset=utf-8',
success: function (data) { SuccessRoleChangeHandler(data); },
error: OnFailRoleChangeHandler
});
return false;
}
function SuccessRoleChangeHandler(data) {
alert("in success role change");
}
function OnFailRoleChangeHandler(result) {
alert('in OnFailRoleChangeHandler');
}
And the problem is with all change of dropdown just Onfail function run and alert me "in OnFailRoleChangeHandler", also I check the RoleDropDownChanged Action with breakpoint and that never run, where is the problem?
UPDATE
when I load the page by chrome there is an error in console window:
http://MyProject/GlobalAccess/AccessMenu/#Url.Action(%22RoleDropDownChanged%22) 404 (Not Found) jquery-1.7.1.js:8102
Remove this setting:
contentType: 'application/json; charset=utf-8',
You are not sending any JSON to the server.
If you want to keep this setting then make sure that you are sending a valid JSON to your server:
data: JSON.stringify({ 'roleId': '61AD3FD9-C080-4BB1-8012-2A25309B0AAF' })
So:
$.ajax({
url: '#Url.Action("RoleDropDownChanged")',
type: 'POST',
data: { 'roleId': '61AD3FD9-C080-4BB1-8012-2A25309B0AAF' },
success: SuccessRoleChangeHandler,
error: OnFailRoleChangeHandler
});
should work (at least it does for me) with the following action:
[HttpPost]
public ActionResult RoleDropDownChanged(Guid roleId)
{
var actions = Enumerable.Range(1, 10).Select(x => x.ToString()).ToList();
return Json(actions);
}
UPDATE:
According to your comments it looks like you are trying to use server side helpers in a separate javascript which is not possible. Here's what I would suggest you. Start by providing the url when generating your dropdown:
<div class="RoleAccess">
#Html.DropDownListFor(
x => x.RoleDropDown,
Model.Roles,
"-- Select role --",
new {
data_url = Url.Action("RoleDropDownChanged")
}
)
</div>
and then in your separate javascript file:
$(document).ready(function() {
$('div.RoleAccess select').change(function () {
var url = $(this).data('url');
$.ajax({
url: url,
type: 'POST',
data: { 'roleId': '61AD3FD9-C080-4BB1-8012-2A25309B0AAF' },
success: function(result) {
alert('success');
},
error: function() {
alert('error');
}
});
});
});
and then of course you could replace the hardcoded roleId with the currently selected value:
data: { 'roleId': $(this).val() }
Move your $(document).ready function to your View like this:
<script type="text/javascript">
$(document).ready(function () {
//Handle Checks of Actions by RoleName Changed
$('div.RoleAccess select').change(function () {
RoleChangeHandler('#Url.Action("RoleDropDownChanged")');
});
});
</script>
Then in your JS file add url parameter to your function and change ajax call:
function RoleChangeHandler(pageUrl) {
$.ajax({
url: pageUrl,
type: 'POST',
data: { 'roleId': '61AD3FD9-C080-4BB1-8012-2A25309B0AAF' },
dataType: 'json',
processData: false,
contentType: 'application/json; charset=utf-8',
success: function (data) { SuccessRoleChangeHandler(data); },
error: OnFailRoleChangeHandler
});
return false;
}
This should work as you expected.
If your script resides in a .JS file then this is not going to work as it'll be treated as plain text. You can either move entire script to the view or you can re-factor script so that majority of the script remains in the .JS and you then pass relevant values from the view.