session storage is not changing dependent box value dynamically on moble - mobile

I have a webform with 2 select boxes (class name & student name ) getting their values from sql database whereas "student name" is dependent on "class name" value. I am saving my data on session storage to display after load. I am successful to get same data after load in "class name" , further i am adding .trigger(change) event to "class name " as student name dependent on changing value of class.
All above is working on desktop but not on mobile .i.e. all values are loading after page reload but .trigger(change) event is not working and hence cant select any other option on mobile.
Plz help me as i am stuck here since 3 weaks.
My code is as follows:
<script>
// Run on page load
window.onload = function() {
var sclass = sessionStorage.getItem('sclass');
if (sclass !== null) $('#class').val(sclass).change();
window.onunload = function() {
sessionStorage.setItem("sclass", $('#class').val());
</script>

Related

Adding multiple owners for Google App Maker records

I need help with Google App Maker data model security. I want to set multiple owners for a single record. Like the current user + the assigned admin + super admin.
I need this because all records can have different owners and super-owners/admins.
I know that we can point google app maker to a field containing record owner's email and we can set that field to the current user at the time of the creation of the record.
record.Owner = Session.getActiveUser().getEmail();
I want to know if it is possible to have field owners or have multiple fields like owner1, owner2 and then assign access levels to owner1, owner2...
Or how can we programmatically control the access/security/permissions of records?
The solution I'd use for this one definitely involves a field on the record that contains a comma separated string of all the users who should have access to it. I've worked on the following example to explain better what I have in mind.
I created a model and is called documents and looks like this:
In a page, I have a table and a button to add new document records. The page looks like this:
When I click on the Add Document button, a dialog pops up and looks like this:
The logic on the SUBMIT button on the form above is the following:
widget.datasource.item.owners = app.user.email;
widget.datasource.createItem(function(){
app.closeDialog();
});
That will automatically assign the creator of the record the ownership. To add additional owners, I do it on an edit form. The edit form popus up when I click the edit button inside the record row. It looks like this:
As you can see, I'm using a list widget to control who the owners are. For that, it is necessary to use a <List>String custom property in the edit dialog and that will be the datasource of the list widget. In this case, I've called it owners. I've applied the following to the onClick event of the edit button:
var owners = widget.datasource.item.owners;
owners = owners ? owners.split(",") : [];
app.pageFragments.documentEdit.properties.owners = owners;
app.showDialog(app.pageFragments.documentEdit);
The add button above the list widget has the following logic for the onClick event handler:
widget.root.properties.owners.push("");
The TextBox widget inside the row of the list widget has the following logic for the onValueEdit event handler:
widget.root.properties.owners[widget.parent.childIndex] = newValue;
And the CLOSE button has the following logic for the onClick event handler:
var owners = widget.root.properties.owners || [];
if(owners && owners.length){
owners = owners.filter(function(owner){
return owner != false; //jshint ignore:line
});
}
widget.datasource.item.owners = owners.join();
app.closeDialog();
Since I want to create a logic that will load records only for authorized users, then I had to use a query script in the datasource that will serve that purpose. For that I created this function on a server script:
function getAuthorizedRecords(){
var authorized = [];
var userRoles = app.getActiveUserRoles();
var allRecs = app.models.documents.newQuery().run();
if(userRoles.indexOf(app.roles.Admins) > -1){
return allRecs;
} else {
for(var r=0; r<allRecs.length; r++){
var rec = allRecs[r];
if(rec.owners && rec.owners.indexOf(Session.getActiveUser().getEmail()) > -1){
authorized.push(rec);
}
}
return authorized;
}
}
And then on the documents datasource, I added the following to the query script:
return getAuthorizedRecords();
This solution will load all records for admin users, but for non-admin users, it will only load records where their email is located in the owners field of the record. This is the most elegant solution I could come up with and I hope it serves your purpose.
References:
https://developers.google.com/appmaker/models/datasources#query_script
https://developers.google.com/appmaker/ui/binding#custom_properties
https://developers.google.com/appmaker/ui/logic#events
https://developers-dot-devsite-v2-prod.appspot.com/appmaker/scripting/api/client#Record

Protractor element caching

I started to learn testing in Angular and have a little problem doing a serie of test in the same view.
I have a form with some inputs for customer data. I use it both for add new customer and edit an existing one.
So, firstly I test adding a new customer, then I click back, and click the first customer in a list (not the recently added). The data shows correctly in the view, but the test fails saying Expected 'new customer' to be 'customer 1'. Somehow element.name is caching the previous value.
Here is the test:
describe('Showing Customer data', function(){
var customersMenu, homeMenu, firstListItem;
beforeEach(function() {
customersMenu = element(by.css('.ion-person-stalker'));
homeMenu = element(by.css('.ion-home'));
firstListItem = element(by.css('.firstListItem'));
});
it('should create a new customer', function() {
customersMenu.click();
var newButton = element(by.css('.button-fab'));
newButton.click();
element(by.name('name')).sendKeys('new customer');
[...] // The other fields...
homeMenu.click();
});
it('should display correct customer data', function() {
customersMenu.click();
firstListItem.click();
expect(element(by.name('name')).getAttribute('value')).toBe('customer 1');
homeMenu.click();
});
});
It looks to me like you are sending the keys "new customer" to the name field here:
element(by.name('name')).sendKeys('new customer');
should you not be sending "customer 1" and the value of the name field like this?
element(by.name('name')).sendKeys('customer 1');
then later when you get the value of the name field, this will be correct:
expect(element(by.name('name')).getAttribute('value')).toBe('customer 1');
Finally I achieve this.
The problem
The problem was I was navigating like an user will do. I was returning to home view and then going again to list view, and detail view. The problem with that is the previous elements remain, so element(by.name('name')) has two posible values: 'new customer' and 'customer 1'. I we use element() instead element.all(), Protractor will pick up the first element in array.
The Solution
Instead of returning home clicking the button in sidemenu, now I use browser.get('/') to return to the root of app. It will clear DOM and seems is like you run the test as the first one.

drupal7 Filter content type based on session in view

I have created a custom type with multiple fields.
1 field is a checkbox to "show for all people"
2nd field is a textfield ( you can add multiple textfields ) for adding a code.
I created a view where all those content types are being shown in a page. ( this works )
But now:
When a person enters the site, he has to insert a code. This code is saved into a cookie because it needs to be remembered for about 2 weeks.
So I can't use the contextual filters.
If the checkbox "show for all people" is checked, this block is shown.
if the checkbox "show for all people" is unchecked, this block is hidden, except for people who came in without a code, or if the code is one of the values that was inserted in the 2nd field.
I don't wan't to use views php_filter. But I have no clue how to proceed with this problem.
I tried some solutions on the web to create a custom filter, but the problem here is, that we can't access the form values.
I found a solution, but I'm not sure if this is the correct drupal way.
I used the hook_node_view function to get all nodes that are printed on that page. I check if the code that was inserted into a cookie with the codes that are allowed ( created in the text fields of the content type )
function code_node_view($node, $view_mode, $langcode) {
if ($node->type == 'winning_codes') {
$code = _code_read_cookie('code');
$winning_codes = (!empty($node->field_winning_codes['und'])) ? $node->field_winning_codes['und'] : array();
$winning_codes = array_map(function ($ar) {
return $ar['value'];
}, $winning_codes);
if (!empty($code) && (!in_array($code, $winning_codes))) {
hide($node->content);
}
}
}

Pass parameter to tab

I am building my first Angular app with a list of product specifications such as "Brand name" etc. The finished app will be connected to an MSSQL db.
I have a list with the saved Specifications and when I click one of them I want the following to happen:
Show Edit Specification Tab
Pass the parameter SpecificationId
Perform an http GET with current Specification Id
I set up a plunker with the app in its basic state:
http://embed.plnkr.co/4F8LMwMorZEF0a42SzTJ/
As you are already sending your id you just need to get it within your method:
Update your controller like this:
app.controller('TabController', function ($scope) { // use $scope here
and set the id in the $scope.spec object like below:
this.setTab = function (selectedTab, specId) { // get the id in the args here
this.tab = selectedTab;
$scope.spec = {id : specId}; // set the id in here
console.log($scope.spec.id);
};
and then you can bind the id value in the markup as this:
The current Specification ID is: <strong>{{spec.id}}</strong>
Updated plunkr demo.

Drupal 7 load profile2 programmatically

I have two profile2 profiles defined - main and customer_profile. Also, I have a node type called Customer.
When creating a new Customer node, I would like to load the custom_profile form. The idea is to create a node and a profile simultaneously.
I know it's definately a hook_form_alter solution but can someone tell me how to programmatically load a profile while creating or editing a Customer node.
You can load profile type and data by using these function
$types = profile2_get_types();
profile2_load_by_user($account, $type_name = NULL)
For Example :
$types = profile2_get_types();
if (!empty($types)) {
foreach ($types as $type) {
$profile = profile2_load_by_user($uid, $type->type);
}
}
Even if you are able to load the customer_profile form, you will need to handle the values separately as they are two different nodes.
I would suggest capturing those fields in the customer node form, and then create a customer_profile programmatically from the values.
If you want to get the profile2 form itself then you can use something like
module_load_include('inc', 'profile2_page', 'profile2_page');
$profile2 = profile2_by_uid_load($uid, 'seeker_profile');
$entity_form = entity_ui_get_form('profile2', $profile2, 'edit');
and then add that to the form you want to place it in.
You can load full profile data using profile2_load_by_user();
params like:-
profile2_load_by_user($account,$type_name)
$account: The user account to load profiles for, or its uid.
$type_name: To load a single profile, pass the type name of the profile to load
So code like bellow
$account->uid = $existingUser->uid;
$type_name = 'user_about';
$profile = profile2_load_by_user($account, $type_name);
//$profile variable have full data of profile fields
//changing data profile2 fields
if(isset($_POST['field_user_first_name'])&& !empty($_POST['field_user_first_name'])){
$profile->field_user_first_name['und'][0]['value'] = $_POST['field_user_first_name'];
}
profile2_save($profile);
Well When creating a new Profile , Profile2 fields are not visible until a manual save is done.
To Automatically create the profile2 object , We use rules Module
Step
1) Go to Drupal admin/config/workflow/rules
2) create new rule
3) Give a name and Select in react/event "After saving a new user account"
4) Action,>> Add Action >> Execute custom PHP code
5) insert php code
$profile = profile_create(array('type' => 'profile2 type machine name', 'uid' => $account->uid));
profile2_save($profile);
6)Save >> Save changes.
This will create profile2 field when a new user is Created.
I had a similar need for creating a custom tab at the user page and loading the user profile2 form in it.
Here is a snap code of how I managed to accomplish just that:
MYMODULE.module https://gist.github.com/4223234
MYMODULE_profile2_MYPROFILE2TYPE.inc https://gist.github.com/4223201
Hope it helps.

Resources