I'm a little desperate because I can not perform a simple search on my zimlet.
I just want to make a search in the custom folder.
The search should only display messages that are within my custom folder.
Like when I click on the custom folder in the left pane. exactly the same.
this is what shows the html header by pressing the icon of my custom folder in the left pane.
{"Header":{"context":{"_jsns":"urn:zimbra","userAgent":{"name":"ZimbraWebClient - FF39 (Linux)","version":"8.6.0_GA_1153"},"session":{"_content":150,"id":150},"account":{"_content":"admin#localhost.local","by":"name"},"csrfToken":"0_a3050edfdf238eadfdfdfdff2f14b4968e3"}},"Body":{"SearchRequest":{"_jsns":"urn:zimbraMail","sortBy":"dateDesc","header":[{"n":"List-ID"},{"n":"X-Zimbra-DL"},{"n":"IN-REPLY-TO"}],"tz":{"id":"America/Mexico_City"},"locale":{"_content":"es_MX"},"offset":0,"limit":100,"query":"in:\\"mycustomfolder\\"","types":"conversation","recip":"0","fullConversation":1,"needExp":1}}}
I'm trying with this code, within my com_zimbra_myzimlet.js
com_zimbra_myzimlet_HandlerObject.prototype._getShowResultFolderId =
function(t) {
var e=AjxSoapDoc.create("SearchRequest","urn:zimbraMail");
var cuery="raulicci";
e.setMethodAttribute("types","conversation");
e.setMethodAttribute("limit",100);
e.setMethodAttribute("offset",0);
e.set("query",cuery);
t.response=appCtxt.getAppController().sendRequest({
soapDoc:e,noBusyOverlay:false}
);
this.handleSearchResponse(t)
};
so far I can not find a way to make the consultation, although I imagine it is something easy as already implemented in zimbra comes when one gives click on the icon in my custom folder in the left pane.
I would like to use the default template that has zimbra to show INBOX, or the current folders.
When you click on the icon of the current folder in the left pane, us a list of emails appears as INBOX
I'm doing with my little zimlet one query with soap and json and I answered a JSON string.
This string json is a mailing list that are in the folder where you perform the query.
For request use:
var jsonObj = {SearchRequest:{_jsns:"urn:zimbraMail"}};
var request = jsonObj.SearchRequest;
request.sortBy = "dateDesc";
request.offset = 0;
request.limit = 100;
request.query = 'in:\"MYCURRENTFOLDER\"';
request.types = "conversation";
request.recips = "0";
request.fullConversation = 1;
request.needExp = 1;
var params = {
jsonObj:jsonObj,
asyncMode:true,
callback: (new AjxCallback(this, this._handleSOAPResponseJSON)),
errorCallback: (new AjxCallback(this, this._handleSOAPErrorResponseJSON)),
};
return appCtxt.getAppController().sendRequest(params);
For response use:
if (result.isException()) {
// do something with exception
var exception = result.getException();
return;
}
else {
response = { _jsns: "urn:zimbraMail", more: false };
}
// do something with response (in JSON format)
var response = result.getResponse();
var name = response.name;
var soapURL = response.publicURL;
var soapURL = response.soapURL;
var aller = result.getResponse();
var searchResult = new ZmSearchResult(this);
appCtxt.setStatusMsg("Response (JSON) success - "+name);
alert(aller.toSource());
JSON response to be displayed in the default template of INBOX integrated zimbra
({SearchResponse:{sortBy:"dateDesc", offset:0, c:[{id:"314", u:0, n:2, f:"s", d:1438663876000, su:"lokitox", fr:"lex", e:[{a:"admin#localhost.local", d:"admin", t:"f"}], m:[{id:"313", l:"300"}, {id:"312", l:"5", f:"s"}], sf:"1438663876000"}, {id:"-309", u:0, n:1, d:1438662639000, su:"Daily mail report for 2015-08-03", fr:"Grand Totals -- messages 91 received 117 delivered 0 forwarded 134 deferred (134 deferrals) 169 bounced 0 rejected (0%) 0 reject warnings 0 held 0 ...", e:[{a:"admin#localhost.local", d:"admin", t:"f"}], m:[{id:"309", s:"7232", l:"300"}], sf:"1438662639000"}], more:false, _jsns:"urn:zimbraMail"}})
Thankz, I hope someone has knowledge of how to do it
Related
So I ran into this problem two days back and still haven't got a proper solution. I would highly Appreciate any help in here.
Let me explain the scenario first, so the idea is I have one django based ecommerce site and I want to render the product showcase page through ajax call (without reloading) and same time also update the url as the selected filters for example (http://vps.vanijyam.com:8000/customerlist?category=category_1).
I want to achieve similar to this site - shutterstock.
My Scenario -
http://vps.vanijyam.com:8000/customerlist this page to showcase all the available products and also have the filters option and pagination.
Now when I change the page or apply some filter I am e.g. http://vps.vanijyam.com:8000/customerlist?category_slug=category_1 then it is working, but when I refresh the page it is not.. the reason behind this the way I am handling this ajax call in the backend.
def customer_categories(request):
# Get attributes from request url
current_page = request.GET.get('page' ,'1')
category_slug = request.GET.get('category_slug')
sortby_filter = request.GET.get('sortby_filter')
price_filter = request.GET.get('price_filter')
search_query= request.GET.get('term')
line_filter_min = request.GET.get('price_min')
line_filter_max = request.GET.get('price_max')
# Set limit and offset for queryset
limit = REQUEST_PER_PAGE * int(current_page)
offset = limit - REQUEST_PER_PAGE
categories = Category.objects.all()
# products = Product.objects.filter(available=True)[offset:limit] # limiting products based on current_page
# products_count = Product.objects.filter(available=True).count()
# Check product already in cartlist
cartlist_check = []
cart_item_count = cart_count(request)
cart_items = cart_list(request)
for cart in cart_items:
cartlist_check.append(cart['product'].id)
# Check product already in wishlist, only if user logged in
wishlist_check =[]
if request.user.is_authenticated:
wishlist_items_check = WishList.objects.filter(user=request.user)
for item in wishlist_items_check:
wishlist_check.append(item.product_id)
wishlist_count = wishlist_counts(request.user)
else:
wishlist_count = 0
# If category_slug True
if category_slug:
category = get_object_or_404(Category, slug=category_slug).\
get_descendants(include_self=True)
else:
category = None
time1 = time.time()
# Filters for multiselect, retun products and products_count
products, products_count, search_list = attribute_filter(category=category,
search_query=search_query,
sortby_filter=sortby_filter,
price_filter=price_filter,
line_filter_min=line_filter_min,
line_filter_max=line_filter_max,
offset=offset,
limit=limit)
time2= time.time()
print('Time Elapsed')
print(time2-time1)
if len(products) > 0:
# adding one more page if the last page will contains less products
total_pages = math.ceil(products_count / REQUEST_PER_PAGE )
cart_product_form = CartAddProductForm()
wish_list_form = WishListForm()
total_pages = math.ceil(products_count / REQUEST_PER_PAGE ) # adding one more page if the last page will contains less products
if not current_page == '1' or category_slug:
print('------------------------------')
return render(request, 'customer/products/products_by_category.html',\
{'products': products,
'wishlist_item_check': wishlist_check,
'cartlist_item_check': cartlist_check,
'current_page': current_page,
'total_products': products_count,
'request_per_page': REQUEST_PER_PAGE,
'total_pages':total_pages
})
else:
return render(request, 'customer/home/customer_showcase.html',\
{'products': products,
'categories':categories,
'cart_product_form': cart_product_form,
'wish_list_form': wish_list_form,
'wishlist_item_check': wishlist_check,
'wishlist_count': wishlist_count,
'cart':cart_items,
'items_count':cart_item_count,
'cartlist_item_check': cartlist_check,
'current_page': current_page,
'total_pages':total_pages,
'total_products': products_count,
'request_per_page': REQUEST_PER_PAGE,
})
Ajax part of the code is here
$('.selected_subcategory').on('click', function () {
send_data['selected_subcategory'] = $(this).attr('data-id');
getPopularProductsData($(this).attr('data-id'));
// getAPIData();
var params = window.location.search;
var path = window.location.pathname;
var old_url = path + params;
var url = old_url;
const state = {}
const title = ''
console.log('old urll', old_url)
let new_url=''
if(params){
new_url = removeDuplicate(old_url)
}
console.log('new url', new_url)
history.pushState(state, title, url)
$.ajax({
method: 'GET',
url: old_url,
data: {
category_slug: send_data['selected_subcategory']
},
beforeSend: function () {
$('#products').html('<div class="alert alert-success">Loading...</div>');
// $('#spinner3').addClass('d-block');
},
success: function (result) {
if (result['error']) {
let message =
'<div class="alert alert-danger">' +
result['error'] +
' <a class="" href="http://vps.vanijyam.com:8000/customerlist/" style="text-decoration: underline">click here</a>' +
'</div>';
$('#products').html(message);
} else {
document.getElementById('products').innerHTML = result;
}
const state = {}
const title = ''
const url = this.url
history.pushState(state, title, url)
},
error: function (response) {
$('html,body').animate({
scrollTop: 200,
});
$('#products').html(
'<div class="alert alert-danger">Something went wrong!!!</div>'
);
$('#list_data').hide();
// $('#spinner3').addClass('d-none');
},
});
});
My expectation is when I browse this http://vps.vanijyam.com:8000/customerlist?page=2&category_slug=category_1 link it would render the same which matches with the query params, but in a ajax way.
Sorry for the long explanation. Hope my point is clear through this explanation. Thanks in advance
Here in your Django part, you are returning two different HTML outputs when there is category_slug and not.
If there is category_slug in your request you returning 'customer/products/products_by_category.html'
But when there is no category slug you are returning 'customer/home/customer_showcase.html'.
Both HTML files are different in their layout. The first one doesn't provide the header or container elements. This is the central problem of your issue.
You can Fix this issue by
You can put a special parameter in ajax api call, by which Django can realize that is is an api call, this time it returns products_by_category.html.
And you want to make unique all other returns to customer_showcase.html, but if there is a category filter you can pass filtered content to the products list. If category_slug is None or empty you can pass all products without the filter to the same HTML file.
You can also differentiate ajax api call by making it a POST request and all other web requests remains GET requests. So you can easily identify the traffic.
Here is the changes in Django:
if request.method == "POST"::
print('------------------------------')
return render(request, 'customer/products/products_by_category.html',\
{'products': products,
'wishlist_item_check': wishlist_check,
'cartlist_item_check': cartlist_check,
'current_page': current_page,
'total_products': products_count,
'request_per_page': REQUEST_PER_PAGE,
'total_pages':total_pages
})
else:
return render(request, 'customer/home/customer_showcase.html',\
{'products': products,
'categories':categories,
'cart_product_form': cart_product_form,
'wish_list_form': wish_list_form,
'wishlist_item_check': wishlist_check,
'wishlist_count': wishlist_count,
'cart':cart_items,
'items_count':cart_item_count,
'cartlist_item_check': cartlist_check,
'current_page': current_page,
'total_pages':total_pages,
'total_products': products_count,
'request_per_page': REQUEST_PER_PAGE,
})
And make your ajax call to "POST", change in your front end code: method: 'POST',
Don't forget to add slash(/) at the end of url when you change to POST.
I have a Kendo.MVC project. The view has a model with a field of type List<>. I want to populate the List from a Javascript function. I've tried several ways, but can't get it working. Can someone explain what I'm doing wrong?
So here is my model:
public class Dashboard
{
public List<Note> ListNotes { get; set; }
}
I use the ListNotes on the view like this:
foreach (Note note in Model.ListNotes)
{
#Html.Raw(note.NoteText)
}
This works if I populate Model.ListNotes in the controller when the view starts...
public ActionResult DashBoard(string xsr, string vst)
{
var notes = rep.GetNotesByCompanyID(user.ResID, 7, 7);
List<Koorsen.Models.Note> listNotes = new List<Koorsen.Models.Note>();
Dashboard employee = new Dashboard
{
ResID = intUser,
Type = intType,
FirstName = user.FirstName,
LastName = user.LastName,
ListNotes = listNotes
};
return View(employee);
}
... but I need to populate ListNotes in a Javascript after a user action.
Here is my javascript to make an ajax call to populate ListNotes:
function getReminders(e)
{
var userID = '#ViewBag.CurrUser';
$.ajax({
url: "/api/WoApi/GetReminders/" + userID,
dataType: "json",
type: "GET",
success: function (notes)
{
// Need to assign notes to Model.ListNotes here
}
});
}
Here's the method it calls with the ajax call. I've confirmed ListNotes does have the values I want; it is not empty.
public List<Koorsen.Models.Note> GetReminders(int id)
{
var notes = rep.GetNotesByCompanyID(id, 7, 7);
List<Koorsen.Models.Note> listNotes = new List<Koorsen.Models.Note>();
foreach (Koorsen.OpenAccess.Note note in notes)
{
Koorsen.Models.Note newNote = new Koorsen.Models.Note()
{
NoteID = note.NoteID,
CompanyID = note.CompanyID,
LocationID = note.LocationID,
NoteText = note.NoteText,
NoteType = note.NoteType,
InternalNote = note.InternalNote,
NoteDate = note.NoteDate,
Active = note.Active,
AddBy = note.AddBy,
AddDate = note.AddDate,
ModBy = note.ModBy,
ModDate = note.ModDate
};
listNotes.Add(newNote);
}
return listNotes;
}
If ListNotes was a string, I would have added a hidden field and populated it in Javascript. But that didn't work for ListNotes. I didn't get an error, but the text on the screen didn't change.
#Html.HiddenFor(x => x.ListNotes)
...
...
$("#ListNotes").val(notes);
I also tried
#Model.ListNotes = notes; // This threw an unterminated template literal error
document.getElementById('ListNotes').value = notes;
I've even tried refreshing the page after assigning the value:
window.location.reload();
and refreshing the panel bar the code is in
var panelBar = $("#IntroPanelBar").data("kendoPanelBar");
panelBar.reload();
Can someone explain how to get this to work?
I don't know if this will cloud the issue, but the reason I need to populate the model in javascript with an ajax call is because Model.ListNotes is being used in a Kendo Panel Bar control and I don't want Model.ListNotes to have a value until the user expands the panel bar.
Here's the code for the panel bar:
#{
#(Html.Kendo().PanelBar().Name("IntroPanelBar")
.Items(items =>
{
items
.Add()
.Text("View Important Notes and Messages")
.Expanded(false)
.Content(
#<text>
#RenderReminders()
</text>
);
}
)
.Events(e => e
.Expand("getReminders")
)
)
}
Here's the helper than renders the contents:
#helper RenderReminders()
{
if (Model.ListNotes.Count <= 0)
{
#Html.Raw("No Current Messages");
}
else
{
foreach (Note note in Model.ListNotes)
{
#Html.Raw(note.NoteText)
<br />
}
}
}
The panel bar and the helpers work fine if I populate Model.ListNotes in the controller and pass Model to the view. I just can't get it to populate in the javascript after the user expands the panel bar.
Perhaps this will do it for you. I will provide a small working example I believe you can easily extend to meet your needs. I would recommend writing the html by hand instead of using the helper methods such as #html.raw since #html.raw is just a tool to generate html in the end anyways. You can write html manually accomplish what the helper methods do anyway and I think it will be easier for you in this situation. If you write the html correctly it should bind to the model correctly (which means it won't be empty on your post request model) So if you modify that html using javascript correctly, it will bind to your model correctly as well.
Take a look at some of these examples to get a better idea of what I am talking about:
http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/
So to answer your question...
You could build a hidden container to hold your list values like this (make sure this container is inside the form):
<div id="ListValues" style="display:none">
</div>
Then put the results your ajax post into a javascript variable (not shown).
Then in javascript do something like this:
$('form').off('submit'); //i do this to prevent duplicate bindings depending on how this page may be rendered futuristically as a safety precaution.
$('form').on('submit', function (e) { //on submit, modify the form data to include the information you want inside of your ListNotes
var data = getAjaxResults(); //data represents your ajax results. You can acquire and format that how you'd like I will use the following as an example format for how you could save the results as JSON data: [{NoteID ="1",CompanyID ="2"}]
let listLength = data.length;
for (let i = 0; i < listLength; i++) {
$('#ListValues').append('<input type="text" name="ListNotes['+i+'].NoteID " value="' + data.NoteID +'" />')
$('#ListValues').append('<input type="text" name="ListNotes['+i+'].CompanyID " value="' + data.CompanyID +'" />')
//for your ajax results, do this for each field on the note object
}
})
That should do it! After you submit your form, it should automatically model bind to you ListNotes! You will be able to inpsect this in your debugger on your post controller action.
Please help, I want to load 2 JSONs from 2 URLs, this loads questions for a survey. If I just load 1 JSON, the output still normal, but if 2 JSONs, the output is the text object, this survey is survey js from surveyjs.io, there is my code. Please help me.
var baris1,baris2 = [];
var url1='url_link';
var url2='url_link';
$.when($.getJSON('url_link'), $.getJSON('url_link')
).done(function(baris1,baris2){
//baris = data
baris1 = JSON.stringify(s.baris1)
baris2 = JSON.stringify(s.baris2);
//alert(baris1);
Survey.Survey.cssType = "bootstrap";
var surveyJSON = {pages:[{elements:[
{type:"matrix",columns:[
{value:1,text:"Strongly Disagree"},
{value:2,text:"Disagree"},
{value:3,text:"Neutral"},
{value:4,text:"Agree"},
{value:5,text:"Strongly Agree"}],
//name:"Pedagogik",rows:baris,
name:"Pedagogik",rows:baris1,
//title:"Silakan Jawab Dengan Sejujur-jujurnya"
},
{type:"matrix",columns:[
{value:1,text:"Strongly Disagree"},
{value:2,text:"Disagree"},
{value:3,text:"Neutral"},
{value:4,text:"Agree"},
{value:5,text:"Strongly Agree"}],
//name:"Pengetahuan Umum",rows:baris,
name:"Pengetahuan Umum",rows:baris2,
//title:"Silakan Jawab Dengan objektif"
}]}]}
function sendDataToServer(survey) {
//send Ajax request to your web server.
alert("The results are:" + JSON.stringify(s.data));}
var survey = new Survey.Model(surveyJSON);
$("#surveyContainer").Survey({
model: survey,
onComplete: sendDataToServer
});
});
Finally i found the answer, just declare the number of array for the output,
Row: baris1;
Change to
Row: baris1,[0];
Just it
I have the skeleton of a chat page but am having issues tying it all together. What I'm trying to do is have messages sent to the server whenever the user clicks send, and also, for the messages shown to update every 3 seconds. Any insights, tips, or general comments would be much appreciated.
Issues right now:
When I fetch, I append the <ul class="messages"></ul> but don't want to reappend messages I've already fetched.
Make sure my chatSend is working correctly but if I run chatSend, then chatFetch, I don't retrieve the message I sent.
var input1 = document.getElementById('input1'), sendbutton = document.getElementById('sendbutton');
function IsEmpty(){
if (input1.value){
sendbutton.removeAttribute('disabled');
} else {
sendbutton.setAttribute('disabled', '');
}
}
input1.onkeyup = IsEmpty;
function chatFetch(){
$.ajax({
url: "https://api.parse.com/1/classes/chats",
dataType: "json",
method: "GET",
success: function(data){
$(".messages").clear();
for(var key in data) {
for(var i in data[key]){
console.log(data[key][i])
$(".messages").append("<li>"+data[key][i].text+"</li>");
}
}
}
})
}
function chatSend(){
$.ajax({
type: "POST",
url: "https://api.parse.com/1/classes/chats",
data: JSON.stringify({text: $('input1.draft').val()}),
success:function(message){
}
})
}
chatFetch();
$("#sendbutton").on('click',chatSend());
This seems like a pretty good project for Knockout.js, especially if you want to make sure you're not re-appending messages you've already sent. Since the library was meant in no small part for that sort of thing, I think it would make sense to leverage it to its full potential. So let's say that your API already takes care of limiting how many messages have come back, searching for the right messages, etc., and focus strictly on the UI. We can start with our Javascript view model of a chat message...
function IM(msg) {
var self = this;
self.username = ko.observable();
self.message = ko.observable();
self.timestamp = ko.observable();
}
This is taking a few liberties and assuming that you get back an IM object which has the name of the user sending the message, and the content, as well as a timestamp for the message. Probably not too far fetched to hope you have access to these data elements, right? Moving on to the large view model encapsulating your IMs...
function vm() {
var self = this;
self.messages = ko.observableArray([]);
self.message = ko.observable(new IM());
self.setup = function () {
self.chatFetch();
self.message().username([user current username] || '');
};
self.chatFetch = function () {
$.getJSON("https://api.parse.com/1/classes/chats", function(results){
for(var key in data) {
// parse your incoming data to get whatever elements you
// can matching the IM view model here then assign it as
// per these examples as closely as possible
var im = new IM();
im.username(data[key][i].username || '');
im.message(data[key][i].message || '');
im.timestamp(data[key][i].message || '');
// the ([JSON data] || '') defaults the property to an
// empty strings so it fails gracefully when no data is
// available to assign to it
self.messages.push(im);
}
});
};
}
All right, so we have out Javascript models which will update the screen via bindings (more on that in a bit) and we're getting and populating data. But how do we update and send IMs? Well, remember that self.message object? We get to use it now.
function vm() {
// ... our setup and initial get code
self.chatSend = function () {
var data = {
'user': self.message().username(),
'text': self.message().message(),
'time': new Date()
};
$.post("https://api.parse.com/1/classes/chats", data, function(result) {
// do whatever you want with the results, if anything
});
// now we update our current messages and load new ones
self.chatFetch();
};
}
All right, so how do we keep track of all of this? Through the magic of bindings. Well, it's not magic, it's pretty intense Javascript inside Knockout.js that listens for changes and the updates the elements accordingly, but you don't have to worry about that. You can just worry about your HTML which should look like this...
<div id="chat">
<ul data-bind="foreach: messages">
<li>
<span data-bind="text: username"></span> :
<span data-bind="text: message"></span> [
<span data-bind="text: timestamp"></span> ]
</li>
</ul>
</div>
<div id="chatInput">
<input data-bind="value: message" type="text" placeholder="message..." />
<button data-bind="click: $root.chatSend()">Send</button>
<div>
Now for the final step to populate your bindings and keep them updated, is to call your view model and its methods...
$(document).ready(function () {
var imVM = new vm();
// perform your initial search and setup
imVM.setup();
// apply the bindings and hook it all together
ko.applyBindings(imVM.messages, $('#chat')[0]);
ko.applyBindings(imVM.message, $('#chatInput')[0]);
// and now update the form every three seconds
setInterval(function() { imVM.chatFetch(); }, 3000);
});
So this should give you a pretty decent start on a chat system in an HTML page. I'll leave the validation, styling, and prettifying as an exercise to the programmer...
I'm trying to create multiple records of an object called Guarantor__c, a child of Opportunity and Contact, on button click. All of the Guarantor records should relate to the Opportunity on the page where the button is. The records are all of the Contacts of the Opportunity's Account with the Guarantor record type. The SOQL below is pretty straightforward. This runs without an error, but doesn't enter any records. Any ideas?
{!REQUIRESCRIPT('/soap/ajax/27.0/connection.js')}
var url = parent.location.href;
var updateRecords = [];
var principalContacts = sforce.connection.query("Select Id From Contact where AccountId ='{!Account.Id}' and RecordTypeId ='012A0000000nr4BIAQ'");
var principalContactsArray = principalContacts.getArray("records");
if (principalContactsArray.length < 1){
alert("There are no guarantors for this opportunity. Go back to the Account and enter the guarantors.")
}else{
for (eachPrincipalContact in principalContactsArray){
var newGuarantor = new sforce.SObject("Guarantor__c");
newGuarantor.COntact__ = eachPrincipalContact;
newGuarantor.Opportunity__c ="{!Opportunity.Id}";
updateRecords.push(newGuarantor);
sforce.connection.create(updateRecords);
}
}
sforce.connection.create(updateRecords);
should be placed outside of the for loop. like
for (eachPrincipalContact in principalContactsArray){
var newGuarantor = new sforce.SObject("Guarantor__c");
newGuarantor.COntact__ = eachPrincipalContact;
newGuarantor.Opportunity__c ="{!Opportunity.Id}";
updateRecords.push(newGuarantor);
}
sforce.connection.create(updateRecords);