Salesforce & Javascript / Ajax - Trying to use a parameters - javascript

Following this post :
Define Apex controller in javascript home component
I tried to improved it, because the limit of Salesforce for an SOQL request is 50k records.
The Code_Postal__c object can have more than 50k of records.
I saw that we can parse item in javascript (i'm pretty bad with this language).
The idea is to make a dynamic call of my controller when the user will start typing the postal code ( id of the field = #acc18zip ). But i got an error with my item list, so i came back to use my string but it didn't work.
When i tried to find the error with the chrome console or firebug i saw this error into my console :
Uncaught SyntaxError: Unexpected end of input
and when i start typing a postal code:
event.returnValue is deprecated. Please use the standard event.preventDefault() instead.
My updated controller is this one :
global class cpSearch2{
webService static String searchCP() {
String pickValues='';
for(Code_Postal__c cp : [Select Commune__c, Code_Postal__c from Code_Postal__c ]){
pickValues = pickValues +cp.Code_Postal__c+ ' - ' + cp.Commune__c+'+';
}
return pickValues;
}
webService static string searchCP2(string searchTerm) {
String pickValues='';
for(Code_Postal__c cp : [Select Commune__c, Code_Postal__c from Code_Postal__c where Code_Postal__c LIKE :searchTerm]){
pickValues = pickValues +cp.Code_Postal__c+ ' - ' + cp.Commune__c+'+';
}
return pickValues;
}
/*
Function with list of object
webService static list<Code_Postal__c> searchCP2(string searchTerm) {
list<Code_Postal__c> matchingCP = new list<Code_Postal__c>();
for(Code_Postal__c cp : [Select Commune__c, Code_Postal__c from Code_Postal__c where Code_Postal__c LIKE :searchTerm]){
matchingCP.add(cp);
}
return matchingCP;
}*/
}
and the updated javascript is :
<link rel="stylesheet" href="https://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.9.1.js"></script>
<script src="https://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="/soap/ajax/15.0/connection.js" type="text/javascript"></script>
<script src="/soap/ajax/15.0/apex.js" type="text/javascript"></script>
<script>
var url = document.URL;
if(url.indexOf('001')!=-1)
{
var sid = document.cookie.match(' sid=([^;]*)')[1];
sforce.debug.trace=true;
sforce.connection.sessionId = sid; ;
var stages;
var cpObjects;
var queryTerm;
$ = jQuery.noConflict();
$(function()
{
$( "#acc18zip" ).autocomplete({
source:function( request, response ) {
queryTerm = request.term;
stages = sforce.apex.execute("cpSearch2", "searchCP2", {queryTerm,function(result, event)});
if(event.type == 'exception') {
alert(event.message);
} else {
cpObjects = stages.toString().split("+");
response(cpObjects);
}
},
focus: function( event, ui ) {
$("#acc18zip").val(selectedArray[0]);
$("#acc18city").val(selectedArray[1]);
return false;
},
select: function( event, ui ) {
console.log(ui.item);
selectedArray = ui.item.split(" - ");
$("#acc18zip").val(selectedArray[0]);
$("#acc18city").val(selectedArray[1]);
return false;
}
});
});
}
</script>
Trying to follow this :
http://jqueryui.com/autocomplete/#remote-jsonp

Related

Using Django and Jquery

In addition to this post https://stackoverflow.com/a/17732956 I want to change the order of a list via drag'n'drop and save it afterwards in django backend.
For test purposes and comprehension I've used following fiddle:
http://jsfiddle.net/LvA2z/#&togetherjs=LvHpjIr7L0
and updated the action of the form with my own action. So, instead of script.php, I used action="{% url 'save_order' %}".
In views my function looks like:
def save_order(request):
if (request.method == 'POST'):
list = request.POST['listCSV']
print(list)
Basically I want to change the order of list elements and save it afterwards with the result that after refreshing the page the saved order is given. However I do not know, how pass vars from jquery to django site. When I change the order, I have the sorted list in 'listCSV'. How do I pass this result to django site to save it in db?
EDIT:
If //$("#listsaveform").submit(); is not commented out and I fire this function referenced with my save_order function, I got this error:
jquery-1.10.2.min.js:6 POST http://localhost:8000/overview/saveOrder/ 405 (Method Not Allowed)
EDIT:
Okay, thanks for the hint. I have never worked with ajax and therefore I'm stucking a bit.
I have my list construct:
{% if habits %}
<ul id="sortable">
{% for habit in habits|dictsort:"priority" %}
<li class="ui-state-default">{{habit.title}}</li>
{% endfor %}
</ul>
{% endif %}
and this list construct is sortable with this lines of code:
$(function() {
$( "#sortable" ).sortable();
});
How does look my form?
Here is my solution based on https://impythonist.wordpress.com/2015/06/16/django-with-ajax-a-modern-client-server-communication-practise/.
In JS
// Sort & save order of habits
$(function () {
$('.sort').sortable({
handle: 'button',
cancel: '',
update: function(event, ui) {
var result = $(this).sortable( "serialize", {key: event.target.id});
// alert(result);
var csrftoken = getCookie('csrftoken');
$.ajax({
url : "/overview/saveOrder/", // the endpoint,commonly same url
type : "POST", // http method
data : { csrfmiddlewaretoken : csrftoken,
result : result,
}, // data sent with the post request
// handle a successful response
success : function(json) {
console.log(json); // another sanity check
//On success show the data posted to server as a message
// alert('Your list '+json['result']);
},
// handle a non-successful response
error : function(xhr,errmsg,err) {
console.log("FAILURE");
console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
}
});
}
});
// var sorted = $( ".selector" ).sortable( "serialize", { key: "sort" } );
// console.log(sorted)
})
//For getting CSRF token
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
and on Django side
def save_habit(request):
print('save_habit')
if (request.method == 'POST'):
if request.is_ajax():
habits = Habit.objects.filter(created_by=request.user.userprofile, is_active=True)
habit_title = request.POST.get('habit_title')
habit_trigger = request.POST.get('habit_trigger')
habit_routine = request.POST.get('habit_routine')
habit_targetbehavior = request.POST.get('habit_targetbehavior')
habit_image = request.POST.get('habit_image')
print(habit_image)
image = habit_image.split('http://localhost:8000/media')
print(image[1])
# TODO: was, wenn routine noch gar nicht existiert? --> speichern
obj_routine = Existingroutine.objects.get(name=habit_routine)
obj_targetbehavior = Targetbehavior.objects.get(name=habit_targetbehavior)
for habit in habits:
habit.priority += 1;
# habit.save();
habit = Habit(created_by=request.user.userprofile, is_active=True,
title=habit_title, trigger=habit_trigger, existingroutine=obj_routine,
targetbehavior=obj_targetbehavior, image=image[1])
#habit.save()
data = {"habit_title":habit_title,
"habit_trigger":habit_trigger,
"habit_routine":habit_routine,
"habit_targetbehavior":habit_targetbehavior };
return JsonResponse(data)
return redirect('display_habits')

Jquery each and split issue

I've this code
<head>
<meta charset="utf-8">
<script src="//code.jquery.com/jquery-2.0.1.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/sunny/jquery-ui.css">
<link rel="stylesheet" href="http://localhost/opencart/preventivo.css">
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script>
var opzione=$("#tutte_le_macro_opzioni").text().split(" ");
$.each(opzione, function( key, value ) {
$(document).on("change","."+value,function () {
//does something//
});
});
<div id="tutte_le_macro_opzioni"><?php echo "city,country,name"; ?></div>
Now the problem is that when I use var opzione=$("#tutte_le_macro_opzioni").text().split(" "); it gives to me this problem:
Sizzle.error = function( msg ) {
throw new Error( "Syntax error, unrecognized expression: " + msg );
};
If I change var opzione=$("#tutte_le_macro_opzioni").text().split(" "); with var opzione="city,country,name" the script works perfectly. It seems a problem with split after a php result.
Could some one help me please?
UPDATE
this is the php code from I populate div tutte_le_macro_opzioni
<?php
$con=mysqli_connect("localhost","root","","test");
$a="";
$query= "SELECT * FROM oc_option_description";
$result=mysqli_query($con,$query);
while($row=mysqli_fetch_array($result)){
$a.=strtolower($row["name"]).",";
}
echo $a;
?>
SOLVED
I replace the php code with this
ALL th code in one line...it seems case sensitive :-)
Try to replace this :
var opzione=$("#tutte_le_macro_opzioni").text().split(" ");
$.each(opzione, function( key, value ) {
$(document).on("change","."+value,function () {
//does something//
});
});
By this :
$(function(){
var opzione=$("#tutte_le_macro_opzioni").text().split(',');
$.each(opzione, function( key, value ) {
$(document).on("change","."+value,function () {
//does something//
});
});
});
Since $("#tutte_le_macro_opzioni").text() contains the same as this "city,country,name" and it's a string, you have to split on ',' to get an array for $.each() loop.
See this fiddle

# Uncaught ReferenceError: safetxt is not defined #

Uncaught ReferenceError: safetxt is not defined
I am trying to build a video and text chat web app using pubnub with their webrtc sdk I would like to know where I went wrong in this code; the video chat works fine - it is when I tried to text that I have the error.
<script src="https://cdn.pubnub.com/pubnub.min.js"></script>
<script src="http://stephenlb.github.io/webrtc-sdk/js/webrtc.js"></script>
<div><script>(function(){
// ~Warning~ You must get your own API Keys for non-demo purposes.
// ~Warning~ Get your PubNub API Keys: http://www.pubnub.com/get-started/
// The phone *number* can by any string value
var phone = PHONE({
number : '7898',
publish_key : 'demo',
subscribe_key : 'demo',
ssl : true
});
// As soon as the phone is ready we can make calls
phone.ready(function(){
// Dial a Number and get the Call Session
// For simplicity the phone number is the same for both caller/receiver.
// you should use different phone numbers for each user.
var session = phone.dial('9365');
});
// When Call Comes In or is to be Connected
phone.receive(function(session){
// Display Your Friend's Live Video
session.connected(function(session){
PUBNUB.$('video-out').appendChild(session.video);
});
});
var chat_in = PUBNUB.$('pubnub-chat-input');
var chat_out = PUBNUB.$('pubnub-chat-output');
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
// Send Chat MSG and update UI for Sending Messages
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
PUBNUB.bind( 'keydown', chat_in, function(e) {
if ((e.keyCode || e.charCode) !== 13) return true;
if (!chat_in.value.replace( /\s+/g, '' )) return true;
phone.send({ text : chat_in.value });
add_chat( '7898' + " (Me)", chat_in.value );
chat_in.value = '';
} )
function add_chat( number, text ) {
if (!text.replace( /\s+/g, '' )) return true;
var newchat = document.createElement('div');
newchat.innerHTML = PUBNUB.supplant(
'<strong>{number}: </strong> {message}', {
message : safetxt(text),
number : safetxt(number)
} );
chat_out.insertBefore( newchat, chat_out.firstChild );
}
function message( session, message ) {
add_chat( session.number, message.text );}
})();</script>
safetext() Method
You can find the source listed in the demonstration: https://github.com/stephenlb/webrtc-sdk/blob/gh-pages/index.html#L326-L331
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
// XSS Prevention
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
function safetxt(text) {
return (''+text).replace( /[<>]/g, '' );
}

Google custom search - manual load/execute from url params

Getting some odd behavior from google custom search that I can't seem to suss out. Maybe someone has a clue.
I'm putting together a Magento site, which has its own internal search engine - but is limited to product only. I want to implement google custom search results on the search results page as well. I figure I should be able to simply execute a search based on the query vars in the url (to return all the non-product content), as such:
<section style="min-height:600px">
<div style="background-color:#DFDFDF; min-height:800px; width:100%;">
<div id="cse">Loading</div>
</div>
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
$(document).ready( function(){
console.log('search initiated');
var t = window.setTimeout( function(){ customSearch(); }, 5000 );
});
function customSearch(){
var q = urlParams()['q'];
if (q != undefined && q != ""){
console.log('q : %s', q); //outputs successfully
google.load('search', '1');
google.setOnLoadCallback(function () {
var customSearchControl = new google.search.CustomSearchControl(MY CUSTOM ID KEY);
var cseDrawOptions = new google.search.DrawOptions();
cseDrawOptions.setAutoComplete(true); //unknown if this is required...
customSearchControl.draw('cse',cseDrawOptions);
customSearchControl.execute(q);
}, true);
}
}
function urlParams(){
var vars = [];
var hash;
var index = window.location.href.indexOf('?');
if( index != -1 ){
var hashes = window.location.href.slice(index + 1).split('&');
for(var i = 0; i < hashes.length; i++){
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1].replace(/\+/g, " ");
}
}
return vars;
}
//]>
</script>
</section>
I'll note that I've pulled all other content out of the logic (but its implementation in magento is identical).
So the behavior goes like this: page loads fine (I'm delaying the google search with a timeout for testing purposes ). Assuming there is a query var in the url the console traces out as expected. Then the page just gets wiped out, with no content back from google. "Wiped out"... meaning all elements on teh page disappear, or are getting overwritten by a new page that google loads. As if the search control isn't creating an iframe - its just replacing the page with a <body>-less html page.
I've ready a number of articles on the subject, and gone over the API - this code looks like it should work. But clearly isn't.
What am I missing?
Cheers -
UPDATE
Continued messing around with this has revealed that for whatever reason :
google.load('search', '1');
google.google.setOnLoadCallback( console.log('loaded') )
Was the cause of the replaced page issue. The responded page, however contained links to the search module that google is hosting. And if I manually linked those files (forgoing a google.load) then I could run a search as expected:
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script src="http://www.google.com/uds/?file=search&v=1" type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
... search logic
Then I found an alternate syntax on the google developers page that seemed to work as expected:
$(document).ready( function(){
google.load("search", "1", {"callback" : customSearch});
});
function customSearch(){
var q = urlParams()['q'];
if (q != undefined && q != ""){
var cseControl = new google.search.CustomSearchControl('MY CUSTOM KEY');
var cseDrawOptions = new google.search.DrawOptions();
cseDrawOptions.enableSearchResultsOnly()
cseControl.draw('cse', cseDrawOptions);
cseControl.execute(q);
}
}
Which works as expected. Only real problem at this point is the host of
Unsafe JavaScript attempt to access frame with URL http://mydomain from frame with URL http://www.google/cse?...
That now gets thrown.
I don't know how the two different versions of load syntax changes anything... but it seemed to of. Whatever the case, I'm unclear as to how to resolve these cross domain errors.
Thoughts would be great.
Nothin huh?
Well - I've basically worked out a good solution, using an alternate method that I think will be more flexible in the long run. Using googles RESTful API and simple jquery .ajax call, I can obtain good, controllable results with no cross-domain errors:
<div id="cse">Loading</div>
<script>
//https://developers.google.com/custom-search/v1/getting_started
//https://developers.google.com/custom-search/v1/using_rest#query-params
//https://developers.google.com/custom-search/v1/cse/list
var _url = "https://www.googleapis.com/customsearch/v1";
var _key = 'AIzaSy... your api key here';
var _cx = '001809... your engine id';
var _q = urlParams()['q']; //query param
jQuery(document).ready(function() {
$j.ajax({
url : _url,
type : 'GET',
dataType : 'jsonp',
data :{
key : _key,
cx : _cx,
q :_q
},
success : function(data, textStatus, jqXHR){ responseHandler(data); },
error : function(jqXHR, textStatus, errorThrown){ console.log('error: %s'), errorThrown},
beforeSend : function(){ console.log('sending request')},
crossDomain : true
});
});
function responseHandler( response, status) {
console.log(response);
var cse = $j('#cse'); // render vars as needed...
for (var i = 0; i < response.items.length; i++) {
var item = response.items[i];
cse.append( "<br>" + item.htmlTitle);
}
}
function urlParams(){
var vars = [];
var hash;
var index = window.location.href.indexOf('?');
if( index != -1 ){
var hashes = window.location.href.slice(index + 1).split('&');
for(var i = 0; i < hashes.length; i++){
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
}
return vars;
}
</script>
And you can too;D
Cheers

Why is my jQuery.post() ajax failing when I return one View but does not fail when i return another?

I'm trying to write a straightforward comment poster. I have this code in the controller:
[HttpPost]
[ValidateInput(false)]
public ViewResult Comments(MemberData md, long EntryId, string Comment, long LastId = 0)
{
bool isModerated = true;
bool isLoggedIn = GenesisRepository.IsNotGuest(md.MemberGUID);
bool isCommentAllowed = GenesisRepository.IsPermissionAssigned(md.MemberGUID, "Comments", "Create");
// Moderate comment?
if (moderateGuestComments == false && isLoggedIn == false) isModerated = false;
if (moderateMemberComments == false && isLoggedIn) isModerated = false;
long memberId = (from m in GenesisRepository.Member
where m.MemberGUID == md.MemberGUID
select m.MemberID)
.FirstOrDefault();
if (
EntryId > 0
&& !string.IsNullOrEmpty(Comment)
&& memberId > 0
&& isCommentAllowed)
{
Comments comment = new Comments {
Comment = Comment,
Date = DateTime.Now,
isActive = isModerated ? false : true,
MemberID = memberId,
StreamEntryID = EntryId,
};
if (GenesisRepository.SaveComment(comment))
{
List<Comments> comments = new List<Comments>();
comments = (from c in GenesisRepository.Comments
where c.StreamEntryID == EntryId
&& c.comID > LastId
select c
).ToList();
return View("DisplayComments", comments);
}
}
return View("CommentError", "Unable to post comment.");
}
When everything is fine and the action returns return View("DisplayComments", comments); the $.post() success function is triggered. But, When the action returns return View("CommentError", "Unable to post comment."); The $.post() ajax fails. I don't understand why the $.post() cares which view I'm returning.
Here's my Javascript:
<script type="text/javascript">
$(document).ready(function () {
$("#comments").ajaxError(function (event, request, settings) {
alert("Error requesting page " + settings.url);
});
$("button#submitComment").click(function () {
var commentList = $("#comments");
var lastId = $(".comment h4").last().attr("id");
var commentData = "EntryId=" + $("input#EntryID").val()
+ "&Comment=" + $("textarea#Comment").val()
+ "&LastId=" + lastId;
$.post(
"/find/Comments/Comments",
commentData,
function (data) {
alert("success");
alert(data);
if ($(data).filter(".error").length > 0) {
error = $(data);
$(this).after(error);
}
else {
newComments = $(data);
newComments.filter(".comment").css('display', 'none');
alert(newComments);
commentList.append(newComments);
$(".comment").each(function () {
$(this).slideDown("fast")
});
$("#Comment").attr("value", "");
}
}
);
});
});
</script>
What about this could cause the ajax to fail?
Here's what the two views look like:
View("DisplayComments", comments); (works)
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<List<Genesis.Domain.Entities.Comments>>" %>
<% foreach (var item in Model) %>
<% { %>
<div class="comment" style="background:#eee; border:1px solid gray; padding:10px 10px 0 10px; margin-bottom:20px;">
<h4 id="<%:item.comID %>"><%: item.Member.ScreenName%> commented on <%: String.Format("{0:f}", item.Date)%></h4>
<p>
<%: item.Comment%>
</p>
</div>
<% } %>
View("CommentError", "Unable to post comment."); (does not work)
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %>
<div class="error">
<%:Model%>
</div>
What about this could cause the ajax post to fail?
If the ajaxError function is triggered this strongly indicates that your controller action returns a status code different than 200, probably 500 which is a strong indication that your controller action throws an exception before ever reaching the last line and be able to return a view.
So here are the steps to do:
Use FireBug
Look at what your server sends as response to the AJAX request
Analyze the response status code and the response contents
Alternative approach:
Put a breakpoint in your controller action
Hit F5
When the controller action is hit step through your code
Observe exactly what happens
Remark: I would very strongly recommend you properly encoding your AJAX input. So instead of:
var commentData = "EntryId=" + $("input#EntryID").val()
+ "&Comment=" + $("textarea#Comment").val()
+ "&LastId=" + lastId;
you definitely should:
var commentData = $.param({
EntryId: $("input#EntryID").val(),
Comment: $("textarea#Comment").val(),
LastId: lastId
});
Note that everytime you use the +, & and = signs when dealing with querystring parameters (no matter what language you are using) you are doing it wrong.

Categories

Resources