Всем привет. Нужна помощь опытных программистов.
Задача (тестовое задание).
(удалено по просьбе правообладателя)
На текущем этапе, ПОЖАЛУЙСТА помогите разобраться, как правильно сделать пагинацию в кастомном контроллере?
У кого такое же задание или кто может помочь и сидит в ВК, пожалуйста пишите в личку vk.com/domovikx любой помощи пуду рад, спасибо заранее!
Всем привет. Нужна помощь опытных программистов. Задача (тестовое задание). (удалено по просьбе правообладателя) На текущем этапе, ПОЖАЛУЙСТА помогите разобраться, как правильно сделать пагинацию в кастомном контроллере? У кого такое же задание или кто может помочь и сидит в ВК, пожалуйста пишите в личку [url=https://vk.com/domovikx]vk.com/domovikx[/url] любой помощи пуду рад, спасибо заранее!
Вот тут есть пример https://salesforce-developer.ru/paginatsiya-na-visualforce-stranitse-pagination-using-standardsetcontroller
gitlab.com/domovikx/tx002
Да, классно уже народ подсказал, тут мои текущие коды, когда закончу ТЗ, выложу, что получилось на форуме в чистовом варианте.
[url=https://gitlab.com/domovikx/tx002]gitlab.com/domovikx/tx002[/url] Да, классно уже народ подсказал, тут мои текущие коды, когда закончу ТЗ, выложу, что получилось на форуме в чистовом варианте.
Промежуточный этап. Пагинация + сортировка готовы и работают.
<apex:page controller="CustomSorting181112Controller">
<!--
Вариант с сортировкой по столбцу
'SELECT Id, Name, Email, Contact_Level__c, AccountId, OwnerId, CreatedById, CreatedDate '
Необходимо отобразить следующие поля:
1 Name (link), 2 Email, 3 Contact Level (picklist), 4 Account (lookup),
5 Owner (lookup), 6 Created By (lookup), 7 Created Date.
-->
<apex:form>
<apex:pageBlock id="thisBlock">
<!-- табличка -->
<apex:pageBlockTable value="{! Contact }" var="ct" id="thisTable">
<apex:column value="{! ct.Name }">
<apex:facet name="header">
<apex:commandLink action="{! sortByName }" reRender="thisBlock">
<apex:outputText value="1. {! $ObjectType.Contact.Fields.Name.Label }" />
</apex:commandLink>
</apex:facet>
</apex:column>
<apex:column value="{! ct.Email }">
<apex:facet name="header">
<apex:commandLink action="{! sortByEmail }" reRender="thisBlock">
<apex:outputText value="2. {! $ObjectType.Contact.Fields.Email.Label }" />
</apex:commandLink>
</apex:facet>
</apex:column>
<apex:column value="{! ct.Contact_Level__c }">
<apex:facet name="header">
<apex:commandLink action="{! sortByContactLevel }" reRender="thisBlock">
<apex:outputText value="3. {! $ObjectType.Contact.Fields.Contact_Level__c.Label }" />
</apex:commandLink>
</apex:facet>
</apex:column>
<apex:column value="{! ct.AccountId }">
<apex:facet name="header">
<apex:commandLink action="{! sortByAccountId }" reRender="thisBlock">
<apex:outputText value="4. Accounts" />
</apex:commandLink>
</apex:facet>
</apex:column>
<apex:column value="{! ct.OwnerId }">
<apex:facet name="header">
<apex:commandLink action="{! sortByOwnerId }" reRender="thisBlock">
<apex:outputText value="5. Owners" />
</apex:commandLink>
</apex:facet>
</apex:column>
<apex:column value="{! ct.CreatedById }">
<apex:facet name="header">
<apex:commandLink action="{! sortByCreatedById }" reRender="thisBlock">
<apex:outputText value="6. Created By" />
</apex:commandLink>
</apex:facet>
</apex:column>
<apex:column value="{! ct.CreatedDate }">
<apex:facet name="header">
<apex:commandLink action="{! sortByCreatedDate }" reRender="thisBlock">
<apex:outputText value="7. {! $ObjectType.Contact.Fields.CreatedDate.Label }" />
</apex:commandLink>
</apex:facet>
</apex:column>
</apex:pageBlockTable>
<!-- кнопочки вперед-назад... -->
<div align="center" id="button">
<apex:commandButton action="{! setList.first }" value=" << " title="First Page" disabled="{!!setList.HasPrevious}" reRender="thisBlock,button"
/>
<apex:commandButton action="{! setList.previous }" value=" Previous " disabled="{!!setList.HasPrevious}" reRender="thisBlock,button"
/>
<apex:commandButton action="{! setList.next }" value=" Next > " disabled="{!!setList.HasNext}" reRender="thisBlock,button"
/>
<apex:commandButton action="{! setList.last }" value=" >> " title="Last Page" disabled="{!!setList.HasNext}" reRender="thisBlock,button"
/>
<!-- поле - колво страниц -->
<span style="float:right">
<apex:outputLabel value=" Page " />
<apex:InputText value="{! PageNumber }" maxLength="4" size="1" />
<apex:outputLabel value=" of {! TotalPages }" />
</span>
</div>
<div>
<!-- выпадающий список - типо пагинация -->
<span style="float:right">
<apex:SelectList value="{! PageSize }" size="1">
<apex:selectOptions value="{! PageSizeList }" />
<apex:actionSupport event="onchange" reRender="thisBlock" />
</apex:SelectList>
</span>
</div>
<!-- ссылка - создать новый аккаунт -->
<apex:outputLink value="{!URLFOR($Action.Contact.NewContact)}" target="_blank">
Create New Contact
</apex:outputLink>
</apex:pageBlock>
</apex:form>
</apex:page>
public class CustomSorting181112Controller {public String sortingColumn = 'Name'; // первичный столбец
public String sortingOrder = ' ASC '; // первичная сортировка
public String column = sortingColumn; // первичное значение нового столбцаpublic String query = 'SELECT Id, Name, Email, Contact_Level__c, AccountId, OwnerId, CreatedById, CreatedDate ' +
'FROM Contact ' +
'ORDER BY ' + sortingColumn + sortingOrder;
// Сортировка начинается здесь ---------------------------------------
// вначале пишем методы которые будут вызываться командой со стринички
public void sortByName() {
sortingColumn = 'Name';
sortingOrder();
}
public void sortByEmail() {
sortingColumn = 'Email';
sortingOrder();
}
public void sortByContactLevel() {
sortingColumn = 'Contact_Level__c';
sortingOrder();
}
public void sortByAccountId() {
sortingColumn = 'AccountId';
sortingOrder();
}
public void sortByOwnerId() {
sortingColumn = 'OwnerId';
sortingOrder();
}
public void sortByCreatedById() {
sortingColumn = 'CreatedById';
sortingOrder();
}
public void sortByCreatedDate() {
sortingColumn = 'CreatedDate';
sortingOrder();
}// проверяем- новый столбец или тот же
// если столбец новый сортировка - ASC и обновляется запрос.
public void sortingOrder() {
if (sortingColumn == column) {
sortingOrder = (sortingOrder == ' ASC ') ? ' DESC ' : ' ASC ';
} else {
sortingOrder = ' ASC ';
column = sortingColumn;
}
// получаем наш запрос с нужной нам сортировкой, аминь!
query = 'SELECT Id, Name, Email, Contact_Level__c, AccountId, OwnerId, CreatedById, CreatedDate ' +
'FROM Contact ' +
'ORDER BY ' + sortingColumn + sortingOrder;// после сортировки ОБЯЗАТЕЛЬНО создается новый экземпляр контроллера с новыми значениями
setList = new ApexPages.StandardSetController(Database.query(query));
}
// конец сортировки --------------------------------------
// Пагинация начинается здесь ---------------------------------
// Вначале делаем выпадающий список - количество записей на странице
public list<SelectOption> getPageSizeList(){ // выпадающий список на странице
list<SelectOption> options = new list<SelectOption>();
options.add(new selectOption('5','5'));
options.add(new selectOption('10','10'));
options.add(new selectOption('25','25'));
options.add(new selectOption('50','50'));
options.add(new selectOption('100','100'));
return options;
}
public ApexPages.StandardSetController setList {
get {
if (setList == null) { // проверка на наличие экземпляра контроллера
setList = new ApexPages.StandardSetController(Database.query(query));
}
if (this.PageSize == null) PageSize = 10; // дефаултное значение записей/стр, попробуй 7 или 8 =)
setList.setPageSize(PageSize); // количество записей/страница
return setList;
} set;
}
public Integer PageSize {
get; set { // Выбираем количество записей на странице
if(value != null) this.PageSize = value;
}
}
public Integer PageNumber {
get { // получаем текущий номер страницы
this.PageNumber = setList.getPageNumber();
return this.PageNumber;
}
set { // это чтобы перейти к введенному номеру страницы
setList.setPageNumber(value); //
}
}
public Integer TotalPages { // Считаем количество страниц
// это я скопировал у других, кто знает как это упростить пишите. это работает
get {
if (setList.getResultSize() <= 10)
this.TotalPages = 1;
if (Math.Mod ( setList.getResultSize(),setList.getPageSize() ) == 0)
this.TotalPages = ( setList.getResultSize()/setList.getPageSize() );
else this.TotalPages = ( setList.getResultSize()/setList.getPageSize() )+1;
return totalpages;
}
set;
}
public List<Contact> getContact() {
return (List<Contact>) setList.getRecords();
}
// Конец пагинации ----------------------------------------
} // конец контроллера =)
Промежуточный этап. Пагинация + сортировка готовы и работают. [size=50] [code]<apex:page controller="CustomSorting181112Controller"> <!-- Вариант с сортировкой по столбцу 'SELECT Id, Name, Email, Contact_Level__c, AccountId, OwnerId, CreatedById, CreatedDate ' Необходимо отобразить следующие поля: 1 Name (link), 2 Email, 3 Contact Level (picklist), 4 Account (lookup), 5 Owner (lookup), 6 Created By (lookup), 7 Created Date. --> <apex:form> <apex:pageBlock id="thisBlock"> <!-- табличка --> <apex:pageBlockTable value="{! Contact }" var="ct" id="thisTable"> <apex:column value="{! ct.Name }"> <apex:facet name="header"> <apex:commandLink action="{! sortByName }" reRender="thisBlock"> <apex:outputText value="1. {! $ObjectType.Contact.Fields.Name.Label }" /> </apex:commandLink> </apex:facet> </apex:column> <apex:column value="{! ct.Email }"> <apex:facet name="header"> <apex:commandLink action="{! sortByEmail }" reRender="thisBlock"> <apex:outputText value="2. {! $ObjectType.Contact.Fields.Email.Label }" /> </apex:commandLink> </apex:facet> </apex:column> <apex:column value="{! ct.Contact_Level__c }"> <apex:facet name="header"> <apex:commandLink action="{! sortByContactLevel }" reRender="thisBlock"> <apex:outputText value="3. {! $ObjectType.Contact.Fields.Contact_Level__c.Label }" /> </apex:commandLink> </apex:facet> </apex:column> <apex:column value="{! ct.AccountId }"> <apex:facet name="header"> <apex:commandLink action="{! sortByAccountId }" reRender="thisBlock"> <apex:outputText value="4. Accounts" /> </apex:commandLink> </apex:facet> </apex:column> <apex:column value="{! ct.OwnerId }"> <apex:facet name="header"> <apex:commandLink action="{! sortByOwnerId }" reRender="thisBlock"> <apex:outputText value="5. Owners" /> </apex:commandLink> </apex:facet> </apex:column> <apex:column value="{! ct.CreatedById }"> <apex:facet name="header"> <apex:commandLink action="{! sortByCreatedById }" reRender="thisBlock"> <apex:outputText value="6. Created By" /> </apex:commandLink> </apex:facet> </apex:column> <apex:column value="{! ct.CreatedDate }"> <apex:facet name="header"> <apex:commandLink action="{! sortByCreatedDate }" reRender="thisBlock"> <apex:outputText value="7. {! $ObjectType.Contact.Fields.CreatedDate.Label }" /> </apex:commandLink> </apex:facet> </apex:column> </apex:pageBlockTable> <!-- кнопочки вперед-назад... --> <div align="center" id="button"> <apex:commandButton action="{! setList.first }" value=" << " title="First Page" disabled="{!!setList.HasPrevious}" reRender="thisBlock,button" /> <apex:commandButton action="{! setList.previous }" value=" Previous " disabled="{!!setList.HasPrevious}" reRender="thisBlock,button" /> <apex:commandButton action="{! setList.next }" value=" Next > " disabled="{!!setList.HasNext}" reRender="thisBlock,button" /> <apex:commandButton action="{! setList.last }" value=" >> " title="Last Page" disabled="{!!setList.HasNext}" reRender="thisBlock,button" /> <!-- поле - колво страниц --> <span style="float:right"> <apex:outputLabel value=" Page " /> <apex:InputText value="{! PageNumber }" maxLength="4" size="1" /> <apex:outputLabel value=" of {! TotalPages }" /> </span> </div> <div> <!-- выпадающий список - типо пагинация --> <span style="float:right"> <apex:SelectList value="{! PageSize }" size="1"> <apex:selectOptions value="{! PageSizeList }" /> <apex:actionSupport event="onchange" reRender="thisBlock" /> </apex:SelectList> </span> </div> <!-- ссылка - создать новый аккаунт --> <apex:outputLink value="{!URLFOR($Action.Contact.NewContact)}" target="_blank"> Create New Contact </apex:outputLink> </apex:pageBlock> </apex:form> </apex:page>[/code] [code]public class CustomSorting181112Controller { public String sortingColumn = 'Name'; // первичный столбец public String sortingOrder = ' ASC '; // первичная сортировка public String column = sortingColumn; // первичное значение нового столбца public String query = 'SELECT Id, Name, Email, Contact_Level__c, AccountId, OwnerId, CreatedById, CreatedDate ' + 'FROM Contact ' + 'ORDER BY ' + sortingColumn + sortingOrder; // Сортировка начинается здесь --------------------------------------- // вначале пишем методы которые будут вызываться командой со стринички public void sortByName() { sortingColumn = 'Name'; sortingOrder(); } public void sortByEmail() { sortingColumn = 'Email'; sortingOrder(); } public void sortByContactLevel() { sortingColumn = 'Contact_Level__c'; sortingOrder(); } public void sortByAccountId() { sortingColumn = 'AccountId'; sortingOrder(); } public void sortByOwnerId() { sortingColumn = 'OwnerId'; sortingOrder(); } public void sortByCreatedById() { sortingColumn = 'CreatedById'; sortingOrder(); } public void sortByCreatedDate() { sortingColumn = 'CreatedDate'; sortingOrder(); } // проверяем- новый столбец или тот же // если столбец новый сортировка - ASC и обновляется запрос. public void sortingOrder() { if (sortingColumn == column) { sortingOrder = (sortingOrder == ' ASC ') ? ' DESC ' : ' ASC '; } else { sortingOrder = ' ASC '; column = sortingColumn; } // получаем наш запрос с нужной нам сортировкой, аминь! query = 'SELECT Id, Name, Email, Contact_Level__c, AccountId, OwnerId, CreatedById, CreatedDate ' + 'FROM Contact ' + 'ORDER BY ' + sortingColumn + sortingOrder; // после сортировки ОБЯЗАТЕЛЬНО создается новый экземпляр контроллера с новыми значениями setList = new ApexPages.StandardSetController(Database.query(query)); } // конец сортировки -------------------------------------- // Пагинация начинается здесь --------------------------------- // Вначале делаем выпадающий список - количество записей на странице public list<SelectOption> getPageSizeList(){ // выпадающий список на странице list<SelectOption> options = new list<SelectOption>(); options.add(new selectOption('5','5')); options.add(new selectOption('10','10')); options.add(new selectOption('25','25')); options.add(new selectOption('50','50')); options.add(new selectOption('100','100')); return options; } public ApexPages.StandardSetController setList { get { if (setList == null) { // проверка на наличие экземпляра контроллера setList = new ApexPages.StandardSetController(Database.query(query)); } if (this.PageSize == null) PageSize = 10; // дефаултное значение записей/стр, попробуй 7 или 8 =) setList.setPageSize(PageSize); // количество записей/страница return setList; } set; } public Integer PageSize { get; set { // Выбираем количество записей на странице if(value != null) this.PageSize = value; } } public Integer PageNumber { get { // получаем текущий номер страницы this.PageNumber = setList.getPageNumber(); return this.PageNumber; } set { // это чтобы перейти к введенному номеру страницы setList.setPageNumber(value); // } } public Integer TotalPages { // Считаем количество страниц // это я скопировал у других, кто знает как это упростить пишите. это работает get { if (setList.getResultSize() <= 10) this.TotalPages = 1; if (Math.Mod ( setList.getResultSize(),setList.getPageSize() ) == 0) this.TotalPages = ( setList.getResultSize()/setList.getPageSize() ); else this.TotalPages = ( setList.getResultSize()/setList.getPageSize() )+1; return totalpages; } set; } public List<Contact> getContact() { return (List<Contact>) setList.getRecords(); } // Конец пагинации ---------------------------------------- } // конец контроллера =)[/code] [/size]
Текущий этап.
Как добавить столбец с кнопками - Edit Del
Как добавить поиск.
Возможно поможет этот код: https://developer.salesforce.com/forums/?id=9060G000000UVLGQA4
Текущий этап. Как добавить столбец с кнопками - Edit Del Как добавить поиск. Возможно поможет этот код: https://developer.salesforce.com/forums/?id=9060G000000UVLGQA4
На вопрос "КАК СДЕЛАТЬ" сложно дать ответ. Существует 100500 способов сделать одну и ту же штуку.
Это основы! Советую сначала погуглить тему создания CRUD приложение для Salesforce.
Если уже не будет получаться, можно детальнее пообщаться на тему "ПОЧЕМУ".
К тому же тут на форуме присутствуют представители различных компаний и в том числе той куда ты планируешь попасть сделав тестовое задание. Возможность находить решения в интернете и адаптировать их под свои требования ценится не меньше чем наличие знаний
На вопрос "[b]КАК СДЕЛАТЬ[/b]" сложно дать ответ. Существует 100500 способов сделать одну и ту же штуку. Это основы! Советую сначала погуглить тему создания CRUD приложение для Salesforce. Если уже не будет получаться, можно детальнее пообщаться на тему "[b]ПОЧЕМУ[/b]". К тому же тут на форуме присутствуют представители различных компаний и в том числе той куда ты планируешь попасть сделав тестовое задание. Возможность находить решения в интернете и адаптировать их под свои требования ценится не меньше чем наличие знаний :)
На форуме уже не раз обсуждались эти вопросы.
Можно "delete" через поиск поискать.
Вот к примеру
https://salesforce-developer.ru/forum/topic-delete-function
Где упоминается
http://salesforcesource.blogspot.com/2009/09/edit-and-delete-command-for-your.html
С полностью готовым решением.
На форуме уже не раз обсуждались эти вопросы. Можно "delete" через поиск поискать. Вот к примеру https://salesforce-developer.ru/forum/topic-delete-function Где упоминается http://salesforcesource.blogspot.com/2009/09/edit-and-delete-command-for-your.html С полностью готовым решением.
На счет поиска тоже упоминалось не раз.
Вот к примеру поиск выдал
https://salesforce-developer.ru/forum/topic-nuzhna-pomosch-1ac98fe6-a206-493a-ada3-a5b48d6465da
На счет поиска тоже упоминалось не раз. Вот к примеру поиск выдал https://salesforce-developer.ru/forum/topic-nuzhna-pomosch-1ac98fe6-a206-493a-ada3-a5b48d6465da
https://salesforce.stackexchange.com/questions/115757/soql-like-and-wildcards-not-returning-full-results
Как писать динамический запрос для поиска.
Примеры тут:
String query = 'SELECT Id, Name FROM Account WHERE name LIKE \'%' + searchVar + '%\'';
List<Account> accts = Database.query(query);
List<Account> accts = [SELECT Id, Name FROM Account WHERE name LIKE :('%' + searchName + '%')];
https://salesforce.stackexchange.com/questions/115757/soql-like-and-wildcards-not-returning-full-results Как писать динамический запрос для поиска. Примеры тут: [code]String query = 'SELECT Id, Name FROM Account WHERE name LIKE \'%' + searchVar + '%\''; List<Account> accts = Database.query(query);[/code] [code]List<Account> accts = [SELECT Id, Name FROM Account WHERE name LIKE :('%' + searchName + '%')];[/code]
Второй вариант предпочтительнее из-за правильного биндинга переменных в запрос.
В первом случае можно словить SOQL Injection если правильно не проверить переменную searchVar.
Это советы на будущее.
Второй вариант предпочтительнее из-за [b]правильного[/b] биндинга переменных в запрос. В первом случае можно словить SOQL Injection если правильно не проверить переменную searchVar. Это советы на будущее.
Спасибо за примеры. Помогло. Сегодня сделал колонку с edit / del
особенно помог пример:
http://salesforcesource.blogspot.com/2009/09/edit-and-delete-command-for-your.html
текущие рабочие коды можно посмотреть тут: https://gitlab.com/domovikx/tx002/tree/master
Следующая задача
- Сделать кнопку ‘New Contact’,
- которая откроет popup на той же странице,
- где можно будет ввести: First Name, Last Name *, Email *, Contact Level, Account
- и нажать Save или Cancel
Кто можешь подсказать ресурсы, которые почитать? Благодарю заранее!
Спасибо за примеры. Помогло. Сегодня сделал колонку с edit / del особенно помог пример: http://salesforcesource.blogspot.com/2009/09/edit-and-delete-command-for-your.html текущие рабочие коды можно посмотреть тут: https://gitlab.com/domovikx/tx002/tree/master [b]Следующая задача[/b] - Сделать кнопку ‘New Contact’, - которая откроет popup на той же странице, - где можно будет ввести: First Name, Last Name *, Email *, Contact Level, Account - и нажать Save или Cancel Кто можешь подсказать ресурсы, которые почитать? Благодарю заранее!
Если хочется именно popup то это уже надо смотреть в сторону Javascript. Честно даже не представляю как это сделать с помощью чистого VF.
[quote="DomovikX"]- которая откроет popup на той же странице, [/quote] Если хочется именно popup то это уже надо смотреть в сторону Javascript. Честно даже не представляю как это сделать с помощью чистого VF.
Итак это popup in salesforce решается с помощью модальных окон.
Create a Modal Popup in Salesforce
для контроллера
// Наш попап
public boolean displayPopup {get; set;}
public void popupShow(){
displayPopup = true;
}
public void popupClose(){
displayPopup = false;
}
// конец попапа
для страницы
<!-- Popup -->
<apex:commandButton value="Create New Contact Popup" action="{!popupShow}" rerender="popupPanel" />
<apex:outputPanel id="popupPanel">
<apex:outputPanel styleClass="popupBackground" layout="block" rendered="{!displayPopUp}" />
<apex:outputPanel styleClass="popupCust" layout="block" rendered="{!displayPopUp}"><h2 id="modal-heading-01" class="slds-text-heading_medium slds-hyphenate">Лучший в мире заголовок</h2>
<p> Clicking on this link you can express your financial gratitude to the developer of this application in dollars equivalent.
<a href="https://vk.com/domovikx" target="_blank">Your developer DomovikX</a>.</p><apex:commandButton value="Close" action="{!popupClose}" rerender="popupPanel" />
</apex:outputPanel>
</apex:outputPanel><style type="text/css">
.popupCust {
background-color: white;
border-width: 0px;
border-style: solid;
z-index: 9001;
left: 50%;
padding: 11px;
position: absolute;
width: 600px;
margin-left: -240px;
top: 100px;
}.popupBackground {
background-color: black;
opacity: 0.20;
filter: alpha(opacity=20);
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 9000;
}
</style>
Итак это popup in salesforce решается с помощью модальных окон. [url=https://www.forcetalks.com/blog/create-a-modal-popup-in-salesforce/]Create a Modal Popup in Salesforce[/url] для контроллера [code]// Наш попап public boolean displayPopup {get; set;} public void popupShow(){ displayPopup = true; } public void popupClose(){ displayPopup = false; } // конец попапа [/code] для страницы [code]<!-- Popup --> <apex:commandButton value="Create New Contact Popup" action="{!popupShow}" rerender="popupPanel" /> <apex:outputPanel id="popupPanel"> <apex:outputPanel styleClass="popupBackground" layout="block" rendered="{!displayPopUp}" /> <apex:outputPanel styleClass="popupCust" layout="block" rendered="{!displayPopUp}"> <h2 id="modal-heading-01" class="slds-text-heading_medium slds-hyphenate">Лучший в мире заголовок</h2> <p> Clicking on this link you can express your financial gratitude to the developer of this application in dollars equivalent. <a href="https://vk.com/domovikx" target="_blank">Your developer DomovikX</a>.</p> <apex:commandButton value="Close" action="{!popupClose}" rerender="popupPanel" /> </apex:outputPanel> </apex:outputPanel> <style type="text/css"> .popupCust { background-color: white; border-width: 0px; border-style: solid; z-index: 9001; left: 50%; padding: 11px; position: absolute; width: 600px; margin-left: -240px; top: 100px; } .popupBackground { background-color: black; opacity: 0.20; filter: alpha(opacity=20); position: absolute; width: 100%; height: 100%; top: 0; left: 0; z-index: 9000; } </style>[/code]
От млин уже за столько лет и позабыл про "rerender". Только хотел поругаться что для открытия окна перезагружать страницу сильно нерационально. А оказывается вот оно как Перезагрузки нет, но все равно задержка присутствует. Не самый оптимальный вариант, но полностью классический для Visualforce.
В принципе раз на бэкенде нет никакой хитрой логики на открытие окна то лучше заморочиться css + jquery.
От млин уже за столько лет и позабыл про "rerender". Только хотел поругаться что для открытия окна перезагружать страницу сильно нерационально. А оказывается вот оно как :) Перезагрузки нет, но все равно задержка присутствует. Не самый оптимальный вариант, но полностью классический для Visualforce. В принципе раз на бэкенде нет никакой хитрой логики на открытие окна то лучше заморочиться css + jquery.
Пользуясь случаем.
Как написать кнопку для открытия ссылки в новой странице. Имитация ссылки под кнопку.
<!-- Это имитация ссылки под кнопку Create New Contact -->
<apex:commandLink target="_blank" styleClass="btn" style="text-decoration:none; padding:4px; float:right" action="{!URLFOR($Action.Contact.NewContact)}"
value="Create New Contact linke" />
<!-- аналог в виде ссылки
<apex:outputLink value="{!URLFOR($Action.Contact.NewContact)}" target="_blank" style="font-weight:bold; float:right">
Create New Contact
</apex:outputLink>
-->
Люди добрый, подскажите, как сделать:
поля First Name, Last Name (обязательное), Email (обязательное с проверкой на емайл), Contact Level (список), Account
и кнопки Save или Cancel
Сейчас разбираю это. Спасибо за ссылки на инфу.
Пользуясь случаем. Как написать кнопку для открытия ссылки в новой странице. Имитация ссылки под кнопку. [code]<!-- Это имитация ссылки под кнопку Create New Contact --> <apex:commandLink target="_blank" styleClass="btn" style="text-decoration:none; padding:4px; float:right" action="{!URLFOR($Action.Contact.NewContact)}" value="Create New Contact linke" /> <!-- аналог в виде ссылки <apex:outputLink value="{!URLFOR($Action.Contact.NewContact)}" target="_blank" style="font-weight:bold; float:right"> Create New Contact </apex:outputLink> -->[/code] [b]Люди добрый, подскажите, как сделать:[/b] поля First Name, Last Name (обязательное), Email (обязательное с проверкой на емайл), Contact Level (список), Account и кнопки Save или Cancel Сейчас разбираю это. Спасибо за ссылки на инфу.
https://salesforce.stackexchange.com/questions/180172/using-custom-controller-to-create-new-contact
https://success.salesforce.com/answers?id=9063A000000e1U2QAI
Сейчас хочу попробовать вот этот вариант - Using custom controller to create new Contact
Вот кривой но рабочий код. работает ровно на одну запись. Как доделаю, перезалью пост.
<apex:page controller="ContactCreateController">
<!--
- 1.First Name, 2.Last Name *, 3.Email *, 4.Contact Level, 5.Account
- кнопки - Save или Cancel
- * обязательные
- Contact Level - список: Primary, Secondary, Tertiary
-->
<apex:pageBlock>
<apex:form>
<apex:pageBlockSection columns="1">
<apex:inputText label="1. First Name" value="{!firstName}" />
<apex:inputText label="2. Last Name" value="{!lastName}" />
<apex:inputText label="Phone" value="{!phone}" />
<apex:commandButton value="Save" action="{!save}" />
</apex:pageBlockSection>
</apex:form>
</apex:pageBlock>
</apex:page>
public class ContactCreateController {public String firstName {get; set;}
public String lastName {get; set;}
public String phone {get; set;}
list <contact> conList;public ContactCreateController(){
conlist=new List<contact>();
}public pageReference save(){
Contact con = new Contact(firstname = firstname, lastname = lastname, phone = phone);
conList.add(con);
insert conList;
return null;
}}
https://salesforce.stackexchange.com/questions/180172/using-custom-controller-to-create-new-contact https://success.salesforce.com/answers?id=9063A000000e1U2QAI Сейчас хочу попробовать вот этот вариант - Using custom controller to create new Contact Вот кривой но рабочий код. работает ровно на одну запись. Как доделаю, перезалью пост. [code] <apex:page controller="ContactCreateController"> <!-- - 1.First Name, 2.Last Name *, 3.Email *, 4.Contact Level, 5.Account - кнопки - Save или Cancel - * обязательные - Contact Level - список: Primary, Secondary, Tertiary --> <apex:pageBlock> <apex:form> <apex:pageBlockSection columns="1"> <apex:inputText label="1. First Name" value="{!firstName}" /> <apex:inputText label="2. Last Name" value="{!lastName}" /> <apex:inputText label="Phone" value="{!phone}" /> <apex:commandButton value="Save" action="{!save}" /> </apex:pageBlockSection> </apex:form> </apex:pageBlock> </apex:page> [/code] [code] public class ContactCreateController { public String firstName {get; set;} public String lastName {get; set;} public String phone {get; set;} list <contact> conList; public ContactCreateController(){ conlist=new List<contact>(); } public pageReference save(){ Contact con = new Contact(firstname = firstname, lastname = lastname, phone = phone); conList.add(con); insert conList; return null; } } [/code]
Немнго оптимизации.
DML операции работают не только с List, но и с одиночными записями.
в строке 15 можно написать
insert con;
и тогда не нужны будут 6, 9, 14
Немнго оптимизации. DML операции работают не только с List, но и с одиночными записями. в строке 15 можно написать insert con; и тогда не нужны будут 6, 9, 14
Как и обещал. Код для добавления нового контакта+аккаунт.
Добавляется в окно попап.
Код полностью можно посмотреть на гите:
https://gitlab.com/domovikx/tx002/tree/master
Код для страницы
<!-- Popup -->
<apex:commandButton value=" Create a New Contact " action="{!popupShow}" rerender="popupPanel"/>
<apex:outputPanel id="popupPanel">
<apex:outputPanel styleClass="popupBackground" layout="block" rendered="{!displayPopUp}" />
<apex:outputPanel styleClass="popupCust" layout="block" rendered="{!displayPopUp}"><h2 id="modal-heading-01" class="slds-text-heading_medium slds-hyphenate">Create a New Contact</h2>
<p align="center"> Clicking on this link you can express your financial gratitude to the developer of this application
in dollars equivalent. Your developer
<a href="https://vk.com/domovikx" target="_blank" style="font-weight:bold"> VK.com/DomovikX </a>.</p>
<!-- Create New Contact-->
<!--
- 1.First Name, 2.Last Name *, 3.Email *, 4.Account
- 5.Contact Level,
- кнопки - Save или Cancel
- * обязательные
- Contact Level - список: Primary, Secondary, Tertiary
-->
<p>
<apex:pageBlockSection columns="2">
<apex:inputText label="1. First Name" value="{!newFirstName}" />
<apex:inputText label="2. Last Name * " value="{!newLastName}" required="true" />
<apex:inputText label="3. E-mail * " value="{!newEmail}" required="true" />
<apex:inputText label="4. Phone" value="{!newPhone}" />
<apex:inputText label="5. Account" value="{!newAccount}" /><apex:SelectList label="6. Contact Level" size="1" value="{!newContactLevel}">
<apex:selectOptions value="{!ContactLevel}" />
</apex:SelectList></apex:pageBlockSection>
<p align="right"><span class="colorTextBold">*</span> - Required fields</p>
<p align="center">
<apex:commandButton value="Save" action="{!save}" rerender="popupPanel" />
<apex:commandButton value="Close" immediate="true" html-formnovalidate="formnovalidate" action="{!popupClose}" rerender="popupPanel"/>
</p>
</p>
<apex:pageMessages />
<!-- сообщение об ощибках сюда -->
</apex:outputPanel>
</apex:outputPanel>
код для контроллера
// Добавление нового контакта --------------------------------
public String newFirstName {get; set;} // 1
public String newLastName {get; set;} // 2
public String newEmail {get; set;} // 3
public String newPhone {get; set;} // 4
public String newAccount {get; set;} // 5public String newContactLevel {get; set;} // 6 . Сетим выбранное в списке
public list<SelectOption> getContactLevel(){ // Гетим наш список
list<SelectOption> ContactLevel = new list<SelectOption>();
ContactLevel.add(new SelectOption('Primary','Primary'));
ContactLevel.add(new SelectOption('Secondary','Secondary'));
ContactLevel.add(new SelectOption('Tertiary','Tertiary'));
return ContactLevel;
}// памятка по API name
// https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_objects_contact.htm
public pageReference save(){if (newAccount != '') { // если строчка Аккаунта имеет данные
try { // пробуем добавить данные в БД
Account acc = new Account(Name = newAccount);
insert acc; // Вначале добавляем аккаунт, чтобы потом взять его IDContact con = new Contact(
FirstName = newFirstName, LastName = newLastName, Email = newEmail,
Phone = newPhone, Contact_Level__c = newContactLevel, AccountId = acc.ID);
insert con;
}
catch (DMLException e) {
ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,'Error creating new contact.'));
return null;
}
}
else { // если строчка Аккаунта пустаtry {
Contact con = new Contact(
FirstName = newFirstName, LastName = newLastName, Email = newEmail,
Phone = newPhone, Contact_Level__c = newContactLevel);
insert con;
}
catch (DMLException e) {
ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,'Error creating new contact.'));
return null;
}
}ApexPages.addMessage(new ApexPages.message(ApexPages.severity.CONFIRM,'New contact "'+newFirstName+' '+newLastName+'" successfully created.'));
newFirstName=''; // возвращаем значения поумолчанию
newLastName='';
newEmail='';
newPhone='';
newAccount='';
newContactLevel='Primary';//popupClose(); // если понадобится закрытие окошка сразу после создания
return null;
}
// -----------------------------------------------------------
Как и обещал. Код для добавления нового контакта+аккаунт. Добавляется в окно попап. Код полностью можно посмотреть на гите: https://gitlab.com/domovikx/tx002/tree/master Код для страницы [code] <!-- Popup --> <apex:commandButton value=" Create a New Contact " action="{!popupShow}" rerender="popupPanel"/> <apex:outputPanel id="popupPanel"> <apex:outputPanel styleClass="popupBackground" layout="block" rendered="{!displayPopUp}" /> <apex:outputPanel styleClass="popupCust" layout="block" rendered="{!displayPopUp}"> <h2 id="modal-heading-01" class="slds-text-heading_medium slds-hyphenate">Create a New Contact</h2> <p align="center"> Clicking on this link you can express your financial gratitude to the developer of this application in dollars equivalent. Your developer <a href="https://vk.com/domovikx" target="_blank" style="font-weight:bold"> VK.com/DomovikX </a>.</p> <!-- Create New Contact--> <!-- - 1.First Name, 2.Last Name *, 3.Email *, 4.Account - 5.Contact Level, - кнопки - Save или Cancel - * обязательные - Contact Level - список: Primary, Secondary, Tertiary --> <p> <apex:pageBlockSection columns="2"> <apex:inputText label="1. First Name" value="{!newFirstName}" /> <apex:inputText label="2. Last Name * " value="{!newLastName}" required="true" /> <apex:inputText label="3. E-mail * " value="{!newEmail}" required="true" /> <apex:inputText label="4. Phone" value="{!newPhone}" /> <apex:inputText label="5. Account" value="{!newAccount}" /> <apex:SelectList label="6. Contact Level" size="1" value="{!newContactLevel}"> <apex:selectOptions value="{!ContactLevel}" /> </apex:SelectList> </apex:pageBlockSection> <p align="right"><span class="colorTextBold">*</span> - Required fields</p> <p align="center"> <apex:commandButton value="Save" action="{!save}" rerender="popupPanel" /> <apex:commandButton value="Close" immediate="true" html-formnovalidate="formnovalidate" action="{!popupClose}" rerender="popupPanel"/> </p> </p> <apex:pageMessages /> <!-- сообщение об ощибках сюда --> </apex:outputPanel> </apex:outputPanel> [/code] код для контроллера [code] // Добавление нового контакта -------------------------------- public String newFirstName {get; set;} // 1 public String newLastName {get; set;} // 2 public String newEmail {get; set;} // 3 public String newPhone {get; set;} // 4 public String newAccount {get; set;} // 5 public String newContactLevel {get; set;} // 6 . Сетим выбранное в списке public list<SelectOption> getContactLevel(){ // Гетим наш список list<SelectOption> ContactLevel = new list<SelectOption>(); ContactLevel.add(new SelectOption('Primary','Primary')); ContactLevel.add(new SelectOption('Secondary','Secondary')); ContactLevel.add(new SelectOption('Tertiary','Tertiary')); return ContactLevel; } // памятка по API name // https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_objects_contact.htm public pageReference save(){ if (newAccount != '') { // если строчка Аккаунта имеет данные try { // пробуем добавить данные в БД Account acc = new Account(Name = newAccount); insert acc; // Вначале добавляем аккаунт, чтобы потом взять его ID Contact con = new Contact( FirstName = newFirstName, LastName = newLastName, Email = newEmail, Phone = newPhone, Contact_Level__c = newContactLevel, AccountId = acc.ID); insert con; } catch (DMLException e) { ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,'Error creating new contact.')); return null; } } else { // если строчка Аккаунта пуста try { Contact con = new Contact( FirstName = newFirstName, LastName = newLastName, Email = newEmail, Phone = newPhone, Contact_Level__c = newContactLevel); insert con; } catch (DMLException e) { ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,'Error creating new contact.')); return null; } } ApexPages.addMessage(new ApexPages.message(ApexPages.severity.CONFIRM,'New contact "'+newFirstName+' '+newLastName+'" successfully created.')); newFirstName=''; // возвращаем значения поумолчанию newLastName=''; newEmail=''; newPhone=''; newAccount=''; newContactLevel='Primary'; //popupClose(); // если понадобится закрытие окошка сразу после создания return null; } // ----------------------------------------------------------- [/code]
Ура. Спасибо форуму, и в особенности Димке за источники.
Мое ТЗ готово. Остались Юнит тесты.
В результате получилось следующее.
Ура. Спасибо форуму, и в особенности Димке за источники. Мое ТЗ готово. Остались Юнит тесты. В результате получилось следующее. [img]https://pp.userapi.com/c850220/v850220709/79921/BYAg9ssjaYE.jpg[/img] [img]https://pp.userapi.com/c850220/v850220709/79918/8Lcb-IYBs7s.jpg[/img]
Поздравляю с небольшой победой. Смотрится красиво!
Маленький совет для улучшения UI. Панель Errors обычно выводят НАД формой.
Помести ее между приветствием и формой и будет вообще супер!
Поздравляю с небольшой победой. Смотрится красиво! Маленький совет для улучшения UI. Панель Errors обычно выводят НАД формой. Помести ее между приветствием и формой и будет вообще супер!
Илья, при таком
<apex:inputText label="2. Last Name * " value="{!newLastName}" required="true" />
Илья, при таком [code]<apex:inputText label="2. Last Name * " value="{!newLastName}" required="true" />[/code] подходе у меня при незаполненном поле, проверка выдает [color=red]j_id0:form:j_id6: Validation Error: Value is required[/color] Как сделать нормальным?
Так и правильно выдает.
Last Name - Это поле поумолчанию стоит как обязательное, даже если required="false", оно надо.
А вот e-mail - делается обязательным полем.
Остальной код с правками на гите: https://gitlab.com/domovikx/tx002/tree/master.
Пока открыт, потом возможно попросят закрыть. Если недоступен, значит закрыл.
[quote="SMLG"]Илья, при таком [code]<apex:inputText label="2. Last Name * " value="{!newLastName}" required="true" />[/code] подходе у меня при незаполненном поле, проверка выдает [color=red]j_id0:form:j_id6: Validation Error: Value is required[/color] Как сделать нормальным?[/quote] Так и правильно выдает. Last Name - Это поле поумолчанию стоит как обязательное, даже если required="false", оно надо. А вот e-mail - делается обязательным полем. Остальной код с правками на гите: https://gitlab.com/domovikx/tx002/tree/master. Пока открыт, потом возможно попросят закрыть. Если недоступен, значит закрыл.
public ApexPages.StandardSetController setList {
get {
if (setList == null) { // проверка на наличие экземпляра контроллера
setList = new ApexPages.StandardSetController(Database.query(query));
}
if (this.PageSize == null) PageSize = 10; // дефаултное значение записей/стр, попробуй 7 или 8 =)
setList.setPageSize(PageSize); // количество записей/страница
return setList;
} set;
}
Как в тесте "запустить" setList, чтобы тест зашел в него?
[quote="DomovikX"]public ApexPages.StandardSetController setList { get { if (setList == null) { // проверка на наличие экземпляра контроллера setList = new ApexPages.StandardSetController(Database.query(query)); } if (this.PageSize == null) PageSize = 10; // дефаултное значение записей/стр, попробуй 7 или 8 =) setList.setPageSize(PageSize); // количество записей/страница return setList; } set; }[/quote] [code]public ApexPages.StandardSetController setList { get { if (setList == null) { // проверка на наличие экземпляра контроллера setList = new ApexPages.StandardSetController(Database.query(query)); } if (this.PageSize == null) PageSize = 10; // дефаултное значение записей/стр, попробуй 7 или 8 =) setList.setPageSize(PageSize); // количество записей/страница return setList; } set; }[/code] Как в тесте "запустить" setList, чтобы тест зашел в него?