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;
});
Related
//anything inside 'pagebeforecreate' will execute just before this page is rendered to the user's screen
$(document).on("pagebeforecreate", function () {
printheader(); //print the header first before the user sees his page
});
$(document).ready(function () {
searchfriend();
function searchfriend() {
var url = serverURL() + "/getcategories.php";
$.ajax({
url: url,
type: 'GET',
dataType: 'json',
contentType: "application/json; charset=utf-8",
success: function (arr) {
_getCategoryResult(arr);
},
error: function () {
validationMsg();
}
});
}
function _getCategoryResult(arr) {
var t; //declare variable t
//loop for the number of results found by getcategories.php
for (var i = 0; i < arr.length; i++) {
//add a new row
t.row.add([ //error
"<a href='#' class='ui-btn' id='btn" + arr[i].categoryID + "'>Category</a>" //add a new [Category] button
]).draw(false);
//We drew a [View] button. now bind it to some actions
$("#btn" + arr[i].categoryID).bind("click", { id: arr[i].categoryID }, function (event) {
var data = event.data;
showcategory(data.id); //when the user clicks on the [View] button, execute showcategory()
});
}
$("#categoryresult").show(); //show the results in the table searchresult
}
function showcategory(categoryID) {
//alert(categoryID);
window.location = "showuser.html?userid=" + userid;
}
});
There is an error on line 33 which stated:
"Uncaught TypeError: Cannot read property 'row' of undefined"
However, it seems that I have no idea where the error is coming from.
Is there anyway I can solve this problem?
You look like you are using a third-party jQuery plugin, DataTables.
Follow the usage of DataTables.
var t; //declare variable t
should be
var t = $("#categoryresult").DataTable();
The variable t is not an object with a property called row.
Try with var t = { row: [] }
Edit: I apologize. I got confused add with push method.
So, you need an object with a method called add and assign that object to t
I stucked on one thing. I have a 2 grid inside checkboxes. When I selected that checkboxes I want to POST that row data values like array or List. Actually when i send one list item it's posting without error but when i get more than one item it couldn't post values.
Example of my grid
Here my ajax request and how to select row values function
var grid = $("#InvoceGrid").data('kendoGrid');
var sel = $("input:checked", grid.tbody).closest("tr");
var items = [];
$.each(sel, function (idx, row) {
var item = grid.dataItem(row);
items.push(item);
});
var grid1 = $("#DeliveryGrid").data('kendoGrid');
var sel1 = $("input:checked", grid1.tbody).closest("tr");
var items1 = [];
$.each(sel1, function (idx, row) {
var item1 = grid1.dataItem(row);
items1.push(item1);
});
$.ajax({
url: '../HeadOffice/CreateInvoice',
type: 'POST',
data: JSON.stringify({ 'items': items, 'items1': items1, 'refnum': refnum }),
contentType: 'application/json',
traditional: true,
success: function (msg) {
if (msg == "0") {
$("#lblMessageInvoice").text("Invoices have been created.")
var del = $("#InvoiceOKWindow").data("kendoWindow");
del.center().open();
var del1 = $("#InvoiceDetail").data("kendoWindow");
del1.center().close();
$("#grdDlvInv").data('kendoGrid').dataSource.read();
}
else {
$("#lblMessageInvoice").text("Problem occured. Please try again later.")
var del = $("#InvoiceOKWindow").data("kendoWindow");
del.center().open();
return false;
}
}
});
This is my C# part
[HttpPost]
public string CreateInvoice(List<Pm_I_GecisTo_Result> items, List<Pm_I_GecisFrom_Result> items1, string refnum)
{
try
{
if (items != null && items1 != null)
{
//do Something
}
else
{
Log.append("Items not selected", 50);
return "-1";
}
}
catch (Exception ex)
{
Log.append("Exception in Create Invoice action of HeadOfficeController " + ex.ToString(), 50);
return "-1";
}
}
But when i send just one row it works but when i try to send more than one value it post null and create problem
How can i solve this? Do you have any idea?
EDIT
I forgot to say but this way is working on localy but when i update server is not working proper.
$.ajax({
url: '../HeadOffice/CreateInvoice',
type: 'POST',
async: false,
data: { items: items, items1: items1 }
success: function (msg) {
//add codes
},
error: function () {
location.reload();
}
});
try to call controller by this method :)
I'm using dialog box for add new users to db , I want to close dialog box if validation pass and user successfully saved. please advice
$('.add_user_link a').each(function () {
var $link = $(this);
var $dialog = $('<div id="dialog"></div>')
.load($link.attr('href') + ' #content')
.dialog({
autoOpen: false,
title: $link.attr('title'),
});
$link.click(function () {
$dialog.dialog('open');
$('#add_user').submit(function () {
url = '/user/useradd/';
$.ajax({
type: "POST",
cache: false,
url: $('#add_user').attr('action'),
data: $('#add_user').serializeArray(),
success: function (data) {
var json_obj = $.parseJSON(data);
var result = json_obj['result'];
var lname = json_obj['lname'];
var email = json_obj['email'];
var fname = json_obj['fname'];
if (!result) {
$("#dialog").dialog('close');
}
else {
//
document.getElementById('email-error').innerHTML = email;
var fname_count = $("label[id*='errorfname']").length;
$('input[name=fname]').after('<label id="errorfname"></label>');
document.getElementById('errorfname').innerHTML = fname;
var lname_count = $("label[id*='errorlname']").length;
if (lname_count == 0) {
$('input[name=lname]').after('<label id="errorlname"></label>');
document.getElementById('errorlname').innerHTML = lname;
}
}
}
});
return false;
});
return false;
});
});
I'm getting this error
jquery-1.11.1.min.js:2 Uncaught Error: cannot call methods on dialog prior to initialization; attempted to call method 'close'
Replace:
$("#dialog").dialog('close');
With
$dialog.dialog('close')
You've already set a variable for your dialog in the click function which should be in scope so you don't need to reselect it.
UPDATE:
Element IDs should be unique so you should make the dialog ID unique when adding it for a link if there are multiple links. Otherwise, you will select multiple dialog elements when you do this $('#dialog') when there are mulitiple links.
When you do this:
$dialog = $('<div id="dialog"></div>')
the ID value "dialog" should be something unique, like "dialog1", "dialog2", etc.
i made a function that sends data (ajax) to the database and depending on the response from the server i need to alert a message but it seems like whenvever i change the select option i get the alert message for each change(if i change the select four times when i click i get the alert four times ) , but if i remove my ajax function and replace it simply by an alert i get it once not repeating itself here is my JS
$('.select_ids').change(function () {
var id = $(this).val();
var form = $('#form_widget_ids_' + id);
var container = form.parent('.ewb_forms');
var box = container.parent('.edit_widget_box');
container.children('.selected').fadeOut(300, function () {
$(this).removeClass('selected');
form.fadeIn(300, function () {
$(this).addClass('selected');
});
});
Widget.updateSSOUrl(box);
$.ajax({
type: "POST",
url: window.location + "",
data: {'id': id}
}).done(function (msg) {
$(".red").on('click', function (evt) {
if ('done' == msg) {
evt.preventDefault();
alert('NOP');
}
})
});
});
the event that you are binding i think is wrong. For newly append items is better in your case to use
$(document).on('click', ".red", function (evt) {
})
And it must be moved outside the ajax success because now you are triggering it every time
----- Edited ---
If you want just to alert the output of the ajax you dont need the onClick event
$('.select_ids').change(function () {
var id = $(this).val();
var form = $('#form_widget_ids_' + id);
var container = form.parent('.ewb_forms');
var box = container.parent('.edit_widget_box');
container.children('.selected').fadeOut(300, function () {
$(this).removeClass('selected');
form.fadeIn(300, function () {
$(this).addClass('selected');
});
});
Widget.updateSSOUrl(box);
$.ajax({
type: "POST",
url: window.location + "",
data: {'id': id}
}).done(function (msg) {
if (msg === 'done') {
evt.preventDefault();
alert('NOP');
}
});
});
If you want to show the latest result on a button click you can store the msg on a global variable and on click of a div show that like
var globalMsg = "";
$('.select_ids').change(function () {
var id = $(this).val();
var form = $('#form_widget_ids_' + id);
var container = form.parent('.ewb_forms');
var box = container.parent('.edit_widget_box');
container.children('.selected').fadeOut(300, function () {
$(this).removeClass('selected');
form.fadeIn(300, function () {
$(this).addClass('selected');
});
});
Widget.updateSSOUrl(box);
$.ajax({
type: "POST",
url: window.location + "",
data: {'id': id}
}).done(function (msg) {
globalMsg = msg
});
});
$(".div").click(function() { alert(globalMSG); });
I am implementing jQuery UI Autocomplete and am wondering if there is any way to only allow a selection from the suggested results that are returned as opposed to allowing any value to be input into the text box.
I am using this for a tagging system much like the one used on this site, so I only want to allow users to select tags from a pre-populated list returned to the autocomplete plugin.
You could also use this:
change: function(event,ui){
$(this).val((ui.item ? ui.item.id : ""));
}
The only drawback I've seen to this is that even if the user enters the full value of an acceptable item, when they move focus from the textfield it will delete the value and they'll have to do it again. The only way they'd be able to enter a value is by selecting it from the list.
Don't know if that matters to you or not.
I got the same problem with selected not being defined. Got a work-around for it and added the toLowerCase function, just to be safe.
$('#' + specificInput).autocomplete({
create: function () {
$(this).data('ui-autocomplete')._renderItem = function (ul, item) {
$(ul).addClass('for_' + specificInput); //usefull for multiple autocomplete fields
return $('<li data-id = "' + item.id + '">' + item.value + '</li>').appendTo(ul);
};
},
change:
function( event, ui ){
var selfInput = $(this); //stores the input field
if ( !ui.item ) {
var writtenItem = new RegExp("^" + $.ui.autocomplete.escapeRegex($(this).val().toLowerCase()) + "$", "i"), valid = false;
$('ul.for_' + specificInput).children("li").each(function() {
if($(this).text().toLowerCase().match(writtenItem)) {
this.selected = valid = true;
selfInput.val($(this).text()); // shows the item's name from the autocomplete
selfInput.next('span').text('(Existing)');
selfInput.data('id', $(this).data('id'));
return false;
}
});
if (!valid) {
selfInput.next('span').text('(New)');
selfInput.data('id', -1);
}
}
}
http://jsfiddle.net/pxfunc/j3AN7/
var validOptions = ["Bold", "Normal", "Default", "100", "200"]
previousValue = "";
$('#ac').autocomplete({
autoFocus: true,
source: validOptions
}).keyup(function() {
var isValid = false;
for (i in validOptions) {
if (validOptions[i].toLowerCase().match(this.value.toLowerCase())) {
isValid = true;
}
}
if (!isValid) {
this.value = previousValue
} else {
previousValue = this.value;
}
});
This is how I did it with a list of settlements:
$("#settlement").autocomplete({
source:settlements,
change: function( event, ui ) {
val = $(this).val();
exists = $.inArray(val,settlements);
if (exists<0) {
$(this).val("");
return false;
}
}
});
i just modify to code in my case & it's working
selectFirst: true,
change: function (event, ui) {
if (ui.item == null){
//here is null if entered value is not match in suggestion list
$(this).val((ui.item ? ui.item.id : ""));
}
}
you can try
Ajax submission and handling
This will be of use to some of you out there:
$('#INPUT_ID').autocomplete({
source: function (request, response) {
$.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
url: autocompleteURL,
data: "{'data':'" + $('INPUT_ID').val() + "'}",
dataType: 'json',
success: function (data) {
response(data.d);
},
error: function (data) {
console.log('No match.')
}
});
},
change: function (event, ui) {
var opt = $(this).val();
$.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
url: autocompleteURL,
data: "{'empName':'" + name + "'}",
dataType: 'json',
success: function (data) {
if (data.d.length == 0) {
$('#INPUT_ID').val('');
alert('Option must be selected from the list.');
} else if (data.d[0] != opt) {
$('#INPUT_ID').val('');
alert('Option must be selected from the list.');
}
},
error: function (data) {
$(this).val('');
console.log('Error retrieving options.');
}
});
}
});
I'm on drupal 7.38 and
to only allow input from select-box in autocomplete
you only need to delete the user-input at the point,
where js does not need it any more - which is the case,
as soon as the search-results arrive in the suggestion-popup
right there you can savely set:
**this.input.value = ''**
see below in the extract from autocomplete.js ...
So I copied the whole Drupal.jsAC.prototype.found object
into my custom module and added it to the desired form
with
$form['#attached']['js'][] = array(
'type' => 'file',
'data' => 'sites/all/modules/<modulname>_autocomplete.js',
);
And here's the extract from drupal's original misc/autocomplete.js
modified by that single line...
Drupal.jsAC.prototype.found = function (matches) {
// If no value in the textfield, do not show the popup.
if (!this.input.value.length) {
return false;
}
// === just added one single line below ===
this.input.value = '';
// Prepare matches.
=cut. . . . . .
If you would like to restrict the user to picking a recommendation from the autocomplete list, try defining the close function like this. The close function is called when the results drop down closes, if the user selected from the list, then event.currentTarget is defined, if not, then the results drop down closed without the user selecting an option. If they do not select an option, then I reset the input to blank.
//
// Extend Autocomplete
//
$.widget( "ui.autocomplete", $.ui.autocomplete, {
options: {
close: function( event, ui ) {
if (typeof event.currentTarget == 'undefined') {
$(this).val("");
}
}
}
});
You can actually use the response event in combination to the change event to store the suggested items like so:
response: function (event, ui) {
var list = ui.content.map(o => o.value.toLowerCase());
},
change: function (event, ui) {
if (!ui.item && list.indexOf($(this).val().toLowerCase()) === -1 ) { $(this).val('');
}