Passing in a global javascript array to jQuery document(ready) - javascript

I have the following html rendered from templating (jsRender)
<div class="noteActions top" style="z-index: 3;">
<span onclick="noteAction('add', 13808, 0 );"></span>
<span onclick="noteAction('update',13808, 106344 );"></span>
<span onclick="noteAction('delete', 13808, 106344 );"></span>
</div>
My issue is I have a function outside the document ready that is setting a data array that later, a jquery dialog window submits via ajax to the handler to update the database
What's happening is the data array correctly passes everything except the jquery vals by class selector (pr-body, pr-title), they pass as NULL
javascript - outside document (ready)
var updateUrl = 'handlers/Poster.ashx',
data;
function noteAction(action, prospectID, noteID){
data = {
'operation': action,
'prospectid':prospectID,
'note-body' : $('.pr-body').val(),
'note-title' : $('.pr-title').val(),
'note-id':noteID,
};
if (action == 'add'){
$( "#dialogPostIt" ).dialog("open", "option", "title", "Add Post It");
} else if (action == 'update'){
$( "#dialogPostIt" ).dialog("open", "option", "title", "Edit Post It");
} else if (action == 'delete'){
if (!confirm('Are you sure you want to delete')) return false;
$.post(updateUrl+"?operation=delete&noteid="+noteID, function(data) {
$('#stickyNote-'+noteID).remove();
});
}
}
jquery - document ready
$(document).ready(function() {
$( "#dialogPostIt" ).dialog({autoOpen: false, modal:true,
buttons: {
'Save': function() {
$.ajax({
url: updateUrl,
data: data,
success: function(json, textStatus, jqXHR){
.....
html
<div id="dialogPostIt" >
<form id="postItNow" action="" method="post" class="note-form">
<label for="note-title">Title (description)</label>
<input type="text" name="note-title" id="note-title" class="pr-title" value="" />
<label for="note-body">Text of the note</label>
<textarea name="note-body" id="note-body" class="pr-body" cols="30" rows="6"> </textarea>
</form></div>
I previously was setting the data array inside the dialog save button function(), which worked fine, but I needed to make some of the array elements dynamic based on event
The array doesnt have to be global from my requirements, i just couldnt think of another way todo this
As Always, any help is greatly appreciated

Well, i feel like a real dope, it actually is working fine, issue was pilot error -_-
The data array was returning the values correctly, problem is there was no values yet , as the data was set prior to the subsequent dialog containing the form, so no form vals couldve been filled in yet
the fix
javascript outside the document ready
function noteAction(action, prospectID, noteID){
data = {
'operation': action,
'prospectid':prospectID,
'notebody' : '',
'notetitle' : '',
'noteid':noteID,
};
jquery in dialog (document ready)
$( "#dialogPostIt" ).dialog({autoOpen: false, modal:true,
buttons: {
'Save': function() {
data.notebody = $('.pr-body').val();
data.notetitle= $('.pr-title').val(),
$.ajax({
url: updateUrl,
data: data,

Related

Autocomplete: Why will my response object not return both first and last name ?

I'm totally new to JQuery Autocomplete using Ajax. I have got 90% the way there with the code below. Using the Chrome dev tools I can see all my values coming through next to the firstname:item.firstname1, that is to say, firstname,lastname, telephone etc. And if I have 3 matches they all are displayed sequentially. Then I screw things up. The lastname and the telephone objects appear to be redundant and nothing appears next to them. Furthermore none of the values appear as options on the screen. However, three empty options show up for the 3 objects which were found. My select:function(event, ui) does not work either. I have read the docs 100 times I am not getting anywhere fast.
I'd be very grateful if you could help to get it to work, but also to explain what I have done wrong. TKS !
Javascript:
$('#customer').autocomplete({
minLength: 2,
source: function(request, response,term) {
var param = request.term;
$.ajax({
url: "quotes/customer_search/"+param,
dataType: "json",
type:"GET",
success: function (data) {
response($.map(data, function(item) {
return {
firstname:item.firstname1, // My objects appear here.
lastname:item.lastname1, // these are redundant
telephone:item.telephone1, // redundant
};
}));//END Success
},
});//END AJAX
},
select: function( event, ui ) {
log( ui.item ?
"Selected: " + ui.item.firstname + " " + ui.item.lastname :
"Nothing selected, input was " + this.value );
}
HTML
<div class="ui-widget">
<label for="customer">Birds: </label>
<input id="customer" class="ui-autocomplete-input" >
</div>
<div class="ui-widget" style="margin-top:2em; font-family:Arial">
Result:
<div id="log" style="height: 200px; width: 300px; overflow: auto;" class="ui-widget-content"></div>
</div>
I found an answer which helped me solve my problem:
How to use JQuery Map
Once I had looked at that I had realized that my syntax for my reponse object needed changing to the code below. Once changed everything worked.
success: function (data) {
response($.map(data, function(item,customer) {
return [item.firstname1+' '+item.lastname1+' '+item.telephone1]
}));//END Success
},

load to work as append in jquery

i am creating form using js functions.. i want that when this function is called twice form should be created twice.. i am using jquery load hence it is overwriting again and again...
my jquery code:
function form(module,user) {
$.post("php/test.php",{ module:module , user:user}, function(data, status){
var f= jQuery.parseJSON( data );
$(".cards-container").load("modules/ams.html",function(){
$(".cards-container > div").addClass("card card-shadow animated fadeInDown");
$(".form-t").append("<input type='text'"+"placeholder="+f.text+" name='fname' required>");
});
});}
form("home",200);form("home",300);
AMS.html:
<div class='w100 large forms'>
<form action='test.php' method='post'>
<div class="form-t"></div>
<input type='submit' value='Submit'></form>
</div>
JQuery load() method always replaces content of "element-receiver". Use get() method to request new content with subsequent appending:
var f= jQuery.parseJSON( data );
$.get('modules/ams.html', function(data){
$(".cards-container").append(data);
$(".cards-container > div").addClass("card card-shadow animated fadeInDown");
$(".form-t:last").append("<input type='text'"+"placeholder="+f.text+" name='fname' required>");
});
Load will always overwrite. It is a shortcut function for an Ajax method. So instead, use Ajax so you have control of the result:
$.ajax({
url: "modules/ams.html",
type: "GET"
}).done(function (result) {
$(".cards-container").append(result);
});
This will just append the content directly into the container. You will have to apply any other logic you need. Remember that ids should be unique and forms cannot be nested so make sure you avoid loading html with a form when your container is already within a form.

bootstrap popover update content

how do you update the content of bootstrap popover after ajax success, I specifically need to change the value of the input field that I have but once I close the popover and click on it, the original value of the input field shows up? can someone help me out?
<button class="btn btn-primary edit" data-content='<input type="text" id="name" value="some value">
<button class="btn btn-primary save">Save</button>'>Edit</button>
JavaScript:
$('.edit').popover({
placement: 'left',
html: true,
});
$('body').on("click", ".save", function() {
var name = $('#name').val();
$.ajax({
type: "POST",
url: "test.php",
data: {
name: name
},
cache: false,
success: function(response) {
if (response.indexOf("success") != -1) {
$('#name').val(name);
$('.edit').popover('hide').next('.popover').remove();
}
}
});
});
after the data is saved the popover is closed and when I click edit again the old value shows in the input box.
Please find enclosed a working demo of a popover that will be updated with the response from an ajax request.
I've removed your request parameters just for the demo to be able to do the request with mocky.io.
The trick was to use .attr('value', text) instead of .val(text). I'm not exactly sure what's going on here. Maybe someone can explain why that's different.
But with attr it changes the popover and it works.
Another thing that is required is to recreate the popover. I also wanted to destroy the first popover but that doesn't work. So I created the same popover again.
You can also find the same code here at jsFiddle.
There is a bug in the code here at SO. If you get the data from the server and then close the popover, the data will be reset to initial value.
Don't know what's wrong, because it works at jsFiddle with-out that bug.
Update 04.12.2014:
I've improved the code a bit. Now there is a close button in the popover and the data is stored so the data from server is still available when the popover is re-opened.
The bug mentioned above was probably not a SO issue, it was because the data from server was not properly stored. That is also fixed now.
I've also removed some not needed script tags in the demo because tooltip and popover are already included in bootstrap 3.
Update 05.12.2014:
I have another improvement to the code.
The line $(this).parent().find('.close').click(...) is not working like I wanted it. I wanted to add the handler only to the close button of the current popover. But it adds it to all elements with class .close.
Because $(this).parent() is the body element. I think it is better to do it like this:
var current_popover = '#' + $(e.target).attr('aria-describedby');
var $cur_pop = $(current_popover);
$cur_pop.find('.close').click({});
With aria-describedby you'll get the id of the current popover and then you can find the close button of that popover.
$(function () {
var editData = 'new value';
var doPopover = function (item, text) {
$('#name').attr('value',text); // use set attr and not val()
//$('#name').val(text); //<<<< not working here doesn't set DOM properly
var $pop = $(item);
$pop.popover({
placement: 'right',
title: 'edit <a class="close" href="#">×</a>',
trigger: 'click',
html: true,
content: function () {
return $('#popup-content').html();
}
}).on('shown.bs.popover', function(e) {
// console.log('triggered');
// 'aria-describedby' is the id of the current popover
var current_popover = '#' + $(e.target).attr('aria-describedby');
var $cur_pop = $(current_popover);
$cur_pop.find('.close').click(function(){
//console.log('close triggered');
$pop.popover('hide');
});
});
return $pop;
};
// enable popover
doPopover('.edit', editData);
// edit button click handler to show popover
$('.edit').click(function() {
doPopover('.edit', editData);
});
$('body').on("click", ".save", function (e) {
e.preventDefault();
var name = $('#name').val();
//console.log($popover);
$.ajax({
type: "GET", //"POST",
url: "http://www.mocky.io/v2/547f86501713955b0a8ed4da", //"test.php",
data: {
//name: name
},
cache: false,
success: function (response) {
editData = response.data;
doPopover('.edit', editData);
console.log('response: ', editData);
}
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
<button class="btn btn-primary edit" data-html="true" data-toggle="popover" class="edit" data-title="Edit">Edit</button>
<div id="popup-content" class="hide">
<input type="text" id="name" value="some value" />
<button class="btn btn-primary save">Save</button>
</div>

Only slideUp the deleted message

I'm using a PM system and added the delete-message feature. I've got a form which checks for the message_id and message_title. The form posts to delete_message.php page which contains the query to delete the message. This has been done via Javascript as I dont want the page to refresh.
I've got two functions for this:
function deleteMessage() {
$.ajax({
url: "message/delete_message.php",
type: "POST",
data: $("#delMsgForm").serialize(),
success: function(data,textStatus,jqXHR){ finishDeleteMessage(data,textStatus,jqXHR); }
});
}
function finishDeleteMessage( data , textStatus ,jqXHR ) {
$(".inboxMessage").slideUp('slow');
}
Currently when I click on the delete button (image of a trashcan) it deletes the message without reloading the page, as a finishing touch, it slidesUp the divclass (inboxMessage) the message is in. Since I tell it to slide up this class, it slides up every message. This is my piece of code containing the classes and the form:
<div class="inboxMessage">
<div class="inboxMessageImg NoNewMsg"></div>
<div class="inboxMessageHeader">
<a id="ajax" class="inboxMessageLink" onclick="showMessage('.$row['message_id'].')">'.$row['message_title'].'</a>
<p class="inboxMessageStatus Read">'.$inboxMessageStatus_Read.'</p>
</div>
<div class="inboxMessageDescription">'.$inboxMessageDescription.'</div>
<div class="inboxMessageActions">
<form id="delMsgForm" name="delMsgForm" action="message/delete_message.php" method="post">
<input type="hidden" id="msgTitle" value="'.$row['message_title'].'" name="message_title">
<input type="hidden" id="msgID" value="'.$row['message_id'].'" name="message_id">
</form>
<input type="submit" id="ajax" value="" name="deleteMessageButton" class="deleteMessageIcon" onclick="deleteMessage()">
</div>
</div>
What I want it to do is to slideUp only the message which has just been deleted by the user. I know this has to be done by telling javascript to only slideUp the deleted message which contains the message_id and/or message_title.
I've tried several things, but no love whatsoever. I'm also not that familiar with javascript/ajax. Any help would be highly appreciate.
Cheers :)
where do you call deleteMessage from? indirect the function call through another function which knows the parent of your "trash can", and can call slide up on that specific one.
function deleteMessage (element) {
//element will be clicked button
var container = $(element).closest("div.inboxMessage"),
//container div including the trashcan
$.ajax({
url: "message/delete_message.php",
type: "POST",
data: $("#delMsgForm").serialize(),
success: function(data,textStatus,jqXHR){
finishDeleteMessage(container);
}
});
});
and this will be your button
<input type="submit" id="ajax" value="" name="deleteMessageButton" class="deleteMessageIcon" onclick="deleteMessage(this)">
Apparently, you've got more divs with class inboxMessage. Since you're adding this code:
$(".inboxMessage").slideUp('slow');
.. all divs with that class will remove. If you want just one div to remove, give it a unique ID or data-attribute and hide it that way.
For example: add the message-id to the div..
<div class="inboxMessage" id="(message_id)">
..and use..
$(".inboxMessage#message_id").slideUp('slow');
.. to slide up the right div.
Edit:
Add your message ID to the div and to the function deleteMessage(), so it will be deleteMessage(message_id).
function deleteMessage(message_id) {
$.ajax({
url: "message/delete_message.php",
type: "POST",
data: $("#delMsgForm").serialize(),
success: function(){ finishDeleteMessage(message_id); }
});
}
function finishDeleteMessage(message_id) {
$(".inboxMessage#"+message_id).slideUp('slow');
}

How can I remove AutoNumeric formatting before submitting form?

I'm using the jQuery plugin AutoNumeric but when I submit a form, I can't remove the formatting on the fields before POST.
I tried to use $('input').autonumeric('destroy') (and other methods) but it leaves the formatting on the text fields.
How can I POST the unformatted data to the server? How can I remove the formatting? Is there an attribute for it in the initial config, or somewhere else?
I don't want to send the serialized form data to the server (with AJAX). I want to submit the form with the unformatted data like a normal HTML action.
I wrote a better, somewhat more general hack for this in jQuery
$('form').submit(function(){
var form = $(this);
$('input').each(function(i){
var self = $(this);
try{
var v = self.autoNumeric('get');
self.autoNumeric('destroy');
self.val(v);
}catch(err){
console.log("Not an autonumeric field: " + self.attr("name"));
}
});
return true;
});
This code cleans form w/ error handling on not autoNumeric values.
With newer versions you can use the option:
unformatOnSubmit: true
Inside data callback you must call getString method like below:
$("#form").autosave({
callbacks: {
data: function (options, $inputs, formData) {
return $("#form").autoNumeric("getString");
},
trigger: {
method: "interval",
options: {
interval: 300000
}
},
save: {
method: "ajax",
options: {
type: "POST",
url: '/Action',
success: function (data) {
}
}
}
}
});
Use the get method.
'get' | returns un-formatted object via ".val()" or
".text()" | $(selector).autoNumeric('get');
<script type="text/javascript">
function clean(form) {
form["my_field"].value = "15";
}
</script>
<form method="post" action="submit.php" onsubmit="clean(this)">
<input type="text" name="my_field">
</form>
This will always submit "15". Now get creative :)
Mirrored raw value:
<form method="post" action="submit.php">
<input type="text" name="my_field_formatted" id="my_field_formatted">
<input type="hidden" name="my_field" id="my_field_raw">
</form>
<script type="text/javascript">
$("#my_field_formatted").change(function () {
$("#my_field").val($("#my_field_formatted").autoNumeric("get"));
});
</script>
The in submit.php ignore the value for my_field_formatted and use my_field instead.
You can always use php str_replace function
str_repalce(',','',$stringYouWantToFix);
it will remove all commas. you can cast the value to integer if necessary.
$("input.classname").autoNumeric('init',{your_options});
$('form').submit(function(){
var form=$(this);
$('form').find('input.classname').each(function(){
var self=$(this);
var v = self.autoNumeric('get');
// self.autoNumeric('destroy');
self.val(v);
});
});
classname is your input class that will init as autoNumeric
Sorry for bad English ^_^
There is another solution for integration which doesn't interfere with your client-side validation nor causes the flash of unformatted text before submission:
var input = $(selector);
var proxy = document.createElement('input');
proxy.type = 'text';
input.parent().prepend(proxy);
proxy = $(proxy);
proxy.autoNumeric('init', options);
proxy.autoNumeric('set', input.val())''
proxy.change(function () {
input.val(proxy.autoNumeric('get'));
});
You could use the getArray method (http://www.decorplanit.com/plugin/#getArrayAnchor).
$.post("myScript.php", $('#mainFormData').autoNumeric('getArray'));
I came up with this, seems like the cleanest way.
I know it's a pretty old thread but it's the first Google match, so i'll leave it here for future
$('form').on('submit', function(){
$('.curr').each(function(){
$(this).autoNumeric('update', {aSign: '', aDec: '.', aSep: ''});;
});
});
Solution for AJAX Use Case
I believe this is better answer among all of those mentioned above, as the person who wrote the question is doing AJAX. So
kindly upvote it, so that people find it easily. For non-ajax form submission, answer given by #jpaoletti is the right one.
// Get a reference to any one of the AutoNumeric element on the form to be submitted
var element = AutoNumeric.getAutoNumericElement('#modifyQuantity');
// Unformat ALL elements belonging to the form that includes above element
// Note: Do not perform following in AJAX beforeSend event, it will not work
element.formUnformat();
$.ajax({
url: "<url>",
data : {
ids : ids,
orderType : $('#modifyOrderType').val(),
// Directly use val() for all AutoNumeric fields (they will be unformatted now)
quantity : $('#modifyQuantity').val(),
price : $('#modifyPrice').val(),
triggerPrice : $('#modifyTriggerPrice').val()
}
})
.always(function( ) {
// When AJAX is finished, re-apply formatting
element.formReformat();
});
autoNumeric("getArray") no longer works.
unformatOnSubmit: true does not seem to work when form is submitted with Ajax using serializeArray().
Instead use formArrayFormatted to get the equivalent serialised data of form.serializeArray()
Just get any AutoNumeric initialised element from the form and call the method. It will serialise the entire form including non-autonumeric inputs.
$.ajax({
type: "POST",
url: url,
data: AutoNumeric.getAutoNumericElement("#anyElement").formArrayFormatted(),
)};

Categories