Отправка <apex:form> по нажатию Enter без page reload
Приветствую, с недавних пор я работаю с Salesforce и сейчас как раз разбираюсь с VF страницами. Была поставлена задача: "После ввода текста в inputField при нажатии Enter данные улетают на Custom Controller и сразу текст появляется в определенном outputFiel, все должно происходить без page reload".
Мои попытки прикрутить JavaScript функции на слушание клавиш пользователя и вызове определенной actionFunction с атрибутом reRender, блока с полем в которые нужно занести новые данные, не дали результата, а стандартный функционал, по крайней мере то что я пролопатил, дает возможность делать это только через commandButton и commandLink.
Буду благодарен если подскажите как можно реализовать такое поведение.
Вот рабочий костяк, но при нажатии Enter страница перезагружается.
Приветствую, с недавних пор я работаю с Salesforce и сейчас как раз разбираюсь с VF страницами. Была поставлена задача: "После ввода текста в [b]inputField[/b] при нажатии [b]Enter[/b] данные улетают на [b]Custom Controller[/b] и сразу текст появляется в определенном [b]outputFiel[/b], все должно происходить без [b]page reload[/b]".
Мои попытки прикрутить JavaScript функции на слушание клавиш пользователя и вызове определенной [b]actionFunction[/b] с атрибутом reRender, блока с полем в которые нужно занести новые данные, не дали результата, а стандартный функционал, по крайней мере то что я пролопатил, дает возможность делать это только через [b]commandButton[/b] и [b]commandLink[/b].
Буду благодарен если подскажите как можно реализовать такое поведение.
Вот рабочий костяк, но при нажатии [b]Enter[/b] страница перезагружается.
[u][i]Page:[/i][/u]
[code]
<apex:page controller="NameTransferController" showHeader="true" sidebar="true">
<apex:pageBlock >
<h1 style="font-size:150%;">Transfer name on <i>client-controller</i> interaction</h1><hr/><br/>
<apex:form>
<apex:outputLabel value="Enter your name here: "/>
<apex:inputText value="{!name}">
<apex:actionSupport event="onclick" reRender="display"/>
</apex:inputText>
<br/><br/>
<apex:outputPanel id="display">
<apex:outputText value="The entered name is - {!name}"/>
</apex:outputPanel>
</apex:form>
</apex:pageBlock>
</apex:page>
[/code]
[u][i]Controller:[/i][/u]
[code]
public class NameTransferController {
public String name;
public String getName() {
if (name == null) return 'Ruslan';
else return name;
}
public void setName(String name) {
this.name = name;
}
}
[/code]
У тебя нет сабмита формы. Используй commanButton или commandLink. Просто повесь на нажатие enter клик по сабмит кнопке. В кнопке в атрибуте rerender указывай ид элемента для рефреша.
PS В контроллере лучше используй properties. public String name {get; set;}
У тебя нет сабмита формы. Используй commanButton или commandLink. Просто повесь на нажатие enter клик по сабмит кнопке. В кнопке в атрибуте rerender указывай ид элемента для рефреша.
PS
В контроллере лучше используй properties.
public String name {get; set;}
Спасибо за ответ, я уже пробовал такой подход, почему-то форма все-равно отправлялась через релоад. Я попробую еще раз реализовать такую функцию немного по другому и отпишу.
[quote="Дима Лисовский"]Просто повесь на нажатие enter клик по сабмит кнопке.[/quote]
Спасибо за ответ, я уже пробовал такой подход, почему-то форма все-равно отправлялась через релоад. Я попробую еще раз реализовать такую функцию немного по другому и отпишу.
Смотри, что у тебя может быть не так: если ты перехватываешь event на кнопке, например onclick, в конце обязательно ставь return false; Если его не поставишь то страница пойдет на перезагрузку. Ну и если используешь такую логику то лучше использовать простой <button> а не <apex:commandButton> В остальном логика абсолютно правильная, и я ее постоянно использую. Еще один совет - смотри консоль. Если до return false в обработчике события будет ошибка, то выполнение кода остановится и страница уйдет на перезагрузку (часто сбивает с толку)
[quote="Руслан Курченко"]Мои попытки прикрутить JavaScript функции на слушание клавиш пользователя и вызове определенной actionFunction с атрибутом reRender, блока с полем в которые нужно занести новые данные, не дали результата[/quote]
Смотри, что у тебя может быть не так:
если ты перехватываешь event на кнопке, например onclick, в конце обязательно ставь return false; Если его не поставишь то страница пойдет на перезагрузку.
Ну и если используешь такую логику то лучше использовать простой <button> а не <apex:commandButton>
В остальном логика абсолютно правильная, и я ее постоянно использую.
Еще один совет - смотри консоль. Если до return false в обработчике события будет ошибка, то выполнение кода остановится и страница уйдет на перезагрузку (часто сбивает с толку)
Если на форме будет сабмит кнопка, не надо никаких событий вешать.
[quote="Руслан Курченко"]Просто повесь на нажатие enter клик по сабмит кнопке.[/quote]
Если на форме будет сабмит кнопка, не надо никаких событий вешать.
Ну и на счет перехвата Enter на input по твоему примеру я так и не понял где ты его перехватываешь
Ну и на счет перехвата Enter на input
по твоему примеру я так и не понял где ты его перехватываешь
Вот сразу из первой ссытке от google
http://stackoverflow.com/questions/7060750/detect-the-enter-key-in-an-text-input-field
[code]$(".input1").keyup(function (e) {
if (e.keyCode == 13) {
// Do something
}
});[/code]
И про return false не забываем.
А reRender мне как тогда реализовать с обычной кнопкой?
[quote="Dmitry Shnyrev"][quote="Руслан Курченко"]Ну и если используешь такую логику то лучше использовать простой <button> [/quote]
А reRender мне как тогда реализовать с обычной кнопкой?
[quote="Руслан Курченко"][quote="Dmitry Shnyrev"][quote="Руслан Курченко"]Ну и если используешь такую логику то лучше использовать простой <button> [/quote]
А reRender мне как тогда реализовать с обычной кнопкой?[/quote]
c actionfunction
rerender у тебя организует apexFunction которую ты вызовешь в теле перехватчика Enter.
[quote="Gres"][quote="Дима Лисовский"]В контроллере лучше используй properties.
public String name {get; set;}[/quote]
Джависты тебя возненавидят)[/quote]
а жависты любят писать getName setName ?
В контроллере лучше используй properties. public String name {get; set;}
[quote="Maxim Elets"][quote="Gres"][quote="Дима Лисовский"]В контроллере лучше используй properties.
public String name {get; set;}[/quote]
Джависты тебя возненавидят)[/quote]
а жависты любят писать getName setName ?[/quote]
В java нет Auto-Implemented Properties
В контроллере лучше используй properties. public String name {get; set;}
[quote="Gres"][quote="Maxim Elets"][quote="Gres"][quote="Дима Лисовский"]В контроллере лучше используй properties.
public String name {get; set;}[/quote]
Джависты тебя возненавидят)[/quote]
а жависты любят писать getName setName ?[/quote]
В java нет Auto-Implemented Properties[/quote]
ААААА вот оно что, я просто не жавист)
[quote="Maxim Elets"]ААААА вот оно что, я просто не жавист)[/quote]
Ну вот теперь и ты это знаешь. Я тоже люблю C#.
если ты перехватываешь event на кнопке, например onclick, в конце обязательно ставь return false; Если его не поставишь то страница пойдет на перезагрузку.
Сделал как вы говорили но страница идет в перезагрузку все-равно. Сделал и через commandButton и через обычную кнопку и actionFunction, результат одинаковый. Может у меня что-тов JS коде не так? (JQuery только начинаю работать)
[quote="Dmitry Shnyrev"]если ты перехватываешь event на кнопке, например onclick, в конце обязательно ставь return false; Если его не поставишь то страница пойдет на перезагрузку.[/quote]
Сделал как вы говорили но страница идет в перезагрузку все-равно. Сделал и через commandButton и через обычную кнопку и actionFunction, результат одинаковый. Может у меня что-тов JS коде не так? (JQuery только начинаю работать)
[code]<apex:page controller="NameTransferController" showHeader="true" sidebar="true" id="page">
<apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" />
<script type='text/javascript'>
j$ = jQuery.noConflict();
j$(document).ready(function() {
j$("#page\\:block\\:form\\:inputField").keyup(function (e) {
console.log('log keyup');
if (e.keyCode == 13) {
console.log('log key enter');
j$("#page\\:block\\:form\\:submit").click();
return false;
} else {
return true;
}
});
});
</script>
<apex:pageBlock id="block">
<h1 style="font-size:150%;">Transfer name on <i>client-controller</i> interaction</h1><hr/><br/>
<apex:form id="form">
<apex:outputLabel value="Enter your name here: "/>
<apex:inputText value="{!name}" id="inputField"/>
<apex:actionFunction name="rerenderDisplay" reRender="display"/>
<input type="button" value="Submit" id="submit" onclick="rerenderDisplay();"/>
<!-- <apex:commandButton value="Submit" id="submit" reRender="display" /> -->
<br/><br/>
<apex:outputPanel id="display">
<apex:outputText value="The entered name is - {!name}"/>
</apex:outputPanel>
</apex:form>
</apex:pageBlock>
</apex:page>[/code]
[quote="Руслан Курченко"]Может у меня что-тов JS коде не так?[/quote]
Как не странно, но ты прав.
Используй partial селекторы jquery.
Открой эту страничку в браузере и посмотри код.
j$ = jQuery.noConflict();
Ну во-первых конфликтов уже давно нет, поэтому без этого работает тоже. Но если так хочется то пиши лучше просто
[quote="Руслан Курченко"]j$ = jQuery.noConflict();[/quote]
Ну во-первых конфликтов уже давно нет, поэтому без этого работает тоже.
Но если так хочется то пиши лучше просто
[quote]
jQuery.noConflict();
jQuery('element').doSomething();
[/quote]
Во-вторых #page\\:block\\:form\\:inputField что это? Кто так с jQuery поступает? Может оно и работает, но это жесть.
В-третьих
зачем ты делаешь j$("#page\\:block\\:form\\:submit").click();
если можно просто вызвать rerenderDisplay
В четвертых где у тебя собственно вызов action? Оно так работает?
<apex:actionFunction name="rerenderDisplay" reRender="display"/>
Проверь консоль браузера - по ходу у тебя там все в ошибках.
Если на форме будет сабмит кнопка, не надо никаких событий вешать.
[quote="Dmitry Shnyrev"]
Оно так работает?
<apex:actionFunction name="rerenderDisplay" reRender="display"/>
Проверь консоль браузера - по ходу у тебя там все в ошибках.
[/quote]
При нажатии на кнопку [i]вручную[/i] display обновляется без перезагрузки. Логи я смотрю, иначе зачем мне [b]console.log('log keyup');[/b]. Ошибок нет.
[quote="Dmitry Shnyrev"]
зачем ты делаешь j$("#page\\:block\\:form\\:submit").click();
если можно просто вызвать rerenderDisplay
[/quote]
При вызове происходит тоже самое, страница идет в релоад.
В том то и прикол что я не знаю какой [b]action[/b] надо для [b]actionFunction[/b] что бы она отправляла форму и потом уже по [b]rerender[/b] перерисовывала мне [b]display[/b].
Без изменений, при нажатии на кнопку actionFunction срабатывает хорошо, display обновляется, при нажатии Enter - reload.
Как я уже говорил, я начинающий в JS и JQuery, до этого просто пробовал, ничего особенного. Вы уверены что возврат false из функции в таком виде должен остановить перезагрузку страницы?
[code]<apex:actionFunction name="rerenderDisplay" action="{!fake}" reRender="display"/>[/code]
[code]public void fake() { }[/code]
[code]
$('input[id$=inputField]').keyup(function (e) {
console.log('log keyup');
if (e.keyCode == 13) {
console.log('log key enter');
rerenderDisplay();
return false;
} else {
return true;
}
});
[/code]
Без изменений, при нажатии на кнопку [b]actionFunction[/b] срабатывает хорошо, [b]display[/b] обновляется, при нажатии [b]Enter[/b] - [b]reload[/b].
Как я уже говорил, я начинающий в JS и JQuery, до этого просто пробовал, ничего особенного. Вы уверены что возврат [b]false[/b] из функции в таком виде должен остановить перезагрузку страницы?
Вы уверены что возврат false из функции
False нужно возвращать не из функции, а после ее выполнения в event'е
[code]
public with sharing class SampleController {
public String name {get; set;}
public PageReference updateAction(){
return null;
}
}
[/code]
[code]
<apex:page controller="SampleController">
<apex:form id="form" onkeypress="return submitListener(event)">
<apex:actionFunction name="onFormSubmit"
action="{!updateAction}"
rerender="text" />
<apex:inputText value="{!name}"/>
<hr/>
<apex:outputText id="text" value="{!name}"/>
</apex:form>
<script>
function submitListener(e){
var keynum = 0;
if (window.event){
keynum = window.event.keyCode;
}
else if (e.which){
keynum = e.which;
}
// Here we check whether the Enter button was pressed
if (keynum == 13){
onFormSubmit();
return false;
}
}
</script>
</apex:page>
[/code]
А вообще ты явно не первый с такой проблемой, а гугл большой, надо просто поискать.
Вчера лазил... не нашел толкового подхода, так и не получилось, поэтому написал суда. Про event не совсем понял, как его можно дернуть и отправить false.
[quote="Gres"]А вообще ты явно не первый с такой проблемой, а гугл большой, надо просто поискать.[/quote]
Вчера лазил... не нашел толкового подхода, так и не получилось, поэтому написал суда. Про [b]event[/b] не совсем понял, как его можно дернуть и отправить false.
public with sharing class SampleController {
public String name {get; set;}
public PageReference updateAction(){ return null; }
[quote="Дима Лисовский"][code]
public with sharing class SampleController {
public String name {get; set;}
public PageReference updateAction(){
return null;
}
}
[/code]
[code]
<apex:page controller="SampleController">
<apex:form id="form" onkeypress="return submitListener(event)">
<apex:actionFunction name="onFormSubmit"
action="{!updateAction}"
rerender="text" />
<apex:inputText value="{!name}"/>
<hr/>
<apex:outputText id="text" value="{!name}"/>
</apex:form>
<script>
function submitListener(e){
var keynum = 0;
if (window.event){
keynum = window.event.keyCode;
}
else if (e.which){
keynum = e.which;
}
// Here we check whether the Enter button was pressed
if (keynum == 13){
onFormSubmit();
return false;
}
}
</script>
</apex:page>
[/code]
[/quote]
Все прекрасно работает, огромное вам спасибо!
Получается все завязано на возврате из [b]actionFunction[/b] пустой PageReference? :)
пустой PageReference? :)
можно и void, PageReference обычно используется для редиректа