There are many checkbox pages in my Rails application.
When clicking on one checkbox, its id should immediately be written to database (I use postgresql)
Сheckbox id should be written to the table as an array.
How to implement this with ajax?
An example of my checkbox:
<input name="skill_list[127]" type="hidden" value="0">
<input class="m-enabled" id="skill_list_127" name="skill_list[127]" type="checkbox" value="1">
<label for="skill_list_127">Zoomerang</label>
UserSkillList controller:
def create
skill_id = params[:skill_id].gsub(/\D/, '').to_i if params[:skill_id].present?
#skill_record = UserSkillList.where(user_id: current_user.id).first
#skill_record.skill_id += [skill_id]
#skill_record.save
end
app.js:
$('input[type=checkbox]').click(function(){
if ($(this).is(':checked')) {
checkbox_id = $(this).attr('id');
$.ajax({
type: "POST",
url: "/user_skill_list",
data: {skill_id: checkbox_id}
});
};
});
Related
I need to be able to send a list of a model back to the controller from a view but only when the input has been checked.
Using AJAX I can get it working but the page refreshes and I don't catch the data but it does show up in the URL. Example: https://localhost:44308/PlayTest/PlayTest?personName=Test+User&DevOps-rate=3&Software+Development-rate=2&Solution+Architecture-rate=1&comments=&save=Save
But when I try and use Javascript and JQuery, I'm only able to catch the "person name" not the comments or rates in the post method.
HTML
<div class="tabcontent" id="testing">
<form name="skillform"
id="skillform"
asp-action="SaveRecord"
asp-controller="YourSkills"
data-ajax="true"
data-ajax-method="post">
<h3 class="tab-title">Testing</h3>
#foreach (var item in Model.Skills)
{
#if (item.SkillGroupID == 2)
{
<div class="star-rating">
<h5 class="skill-name" id="skill-title">#item.SkillName</h5>
<input type="radio" id="#item.SkillName#item.SkillGroupID-star3" name="#item.SkillName-rate" value="3" /><label for="#item.SkillName#item.SkillGroupID-star3" title="Advanced - 3 Stars">3 Stars</label>
<input type="radio" id="#item.SkillName#item.SkillGroupID-star2" name="#item.SkillName-rate" value="2" /><label for="#item.SkillName#item.SkillGroupID-star2" title="Intermediate - 2 Stars">2 Stars</label>
<input type="radio" id="#item.SkillName#item.SkillGroupID-star1" name="#item.SkillName-rate" value="1" /><label for="#item.SkillName#item.SkillGroupID-star1" title="Beginner - 1 Star">1 Stars</label>
</div>
<br />
<br />
}
}
<div class="comments">
<h6 class="comment-name">Comments</h6>
<textarea rows="4" cols="50" name="comments" id="comment-text-area" spellcheck="true"></textarea>
</div>
<div class="buttons">
<input type="reset" value="Clear">
<button type="button" class="edit" onclick="alert('This will allow the tab to be edited')">Edit</button> <!--add cancel button when opened-->
<input type="submit" name="save" value="Save" id="btnSave" skill-group="2"/>
</div>
</form>
</div>
Post Method
public JsonResult SaveRecord(string PersonName, List<SkillsModel> skill, string comment)
{
SkillsMatrixDB database = HttpContext.RequestServices.GetService(typeof(SkillsMatrix.Models.SkillsMatrixDB)) as SkillsMatrixDB;
List<PersonModel> people = database.GetAllPeople();
PersonModel recordingPerson = FindPerson(people, PersonName);
if (skill.Count() > 1)
{
for (int i = 0; i < skill.Count(); i++)
{
RecordsModel records = new RecordsModel();
records.PersonID = recordingPerson.PersonID;
records.SkillGroupID = skill[i].SkillGroupID;
records.SkillID = skill[i].SkillID;
records.SkillLevelID = Convert.ToInt32(HttpContext.Request.Form[skill[i].SkillName + skill[i].SkillGroupID + "-rate"]);
records.Comments = HttpContext.Request.Form["comments"].ToString();
records.DateSaved = DateTime.Now;
records.YearlyQuarter = DateTime.Now.Month / 3;
//database.SaveRecord(records);
}
}
else if (skill.Count() == 1)
{
RecordsModel records = new RecordsModel();
records.PersonID = recordingPerson.PersonID;
records.SkillGroupID = skill[0].SkillGroupID;
records.SkillID = skill[0].SkillID;
records.SkillLevelID = Convert.ToInt32(HttpContext.Request.Form[skill[0].SkillName + skill[0].SkillGroupID + "-rate"]);
records.Comments = HttpContext.Request.Form["comments"].ToString();
records.DateSaved = DateTime.Now;
records.YearlyQuarter = DateTime.Now.Month / 3;
//database.SaveRecord(records);
}
return Json(recordingPerson.Name);
}
JS
$(document).ready(function () {
$("#btnSave").click(function () {
$.ajax({
contentType: 'application/json; charset=utf-8',
dataType: 'json',
type: "POST", //HTTP POST Method
url: "YourSkills/SaveRecord", //Controller/View
data: $('#skillform').serialize(),
success: function (data) {
console.log(data);
alert('You saved it!');
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(textStatus);
alert('Something went wrong. save failed!');
}
});
});
});
I feel like the way I've read to make the list in JS is wrong and to catch the data is not all that correct either. If someone could help that would be great. I'm so confused why doing it without JS works and picks up the right data but for some reason, I can't.
EDIT
I have tried what Emiel Zuurbier said but I am using Visual Studio 2019 and In the console, all I am getting is the following:
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request starting HTTP/2.0 POST https://localhost:44308/PlayTest/YourSkills/SaveRecord application/json; charset=UTF-8 235
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request finished in 6.0162ms 404
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request starting HTTP/2.0 POST https://localhost:44308/PlayTest/SaveRecord application/x-www-form-urlencoded 233
Failed to load resource: the server responded with a status of 404 () [https://localhost:44308/PlayTest/YourSkills/SaveRecord]
Microsoft.AspNetCore.Routing.EndpointMiddleware: Information: Executing endpoint 'SkillsMatrix.Controllers.PlayTestController.SaveRecord (SkillsMatrix)'
error
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Information: Route matched with {action = "SaveRecord", controller = "PlayTest"}. Executing controller action with signature Microsoft.AspNetCore.Mvc.JsonResult SaveRecord(System.String, System.Collections.Generic.List`1[SkillsMatrix.Models.SkillsModel], System.String) on controller SkillsMatrix.Controllers.PlayTestController (SkillsMatrix).
Your page is being reloaded because you are submitting the form whenever you click the the #btnSave button. What you want to do is listen for the submit event on the form itself and cancel it with event.preventDefault(). This allows you to create your own submission behavior when submitting. And prevents the form from reloading the page.
$(document).ready(function() {
$('#skillform').on('submit', function(event) {
...
event.preventDefault();
});
});
Your HTML seems to miss the #skill-id element. If you mean to include data from your form into your controller then I suggest that you use hidden input fields instead of reading attributes from your elements.
<input type="hidden" name="skill-name" value="">
<input type="hidden" name="skill-id" value="">
<input type="hidden" name="skill-group" value="">
These fields will not be visible to the user but will contain data that the server is able to read.
Then instead of use .val() to get each individual field use $('form').serialize() to extract the name and value pairs out of the form and use them in your AJAX request. This way you are sending the same data as you would with a normal submit.
$.ajax({
contentType: 'application/json; charset=utf-8',
dataType: 'json',
type: "POST",
url: "YourSkills/SaveRecord",
data: $('#skillform').serialize(); // <-- Get all values from the form.
success: function (data) { // <-- data is the response you receive from the controller.
console.log(data);
alert('You saved it!');
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Something went wrong. save failed!');
}
});
I recommend that you check the $.ajax docs to use the correct methods and notation to use the function properly.
page reloading may happens because the error occurred in js execution while you are creating skills object.as its not the right way
define skills object this way rest of the things look good.
let skills = {};
skills['SkillID'] = $("#skill-id").val();
skills['SkillGroupID'] = $(this).attr('skill-group');
skills['SkillName'] = $("#skill-title").val();
I'm a newbie Javascript learner and I want to post serialized data of input checkboxes. The data are sent to the server in order to update the corresponding field in SQL table. Later, the user can review the selections he made the first time and deselect some checkboxes. If I understand well, only the selected items will be sent, not the unselected ones. How can I send all the info I need to update the newly selected items and the newly unselected ones?
The only solution I found is to make 2 updates: the first resets to 0 all the rows and the second one sets to 1 the selected items (newly selected or not) that are sent in the serialized array. Is there a more optimal way to do the job? Ideally, I would update only the data that have changed. Is it possible?
Regards,
Patrick
If I understand it correctly you can filter the checkboxes and then you can add the unselected boxes to the parameters too.
I've found the code for that here at SO. See this question.
The demo below and here a jsfiddle is doing a ajax post only if the user changed the data. Not sure if this is what you want.
(The demo at SO is a bit modified because JSONP is required to get no CORS error.)
var data = "";
$('form').submit(function (evt) {
evt.preventDefault();
//console.log($(this).serialize());
var formData = $(this).serialize();
// source from this SO question https://stackoverflow.com/questions/10147149/how-can-i-override-jquerys-serialize-to-include-unchecked-checkboxes
// include unchecked checkboxes. use filter to only include unchecked boxes.
$.each($('form input[type=checkbox]')
.filter(function (idx) {
return $(this).prop('checked') === false
}),
function (idx, el) {
// attach matched element names to the formData with a chosen value.
var emptyVal = "off";
formData += '&' + $(el).attr('name') + '=' + emptyVal;
});
console.log(formData);
if ( data != formData ) { // check if user changed the data.
$.ajax({
url: 'http://jsfiddle.net/echo/jsonp/',
type: 'POST',
//data: formData, // this will work but for jsfiddle echo the code below is required.
dataType: "jsonp",
data: {
json: JSON.stringify({
serialized: formData
}),
delay: 1
},
success: function(res) {
console.log('posted: ', res);
}
});
}
data = formData;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<label for="first">check1</label>
<input name="first" id="first" type="checkbox" />
<label for="second">check2</label>
<input name="second" id="second" type="checkbox" />
<label for="third">check3</label>
<input name="third" id="third" type="checkbox" />
<label for="fourth">check4</label>
<input name="fourth" id="fourth" type="checkbox" />
<input type="submit" value="update" />
</form>
How I can get the values of these elements and post them as array by ajax:
<input type="checkbox" name="Broadcast[m]"/> Members
<input type="checkbox" name="Broadcast[i]"/> IATA agencies
<input type="checkbox" name="Broadcast[n]"/> non-IATA agencies
<input type="checkbox" name="Broadcast[c]"/> Commitees
try this:
First change your input name to simply name="Broadcast[]"
<input type="checkbox" name="Broadcast[]" value="Members"/> Members
<input type="checkbox" name="Broadcast[]" value="IATA agencies"/> IATA agencies
<input type="checkbox" name="Broadcast[]" value="non-IATA agencies"/> non-IATA agencies
<input type="checkbox" name="Broadcast[]" value="Commitees"/> Commitees
and then in jquery to send the data in array via ajax, create a variable to mapping all the values to an array.
jquery:
var BroadCast = $("input[name='BroadCast\\[\\]']").map(function () { return $(this).val(); }).get();
and put the variable BroadCast into the ajax data.
$.ajax({
type:"post",
url:'your action url',
data: {BroadCast: BroadCast},
success:function(data){
//do what you want here
}
});
Hope this helps you.
var items = $("input[type=checkbox][name^=Broadcast]"), values = [];
items.each(function(){
values.push([$(this).attr("name"),$(this).is(":checked")]);
});
console.log(values);
sorry was wrong before, here is a fiddle for you
fiddle
you can use serialize method to do this.first in your html add value to checkboxes and remove whatever inside [] and make it name='Broadcast[]' for each checkbox.
$.ajax({
type:"post",
url:'your url',
data:$("form").serialize(),
success:function(data){
//do stuff here
}
});
I have multiple input fields of checkboxes and textboxes. I want to post the data of the textboxes respective to the selected checkboxes.
Here's the scenario: I'm making an add to cart page. If one checkbox is checked, it will then retrieve the values from the textbox with the same key as the checkbox. Checkboxes and textboxes are created dynamically in PHP while fetching data from the database.
I've named each checkboxes in an array manner as well as the textboxes like this name="checkbox[1]" and name="textbox[1]" and so on.
The thing is, i cannot pass that data through jquery/ajax. I've tried using .map() function together with .get() function but still of no use. .serialize() isn't working for me as well. This is done in a wordpress plugin, Thanks.
HTML: <input type='check' name='checkbox[1]' value='' />
<input type='text' name='textbox[1]' value='' />
<input type='check' name='checkbox[2]' value='' />
<input type='text' name='textbox[2]' value='' />
var dataFromInput1 = $( "input[value='textbox[1]']" ).val;
var dataFromInput2 = $( "input[value='textbox[2]']" ).val;
var dataFromInput3 = $( "input[value='textbox[3]']" ).val;
$.ajax({
type: "POST",
url: "../WebService.php",
data: { 'data1': dataFromInput1,'data2': dataFromInput2,'data3': dataFromInput3 },
contentType: "application/json; charset=utf-8",
dataType: "json"
});
I'm working on a website which should be done any time now, but I've got a new task to complete where I need to check check-boxes to simply archive news items. Or "blog posts" if you like.
The idea is to have a check-box on every blog post and if you check that check-box, the post should be archived. (This is in admin mode only).
I need ajax to do the job, but I haven't learned that yet. The PHP part is no problem.
Well the problem really is that I don't know how to pass the unique ID of every check-box, to the JavaScriptfunction and then to the PHP function.
OK, I have a set of blog posts, witch check-boxes, like so:
<div class="news_item">
<input name="checkbox_blog" id="checkbox1" value="1" type="checkbox" />
</div>
<div class="news_item">
<input name="checkbox_blog" id="checkbox2" value="1" type="checkbox" />
</div>
and so on. The Id's are populated from the ID from MySQL.
I have some kind of plugin for ajax checkboxes, but it will only work for one checkbox.
It's basically like this:
$("#checkbox").change(function() {
if($(this).is(":checked")) {
$.ajax({
url: 'admin/archive_it',
type: 'POST'
});
} else {
$.ajax({
url: 'admin/dont_archive_it',
type: 'POST'
});
}
});
Works great on one check-box, but I have no idea how to proceed.
Any tips?
I think it's OK that it uses two different php-scripts for checking and un-checking the blog-posts, it doesn't really matter, I only want it to start working with different check-boxes.
Thanks!
Solution:
I changed the id's to classes, and used Arun P Johny's code:
$('.checkbox_blog').change(function () {
$.ajax({
url: this.checked ? 'admin/archive_it' : 'admin/dont_archive_it',
type: 'POST',
data: {
id: this.value
}
});
});
And because I'm using CodeIgniter, and have the CSRF-security option turned on, I had to add this to the data:
<?=$this->security->get_csrf_token_name()?> : '<?=$this->security->get_csrf_hash()?>',
And now it works perfectly! Thanks all!
There is no need for an ID here, use a class attribute to group the check boxes and give the database id as the value of the checkbox
<div class="news_item">
<input name="checkbox_blog" class="checkbox_blog" value="1" type="checkbox" />
</div>
<div class="news_item">
<input name="checkbox_blog" class="checkbox_blog" value="2" type="checkbox" />
</div>
then in the write change handlers for the .checkbox_blog elements, and pass the id of the database item to to archived or not as a parameter to the server side PHP
$('.checkbox_blog').change(function () {
$.ajax({
url: this.checked ? 'admin/archive_it' : 'admin/dont_archive_it',
type: 'POST',
data: {
id: this.value
}
});
});
you are almost there, except that there were few things which you may need to take care ,like
add a generic class for all the checkboxes, so that the below event handler will work fine for all checkboxes.
there is no need to keep multiple ajax call references, although url is the only differentiator,so i have refined your code and even corrected few things which i noticed .
JS CODE:
$(".checkbox").on('change',function() {
var chkBit=$(this).is(":checked");
var url;
if(chkBit)
tarUrl='admin/archive_it';
else
tarUrl='admin/dont_archive_it';
$.ajax({
url: tarUrl,
type: 'POST',
success:function(){
//when the call is successful do something
}
});
});`
Give all your checkboxes same class and then on change of any checkbox pass the ids of the checkboxes that are selected using the data attribute(probably by iterating over all the checkboxes with the class and collecting the ids of the ones that are checked)
<input name="checkbox_blog" id="checkbox1" value="1" type="checkbox" onClick="YourFunction()" />
<input name="checkbox_blog" id="checkbox2" value="1" type="checkbox" onClick="YourFunction()" />
function YourFunction(){
if($(this).is(":checked")) {
$.ajax({
url: 'admin/archive_it',
type: 'POST'
});
} else {
$.ajax({
url: 'admin/dont_archive_it',
type: 'POST'
});
}
}
if you are dead-set on using id from checkbox, you can pass data like so: (note the change to selector $("input[id^=checkbox]")
$("input[id^=checkbox]").change(function() {
if($(this).is(":checked")) {
$.ajax({
url: 'admin/archive_it',
type: 'POST',
data: {
id: $(this).attr('id').split('checkbox')[1]
}
});
} else {
$.ajax({
url: 'admin/dont_archive_it',
type: 'POST',
data: {
id: $(this).attr('id').split('checkbox')[1]
}
});
}
});