Jira Code: VG-88
The contact info module is a custom module used for accessing and modifying the contact details of a customer from the SCA web store. This module deals with Fetching and displaying the list of contacts of a customer, adding a new contact to a customer, editing an existing contact of the customer, removing an existing contact of the customer
JAVA SCRIPT
ContactDetails.Collection.js:
define(
'ContactDetails.Collection',
[
'Backbone',
'ContactDetails.Model'
],
function
(
Backbone,
Model
)
{
return Backbone.Collection.extend({
model: Model,
url: _.getAbsoluteUrl('services/ContactDetails.Service.ss')
});
}
);
ContactDetails.Details.View.js:
define('ContactDetails.Details.View',
[
'Backbone',
'contactdetails_details.tpl'
],
function (Backbone, contactdetails_details_tpl) {
return Backbone.View.extend({
template: contactdetails_details_tpl
, initialize: function ()
{
this.model.on('sync', _.bind(this.render, this));
}
, getContext: function () {
return {
'name': this.model.get('name'),
'phone': this.model.get('phone'),
'address': this.model.get('address'),
'internalid': this.model.get('internalid')
}
},
});
}
)
ContactDetails.Edit.View.js:
define('ContactDetails.Edit.View',
[
'Backbone',
'contactdetails_edit.tpl',
'SC.Configuration',
'GlobalViews.Message.View',
'GlobalViews.CountriesDropdown.View',
'GlobalViews.States.View',
'Backbone.CompositeView',
'Backbone.FormView',
'underscore',
'jQuery',
'Utils'
],
function (
Backbone,
contactdetails_edit_tpl,
Configuration,
GlobalViewsMessageView,
CountriesDropdownView,
GlobalViewsStatesView,
BackboneCompositeView,
BackboneFormView,
_,
jQuery
)
{
return Backbone.View.extend({
template: contactdetails_edit_tpl,
events: {
'submit form': 'save'
},
save: function(e)
{
return this.saveForm(e,this.model);
},
bindings: {
'[name="name"]': 'name'
, '[name="phone"]': 'phone'
, '[name="company"]': 'company'
, '[name="address1"]': 'address1'
, '[name="address2"]': 'address2'
, '[name="city"]': 'city'
, '[name="state"]': 'state'
, '[name="zipcode"]': 'zipcode'
, '[name="country"]': 'country'
},
getSelectedMenu: function ()
{
return 'contacts';
},
getBreadcrumbPages: function ()
{
return [
{
text: _('Contact').translate()
, href: '/contacts'
}
, {
text: this.title
, href: '/contacts/new'
}
];
},
render: function ()
{
Backbone.View.prototype.render.apply(this, arguments);
this.$('[rel="tooltip"]').tooltip({
placement: 'right'
}).on('hide', function (e)
{
e.preventDefault();
jQuery(e.target).next('.tooltip').hide();
});
},
initialize: function(options) {
var addNewContactLabel = _('ADD NEW CONTACT').translate();
var editContactLabel = _('EDIT CONTACT ADDRESS').translate();
this.title = this.model.isNew() ? addNewContactLabel : editContactLabel;
this.application = options.application;
this.model = options.model;
this.countries = Configuration.get('siteSettings.countries');
this.selectedCountry = this.model.get('country') || Configuration.get('siteSettings.defaultshipcountry');
if (!this.selectedCountry && _.size(this.countries) === 1)
{
this.selectedCountry = _.first(_.keys(this.countries));
}
if (!!this.selectedCountry)
{
this.model.set('country', this.selectedCountry);
}
BackboneCompositeView.add(this);
BackboneFormView.add(this);
},
childViews: {
'CountriesDropdown': function ()
{
return new CountriesDropdownView({
countries: this.countries
, selectedCountry: this.selected_country
, manage: this.options.manage
});
}
, 'StatesView': function ()
{console.log("this in states view contact detailsedit",this);
return new GlobalViewsStatesView({
countries: this.countries
, selectedCountry: this.model.attributes.country
, selectedState: this.model.get('state')
, manage: this.options.manage
});
}
},
getContext: function() {
return {
isNew: this.model.isNew(),
name: this.model.get('name'),
phone: this.model.get('phone'),
address: this.model.get('address'),
}
}
});
}
)
ContactDetails.js:
//@module ContactDetails
define('ContactDetails',
[
'ContactDetails.Router'
],
function (Router) {
'use strict';
return {
MenuItems: {
parent: 'settings',
id: 'contactinfo',
name: 'Contact info',
url: 'contacts',
index: 6
},
mountToApp: function(application) {
return new Router(application);
}
}
}
);
ContactDetails.List.View.js:
define(
'ContactDetails.List.View',
[
'Backbone.CompositeView'
, 'Backbone.CollectionView'
, 'ContactDetails.Details.View'
, 'Backbone'
, 'contactdetails_list.tpl'
, 'GlobalViews.Confirmation.View'
, 'jQuery'
, 'Profile.Model'
, 'Profile.Information.View'
]
, function(
BackboneCompositeView
, BackboneCollectionView
, ContactDetailsDetailsView
, Backbone
, contactdetails_list_tpl
, GlobalViewsConfirmationView
, jQuery
, ProfileModel
, ProfileInformationView
)
{
return Backbone.View.extend({
template : contactdetails_list_tpl
, events: {
'click button[data-action="remove"]': 'removecontact'
}
, removeModel: function(options) {
var model = options.context.collection.get(options.id);
model.destroy();
}
, removecontact: function(e) {
e.preventDefault();
var view = new GlobalViewsConfirmationView({
title: 'Remove Contact',
body: 'Are you sure you want to remove this contact?',
callBack: this.removeModel,
callBackParameters: {
context: this,
id: jQuery(e.target).data('id')
},
autohide: true
});
this.application.getLayout().showInModal(view);
}
, page_header: _('CONTACT INFO').translate()
, title: _('Contact info').translate()
, attributes: { 'class': 'ContactDetailsListView' }
, initialize: function (options) {
BackboneCompositeView.add(this);
var self = this;
this.application = options.application;
this.collection = options.collection;
this.collection.on('reset sync add remove change destroy', function ()
{
self.render();
});
}
, getSelectedMenu: function ()
{
return 'contacts';
}
, getBreadcrumbPages: function ()
{
return {
text: this.title
, href: '/contacts'
};
}
, childViews: {
'ContactDetails.Collection': function() {
return new BackboneCollectionView({
childView: ContactDetailsDetailsView,
collection: this.collection,
viewsPerRow: 1
});
}
, 'Profile.Information' : function(){
return new ProfileInformationView({
application: this.application
, model: ProfileModel.getInstance()
});
}
}
, getContext: function ()
{
//@class Address.List.View.Context
return {
//@property {String} pageHeader
pageHeader: this.page_header
, isEmailSubscribeChecked:SC.ENVIRONMENT.siteSettings.defaultSubscriptionStatus
};
}
});
});
ContactDetails.Model.js:
define(
'ContactDetails.Model',
[
'Backbone',
'underscore',
'Utils'
],
function
(
Backbone,
_
)
{
return Backbone.Model.extend({
urlRoot: _.getAbsoluteUrl('services/ContactDetails.Service.ss')
, validation: {
name: { required: true, msg: _('Name is required').translate() }
, address1: { required: true, msg: _('Address is required').translate() }
, city: { required: true, msg: _('City is required').translate() }
, state: { required: true, msg: _('state is required').translate() }
, zipcode: { required: true, msg: _('zipcode is required').translate() }
/* , state: { fn: _.validateState }
, zip: { fn: _.validateZipCode }*/
, country: { required: true, msg: _('Country is required').translate() }
}
});
}
);
ContactDetails.Router.js:
define(
'ContactDetails.Router'
, [
'Backbone',
'ContactDetails.List.View',
'ContactDetails.Model',
'ContactDetails.Collection',
'ContactDetails.Edit.View',
'jQuery'
]
, function (
Backbone
, ContactDetailsListView
, Model
, Collection
, ContactDetailsEditView
, jQuery
)
{
return Backbone.Router.extend({
initialize: function(application) {
this.application = application;
}
, routes: {
'contacts': 'contactList',
'contacts/new': 'contactDetails',
'contacts/:id': 'contactDetails'
}
, contactList: function()
{
var collection = new Collection();
var view = new ContactDetailsListView({collection: collection,application: this.application});
collection.fetch().done(function(){
view.showContent();
})
}
/*, newContact: function () {
var view = new ContactDetailsEditView({model: new Model(), application: this.application});
view.showContent();
}*/
, contactDetails: function (id) {
var model = new Model();
var promise = jQuery.Deferred();
var self = this;
if (!id) {
promise.resolve();
} else {
model.fetch({
data: {
internalid: id
}
}).done(function () {
promise.resolve();
});
}
promise.done(function () {
var view = new ContactDetailsEditView({model: model, application: self.application});
view.showContent();
view.model.on('sync', function (model) {
Backbone.history.navigate('contacts', {trigger: true});
location.reload(0);
});
});
}
});
});
SUITESCRIPT
SUITESCRIPT:-
ContactDetails.Model.js:
define('ContactDetails.Model',
[
'SC.Model'
, 'SC.Models.Init'
, 'Backbone.Validation'
, 'underscore'
],
function (
SCModel
, ModelsInit
, BackboneValidation
, _
)
{
return SCModel.extend({
name: 'ContactDetails',
get: function(id) {
var field= ModelsInit.customer.getFieldValues();
var contactSearch = nlapiSearchRecord("contact",null,
[
["internalidnumber","equalto",id]
],
[
new nlobjSearchColumn("entityid").setSort(false),
new nlobjSearchColumn("phone"),
new nlobjSearchColumn("address"),
new nlobjSearchColumn("internalid"),
new nlobjSearchColumn("attention","Address",null),
new nlobjSearchColumn("address1","Address",null),
new nlobjSearchColumn("address2","Address",null),
new nlobjSearchColumn("city","Address",null),
new nlobjSearchColumn("state","Address",null),
new nlobjSearchColumn("zipcode","Address",null),
new nlobjSearchColumn("country","Address",null)
]
);
if (contactSearch && contactSearch.length === 1) {
return {
phone: contactSearch[0].getValue('phone'),
name: contactSearch[0].getValue('entityid'),
address: contactSearch[0].getValue('address'),
internalid: contactSearch[0].getValue('internalid'),
company: contactSearch[0].getValue("attention","Address",null),
address1: contactSearch[0].getValue("address1","Address",null),
address2: contactSearch[0].getValue("address2","Address",null),
city: contactSearch[0].getValue("city","Address",null),
state: contactSearch[0].getValue("state","Address",null),
zipcode: contactSearch[0].getValue("zipcode","Address",null),
country: contactSearch[0].getValue("country","Address",null),
};
} else {
throw notFoundError;
}
},
list: function() {
var field= ModelsInit.customer.getFieldValues();
var customerId = field.internalid;
var contactSearch = nlapiSearchRecord("contact",null,
[
["customer.internalidnumber","equalto",customerId]
],
[
new nlobjSearchColumn("entityid").setSort(false),
new nlobjSearchColumn("phone"),
new nlobjSearchColumn("address"),
new nlobjSearchColumn("internalid"),
new nlobjSearchColumn("attention","Address",null),
new nlobjSearchColumn("address1","Address",null),
new nlobjSearchColumn("address2","Address",null),
new nlobjSearchColumn("city","Address",null),
new nlobjSearchColumn("state","Address",null),
new nlobjSearchColumn("zipcode","Address",null),
new nlobjSearchColumn("country","Address",null)
]
);
return _.map(contactSearch, function(result) {
var data = {
phone : result.getValue("phone") || undefined, //TEXT
name: result.getValue("entityid") || undefined, //TEXT
address: result.getValue("address") || undefined, //TEXT
internalid: result.getValue("internalid") || undefined, //TEXT
company: result.getValue("attention","Address",null) || undefined, //TEXT
address1: result.getValue("address1","Address",null) || undefined, //TEXT
address2: result.getValue("address2","Address",null) || undefined, //TEXT
city: result.getValue("city","Address",null) || undefined, //TEXT
state: result.getValue("state","Address",null) || undefined, //TEXT
zipcode: result.getValue("zipcode","Address",null) || undefined, //TEXT
country: result.getValue("country","Address",null) || undefined, //TEXT
};
return data;
});
},
create: function(data) {
var record = nlapiCreateRecord('contact');
record.setFieldValue('phone', data.phone);
record.setFieldValue('entityid', data.name);
record.setFieldValue('company', nlapiGetUser());
var contactid = nlapiSubmitRecord(record);
var rec = nlapiLoadRecord('contact', contactid, {
recordmode : 'dynamic'
});
var addrSubrecord = rec.createCurrentLineItemSubrecord(
'addressbook', 'addressbookaddress');
addrSubrecord.setFieldValue('addressee', data.name);
addrSubrecord.setFieldValue('addr1', data.address1);
addrSubrecord.setFieldValue('addr2', data.address2);
addrSubrecord.setFieldValue('city', data.city);
addrSubrecord.setFieldValue('state', data.state);
addrSubrecord.setFieldValue('zip', data.zipcode);
addrSubrecord.setFieldValue('attention', data.company);
addrSubrecord.commit();
rec.commitLineItem('addressbook');
var recordId = nlapiSubmitRecord(rec);
return recordId;
},
update: function(id, data) {
/* this.validate(data);*/
var rec = nlapiLoadRecord('contact', id, {
recordmode : 'dynamic'
});
rec.selectLineItem('addressbook', 1);
/* rec.setCurrentLineItemValue('addressbook', 'defaultshipping', data.defaultshipaddr);*/
var addrSubrecord= rec.editCurrentLineItemSubrecord('addressbook', 'addressbookaddress');
addrSubrecord.setFieldValue('addressee', data.name);
addrSubrecord.setFieldValue('addr1', data.address1);
addrSubrecord.setFieldValue('addr2', data.address2);
addrSubrecord.setFieldValue('city', data.city);
addrSubrecord.setFieldValue('state', data.state);
addrSubrecord.setFieldValue('zip', data.zipcode);
addrSubrecord.setFieldValue('attention', data.company);
addrSubrecord.commit();
rec.commitLineItem('addressbook');
var recordId = nlapiSubmitRecord(rec);
return recordId;
},
remove: function(id) {
nlapiDeleteRecord('contact', id);
}
});
}
)
ContactDetails.ServiceController.js:
define(
'ContactDetails.ServiceController'
, [
'ServiceController'
, 'Application'
, 'ContactDetails.Model'
]
, function(
ServiceController
, Application
, ContactDetailsModel
)
{
'use strict';
// @class ContactDetails.ServiceController Manage ContactDetailses requests
// @extend ServiceController
return ServiceController.extend({
// @property {String} name Mandatory for all ssp-libraries model
name:'ContactDetails.ServiceController'
// @property {Service.ValidationOptions} options. All the required validation, permissions, etc.
// The values in this object are the validation needed for the current service.
// Can have values for all the request methods ('common' values) and specific for each one.
, options: {
common: {
requireLogin: true
}
}
// @method get The call to ContactDetails.Service.ss with http method 'get' is managed by this function
// @return {ContactDetails.Model.Attributes | Array<ContactDetails.Model.Attributes>} one or all user ContactDetailses
, get: function()
{
var id = this.request.getParameter('internalid');
return id ? ContactDetailsModel.get(id) : (ContactDetailsModel.list() || []);
}
// @method post The call to ContactDetails.Service.ss with http method 'post' is managed by this function
// @return {ContactDetailsModel.Attributes}
, post: function()
{
var id = ContactDetailsModel.create(this.data);
//Do not return anything here, we need send content with status 201
this.sendContent(ContactDetailsModel.get(id), {'status': 201});
}
// @method update The call to ContactDetails.Service.ss with http method 'put' is managed by this function
// @return {ContactDetails.Model.Attributes}
, put: function()
{
var id = this.request.getParameter('internalid');
ContactDetailsModel.update(id, this.data);
return ContactDetailsModel.get(id);
}
// @method delete The call to ContactDetails.Service.ss with http method 'delete' is managed by this function
// @return {StatusObject}
, delete: function()
{
var id = this.request.getParameter('internalid');
ContactDetailsModel.remove(id);
// If something goes wrong in the remove, an exception will fire
return {'status': 'ok'};
}
});
}
);
TEMPLATES
contactdetails_details.tpl:
<div class="contactdetails-details">
<div class=contactdetails-details-area>
<tr>
<td>
<div class="contactdetails-details-contact-name">{{name}}</div>
<div class="contactdetails-details-contact-address">{{address}}</div>
<div class="contactdetails-details-contact-phone">Phone: {{phone}}</div>
</td>
</tr>
</div>
<hr class="contactdetails-details-divider">
<div class="contactdetails-details-actions">
<a class="contactdetails-details-edit" href="/contacts/{{internalid}}" data-toggle="show-in-modal">EDIT</a>
<button class="contactdetails-details-remove" data-action="remove" data-id="{{internalid}}">REMOVE</button>
</div>
</div>
contactdetails_edit.tpl:
<form>
<div data-validation="control-group">
<label class="contactdetails-edit-label"><span class="contactdetails-edit-required">*</span>Name</label>
<span data-validation="control">
<input class="contactdetails-edit-fields" id="name" name="name" type="text">
</span>
</div>
{{#if isNew}}
<label class="contactdetails-edit-label">Phone</label><input class="contactdetails-edit-fields" id="phone" name="phone" type="text">
{{/if}}
<input class="contactdetails-edit-fields" id="company" name="company" type="text" placeholder="Additional company line (optional)">
<div data-validation="control-group">
<label class="contactdetails-edit-label"><span class="contactdetails-edit-required">*</span>Address</label>
<span data-validation="control">
<input class="contactdetails-edit-fields" id="address1" name="address1" type="text">
</span>
</div>
<input class="contactdetails-edit-fields" id="address2" name="address2" type="text">
<div class="contactdetails-edit-fields-group col-sm-12">
<div data-validation="control-group" class="contactdetails-edit-fields-cell-left col-sm-6">
<label class="contactdetails-edit-label"><span class="contactdetails-edit-required">*</span>City</label>
<span data-validation="control">
<input class="contactdetails-edit-fields" id="city" name="city" type="text">
</span>
</div>
<!-- <div data-validation="control-group">
<label>State</label>
<span data-validation="control">
<input id="state" name="state" type="text">
</span>
</div> -->
<div class="contactdetails-edit-fields-cell-right col-sm-6" data-input="state" data-view="StatesView" data-validation="control-group"></div>
</div>
<div class="contactdetails-edit-fields-group col-sm-12">
<div data-validation="control-group" class="contactdetails-edit-fields-cell-left col-sm-6">
<label class="contactdetails-edit-label"><span class="contactdetails-edit-required">*</span>Zip/Postal Code</label>
<span data-validation="control">
<input class="contactdetails-edit-fields" id="zipcode" name="zipcode" type="text">
</span>
</div>
<!-- <div data-validation="control-group">
<label>Country</label>
<span data-validation="control">
<input id="country" name="country" type="text">
</span>
</div> -->
<div class="contactdetails-edit-fields-cell-right col-sm-6" data-view="CountriesDropdown" data-input="country" data-validation="control-group">
</div>
</div>
<div class="contactdetails-edit-checkbox">
<input id="defaultshipaddr" name="defaultshipaddr" type="checkbox" value="T">
<label class="contactdetails-edit-label">Set as my default shipping address</label>
</div>
<div class="contactdetails-edit-action">
<button type="submit" class="contactdetails-edit-form-button-submit">{{#if isNew}}ADD{{else}}SAVE{{/if}}</button>
</div>
</form>
contactdetails_list.tpl:
<section class="contactdetails-list">
<!-- <h2>{{pageHeader}}</h2> -->
<div class="contactdetails-list-pageheader">{{pageHeader}}</div>
<div class="profileinformation-list-title">PERSONAL INFORMATION</div>
<div class="contactdetails-profileinfo-call" data-view="Profile.Information"></div>
<div class="contactdetails-list-edit-help-message">
{{translate 'Click "Edit" to modify your information and/or sign up to receive email announcements for special offers and promotions from Alibi Security.'}}
</div>
<div class="contactdetails-list-subscription-main">
<label class="contactdetails-list-subscription">
<input type="checkbox" name="emailsubscribe" value="T" {{#if isEmailSubscribeChecked}} checked {{/if}} disabled class="newsletter-edit-checkbox">
<!-- {{translate 'Sign me up to receive Alibi Security marketing emails featuring special promotions, featured products and services, time-saving features and more.'}} -->
<span class="signmeuptext">Sign me up to receive Alibi Security marketing emails featuring special promotions, featured products and services, time-saving features and more.</span>
</label>
</div>
<div class="contactdetails-list-title">CONTACT ADDRESS</div>
<!-- <table>
thead>
<tr>
<th>Internal ID</th>S
<th>Artist</th>
<th>Genre</th>
</tr>
</thead>
<tbody data-view="ContactDetails.Collection"></tbody>
</table> -->
<div data-view="ContactDetails.Collection"></div>
<a href="/contacts/new" class="contactdetails-list-newcontact" data-toggle="show-in-modal">ADD NEW CONTACT</a>
</section>
SASS
_contactdetails-details.scss:
.contactdetails-details{
color: $ob-color-primary;
background-color: #e5e5e5;
margin-bottom: 30px;
}
.contactdetails-details-area{
padding: 30px;
}
.contactdetails-details-contact-name{
margin-bottom: 20px;
font-weight: 600;
}
.contactdetails-details-contact-address{
margin-bottom: 20px;
}
.contactdetails-details-contact-phone{
font-weight: 600;
}
.contactdetails-details-divider{
background-color: darkgrey;
}
.contactdetails-details-actions{
text-align: right;
font-size: 16px;
color: $ob-color-primary;
font-weight: 600;
}
.contactdetails-details-edit{
color: $ob-color-primary;
}
.contactdetails-details-remove{
color: $ob-color-secondary;
background-color: #e5e5e5;
margin: 10px 40px 10px 40px;
}
_contactdetails-edit.scss:
.contactdetails-edit-required{
@extend .input-required;
}
.contactdetails-edit-fields{
background-color: #ededed;
border: none;
}
.contactdetails-edit-label{
color: $ob-color-primary;
margin-bottom: 5px;
}
.contactdetails-edit-fields-cell-left{
padding-left: 0px;
}
.contactdetails-edit-fields-cell-right{
padding-right: 0px;
}
.contactdetails-edit-fields-group{
padding: 0px;
}
.contactdetails-edit-form-button-submit{
@extend .button-primary;
@extend .button-medium;
background-color: #435363;
border-radius: 0px;
border:none;
width: 25%;
height: 40px;
}
.contactdetails-edit-action{
text-align: center;
}
.contactdetails-edit-checkbox{
input[type=checkbox] {
position: relative;
cursor: pointer;
}
input[type=checkbox]:before {
content: "";
display: block;
position: absolute;
width: 13px;
height: 13px;
top: 0;
left: 0;
border: 2px solid #435363;
border-radius: 3px;
background-color: white;
}
input[type=checkbox]:checked:after {
content: "";
display: block;
width: 3px;
height: 6px;
border: solid black;
border-width: 0 2px 2px 0;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
position: absolute;
top: 3px;
left: 6px;
}
}
_contactdetails-list.scss:
.contactdetails-list{
padding: 30px;
margin-bottom:30px;
}
.contactdetails-list-pageheader{
font-size: 22px;
font-weight: 600;
color: #00a7ce;
}
.ContactDetailsListView{
background-color: white;
}
.contactdetails-list-title{
font-size: 18px;
font-weight: 700;
color:$ob-color-primary;
}
.contactdetails-list-newcontact{
border-radius: 0px;
background:$ob-color-primary;
text-transform:uppercase;
padding: 10px 30px 10px 30px;
font-weight: 600;
color: white;
&::before {
content: url("https://www.alibisecurity.ml/SSP Applications/NetSuite Inc. - SCA Aconcagua/Development/img/plus_button1.png");
position: relative;
top: 4px;
left: -10px;
}
&:hover{
color: white;
};
}
.contactdetails-profileinfo-call{
background-color: #e5e5e5;
}
.profileinformation-list-title{
font-size: 18px;
font-weight: 700;
color:$ob-color-primary;
margin-top: 20px;
}
.contactdetails-list-subscription{
margin-bottom: 20px;
color: $ob-color-primary;
display: inline-flex;
}
.contactdetails-list-subscription-main{
display: flex;
input[type=checkbox] {
position: relative;
cursor: pointer;
}
input[type=checkbox]:before {
content: "";
display: block;
position: absolute;
width: 13px;
height: 13px;
//top: -1px;
left: 0;
border: 2px solid #435363;
border-radius: 4px;
background-color: white;
//bottom: -8px;
}
input[type=checkbox]:checked:after {
content: "";
display: block;
width: 3px;
height: 6px;
border: solid black;
border-width: 0 2px 2px 0;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
position: absolute;
top: 4px;
left: 6px;
}
}
.contactdetails-list-edit-help-message{
margin-bottom: 10px;
color: $ob-color-primary;
}
.signmeuptext{
margin-top: -5px;
}