My table get duplicated rows with Jquery Table Sorter - javascript

I have search field in my project, which uses $.post for getting the results for the search query.
My problem: When a user click on the search button it works correctly, however when a user click on the search button again, and then click on my thead columns jquery sorter duplicates it with the previous search shows in the table.
How can I solve this so my sorter function does not duplicate?
this is the Jquery code for the search button click.
$(function () {
$('#submitfloat').click(function () {
$('#loading').show();
setTimeout(function () { $("#loading").hide(); }, 800);
var SubjectTypes = $('#SubjectTypes').val();
var Teams = $('#Teams').val();
var Companies = $('#Companies').val();
var Consultants = $('#Consultants').val();
var PlannedDates = $('#PlannedDates').val();
var CompletedDates = $('#CompletedDates').val();
var DateTypes = $('#DateTypes').val();
var data = {
Subjectypes: SubjectTypes,
Companies: Companies,
Teams: Teams,
Consultants: Consultants,
PlannedDates: PlannedDates,
CompletedDates: CompletedDates,
DateTypes: DateTypes
};
var fromDate = $('#PlannedDates').val();
var endDate = $('#CompletedDates').val();
if (Date.parse(fromDate) > Date.parse(endDate)) {
jAlert("End date must be later than start date", "Warning");
return false;
} else {
$('#GoalcardSearchResult tbody').hide();
setTimeout(function () { $("#GoalcardSearchResult tbody").show(); }, 800);
$.post('#Url.Action("Search", "SearchNKI")', data, function (result) {
$("#GoalcardSearchResult tbody").empty();
result.forEach(function (goalcard) {
$("#GoalcardSearchResult tbody").append(
$('<tr/>', {
click: function () {
id = goalcard.Id;
var url = '#Url.Action("AnswerForm", "AnswerNKI", new { id = "__id__"})';
window.location.href = url.replace('__id__', id);
},
html: "<td>" + goalcard.Name + "</td><td>" + goalcard.Customer + "</td><td>" + goalcard.PlannedDate + "</td><td>" + goalcard.CompletedDate + "</td>"
}));
});
$("#GoalcardSearchResult").tablesorter();
});
return false;
}
});
});
Your help is appreciated, thanks in advance!

I'm guessing tablesorter has already been initialized before the user clicks on the sort button. In that case, replace this code:
$("#GoalcardSearchResult").tablesorter();
with this:
$("#GoalcardSearchResult").trigger('update');

Related

Append url and redirect onclick

I currently have a function used to get a list of 5 website names (title) as well as 5 urls
The code below is pulling the list of 5 titles but how would I go about append the title so that it will redirect to the url on click
function getFavorites() {
$.getJSON("/Home/UserFavorites", function (result) {
var options = $("#userfavorites");
List = "";
$('#userfavorites >option').remove();
$.each(result, function () {
options.append($("<option />").val(this.url).text(this.title));
List = List + "," + this.title;
});
}).complete(function () {
$.unblockUI();
});
}
$("#userfavorites").change(function(){
window.location.href = $(this).val();
});

How to represent and autocomplete JSON of suggestions based on Google Books API?

This question is based on Results of recommendations using Google Books API are irrelevant .
In general I am building possibility for user to add the book to his collection.
For this purpose user searches through books using information from Google Books. But without suggestions based on what user types in the search field, it would be extremely uncomfortable.
At this point now we get jSON text of book suggestions, but I do not really understand how to represent this? So how to create a normal list of that JSON and create possibility for user to choose one of those recommendations,so that each of them will be autocompleted in the search field on click?
var requestUrl = "https://suggestqueries.google.com/complete/search?client=chrome&ds=bo&q=";
var xhr;
$(document).on("input", "#query", function () {
typewatch(function () {
var queryTerm = $("#query").val();
$("#indicator").show();
if (xhr != null) xhr.abort();
xhr = $.ajax({
url: requestUrl + queryTerm,
dataType: "jsonp",
success: function (response) {
$("#indicator").hide();
$("#output").html(response);
}
});
}, 500);
});
$(document).ready(function () {
$("#indicator").hide();
});
var typewatch = (function () {
var timer = 0;
return function (callback, ms) {
clearTimeout(timer);
timer = setTimeout(callback, ms);
};
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<input type=text id="query" placeholder="Start typing..." /><span id="indicator"></span>
<div style="width:600px;height:700px;padding-bottom:100px;position:relative;background:#6c94b8;" id="output"></div>
<label for="query" style="position:relative;margin-left:100px;margin-top:100px;">Tags: </label>
</div>
I think this is what you are after:
https://www.librarieshacked.org/tutorials/autocompletewithapi
$(document).ready(function () { // only begin once page has loaded
$("#txtBookSearch").autocomplete({ // attach auto-complete functionality to textbox
// define source of the data
source: function (request, response) {
// url link to google books, including text entered by user (request.term)
var booksUrl = "https://www.googleapis.com/books/v1/volumes?printType=books&q=" + encodeURIComponent(request.term);
$.ajax({
url: booksUrl,
dataType: "jsonp",
success: function(data) {
response($.map(data.items, function (item) {
if (item.volumeInfo.authors && item.volumeInfo.title && item.volumeInfo.industryIdentifiers && item.volumeInfo.publishedDate)
{
return {
// label value will be shown in the suggestions
label: item.volumeInfo.title + ', ' + item.volumeInfo.authors[0] + ', ' + item.volumeInfo.publishedDate,
// value is what gets put in the textbox once an item selected
value: item.volumeInfo.title,
// other individual values to use later
title: item.volumeInfo.title,
author: item.volumeInfo.authors[0],
isbn: item.volumeInfo.industryIdentifiers,
publishedDate: item.volumeInfo.publishedDate,
image: (item.volumeInfo.imageLinks == null ? "" : item.volumeInfo.imageLinks.thumbnail),
description: item.volumeInfo.description,
};
}
}));
}
});
},
select: function (event, ui) {
// what to do when an item is selected
// first clear anything that may already be in the description
$('#divDescription').empty();
// we get the currently selected item using ui.item
// show a pic if we have one
if (item.image != '')
{
$('#divDescription').append('<img src="' + ui.item.image + '" style="float: left; padding: 10px;">');
}
// and title, author, and year
$('#divDescription').append('<p><b>Title:</b> ' + ui.item.title + '</p>');
$('#divDescription').append('<p><b>Author:</b> ' + ui.item.author + '</p>');
$('#divDescription').append('<p><b>First published year:</b> ' + ui.item.publishedDate + '</p>');
// and the usual description of the book
$('#divDescription').append('<p><b>Description:</b> ' + ui.item.description + '</p>');
// and show the link to oclc (if we have an isbn number)
if (ui.item.isbn && ui.item.isbn[0].identifier)
{
$('#divDescription').append('<P><b>ISBN:</b> ' + ui.item.isbn[0].identifier + '</p>');
$('#divDescription').append('View item on worldcat');
}
},
minLength: 2 // set minimum length of text the user must enter
});
});

assign multiple value to javaScript array object

i have coded jQuery widget, which list all the record title in table which user can select of multiple records but with each record user to need to put value in text box.
now i want to built jQuery or JavaScript array where i can push record with each user click add and remove data if click remove against each button.
i want to push "recordId" & "ComponentSchemeMarks" to javaScript array selectedComponentList
var selectedComponentList = {
componentIndex: "",
componentMark:""
};
$(document).ready(function () {
//click on Confirm Component Scheme
$("#ComponentSchemeTable").on("click", ".k-grid-confirm", function () {
var recordId = $(this).data("id");
var ComponentSchemeMarks = $("#" + recordId + "_CM").val();
alert("recordId " + recordId + " ComponentSchemeMarks " + ComponentSchemeMarks);
//
$(this).hide();
$(this).siblings(".k-grid-input").hide();
$(this).siblings(".k-grid-cancel").hide();
$(this).siblings(".k-grid-Remove").show();
//add data to array//
});
$("#ComponentSchemeTable").on("click", ".k-grid-Remove", function () {
$(this).hide();
$(this).siblings(".k-grid-Add").show();
});
Your selectedComponentList is not an array... I guess you want something like this:
var selectedComponentArray = [];
$(document).ready(function () {
//click on Confirm Component Scheme
$("#ComponentSchemeTable").on("click", ".k-grid-confirm", function () {
var recordId = $(this).data("id");
var ComponentSchemeMarks = $("#" + recordId + "_CM").val();
alert("recordId " + recordId + " ComponentSchemeMarks " + ComponentSchemeMarks);
//
$(this).hide();
$(this).siblings(".k-grid-input").hide();
$(this).siblings(".k-grid-cancel").hide();
$(this).siblings(".k-grid-Remove").show();
//add data to array//
selectedComponentArray.push({ComponentIndex: recordId, ComponentMark: ComponentSchemeMarks});
});
$("#ComponentSchemeTable").on("click", ".k-grid-Remove", function () {
$(this).hide();
$(this).siblings(".k-grid-Add").show();
var recordId = $(this).data("id");
selectedComponentArray = $.grep(selectedComponentArray, function(value) {
return value.ComponentIndex != recordId;
});
});
...
}
Moreover you should give the buttons IDs and use them for binding the click listeners...

Refreshing Pagination in DataTables?

I'm having a strange issue that's only arising in my dataTable in select environments. I've written a function that allows the user to delete a row, then if it's the last row on that particular page, reload the Table and send the user to the 'new' last page.
However, on some servers, it's not working properly -- I think it has to do with the fact that with after using fnClearTable and fnDraw, the pagination of the table still holds the last 'empty' page.
Here's the function I'm working with now:
function fnDelete(elem) {
if (selected.length > 0) {
var c;
c = confirm("Are you sure you want to delete the selected Agency?");
if (c) {
var deleteURL = urlstr.substring(0, urlstr.lastIndexOf("/") + 1) + "delete.do";
deleteRecord(deleteURL, selected[0]);
if ($(".tableViewer tbody tr:visible").length === 1) {
oTable.fnClearTable();
oTable.fnDraw();
oTable.fnPageChange("last");
}}}}
In addition, here's my delet function.
function deleteRecord(deleteURL, iid){
var didDelete = false;
jQuery.ajax({
type: "POST",
url: deleteURL,
dataType:"html",
data:"recordID="+iid,
async : false,
success:function(response){
didDelete = true;
oTable.fnDraw(true);
selected = [];
selectedRecord = [];
enableButtons(selected);
},
error:function (xhr, ajaxOptions, thrownError){
<%-- is the message in a range we can handle? --%>
if ((xhr.status >=400) && (xhr.status < 500)) {
alert(xhr.responseText);
}
else {
alert('<spring:message arguments="" text="Internal Server Error" code="ajax.internal.server.error"/>');
}
}
});
return didDelete;
}
Again, this issue is only coming up on certain computers. Can anyone help?
Also, here's the configuration for my DataTable::
oTable = $('#${tableName}_grid').dataTable({
bDestroy: true,
bSort: true,
bFilter: true,
bJQueryUI: true,
bProcessing: true,
bAutoWidth: true,
bInfo: true,
bLengthChange: true,
iDisplayLength: ${sessionScope.displayLength},
sPaginationType: 'full_numbers',
bServerSide: true,
sAjaxSource: "<c:url value='${dataUrl}'/>",
aaSorting: [<c:forEach items="${sortInfo}" var="oneSort"> [${oneSort.columnIndex},'${oneSort.ascending ? "asc":"desc"}']</c:forEach>],
aoColumns: [
<c:forEach items="${columns}" var="curCol" varStatus="colLoop">
{sName: '${curCol.fieldName}', bSortable: ${curCol.sortable}, bSearchable: false, sTitle: "<c:out value='${curCol.title}'/>", sType: '${curCol.displayType}', bVisible:${curCol.visible}, vdbType:'${curCol.vdbType}', sClass:'${curCol.displayType}'}${colLoop.last ? '' : ','}
</c:forEach>
],
aoColumnDefs:[{sClass:"color_col", aTargets:['color']}],
fnRowCallback: function( nRow, aData, iDisplayIndex ) {
$('#${tableName}_grid tbody tr').each( function () {
if ($.inArray(aData[0], selected)!=-1) {
$(this).addClass('row_selected');
}
});
return nRow;
},
fnInfoCallback: function( oSettings, iStart, iEnd, iMax, iTotal, sPre ) {
if(myPos>=iStart && myPos<=iEnd){
//alert(myPos+" visible")
}else{
selected = [];
selected = [];
selectedRecord = [];
$('tr').removeClass('row_selected');
enableButtons(selected);
}
},
fnDrawCallback: function ( oSettings ) {
$('#${tableName}_grid tbody tr').each( function () {
var iPos = myPos = oTable.fnGetPosition( this );
if (iPos!=null) {
var aData = oTable.fnGetData( iPos );
if ($.inArray(aData[0], selected)!=-1) {
$(this).addClass('row_selected');
}
}
var htxt = '';
$(this).find('.color').filter(function(i,tdata){
htxt = '';
htxt = '#'+($(tdata).text());
return true;
}).css("background",htxt);
$(this).dblclick( function(){
var iPos = myPos = oTable.fnGetPosition(this);
var aData = oTable.fnGetData(iPos);
var iId = aData[0];
selected = [];
selectedRecord = [];
selected.push(iId);
selectedRecord.push(aData);
$('tr').removeClass('row_selected');
$(this).addClass('row_selected');
enableButtons(selected);
<%-- in case there is no edit button or its enablement is more complex,
// click the button instead of assuming it will call fnEdit.
// Do first() because jQuery is returning the same element multiple times.--%>
$(".${tableName}_bttns > span.edit-doubleclick:not(.disabld)").first().click();
});
$(this).click( function () {
var iPos = myPos = oTable.fnGetPosition(this);<%-- row index on_this_page --%>
var aData = oTable.fnGetData(iPos);
var iId = aData[0];
var is_in_array = $.inArray(iId, selected);
<%-- alert("iPos: " + iPos + "\nData: " + aData + "\niId: " + iId + "\nselected: " + selected + "\nis_in_array: " + is_in_array); --%>
selected = [];
selectedRecord = [];
if (is_in_array==-1) {
selected.push(iId);
selected.sort(function(a,b){return a-b});
selectedRecord.push(aData);
selectedRecord.sort(function(a,b){return a[0]-b[0]});
}
else {
selected = $.grep(selected, function(value) {
return value != iId;
});
selectedRecord = $.grep(selectedRecord, function(value) {
return value != aData;
});
}
if ( $(this).hasClass('row_selected') ) {
$(this).removeClass('row_selected');
}
else {
$('#${tableName}_grid tr').removeClass('row_selected');
$(this).addClass('row_selected');
}
enableButtons(selectedRecord);
});
});
} ,
"sDom": '<"H"lTfr>t<"F"ip>',
"oTableTools":{
"aButtons":[ {
"sExtends":"print",
"bShowAll": true,
"sInfo": printmsg,
"sButtonClass":"ui-icon fg-button ui-button edit-print DTTT_button_print",
"sButtonClassHover":"ui-icon fg-button ui-button edit-print DTTT_button_print"
} ] }
});
$('#${tableName}_grid_filter input').attr("maxlength", "255").attr("size", "35");
$('#${tableName}_grid').ready(function(){
$(".DTTT_containerc").remove();
BuildToolBarButtons();
var tt;
$(".DTTT_containerc").each(function(){
tt = $(this).find("#Print").attr("title");
$(this).find("#Print").remove();
$(this).find(".DTTT_container").remove();
}
);
$(".DTTT_container > button").attr("title",tt).css("border","1px solid #9597A3").removeClass("ui-state-default");
$(".DTTT_containerc").append($(".DTTT_container").removeAttr("style"));
});
});
Your datatable is configured to load data using ajax. This means that any action against the data happens asynchronously. Specifically, the fnDraw() function allows control to go to the statement where you change the page page before the new data is back from the server. You should move the logic that takes you to the last page to the fnDrawCallback. I believe that should resolve your issue.
Thought I'd write a response to help others to show how I fixed it.
#Gavin was correct in that it was in the wrong place -- I moved the function in question to the sucess callback in AJAX. However, to fix it fully, I had to 'premptively' read what page the deletion was happening on (using fn.PageChange plugin), subtract 1 (bc DataTables is zero-based) and send the user there.
Hope this helps anyone! #Gavin, thank you for your help and for leading me int he right direction!
you can keep on the same page after the table refreshed. you need to use the following snippet to keep your pagination same after refreshing datatable. just copy paste following js code on a separate file and hook it with your current page.
$.fn.dataTableExt.oApi.fnStandingRedraw = function(oSettings) {
if(oSettings.oFeatures.bServerSide === false){
var before = oSettings._iDisplayStart;
oSettings.oApi._fnReDraw(oSettings);
oSettings._iDisplayStart = before;
oSettings.oApi._fnCalculateEnd(oSettings);
}
oSettings.oApi._fnDraw(oSettings);
};
and now, you might be used the "fnDraw" to refresh the dataTable. So now, instead of that code. change it like this.
oTable1.fnStandingRedraw();
Now, your dataTable will keep the same page after refreshing it.

Update row in WebGrid with JQuery

FOUND THE PROBLEM:
Just needed to replace row.replaceWith with row.parent().parent().replaceWith().
I'm trying to update a WebGrid row with JQuery after I've clicked a submit button in a modal dialog, but the updated data just append the last column, not the whole row as I want.
Let's say I want the table to look like this after the update:
ID - Name - Phone number
But with my code it looks like this after the update:
ID - Name - ID - Name - Phone number
as it just replaces the last column with a new table within the last column with the updated data.
I'm getting the correct data as output, but in the wrong place in the row.
Please help! :)
Here is the Javascript code:
$(function () {
$("#edit-event-dialog").dialog({
resizable: false,
height: 300,
modal: true,
autoOpen: false,
open: function (event, ui) {
var objectid = $(this).data('id');
$('#edit-event-dialog').load("/Events/CreateEditPartial", { id: objectid });
},
buttons: {
"Save": function () {
var ai = {
EventID: $(this).data('id'),
Name: $("#Name").val(),
Phone: $("#Phone").val()
};
var json = $.toJSON(ai);
var row = $(this).data('row');
$.ajax({
url: $(this).data('url'),
type: 'POST',
dataType: 'json',
data: json,
contentType: 'application/json; charset=utf-8',
success: function (data) {
var grid = $(".pretty-table");
row.replaceWith('<tr><td>' + data.ev.EventID + '</td><td>' +
data.ev.Name + '</td><td>' + data.ev.Phone + '</td></tr>');
},
error: function (data) {
var data = data;
alert("Error");
}
});
$(this).dialog("close");
},
Cancel: function () {
$(this).dialog("close");
}
}
});
$("#event-edit-btn").live("click", function () {
var url = $(this).attr('controller');
var row = $(this);
var id = $(this).attr('objectid');
$("#edit-event-dialog")
.data('id', id)
.data('url', url)
.data('row', row)
.dialog('open');
event.stopPropagation();
return true;
});
You have set row to $(this) which is your case represents $("#event-edit-btn") ( btw i suggest using classes as identifiers, but it's not a problem ). Later on you replace your actual button with the new <tr> set but what you actually need to do is traverse to the tr parent of that button and replace it.
Change your live handler to:
$("#event-edit-btn").live("click", function () {
var url = $(this).attr('controller');
var row = $(this).closest('tr'); //or use some #id or .class assigned to that element
var id = $(this).attr('objectid');
$("#edit-event-dialog")
.data('id', id)
.data('url', url)
.data('row', row )
.dialog('open');
event.stopPropagation();
return true;
});

Categories

Resources