Seems that the code is correct!
so, someone could spare any information why the second(subcategories) partial did not update? Thank's
I put on js:
$(document).ready(function() {
return $(document).on('click', "input[type='radio'][name='product[gender_id]']", function(evt) {
return $.ajax('update_category_select', {
type: 'GET',
dataType: 'script',
data: {
gender_id: $("input[type='radio'][name='product[gender_id]']:checked").val()
},
error: function(jqXHR, textStatus, errorThrown) {
return console.log("AJAX Error: " + textStatus);
},
success: function(data, textStatus, jqXHR) {
return console.log("Dynamic state select OK!");
}
});
});
return $(document).on('change', '#categories_select', function(evt) {
return $.ajax('update_subcategory_select', {
type: 'GET',
dataType: 'script',
data: {
category_id: $("#categories_select option:selected").val()
},
error: function(jqXHR, textStatus, errorThrown) {
return console.log("AJAX Error: " + textStatus);
},
success: function(data, textStatus, jqXHR) {
return console.log("Dynamic state select OK!");
}
});
});
});
First Partial:
$("#categories_select").empty().append("<%= escape_javascript(render(:partial => #categories)) %>")
If the firt partial is updated update the second partial
Second partial:
$("#subcategories_select").empty().append("<%= escape_javascript(render(:partial => #subcategories)) %>")
Products Controller
#catagories = Category.where("gender_id = ?", params[:gender_id])
respond_to do |format|
format.js
end
end
def update_subcategory_select
#subcategories = Subcategory.where("category_id = ?", params[:category_id])
respond_to do |format|
format.js
end
end
The return is used inside a function to return a value/expression and the following sentences are not executed.
In your javascript do you have something like:
function(){ //Document ready
return 1; //Here you on click
return 2; //Here you on change
}
So return 2 is never called. In your case, the event handler for 'change' is never attached so subcategories are not updated.
Just remove all return in your javascript code.
Related
am using .netcore 1.1 , Visual studio 2017 , Jquery version = "3.2.1"
,am trying to make the MVC controller to get data from my page ,
i have 2 arrays in java , one is an array of Object (model view) and one is an array of strings
objects array always return error 400 (bad request)
2- string array ,always send null to the controller
i followed the below answers with no success
https://stackoverflow.com/a/13255459/6741585
and
https://stackoverflow.com/a/18808033/6741585
below is my chtml page
//#region send data back t oserver
$('#Savebtn').click(function () {
console.log(editedRows);
var UpdatedRows = JSON.stringify({ 'acActivityed': editedRows });
console.log(UpdatedRows);
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/acActivity/Edit",
//traditional: true,
data: UpdatedRows ,
dataType: "json",
success: function (data) {
// here comes your response after calling the server
alert('Suceeded');
},
error: function (jqXHR, textStatus, errorThrown) {
alert("error : " + jqXHR.responseText);
}
});
});
//#endregion
//#region deleted all selected
$('#DeleteSelectedbtn').on('click', function () {
if (confirm("Are you sure to delete All Selected ?????")) {
var selectedData = [];
var selectedIndexes;
selectedIndexes = grid.getSelectedRows();
jQuery.each(selectedIndexes, function (index, value) {
selectedData.push(grid.getDataItem(value).id);
});
console.log(selectedData);
var SelectedIds = selectedData.join(',') ;
console.log(SelectedIds);
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/acActivity/DeleteSelected",
data: JSON.stringify({ "ids": SelectedIds }),
dataType: "json",
success: function (data) {
grid.render();
},
error: function (err) {
alert("error : " + err);
}
});
}
});
//#endregion
and both do have data as below console shots
the selected ID's one
my Controller
this one should expect the list of object and always return bad request ,
[HttpPost]
[ValidateAntiForgeryToken]
//public jsonResult Edit( List<acActivitytbl> acActivityed)
public ActionResult Edit( List<acActivitytbl> acActivityed)
{
foreach (acActivitytbl it in acActivityed)
{
logger.Log(LogLevel.Info, it.ID);
logger.Log(LogLevel.Info, it.Name);
logger.Log(LogLevel.Info, it.IsActive);
}
//return View(acActivityed);
return Json(new { success = true, responseText = "end of Page" });
}
that one should expect the delimited string ,but always receive null
public ActionResult DeleteSelected(string ids)
{
try
{
char[] delimiterChars = { ' ', ',', '.', ':', ' ' };
string[] words = ids.Split(delimiterChars, StringSplitOptions.RemoveEmptyEntries);
if (words != null && words.Length > 0)
{
foreach (var id in words)
{
bool done = true; //new acActivitiesVM().Delete(Convert.ToInt32(id));
logger.Log(LogLevel.Info, " acActivities ID {0} is Deleted Scussefully ", id);
}
return Json(new { success = true, responseText = "Deleted Scussefully" });
}
return Json(new { success = false, responseText = "Nothing Selected" });
}
catch (Exception dex)
{
..... removed to save space
});
}
}
i know there is something missing here ,but i cannot find it ,any help in that ??
I'm getting bad request error 400 using Ajax on Rails.
When i submit my form I have a string to send as parameter from Jquery and i want to retrieve it from params[:assignee] so i can extract the string and save it through my controller.
My controller:
def create
#task = Task.new(task_params)
#task.user = current_user
username = params.permit[:assignee]
#task.assignee = username
#set_category
respond_to do |format|
if #task.save
format.html { redirect_to tasks_url, notice: 'Task was successfully created. '+task_params.inspect}
#format.html { redirect_to #task, notice: 'Task was successfully created.' }
format.json { render :show, status: :created, location: #task }
else
format.html { render :new }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
def task_params
params.require(:task).permit(:owner, :value, :completed, :category, :date, :assignee)
end
And this is my JS:
$( "#new_task" ).submit(function() {
alert("form: "+assignee);
//event.preventDefault();
$.ajax({
url: "/tasks",
type: "POST",
data: {assignee},
dataType: "json",
success: function(data) {
alert('successfully');
},
error: function(xhr, textStatus, error) {
alert(xhr.statusText+""+textStatus+""+error);
}
});
});
assignee is an username selected in a jquery auto-complete form:
select: function(event, ui) {
var terms = split(this.value);
// remove the current input
terms.pop();
// add the selected item
terms.push(ui.item.value);
// add placeholder to get the comma-and-space at the end
terms.push("");
this.value = terms.join("");
assignee=this.value;
$('input[name=commit]').prop("disabled",false);
return false;
}
My root is "task/" where you can see saved tasks and a form to create a new one.
I searched a lot on the net and I tried them all. How can I do? Thanks so much
400 Bad Request - The server cannot or will not process the request due
to an apparent client error (e.g., malformed request syntax, too large
size, invalid request message framing, or deceptive request routing).
wiki
Change the ajax code to:
$.ajax({
url: "/tasks",
type: "POST",
dataType: "json",
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'), // Optional
'Content-Type': 'application/json'
},
data: JSON.stringify({ assignee: assignee }),
success: function(data) {
alert('successfully');
},
error: function(xhr, textStatus, error) {
alert(xhr.statusText+""+textStatus+""+error);
}
});
{assignee} that's a not valid JSON object it should be {assignee: assignee}
Also you should add a valid headers, The 'Content-Type' and (X-CSRF-TOKEN optional)
Solved!
$( "#new_task" ).submit(function(event) {
alert("form: "+assignee);
var value = $('#new_task').find('input[name="task[value]"]').val();
event.preventDefault();
$.ajax({
url: "/tasks",
type: "post",
contentType: "application/json",
data: JSON.stringify({ assignee: assignee, value: value }),
success: function(data) {
alert('successfully');
},
error: function(xhr, textStatus, error) {
alert(xhr.statusText+" "+textStatus+" "+error);
}
});
});
event.preventDefault(); --> without this, the form is submitted twice.
var value = $('#new_task').find('input[name="task[value]"]').val(); --> without this, i could lose my form value because of "post tasks" that reminds to task#create
I have an MVC5 view and in this view I have:
#using (Html.BeginForm("MyAction", "MyController", FormMethod.Post))
{
// My controls
<input type="submit" id="btnSubmit" class="btn btn-primary" value="Submit" />
}
What I want is to make an ajax call checking the record count prior to posting to the controller.
If the record count is high I want to stay on the view and prompt the user.
Everything appears to be working with the exception that the view is still posting to MyAction. I would have expected "return false;" to prevent that.
Why is "return false" not stopping the post to the controller?
$("#btnSubmit").click(function (e) {
var p1= $("#Value1").val();
var p2= $("#Value2").val();
$.ajax({
type: "GET",
url: "/MyController/GetRecordCount",
data: { "param1": p1, "param2": p2 },
async: false
}).done(function (recCount) {
if (recCount> 999)
{
$(".showAdditionalInfo").show();
return false;
}
}).fail(function (xhr, status, err) {
alert(xhr.responseText);
});
});
Your return should be within the click handler itself. Right now it is inside of the AJAX callback.
It should be this instead:
$("#btnSubmit").click(function (e) {
e.preventDefault();
var p1= $("#Value1").val();
var p2= $("#Value2").val();
var doPost = true;
$.ajax({
type: "GET",
url: "/MyController/GetRecordCount",
data: { "param1": p1, "param2": p2 },
async: false
}).done(function (recCount) {
if (recCount> 999)
{
$(".showAdditionalInfo").show();
doPost = false;
}
}).fail(function (xhr, status, err) {
alert(xhr.responseText);
});
return doPost;
});
This assumes that the ajax request will not be async. Once it is then this shouldn't work anymore.
jQuery executes the function "success" if the HTTP status code is in the range of 200 and 299 or is equal to 304.
However, for example, for the code 401 I need jQuery considers that the Ajax call is successful, and it evaluates the response as JSON and executes the function "success".
The problem is that this behavior is hard-coded in the method "done":
// Determine if successful
isSuccess = status> = 200 && status <300 || === status 304;
I do not really see how to do that.
EDIT:
This is what I have for the moment:
var options = {
url: '',
type: 'POST',
data: {},
success: function(response, status){},
error: function(res, status, error){
notify("Une erreur s'est produite !", "danger");
},
complete: function(res, status){}
};
$.extend(options, opts);
var dataString = '';
$.each(options.data, function(key, value){
dataString += ((dataString.length > 0) ? '&' : '') + encodeURIComponent(key) + '=' + encodeURIComponent(value)
});
$.ajax({
url: site_url + options.url,
type: options.type,
data: dataString,
dataType: 'json',
statusCode: {
401: function() {
setTimeout(function(){
location.reload();
}, 2000);
}
},
success: function(response, status){
if (response.response.result.status == 'ok'){
options.success(response, status);
} else {
if ('message' in response.response.result){
notify(response.response.result.message, "danger");
} else if (response.response.errors.length > 0) {
notify(response.response.errors[0], "danger");
}
}
},
error: options.error,
complete: options.complete
});
I want the answer to be parsed according to the dataType provided (which is only for the "success" method), and, in the case of a code 401, processing is the same as for the other responses containing the correct JSON code, except for a further instruction.
I think it is a mistake for jQuery not be able to change the codes indicating a request as having failed. The content of the response may be important anyway and require special processing.
For a complete web page, the browser still displays the content returned by the server in case of error.
Instead of trying to override the "success" callback why not just make the function call inside the "error" callback,ofcourse before checking the specific error occurred.
error: function(a, b, c){
if(a.status == 401){
// Your custom function call / code.
}
}
Do you have to handle the status code in the success or error block? How about the complete block? It follows both outcomes..
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"). As of jQuery 1.5, the complete setting can accept an array of functions. Each function will be called in turn. This is an Ajax Event.
Source: http://api.jquery.com/jquery.ajax/
Example:
$.ajax({
url: "http://www.google.com"
}).success(function(){ //--> use .done() instead
//things to do on success
}).error(function(){ //--> use .fail() instead
//things to do on error
}).complete(function( data ) { //--> use .always() instead
switch(data.status){
//your logic here
}
});
Finally, given the need for that to go through the "complete" method, it is necessary to recode the entire automation of jQuery.
So there is no interest in using $ .ajax in this case.
That's why I had to code this replacement function that uses the jQuery syntax:
var altAjax = function(opts){
var options = {
url: '',
type: 'GET',
data: {},
dataType: 'text',
successCodes: [304, 401, 403, 404, 500],
statusCode: {},
success: [],
error: [],
complete: []
};
$.extend(options, opts);
var success = function(data, textStatus, xhr){
if ($.isArray(options.success)){
$.each(options.success, function(index, callback){
callback(data, textStatus, xhr);
});
} else if ($.isFunction(options.success)){
options.success(data, textStatus, xhr);
}
if ($.isFunction(options.statusCode[xhr.status])){
options.statusCode[xhr.status](data, textStatus, xhr);
}
}
var error = function(xhr, textStatus, errorThrown){
if ($.isArray(options.error)){
$.each(options.error, function(index, callback){
callback(xhr, textStatus, errorThrown);
});
} else if ($.isFunction(options.error)){
options.error(xhr, textStatus, errorThrown);
}
if ($.isFunction(options.statusCode[xhr.status])){
options.statusCode[xhr.status](xhr, textStatus, errorThrown);
}
}
var complete = function(xhr, textStatus){
if ($.isArray(options.complete)){
$.each(options.complete, function(index, callback){
callback(xhr, textStatus);
});
} else if ($.isFunction(options.complete)){
options.complete(xhr, textStatus);
}
}
var dataString = '';
$.each(options.data, function(key, value){
dataString += ((dataString.length > 0) ? '&' : '') + encodeURIComponent(key) + '=' + encodeURIComponent(($.isArray(value) || $.isPlainObject(value)) ? JSON.stringify(value) : value);
});
var req = new XMLHttpRequest();
var url = options.url;
if (options.type.toUpperCase() != 'POST'){
url += ((url.indexOf('?') > -1) ? '&' : '?') + dataString;
}
req.onload = function(){
var textStatus = 'error';
if ((this.status >= 200 && this.status <= 299) || $.inArray(this.status, options.successCodes) > -1) {
var data;
switch (options.dataType.toLowerCase()) {
case 'json':
try {
data = JSON.parse(this.responseText);
} catch (ex){
error(this, textStatus, ex.name + ': ' + ex.message);
break;
}
textStatus = 'success';
success(data, textStatus, this);
break;
case 'xml':
try {
data = $.parseXML(this.responseText);
} catch (ex){
error(this, textStatus, ex.name + ': ' + ex.message);
break;
}
textStatus = 'success';
success(data, textStatus);
break;
default:
textStatus = 'success';
success(this.responseText, textStatus);
}
} else {
error(this, textStatus, null);
}
complete(this, textStatus);
};
req.open(options.type, url, true);
if (options.type.toUpperCase() == 'POST'){
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.send(dataString);
} else {
req.send();
}
req = null;
};
Instead of success use the complete function and check the xhr.statusText value
$.ajax('url.json', {
complete:function(result) {
if(/^(2\d\d|304|401)$/.test(result.statusText)) {
success();
} else {
error();
}
}
});
You need to handle the conditions at client side checking the status code. You can fetch the status as below:
success: function(data, textStatus, xhr) {
console.log(xhr.status);
},
I want to reuse a javascript function using a scala template so I would only have to pass a different success/failure function, but I don't seem to be able to able to pass a javascript function to a scala template.
Please note I'm veeeeerry new to this and don't even know if what I am doing is possible.
This is kind of what I'm trying to achieve:
#(formId: String, success: JavaScript, fail: JavaScript)
<script type="text/javascript">
$("#formId").submit(function(e)
{
var data = $(this).serializeArray();
var action = $(this).attr("action");
$.ajax(
{
url : action,
type: "POST",
data : data,
success:function(data, textStatus, jqXHR) // Change contents to dynamic parameter for scala??? perhaps a javascript function to execute???
{
#success()
/*console.log("save succesfull, progress!")
alert('Save successfull, now move on!');*/
},
error: function(jqXHR, textStatus, errorThrown) // Change contents to dynamic parameter for scala??? perhaps a javascript function to execute???
{
//if fails
#fail()
/*console.log(jqXHR.responseText);
var errors = JSON.parse(jqXHR.responseText);
console.log(errors);
alert('Woops, something went wrong: ' + jqXHR.responseText);*/
}
});
e.preventDefault();
});
</script>
How it would be used:
#snippets.ajaxFormSubmit("#form",
function()
{
alert("Save successfull, now move on!");
},
function()
{
alert("Save failed!");
}
)
You can pass any content to a template via Html type.
#(formId: String, success: Html, fail: Html)
<script type="text/javascript">
$("#formId").submit(function(e)
{
var data = $(this).serializeArray();
var action = $(this).attr("action");
$.ajax(
{
url : action,
type: "POST",
data : data,
success:function(data, textStatus, jqXHR) // Change contents to dynamic parameter for scala??? perhaps a javascript function to execute???
{
#success
},
error: function(jqXHR, textStatus, errorThrown) // Change contents to dynamic parameter for scala??? perhaps a javascript function to execute???
{
#fail
}
});
e.preventDefault();
});
</script>
In a client view you can user it as follows:
#successFunc = {
alert("Save successfull, now move on!");
}
#failureFunc = {
alert("Save failed!");
}
#snippets.ajaxFormSubmit("#form", successFunc, failureFunc)