Drop down options enabled based on the user - google-docs

Okay, this might seem stupid since it's my first time using Google Docs, and this could have a very simple solution, but I have not managed to find an answer by googling.
Basically, my sheet has a dropdown with 3 options. The sheet has 3 active users editing it. How would I go about making the option "A" on dropdown only available to user "A", and so on? Basically, letting user "A" pick only the option I allow him to. If such a thing is not possible, what would be the workaround? Once again, I'm sorry for asking something this seemingly simple, and thank you.

What you want cannot be achieved since protection for ranges works for a chosen range whereas the data validation options are all in the same range, and not separate ones.
What you can do:
1. Protect the range for each specific user
Since each user has only one option available, you can create three cells which would represent the options for each user. Afterwards, you will have to protect each of them in order to let only the wanted user access the wanted cell/option.
2. Make use of Apps Script
Apps Script is a powerful development platform which can be used to build web apps and automate tasks. What makes it special is the fact that it is easy to use and to create applications that integrate with G Suite.
Even though this still won't allow you to achieve the task directly, you can ask the user to input their email address and based on the response, display the customized content:
function onOpen() {
var ss = SpreadsheetApp.getActiveSheet();
var ui = SpreadsheetApp.getUi();
var result = ui.prompt('Please enter your email address:', ui.ButtonSet.OK_CANCEL);
var button = result.getSelectedButton();
var text = result.getResponseText();
if (button == ui.Button.CANCEL) {
ui.alert('I didn\'t get your name.');
} else if (button == ui.Button.CLOSE) {
ui.alert('You closed the dialog.');
}
if (text == 'user_a#email.com')
// display the content for user A
else if (text == 'user_b#email.com')
//display the content for user B
else if (text == 'user_c#email.com')
//display the content for user C
}
Reference
Protect, hide, and edit sheets;
Apps Script;
Promp Dialogs Apps Script.

Related

Extract Instagram Follower/Following Data

I wanted to extract Instagram Follower/Following Data(other user, not my own) and also the names/userid of the Follower/Following. I have searched through the forum but so far what I found is that need authentication before could access any basic data from the Instagram user.
May I know is it possible not to go through the authentication but still able to pull the relationship data (following/follower) data?
What I am trying to achieve here is to track for example do a data analysis of how many followers does a particular public profile of a instagram user has (i.e. maybe some newly opened toy shop that has started a instagram profile). Authenticating each and every single shops that have started a public instagram profile is not feasible. Hence, would there be a way to extract that data using going through the authentication process as described by the API?
Thanks.
My answer is that you need need authentication with some IG account first. After that, the information is all available as long as the account you are looking at is 'public'
API doesn't provide the list of follower anymore even if you are authentificate
You need to do some other technique like the web scraping one (parse the code of the HTML )
This is seriously not my area and the question I was answering to has been closed.
I have spent so long trying to figure this out and although it is a very different solution it's probably going to work for longer.
Open your browser in Mobile mode (no idea how to do).
I have used a python script which did this for me but I will update it with help from the comments
Open a New Tab, acess the profile you want to explore and press followers/following respectively.
Looking at the list of followers/folowing
Inspect any element and go to 'Console' at the top
On the console, paste this and hit Enter.
const arrHtml = document.getElementsByClassName('_ab8w _ab94 _ab99 _ab9f _ab9m _ab9p _abb- _abcm');
while (!!arrHtml.length) {
arrHtml[0].parentNode.removeChild(arrHtml[0])
}
And this
const arrHtml = document.getElementsByClassName('_ab8w _ab94 _ab99 _ab9f _ab9m _ab9p _abbj _abcm');
while (!!arrHtml.length) {
arrHtml[0].parentNode.removeChild(arrHtml[0])
}
And this
const arrHtml = document.getElementsByClassName('_ab8y _ab94 _ab99 _ab9f _ab9m _ab9p _aba_ _abcm');
while (!!arrHtml.length) {
arrHtml[0].parentNode.removeChild(arrHtml[0])
}
And this
const arrHtml = document.getElementsByClassName('_ab8w _ab94 _ab97 _ab9h _ab9k _ab9p _abb0 _abcm');
while (!!arrHtml.length) {
arrHtml[0].parentNode.removeChild(arrHtml[0])
}
Now that everything has been stripped away, except for the usernames.
Click anywhere and use Ctrl + A
Copy (Ctrl + C)
And paste (Ctrl + V) wherever you like. enjoy'

Searchable civiEvents in drupal7

I have a site that is running on drupal 7 and uses civicrm 4.4.1. I need the events to be included in the search results.
So far all I have found was dated documentation on civicrm that required modules that are not available for Drupal 7.
I also tried the search page module and it is not grabbing the events.
It's a little unclear what you're looking for, so I'll answer two ways.
You can search for event participants most easily by going into the Search menu and selecting Advanced Search. You can see the events information by clicking on the Events header--the section will open up. You don't need to enter anything else on the search form unless you want to search for that too (i.e. fundraiser attendees who live in West Virginia).
If you want CiviCRM events to show up in your Drupal content search results, you'll need to get the events to appear as content. CiviCRM information is 100% separate from Drupal content, but you may have some luck using the CiviCRM Entity module https://drupal.org/project/civicrm_entity to expose CiviCRM events as entities.
I haven't seen anything pre-built that will include CiviCRM events in the standard Drupal site search. Looking at the search api, I think it is possible to create a module to do that, but I don't think it is trivial. I haven't written any modules for the search api, but it seems like there is a bit of bookkeeping to be done to write this kind of integration.
I've handled this in a couple of ways for my customers. One, create a content type for Events and put a detailed description and basic date information in the content type. When creating events in CiviCRM, just make a barebones event for registration and link to the event registration page directly from the event node. Two, make event search a separate action, with a nice link and a view.
I know that neither of these solutions is ideal, but I don't see a quick solution apart from writing your own search plugin.
We create content in Drupal and link it to Civi event pages using a Computed Field that matches Event Name to the node's Title field, and Event Start Date to the node's Event Date field. Sample code for the Computed Field:
list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
$query = "SELECT
ce.id
FROM {node} n
INNER JOIN {field_data_field_event_date} de ON n.nid = de.entity_id AND n.vid = de.revision_id
INNER JOIN {civicrm_event} ce ON n.title = ce.title COLLATE utf8_unicode_ci
AND ce.start_date = convert_tz(field_event_date_value,'GMT','America/New_York')
WHERE n.nid = :nid
AND n.vid = :vid
LIMIT 1";
$result = db_query($query,
array(':vid' => $vid, ':nid' => $id))->fetchField(0);
if ($result === NULL || $result == "")
{
$entity_field[0]['value'] = 0;
}
else
{
$entity_field[0]['value'] = $result;
}
Then you can use a bit of display code like this:
if ($entity_field_item['value'] == 0)
{
$display_output = '';
}
else
{
$display_output = 'Buy tickets';
}
Since we have the Civi event code saved to the node, we can also use any native Drupal search or Views functionality, and get creative in Drupal templates as needed. Other options could be to write your own module that does something like this, or consider using the Civi REST endpoint /sites/all/modules/civicrm/extern/rest.php?entity=Event&action=getlist&json={"sequential":1}&api_key=yoursitekey&key=yourkey with Drupal Feeds and Feeds Extensible Parsers modules for a solution that creates and updates the Drupal events with minimal code required.

How should I implement `OnLoad` event handler when creating an activity using a contact?

I've created my own solution with a custom entity of type activity. I'd like to show a message whenever a new instance of it is created using an existing contact but not allow the user to create one, if only attempting to do that without going via contact.
Basically, my aim is that it won't be impossible to just create that activity (the form will be hidden directly at any attempt except for one way only). The user will have to go to contacts (or leads etc.) and in there add and create an instance of the custom activity entity. That way, I can assure that the field "regarding" will be filled out already.
I'm guessing that I need to detect somehow that the opening of the form is a creation attempt. How can I do that?
Also, as it is now, the user can't create a contact-less activity of the custom type because it doesn't appear on the menu with other activities. I must have disabled it somehow but I have no idea how. Anybody who has one?
You could do this a bunch of ways but the easiest would probably be to:
Make the regarding field read only.
Make the regarding field mandatory.
That way if a user opens a create new form they wont be able to set the regarding and because its mandatory they wont be able to save the record. When they open via an existing contact the regarding field will be mapped automatically. That said in this case just making it mandatory my be enough.
(As a side JavaScript can be used to identify the current form state, but I'm not sure how useful that is here).
In terms of where custom activities appear, by default mine show in a number of locations, for example:
CRM > Workplace > Activities > Ribbon > Other Activities > XXX.
CRM > Workplace > Activities > View Selector > XXX.
They don't show under the left hand navigation of the workplace because they are grouped under 'Activities'. I'm pretty sure these are all the default settings.
You can exercise greater control by editing the sitemap, where you can put pretty much anything, anywhere.
In addition to Mr Wood, I'd like to show you some code. It works as supposed to but I'm not sure if it's optimal.
var foo = function () {
var whatIsGoingOn = Xrm.Page.ui.getFormType();
if (whatIsGoingOn === 1)
alert("Let there be an entity!");
else
alert("Not a creation...");
}
The other states' (deletion, update etc.) numeric values are listed here.
Answering the second part of your question:
When you create a custom activity you can choose whether to have it appear in 'normal' Activity menus or not by checking the box at the top right of the entity form. This is a once-only choice as far as I know and can't be changed later.
For your setup, I would suggest NOT checking this box, so it does not appear in the activity menus to avoid users even being tempted to do it that way.
Instead, add an explicit relationship to the activity N:1 to Contact, and another N:1 to Lead. Use this relationship to add your activity to the left navigation of Contact and Lead forms, or add a grid for them (depends on how you want to use this and if you need to filter the view to something other than the default "Associated View").
When a user navigates to this section they will see if any previous activities of this type exist, and be able to add a new one. BUT this means that the child record is a child via this relationship, not using "regarding", so use a script on the form for the activity so that if Contact is filled in, it is copied to Regarding, and if Lead is filled in then that is copied. If neither, then use an alert or other means to warn the use that something is wrong (see comment earlier). If you want Regarding to be read-only but filled in by script, you will need to make sure to use the force the value to be saved:
Xrm.Page.getAttribute("regardingobjectid").setSubmitMode("always");
You must have the lookups for Contact and Lead on the form to be able to use them in your scripts, but you can make them not "visible by default" so they are there but not seen by the user (and taking up no space).

Sharepoint 2007 Webpart variables problem on reload

I'm having trouble with the webparts variables... I came from standard ASP language, so, to me, store variables in session and other parts is the common way to do everything =)
Now i had to create a webpart, the wp has to write a graph from parameter and i cannot understand HOW variables works: i cannot understand WHEN saved and WHEN erased and other thing like this!
Let me explain: i have a web part with the configuration toolbar on the right in which i put the values.. Everytime a button is pressed or a value in the dropdown list changes, it raises an event which causes the "CreateChild" function..
Many times the data is "stored", other time they are not!
That's the way i used to store value (in the ApplyChanges override function):
WPChartGenerator wpParent = (WPChartGenerator)this.ParentToolPane.SelectedWebPart;
wpParent.WebUrl = txtWebUrl.Text.Trim();
And in the CreateChild event i get the value like:
WPChartGenerator wpParent = (WPChartGenerator)this.ParentToolPane.SelectedWebPart;
this.ddlWeb = new DropDownList();
this.ddlWeb.ID = "ddlweb" + wpParent.ID;
ddlWeb.SelectedValue = wpParent.WebService;
Now.. Sometimes this works, for example, when i push a button I invoke in the code of the button and then the code to store every value.. In some case (like buttons) this works, in other (like dropdown list index changed event) this fails and i found every object in the wpParent equal to it's initial value.
Another thing i noticed, is that in certain cases when an event is triggered, the first thing to be executed (even first than the event's associated code) il CreateChild (even first than OnLoad!!!)
Can anybody tell me what I'm doing in the wrong way? Do anybody has a good tutoria for this matter?
Thanks & sorry 4 my School level English =)
Forget to say that every variable has been implemented as a Property, like that:
[WebBrowsable(false)]
[Personalizable(PersonalizationScope.Shared)]
[WebPartStorage(Storage.Shared)]
public string WebUrl
{
get
{
return this.webUrl;
}
set
{
this.webUrl = value;
}
}
I can't see all the code there so I don't really know what you're doing wrong (i.e. do you actually have an ApplyChanges method) but from the way you've worded your question it sounds like you really need to start at the beginning, follow one of these walkthrough tutorials and make sure you understand the basics and then start adding in the code for your project.
MSDN - Creating Web Parts for SharePoint (VS2010)
MSDN - Walkthrough: Creating a Basic SharePoint Web Part (WSS 3.0)
Developing SharePoint 2007 Web Parts

How to enable "Connect to Outlook" function in your custom list?

How can I enable the functionality to sync my custom list with Outlook 2007 todo or calendar list? I assume it's possible with custom lists too, but I cannot find any documentation on it.
To my knowledge this is not possible. If you need to sync a todo list, create a task list. Then you can delete all the columns that don't interest you, and add whatever columns you want to use.
The same goes for calendar, if you want a list syncronised with your outlook calendar, then create a calendar list and customize it to your needs.
To expand upon Filip's great answer . . .
According to this MSDN post, the custom list template has a different type designation (100) than the Task Template (106 in the article above, 107 in my research of SP2010). This is what the UI looks at to disable the Outlook Sync button. So, if your custom list is based on a custom content type you created then you can recreate your list to be Outlook compatible.
If your list already contains data, export it to Excel
Create a new list based on the Task template (instead of Custom)
Add your CT and delete the Task CT (if your content type is based on the Task CT i.e. has the columns) and any others your list doesn't need
Add any other columns your list needs but may not be part of your CT (or if you don't use a custom CT)
Use Datasheet view to copy and paste your data into the new list (observe column order)
Caveats: Not all data columns can be copied using this method (e.g. Attachments, system fields, etc.)
Hope this helps clarify
This is available / possible (well it takes some programming to achieve it) - see here.
For my solution, I aggregate data between sites and sync them with outlook. There are some tricky things like to map item's uniqueId to integer ID (probably a database table with mappings) to refer to specific item correctly, but it's not impossible.
But it's not something you can use right away - coding required. However if you really, really need it, then it's a some-way to go.
If your custom list is based off of a sharepoint list, then you can connect it to outlook by generating a link formatted based off the stssync protocol.
I created a custom list definition based off the events (Calendar) list.
It uses the base calendar list template plus some custom fields and forms.
I created a link formatted in accordance with the stssync protocol, and successfully connected it with outlook:
stssync://sts/?ver=1.1&type=calendar&cmd=add-folder&base-url=[site url]&list-url=[your list url]&guid=[GUID of list]&site-name=[SiteName]&list-name=[ListName]
Yeah not possible sadly. Also, if you create custom columns in a task list or calender, Outlook won't sync those columns.
I have been struggling with the same issue and found that it cannot be done with the built in functionality that SharePoint has, but there is a 3rd party program that allows this to be done. You can try with ProperSync. It will allow you to connect the custom fields of a custom list from SharePoint and view and edit them using Outlook.
This is the link to the main site: http://propersync.com/default.aspx
You can override List Ribbon Button, which holds sync logic, and create your custom action on it.
Here is good article about creating ribbons: http://blogs.msdn.com/b/sharepointdeveloperdocs/archive/2009/12/07/sharepointfoundationhowtoaddtabtoribbon.aspx
For List View OutlookSyncButton you should in CommandUIDefinition specify Location="Ribbon.List.Actions.ConnectToClient".
For Calendar View - you should specify Location="Ribbon.Calendar.Calendar.Actions.ConnectToClient".
Now, in CommandUIHandler/CommandAction you specifing JS code that connects to outlook (simply I grab it from SP :)):
alert("Let's go!");
var listid = '{ListId}';
var list;
ExecuteOrDelayUntilScriptLoaded(GetParamsAndSync, 'sp.js');
function GetParamsAndSync()
{
var clientContext = new SP.ClientContext.get_current();
var web = clientContext.get_web();
list = web.get_lists().getById(listid);
clientContext.load(list);
clientContext.load(web);
rf = list.get_rootFolder()
clientContext.load(rf);
clientContext.executeQueryAsync(
function() {
viewUrl=rf.get_serverRelativeUrl();
ExportHailStormOverride('calendar','{SiteUrl}','{ListId}', web.get_title(),list.get_title(),viewUrl,viewUrl,'')
},
function() {alert('Error')});
}
//This function was taken from SharePoint sp.init.js
function ExportHailStormOverride(type,weburl,guid,webname,listname,viewurl,passport,listrooturl,folderurl,folderid)
{ULSA13:;
var strAppName=GetCookie('stsSyncAppName');
var strIconName=GetCookie('stsSyncIconPath');
var maxLinkLength=500;
var maxNameLength=20;
var link='stssync://sts/?ver=1.1'
+'&type='+escapeProperly(type)
+'&cmd=add-folder'
+'&base-url='+escapeForSync(weburl)
+'&list-url='+escapeForSync('/'
+ makeAbsUrl(viewurl).substr(weburl.length+1)+'/')
+'&guid='+escapeProperly(guid);
if (window.self.offlineBtnUser !=undefined)
link+='&user-id='+offlineBtnUser;
var names='&site-name='+escapeForSync(webname)
+'&list-name='+escapeForSync(listname);
var context='';
if (folderurl)
context+='&folder-url='
+ escapeForSync('/'+folderurl.substr(listrooturl.length+1));
if (folderid)
context+='&folder-id='+folderid;
if (link.length+names.length+context.length > maxLinkLength &&
(webname.length > maxNameLength || listname.length > maxNameLength))
{
if (webname.length > maxNameLength)
webname=webname.substring(0, maxNameLength-1)+'...';
if (listname.length > maxNameLength)
listname=listname.substring(0, maxNameLength-1)+'...';
names='&site-name='+escapeForSync(webname)
+'&list-name='+escapeForSync(listname);
}
link=link+names+context;
var L_StssyncTooLong_Text='The name of site or list is too long. Make it shorter.';
if (link.length > maxLinkLength)
alert(L_StssyncTooLong_Text);
else
{
try
{
window.location.href=link;
}
catch (e)
{
alert('Sync error.');
}
}
}

Resources