Using ajax to check radiobutton by Id in ASP.Net MVC - javascript

I saw a code that checks the radio button by value, but how do I do this by id? My current scenario is that I'm populating a table by appending html codes using ajax. I'm looping the prices of a certain item while building the html table. After that, I need to check the radio button of a price where default flag is equal to 'Y'.
Here's my if statement that checks the radiobutton by value only, this is not working yet as my radiobutton values are null, only the id and name has value:
if (item.defaultflag == 'Y')
$('#divItemPrice').find(':radio[name=rbDefaultPrice][value="iPrice_' + item.channelid + '"]').prop('checked', true);
else
$('#divItemPrice').find(':radio[name=rbDefaultPrice][value="iPrice_' + item.channelid + '"]').prop('checked', false);
Complete code:
$.ajax({
url: '/Item/RetrievePrice',
type: 'POST',
dataType: 'json',
data: JSON.stringify(json),
contentType: 'application/json; charset=utf-8',
cache: false,
async: true,
success: function (data) {
var trHTML = "";
debugger;
trHTML = '<tbody id="dbBody2">';
$.each(data, function (i, item) {
trHTML += '<tr><td class="hidden">' + item.itemid + '</td>' +
'<td style="width:20px"><label><input type="radio" name="rbDefaultPrice" id = "iPrice_' + item.itemid + '" /></label></td>' +
'<td>' + item.itemprice + '</td>' +
'<td>' + ToJavaScriptDate(item.startdate) + '</td>' +
'<td>' + ToJavaScriptDate(item.enddate) + '</td>' +
'</tr>';
//How do I check the radiobutton by id?
if (item.defaultflag == 'Y')
$('#divItemPrice').find(':radio[name=rbDefaultPrice][value="iPrice_' + item.itemid + '"]').prop('checked', true);
else
$('#divItemPrice').find(':radio[name=rbDefaultPrice][value="iPrice_' + item.itemid + '"]').prop('checked', false);
});
trHTML += '</tbody>';
$("#tblItemPrice tbody").remove();
$('#tblItemPrice').append(trHTML);
},
error: function (xhr, ajaxOptions, thrownError) {
alert("Error! " + xhr.status);
}
});
View (modal part)
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<div id="divItemPrice" class="" style="border: 0px solid green; ">
<table id="tblItemPrice" onclick="gettabledata('tblItemPrice', '0,2,3,4', 'itemPriceId,itemPrice,strtDt,endDt')" class="table table-hover table-bordered table-striped bootgrid-table" aria-busy="false" padding-left:10px;">
<thead>
<tr class="inner-table-head">
<th class="hidden">
#Html.DisplayNameFor(model => model.itemPriceId)
</th>
<th>
Price
</th>
<th>
Start Date
</th>
<th>
End Date
</th>
</tr>
</thead>
<tbody id="bodyToAppend">
</tbody>
</table>
</div>
<div class="form-group">
<div class="row form-row">
<span class="form-item">
#Html.HiddenFor(m => m.itemPriceId)
#Html.LabelFor(m => m.itemPrice, new { #class = "lbl-width" })
#Html.TextBoxFor(m => m.itemPrice, new { #class = "form-control input-sm" })
</span>
</div>
<div class="row form-row">
<span class="form-item ">
#Html.LabelFor(m => m.strtDt, new { #class = "lbl-width" })
#Html.TextBoxFor(m => m.strtDt, new { #class = "form-control input-sm", #Value = "" })
</span>
</div>
<div class="row form-row">
<span class="form-item ">
#Html.LabelFor(m => m.endDt, new { #class = "lbl-width" })
#Html.TextBoxFor(m => m.endDt, new { #class = "form-control input-sm", #Value = "" })
</span>
</div>
<div class="row form-row maintenance-btn">
<div class="btn-group">
<input type="submit" id="btnSavePrice" value="Save" class="btn btn-theme btn-sm" formmethod="post" />
<input type="submit" id="btnUpdatePrice" value="Update" class="btn btn-theme btn-sm" formmethod="post" style="display:none" />
#*<input type="submit" id="btnCancelPrice" value="Cancel" class="btn btn-theme btn-sm" />*#
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button id="closeModal" type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>

The code in your if/else block cannot work because its attempting to .find() and element in the DOM which does not even exist yet (you have not added it). And even if you did add the <tr> to the DOM in each iteration it would result in poor performance (searching the whole table in each iteration).
A simple way to solve this (and much easier to debug the html your generating) is to create a hidden template that is cloned and added in each iteration. I also assume that you want to add the value of itemprice as the value attribute of the radio button so that you can get the value of the selected radio button using var price = $('input[name="rbDefaultPrice"]').val();
<table id="template" style="display:none;">
<tr>
<td>
<label>
<input type="radio" name="rbDefaultPrice" class="radio" />
<span class="price"></span>
</label>
</td>
<td class="startdate"></td>
<td class="enddate"></td>
</tr>
</table>
Then in the .each() loop, clone the template, update its values and append it to the DOM
var tbody = $('#tblItemPrice tbody');
....
success: function (data) {
tbody.empty() // remove existing rows
$.each(data, function (i, item) {
// clone the template row
var row = $('#template').clone().find('tr');
// update properties
var radio = row.find('.radio');
radio.val(item.itemprice);
if (item.defaultflag == 'Y') {
radio.prop('checked', true);
}
row.find('.price').text(item.itemprice);
row.find('.startdate').text(....
// add the row to the DOM
tbody.append(row);
});
}
Side note: Its not clear what your ToJavaScriptDate() function is doing, but I suggest you just pass the correctly formatted value to client so you can just use row.find('.startdate').text(item.startdate); etc

Related

jquery Validate Casuing Initail invalid elements to become valid on second 'save' button click

So, I am trying to use jQuery Validate to check for duplicate values in a form, and it's working for the most part. However, I am getting the following weird behavior:
The user will enter a couple duplicate values, and click save
jQuery Validate will show 'Duplicate Name' in the UI for each of the duplicate values
The user does not fix the duplicate values, but rather, adds another duplicate value
The user clicks save again, and the previous two invalid elements are marked valid, and the Duplicate Name message disappears, but the third value is correctly marked as invalid.
If the user clicks save again, then all three error messages are shown correctly.
If the user clicks on save without correcting any, the client-side validation is not followed and the server-side errors are shown for duplicate values.
Basically, I'm wondering what is wrong with my jQuery validation logic? Is it that I'm not forcing a revalidation every time the save button is clicked?
Here is my jQuery Validation code:
$.validator.addMethod("checkForDuplicateClaimName", function (value, element) {
console.log('calling checkDuplicateClaimName')
var customClaimForm = $("form.form-horizontal");
var claimRepeated = 0;
if (value != '') {
var matchingClaims = 0;
// Loop through the whole form to find duplicate claim names
customClaimForm.children().each(function (count, item) {
// Have to iterate through the custom claim div to find the names
if ($(item).attr("id") === "custom-claims-div") {
var customClaimDiv = $("#custom-claims-div");
customClaimDiv.children().each(function (count, claim) {
var customClaimNameToCompare = $(claim).find('label').text();
if (value == customClaimNameToCompare) {
matchingClaims++;
}
});
}
// Not the custom claim div, just the labels from the default scopes
else {
var nameToCompare = $(item).find('label').text();
if ((value == nameToCompare)) {
matchingClaims++;
}
}
});
}
return matchingClaims === 1 || matchingClaims === 0;
}, "Duplicate Name");
$.validator.addClassRules("duplicateClaimName", {
checkForDuplicateClaimName: true
});
var validate = $("form.form-horizontal").validate({
ignore: "", // This checks hidden input values, which is what we want for the claim name validation
errorElement: 'div',
errorClass: 'custom-claim-validation-error',
errorPlacement: function (error, element) {
error.appendTo($(element).parent().find("#claim-name-lbl"))
},
submitHandler: function (form) {
console.log('calling submit handler');
form.submit();
}
});
$('form.form-horizontal').submit(function () {
console.log('calling submit form');
console.log(validate);
});
Here is the code for when a new claim is added to the custom-claims-div. It is the code that adds the class duplicateClaimName for jquery validation.
function oidc_addCustomProfileClaim() {
// Grab the custom claim name and value
var customAttName = $("#dialog-add-custom-scope-claim #customAttName").val();
var customAttValue = $("#dialog-add-custom-scope-claim #customAttValue").val();
// Get the last index of the custom claim div
var lastId: number = -1;
var div = $("#custom-claims-div");
if ($("#custom-claims-div").children().length) {
lastId = parseInt($("#custom-claims-div").children().last().attr("data-id"), 10);
}
lastId++;
// Create the new form-group
var newDiv = $("<div data-id=\"" + lastId + "\" id=\"claim-info-div\" class=\"form-group row\">");
newDiv.append("<label data-id=\"" + lastId + "\" id=\"claim-name-lbl\" name=\"CustomClaims[" + lastId + "].ClaimLabel\" class=\"col-sm-2 control-label no-padding-right\" style=\"padding-right: 10px! important;\" value=\"" + customAttName + "\">" + customAttName + "</label>");
//Need to make a hidden input so that the model will be correctly filled when passed to the controller
newDiv.append("<input data-id=\"" + lastId + "\" id=\"claim-value\" name=\"CustomClaims[" + lastId + "].ClaimValue\" type=\"text\" class=\"col-md-5\" value=\"" + customAttValue + "\" />")
newDiv.append("<input id=\"hidden-claim-value\" name=\"CustomClaims[" + lastId + "].ClaimLabel\" class=\"duplicateClaimName\" type=\"hidden\" value=\"" + customAttName + "\" />")
// Create the label for disabling/enabling the claim
newDiv.append("<input data-id=\"" + lastId + "\" id=\"disable-claim-chkbx\" name=\"CustomClaims[" + lastId + "].IsDisabled\" style=\"margin-left: 75px;\" type=\"checkbox\" value=\"false\"/>");
// Create the Button
var button = $("<button class=\"btn btn-xs btn-white btn-danger\" data-action=\"delete\" style=\"margin-left: 79px; width=80px;\" type=\"button\">");
var deleteText = $("<i class=\"ace-icon fa fa-trash-o fa-lg\">");
// Build the form group
button.append(deleteText);
button.append(" Delete");
newDiv.append(button);
div.append(newDiv);
}
This is the modal JS to add a new claim to the form:
$("#dialog-add-custom-scope-claim").dialog({
autoOpen: false,
resizable: false,
modal: true,
width: 420,
title: "<div class=\"widget-header\">Add a new profile custom scope</div>",
title_html: true,
buttons: [
{
text: "Add",
"class": "btn btn-primary btn-xs no-border",
click: function () {
oidc_addCustomProfileClaim();
$('#new-claim-name-form').find('#customAttName').val('');
$('#new-claim-value-form').find('#customAttValue').val('');
$(this).dialog("close");
}
},
{
text: "Cancel",
"class": "btn btn-xs no-border",
click: function () {
$('#new-claim-name-form').find('#customAttName').val('');
$('#new-claim-value-form').find('#customAttValue').val('');
$(this).dialog("close");
}
}
]
});
The elements in question have the correct duplicateClaimName class in the HTML:
<input id="hidden-claim-value" name="CustomClaims[#i].ClaimLabel" type="hidden" class="duplicateClaimName" value="#Model.CustomClaims[i].ClaimLabel" />
Thanks in advance for any input!
Edit:
Here is the relevant HTML for my form submit button, if it helps:
#using (Html.BeginFormWithCss("form-horizontal"))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "Please, fix the following errors.", new { #class = "alert alert-block alert-danger no-style-list" })
<h3 class="header smaller lighter green">Scope profile</h3>
<div class="form-group">
<label class="col-sm-2 control-label no-padding-right">Name</label>
<div class="col-sm-10">
<input id="Name" name="Name" type="text" data-auto="attributes" class="col-xs-12 col-md-4" value="#Model.Name" />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label no-padding-right">FamilyName</label>
<div class="col-sm-10">
<input id="FamilyName" name="FamilyName" type="text" data-auto="attributes" class="col-xs-12 col-md-4" value="#Model.FamilyName" />
</div>
</div>
<div id="custom-claims-div" class="form-group">
#if (#Model.CustomClaims.Count() > 0)
{
for (int i = 0; i < #Model.CustomClaims.Count(); i++)
{
<div data-id="#i" id="claim-info-div" class="form-group row">
<label data-id="#i" id="claim-name-lbl" name="CustomClaims[#i].ClaimLabel" class="col-sm-2 control-label no-padding-right" style="padding-right: 10px !important;" value="#Model.CustomClaims[i].ClaimLabel">#Model.CustomClaims[i].ClaimLabel</label>
<input data-id="#i" id="claim-value" name="CustomClaims[#i].ClaimValue" type="text" data-auto="attributes" class="col-md-5" value="#Model.CustomClaims[i].ClaimValue" />
<input id="hidden-claim-value" name="CustomClaims[#i].ClaimLabel" type="hidden" value="#Model.CustomClaims[i].ClaimLabel" />
#if (Model.CustomClaims[i].IsDisabled)
{
<input data-id="#i" id="disable-claim-chkbx" name="CustomClaims[#i].IsDisabled" style="margin-left: 75px;" type="checkbox" checked="checked" value="true" />
}
else
{
<input data-id="#i" id="disable-claim-chkbx" name="CustomClaims[#i].IsDisabled" style="margin-left: 75px;" type="checkbox" value="false" />
}
<button class="btn btn-xs btn-white btn-danger" data-action="delete" style="margin-left: 75px;" type="button">
<i class="ace-icon fa fa-trash-o fa-lg"></i>
Delete
</button>
</div>
}
}
</div>
<div id="dialog-add-custom-scope-claim" class=modal>
<div>
<div id="new-claim-name-form" class="form-group">
<label class="control-label">Claim Name</label>
<input id="customAttName" style="margin-bottom: 10px" type="text" value="" class="col-xs-12" placeholder="Claim Name" />
</div>
<div id="new-claim-value-form" class="form-group">
<label class="control-label">Claim Value</label>
<input id="customAttValue" type="text" value="" class="col-xs-12" placeholder="Claim Value (attribute name from FID)" />
</div>
</div>
</div>
<div class="clearfix form-actions">
<div class="col-md-offset-1 col-md-9">
<button class="btn btn-info" type="submit">
<i class="ace-icon fa fa-check fa-lg"></i>
Save
</button>
<a class="btn" href="#Url.Action("Index")">
<i class="ace-icon fa fa-times fa-lg"></i>
Cancel
</a>
</div>
</div>

The event in jquery popup is triggered more than once

I am working on a survey application using Asp.net MVc. My events in jquery popup are triggered more than once. The more a popup is opened, the more it triggers in the event in the popup. What is the reason of this. Every time browsers are opened, the temporary javascript file that starts with the VM is removed. When the popup is closed, these opened virtual javascript files are not destroyed. What is the reason of this?
These events include adding rows to the table, updating and deleting rows.The AddOrEdit.cshtml file contains both screen components and javascript codes.
Images;
AddOrEdit.cshtml(Jquery Popup)
#using MerinosSurvey.Models
#model Questions
#{
Layout = null;
}
#using (Html.BeginForm("AddOrEdit", "Question", FormMethod.Post, new { onsubmit = "return SubmitForm(this)", onreset = "return ResetForm(this)", id = "questionForm" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group row">
#Html.Label("QuestionId", "Soru No", new { #class = "col-form-label col-md-3" })
<div class="col-md-9">
#Html.TextBoxFor(model => model.QuestionId, new { #readonly = "readonly", #class = "form-control", })
</div>
</div>
<div class="form-group row">
#Html.Label("QuestionName", "Soru Adı", new { #class = "col-form-label col-md-3" })
<div class="col-md-9">
#Html.EditorFor(model => model.QuestionName, new { htmlAttributes = new { #class = "form-control"
} })
#Html.ValidationMessageFor(model => model.QuestionName)
</div>
</div>
<div class="form-group row">
<div class="col-md-9 offset-md-3">
<div class="custom-control custom-checkbox">
#Html.CheckBoxFor(m => m.IsOtherOptionRequired, new { #class = "custom-control-input ", id = "IsOtherOptionRequired", })
<label class="custom-control-label" for="IsOtherOptionRequired">Diğer Seçeneği Eklensin mi?
</label>
</div>
</div>
</div>
<br>
<hr class="style14">
<br>
#Html.ValidationMessageFor(model => model.Options)
<div class="table-wrapper form-group table-responsive-md">
<div class="table-title">
<div class="form-group row">
<div class="col-md-9">Options</div>
<div class="col-md-3">
<button type="button" class="btn btn-success add-new" style="margin-bottom: 10px"><i class="fa fa-plus"></i>Add Option</button>
</div>
</div>
</div>
<table class="table optionTable">
<thead class="thead-light">
<tr>
<th style="display:none;" width="20%" scope="col">Seçenek Id</th>
<th scope="col">Option Name</th>
<th width="25%" scope="col">Update/Delete</th>
</tr>
</thead>
<tbody>
#foreach (Options options in Model.Options)
{
<tr>
<td style="display:none;">#options.OptionId</td>
<td>#options.OptionName</td>
<td>
<a class="add btn btn-primary btn-sm" title="Add" data-toggle="tooltip">
<i class="fa fa-check">Approve</i>
</a>
<a class="edit btn btn-secondary btn-sm" title="Edit" data-toggle="tooltip">
<i class="fa fa-pencil">Update</i>
</a>
<a class="delete btn-danger btn-sm" title="Delete" data-toggle="tooltip">
<i class="fa fa-trash">Delete</i>
</a>
</td>
</tr>
}
</tbody>
</table>
</div>
<div class="form-group row d-flex justify-content-end">
<button type="submit" class="btn btn-primary" style="margin-bottom: 10px; color: black"><i class="fa fa-save"></i>Kaydet</button> </div>
}
Jquery add, edit, delete click events
<script>
$(document).ready(function () {
$('[data-toggle="tooltip"]').tooltip();
//var actions = $("table.optionTable td:last-child").html();
var actions =
' <a class="add btn btn-primary btn-sm" title="Add" data-toggle="tooltip"><i class="fa fa-check">Onayla</i></a>' +
'<a class="edit btn btn-secondary btn-sm" title="Edit" data-toggle="tooltip"><i class="fa fa-pencil">Güncelle</i></a>' +
'<a class="delete btn-danger btn-sm" title="Delete" data-toggle="tooltip"><i class="fa fa-trash">Sil</i></a>';
// Append table with add row form on add new button click
$(".add-new").click(function () { //RUNS MULTIPLE TIMES ON CHROME
debugger;
$(this).attr("disabled", "disabled");
$(".btnSubmit").attr("disabled", "disabled");
var index = $("table.optionTable tbody tr:last-child").index();
var row = '<tr>' +
'<td style="display:none;">0</td>' +
'<td><input type="text" class="form-control" name="optionName" id="optionName"></td>' +
'<td>' +
actions +
'</td>' +
'</tr>';
$("table.optionTable").append(row);
$("table.optionTable tbody tr").eq(index + 1).find(".add, .edit").toggle();
$('[data-toggle="tooltip"]').tooltip();
});
// Add row on add button click
$(".add").click(function () { //RUNS MULTIPLE TIMES ON CHROME
debugger;
var empty = false;
var input = $(this).parents("tr").find('input[type="text"]');
input.each(function () {
if (!$(this).val().trim()) {
$(this).addClass("error");
empty = true;
} else {
$(this).removeClass("error");
}
});
$(this).parents("tr").find(".error").first().focus();
if (!empty) {
input.each(function () {
$(this).parent("td").html($(this).val().trim());
});
$(this).parents("tr").find(".add, .edit").toggle();
$(".add-new").removeAttr("disabled");
$(".btnSubmit").removeAttr("disabled");
}
});
// Edit row on edit button click
$(".edit").click(function () { //RUNS MULTIPLE TIMES ON CHROME
debugger;
/*td: nth - child(2)*/
//$(this).parents("tr").find("td:nth-child(2)").each(function () {
$(this).parents("tr").find("td:not(:first-child, :last-child)").each(function () {
$(this).html('<input type="text" class="form-control" value="' + $(this).text() + '">');
});
$(this).parents("tr").find(".add, .edit").toggle();
$(".add-new").attr("disabled", "disabled");
$(".btnSubmit").attr("disabled", "disabled");
});
// Delete row on delete button click
$(".delete").click(function () {//RUNS MULTIPLE TIMES ON CHROME
debugger;
$(this).parents("tr").remove();
$(".add-new").removeAttr("disabled");
var rowCount = $('table.optionTable tbody tr').length;
if (rowCount > 0) {
$(".btnSubmit").removeAttr("disabled");
} else {
$(".btnSubmit").attr("disabled", "disabled");
}
});
});
It seems you are binding event multiple time by using class selector. It means After adding new DOM in the document, bind a click event on newly added action buttons, but it is binding click event on existing action buttons also.
So simple tick to solve your problem is you have to unbind existing click event and bind new once.
$(".add-new").unbind('click').bind('click', function(){
//your code here
});
$(".add").unbind('click').bind('click', function(){
//your code here
});
$(".edit").unbind('click').bind('click', function(){
//your code here
});
$(".delete").unbind('click').bind('click', function(){
//your code here
});
You can use jQuery on/off methods to handle this.
$(".add-new").off('click').on('click', function(){
});
When you open popup for the second time I believe running $(".add-new").length will return 2 for you. Try to resolve that first which will automatically resolve your events problem.
Do changes such that $(".add-new").length is always 1

How to print the values in jquery into html text?

I wanted to join the HTML text with the values of the item.certificate_name.
I've tried many things but any of it didn't works.
The line I mean is I commented <!-- I WANTED THE CERTIFICATE NAME TO BE HERE-->. I've already inspected, I've already got the name value. The only problem is how to join the text with the value?
<div class="col-xs-12">
<div class="row">
<div class="col-xs-2">
<i class="glyphicon glyphicon-trash center" style="font-size: 50px"></i>
</div>
<div class="col-xs-8">
<div class="clTulisanHapus center" id="idTulisanHapus">
Anda Yakin ingin menghapus Pelatihan?
<!-- I WANTED THE CERTIFICATE NAME TO BE HERE -->
</div>
</div>
</div>
</div>
<div class="col-md-offset-8">
<div class="btn-group">
<input type="hidden" id="idDataId">
<input type="hidden" id="idDataNama">
<button type="button" id="idBtnHapusBatal" class="btn clBtnMdlHapus">Tidak</button>
<button type="button" id="idBtnHapusHapus" data-id="${item.id}" class="btn clBtnMdlHapus">Ya</button>
</div>
</div>
$('#idBtnHapusHapus').click(function() {
var angka = $('#idDataId').val();
var angka = $('#idDataNama').val();
debugger;
$.ajax({
url: './hapussertifikasi/' + angka,
type: 'DELETE',
success: function(model) {
debugger;
window.location = './sertifikasi'
},
error: function(model) {
debugger;
}
});
});
Use Node.textContent to concatenate the text content of the div with item.certificate_name value and CSS white-space: pre; to wrap text on line breaks:
var item = {
certificate_name: 'Certificate Name'
};
var div = document.getElementById('idTulisanHapus');
div.style.whiteSpace = "pre";
div.textContent += ' ' + item.certificate_name
<div class="clTulisanHapus center" id="idTulisanHapus">
Anda Yakin ingin menghapus Pelatihan?
</div>

How can i store at a time 3 value same textbox?

<script type="text/javascript">
document.getElementById("subcategory").addEventListener("change", function() {
console.log(this.value);
});
$(function(){
$('.categoryList').click(function(){
console.log($(this).attr("name"));
var cat_id = event.target.value;
var url = "http://localhost:8000/api/getSubcategory/"+cat_id;
$.ajax({
type: "GET",
url: url,
dataType: "JSON",
success: function(res)
{
var html = "";
$.each(res, function (key, value) {
html += "<li class="+'subcategorys'+" value="+key+" name="+value+">"+value+" </li>";
});
$('#subcategory').html($(html).addClass('subcategoryList'));
$('.subcategorys').on('click', function(event) {
console.log($(this).attr("name"));
var subcat_id =event.target.value;
console.log(subcat_id);
});
}
});
});
});
$(document).ready(function() {
$('#subcategory').on('click', function(event) {
var subcat_id =event.target.value;
console.log(subcat_id);
var url = "/api/getSubcategorytwo/"+subcat_id;
$.ajax({
type: "GET",
url: url,
dataType: "JSON",
success: function(res)
{
var html = "";
$.each(res, function (key, value) {
html += "<li value="+key+">"+value+"</option></li>";
});
$("#subcategorytwo").html(html);
}
});
});
$('#subcategorytwo').on('click', function(event) {
var opt_subcat_two =event.target.value;
var opt = $(event.target).text();
console.log(opt,opt_subcat_two);
$( "#fetchvalue" ).replaceWith("<input type='text' class='form-control' name='subcategorytwo' value="+opt_subcat_two+" id='fetchvalue' data-toggle='modal' data-target='#myModal'> "+opt+"</input>");
$('#myModal').modal('hide');
$('.modal-backdrop').remove();
});
});
</script>
<input type="text" class="form-control" name="subcategorytwo" id="fetchvalue" data-toggle="modal" data-target="#myModal" ></input>
<!-- The Modal -->
<div class="modal" id="myModal">
<div class="modal-dialog modal-lg" >
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<a type="button" class="close" data-dismiss="modal" aria-hidden="true">×</a>
</div>
<div class="modal-body">
<div class="row">
<table class="table table-striped">
<thead>
</thead>
<tbody class="table">
<tr>
<td style="background-color: green">
<div class="col-md-7" >
#foreach($categories as $category)
<option class="categoryList" name="{{$category->category}}" value="{{$category->id}}">{{$category->category}}</option>
#endforeach
</div>
</td>
<td>
<div class="col-md-7">
<ul style="list-style: none" id="subcategory"></ul>
</div>
</td>
<td>
<div class="col-md-7">
<ul style="list-style: none" name="subcategorytwo" id="subcategorytwo" ></ul>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
Here is javascript code and modal code...I have total 4 table...
category subcategory
subcategory
subcategorytwo
post table
all are connected to a foreign key
Post table structure
When try to save category value, subcategory value, subcategorytwo value error is
How can I store 3 value at a time different place in db
Modal show like this
Modal like this
MySQL is most likely in STRICT mode try to
change the column to allow null:
ALTER TABLE `posts` CHANGE `subcategory2` `subcategory2` varchar NULL
Or try running
SET GLOBAL sql_mode='' or

Looking For Advice On Paginating AJAX Results

I currently am working on a feature for a web app that allows users to dynamically search and filter a list of cards. I've accomplished the filtering and search, but as the search results grow, I end up with either an incredibly slow page, or a very large number of results to sift through. I thought pagination might be a solution given the maximum number of results are in the thousands, and eventually I'd like to have very broad filter buttons, as well as text-based search.
A screenshot of it in action:
The code is as follows:
deckbuilder.js
document.addEventListener("turbolinks:load", function() {
$(document).on("click", ".deck-adjust-button", adjustDeck)
$(document).on("click", "#decklist-submit", submitDecklist)
$(document).on("input", "#list-search", updateMiniList)
})
function adjustDeck(e) {
card_name = $(this).parents('tr').data("name")
card_name_sanitized = card_name.replace(/\s+/g, '-').replace(/,/g, '').replace(/'/g, '').toLowerCase();
num_cards = $(this).parents('tr').find("#num-cards").val()
deck = $(this).text().toLowerCase() + "-deck"
console.log(card_name + "|" + num_cards + "|" + deck)
deck_div = $("#" + deck)
deck_div.find("#" + card_name_sanitized).remove()
if (parseInt(num_cards) > 0) {
deck_div.append("<div id=" + card_name_sanitized + ">" + num_cards + "x " + card_name + "</div>")
}
}
function submitDecklist(e) {
e.preventDefault()
deck_divs = $(".deck")
decklist_decks = []
decklist_name = $('#name').val()
decklist_description = $("#description").val()
deck_divs.each(function(div) {
deck = $(deck_divs[div])
deck_name_raw = deck.find('div').attr("id")
deck_name = deck_name_raw.split("-")[0]
deck_name = deck_name.charAt(0).toUpperCase() + deck_name.slice(1)
deck_div = deck.find('#' + deck_name_raw)
cards_array = []
deck_div.children().each(function() {
card_text = $(this).text().trim()
card_name = card_text.substr(card_text.indexOf(' ')+1)
card_num = parseInt(card_text.substr(0,card_text.indexOf(' ')).replace(/x/g, ''))
cards_array.push({
name: card_name,
num: card_num,
})
})
decklist_decks.push({
name: deck_name,
cards: cards_array
})
})
decklist = {
decklist: {
name: decklist_name,
description: decklist_description,
decks: decklist_decks
}
}
$.ajax({
method: "POST",
url: "/decklists",
data: decklist
})
.done(function( msg ) {
window.location.replace("/decklists/" + msg.id);
})
.fail(function( msg) {
window.location.replace("/decklists/new");
})
}
function updateMiniList(e) {
inputValue = $(this).val().toLowerCase()
listEntries = $(this).parents().siblings('#mini-card-list').find('tr')
listEntries.each(function() {
entry = $(this)
entryName = $(this).data("name").toLowerCase()
if (!entryName.includes(inputValue)) {
entry.hide()
} else {
entry.show()
}
})
if(inputValue.length > 2) {
data = { "name": inputValue }
ApiCall("POST", "/cards/search", data, appendCards)
}
}
function ApiCall(method, target, data, callback) {
$.ajax({
method: method,
url: target,
data: data,
success: callback
})
}
function appendCards(cards) {
cards.forEach(function(card) {
name = card.name
newCardDiv = $('<tr data-name="' + name + '">\
<td>\
<select class="form-control" id="num-cards">\
<option value=0>0</option>\
<option value=1>1</option>\
<option value=2>2</option>\
<option value=3>3</option>\
<option value=4>4</option>\
</select>\
</td>\n\
<td>' + name + '</td>\n\
<td>\
<div class="btn-group btn-group-sm" role="group">\
<button type="button" class="btn btn-secondary deck-adjust-button">Main</button>\
<button type="button" class="btn btn-secondary deck-adjust-button">Stone</button>\
<button type="button" class="btn btn-secondary deck-adjust-button">Side</button>\
<button type="button" class="btn btn-secondary deck-adjust-button">Ruler</button>\
</div>\
</td>\
</tr>')
$('#mini-card-list').find('table').append(newCardDiv)
});
}
new.html.erb (Page interacting with JS)
<div class="container">
<div class="row">
<div class="col">
<h2>Create a New Decklist</h2>
</div>
</div>
<div class="row">
<div class="col-md-5">
<hr>
<h4>Decks</h4>
<hr>
<%= render "decklists/deck_div", deck_name: "Ruler" %>
<%= render "decklists/deck_div", deck_name: "Main" %>
<%= render "decklists/deck_div", deck_name: "Stone" %>
<%= render "decklists/deck_div", deck_name: "Side" %>
<%= render "decklists/form", decklist: #decklist %>
</div>
<div class="col-md-7">
<%= render "cards/mini_list", cards: #cards %>
</div>
</div>
</div>
deck_div partial
<div class="row">
<div class="col deck">
<hr>
<h4><%= deck_name %></h4>
<hr>
<div id="<%= deck_name.downcase + "-deck" %>">
</div>
</div>
</div>
Mini-List Partial
<div class="col">
<hr>
<h4>Cards</h4>
<hr>
<div>
<input type="text" placeholder="Search" class="form-control" id="list-search">
</div>
<div id="mini-card-list" style="overflow:scroll; height:400px;">
<table class="table">
</table>
</div>
</div>

Categories