Заглянул сегодня под одну кастомную кнопку, и удивился тем, что там обнаружил.
Представьте ситуацию: на детайл пейдж нужно создать кнопку, которая создают и вносит запись другого объекта, затем делает редирект на дитэл страницу той записи.
Что первое приходит в голову новичка? сделать кастомную VF дитейл стрраницу с кнопкой и функционалом заложенным в кастомный или расширенный контроллер, откуда и делается редирект.
Второе что приходит в голову чуть более опытному новичку: оставь стандарную дитэйл страницу как есть, парень, но создай на ней кастомную кнопку которая ведет на VF страницу с единственным методом на он-лоад, который создает запись и делает редирект.
Но сегодня я увидел другой путь и он меня сильно удивил:
под кастомной кнопкой на стандарной дитейл странице лежит JS скрипт со сл содержанием (кратко):
{!REQUIRESCRIPT("/soap/ajax/22.0/connection.js")}
var connection = sforce.connection;
var bp = new sforce.SObject("MyCustomObject__c");
....заполняются поля, вносится запись, получаем ее ID...и все это в браузере...
window.location.href = "/"+rs[0].id;
получается что JS скрипт в данном случае выполняет функцию расширения страндарного контроллера!!! при этом мы все делаем в пределах стандарной дитейл или лист страницы и при стандарном контроллере! Моя удивляться...
Где можно почитать об этом?
Также более простые вопросы, подскажите кракто:
- в чем механизм работы кастомной кнопки, если ее Content Source - URL (не разобрал, как это создается и работает);
- и зачем нужны New Action - это находится в том же разделе описания кастомного объекта, где и кастомные кнопки.
Спасибо
Да, custom buttons это замечательная и очень нужная штука для стандартных салесфорсовских страниц.
Если в приложении делается упор на standard layouts, а не на Visualforce страницы, то без custom buttons не обойтись.
Кастомные кнопки позволяют открыть Visualforce страницу, любой URL, а также выполнить Javascript. В теле кнопки можно реализовать очень сложную логику с помощью javascript и FORMULA. Иногда получается жуткая, не читаемая вермишель из кода. Те кто сталкивался поймут о чем я. Но там действует ограничение по количеству символов. Так что вставить в тело кнопки БОЛЬШОЙ код не получится.
Почитать про custom buttons можешь здесь - Understanding Custom Buttons and Links
или посмотреть здесь
На счет action каюсь, так руки и не дошли изучить что это такое. Так что буду признателен, если ты прочитаешь и в двух словах расскажешь о своих впечатлениях.
А то что у тебя в примере
{!REQUIRESCRIPT("/soap/ajax/22.0/connection.js")}
Это AJAX Toolkit
Тоже мощный инструмент для работы с Salesforce напрямую из javascript.
В общем поднял ты отдельную огромную тему
Удачи в изучении.
Невероятно интересно. JS это как раз то что я люблю. Буду изучать.
И сразу забавные вопросы, ответы на которые конечно найду позже в том Руководстве, но вам просто для размышления:
(1) а лимиты по DML операциям и прочему при обращении к API через JS те же?
(2) JS работает с API, а вот тестировать перед размещением в прод то и не нужно?
надеюсь скоро сам найди ответы на это.
Ajax toolkit - это javascript обертка для работы с Salesforce API.
Т.е. обычного программирования оно не заменит.
Большой недостаток Ajax toolkit в том что он жрет API Calls а их не так много. Например на Developer Edition их всего 5000 и это на сутки. Поверь они съедаются очень хорошо.
Поэтому использовать Ajax toolkit надо в крайних (или экзотических) случаях, когда нельзя использовать Visualforce page.
В "том самом" начальном workbookе есть пример создания класса с вебметодом, который вызывается через AJAX API с кнопки. Мне понравилось.
Воодушевленный этим я решил одну из рабочих задач именно через AJAX API, не взирая на то, что он ест вызовы. Все работает.
А потом я подумал, подумал и согласился с Дмитрием, что все нужно делать по человечески, т.е. через VF страницы и их контроллеры.
Задача была: на детальной странице записи создать кнопку при нажатии на которую всплывает запрос "Сколько дочерних записей создать?" (от 1 до 10). После ввода, создаются записи, перегружается текущая страница (чтобы видеть новые дочерние записи), отрывается новое окно, где в ПДФ выводятся (на пример) ID созданных записей. Код ниже.
Но как только я это сделал, на меня навалилась параноя:
- а что если в браузере заблокировано открытие alert/prompt/confirm? (впрочем SFDC их по-любому использует в работе - попробуйте удалить какую-нибудь запись);
- а что если JS отключен? (впрочем не уверен что в таком случае интерфейс SFDC вообще будет работать);
- а что если будет сделан вредителський ввод, который не остановят мои проверки? (впрочем, вместо промпта можно поднимать дивчик с селектом и фиксированными значениями, которые и читать)
Вобщем, наверное, будет более правильно сделать кнопку не с JS AJAX API логикой, а кнопку "КастомнаяКнопка" окрывающее новое окно с VF страницей с стандартно-расширенным контроллером, где есть только дроп-даун лист с числом требуемых записей и кнопкой "создать записи", после нажатия на которую создаются записи и данное окно уходит на страницу с ПДФ распечаткой. Вот как только при нажатии на "создать записи" перегрузить родительское окно с (перегружать его при нажатии на кнопку "КастомнаяКнопка" нет смысла, так как в тот момет новых дочерних записей еще нет).
Вот JS код:
/*
{!REQUIRESCRIPT("/soap/ajax/29.0/connection.js")}
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
var URL="apex/СтраницаКотораяВыводитПДФ?";
var quantity = prompt('How many records do you want to create? (Choose from 1 to 10)', '');
if (!isNumeric(quantity)) { // проверяем на число
quantity=null;
alert("Please enter a number from 1 to 10");
} else {
quantity=Math.floor(+quantity); //округляем вниз
if (quantity<=0||quantity>10) { //проверям диапазон
quantity=null;
alert("Please enter a number from 1 to 10");
}
}
if(quantity!=null){
var connection = sforce.connection;
// циклом создаем требуемое кол-во записей, НЕ уверен что можно создать несколько записей за один вызов, хотя это было бы гораздо более правильное решение
// также можно было бы написать апекс класс с вебметодом, который на вход получал бы кол-во записей и возвращал бы их ID, а здесь просто бы вызвать метод.
for (var i=0; i<quantity; i++) {
var Item = new sforce.SObject("кастомный_объект__c");
Item.ПолесIDмастерЗаписи = "{!текущая запись.Id}";
var rs = connection.create([Item]);
if (rs[0].success=='false')
alert("Message"+rs[0].errors.message);
else
{
URL+=i+"="+rs[0].id+"&"; //собираем URL со всеми необходимыми параметрами
}
}
window.open().location.href = "/"+URL; //открываем в новом окне страницу с распечаткой
window.location.reload(); // перегружаем текущее окно, чтобы видеть появившиеся дочерние записи
}
*/