I have a SharePoint 2013 Community Site that is used for discussions. I want to create a link to a specific discussion item that will open the discussion item in "Reply" mode, i.e. the mode you get to if you click the Reply button just under the Discussion item text. I want to do this because the Reply mode text entry box is right under the discussion item text where it is obvious to see. The default reply text entry box is at the bottom of the page and it scrolls off the page if there are already a lot of replies on the topic.
Here is the default view on a Discussion item
If you click the "Reply" link here
then the a Reply Pane opens up right under the discussion item text.
But what I want to do it to be able to send a URL by mail that will open the discussion thread already in Reply mode.
The solution I found to do this consisted of customizing the /Lists/Community Discussion/Flat.aspx with client-side script as follows.
First insert a Script Editor into the page (Settings -> Edit Page -> Add a Web Part -> Categories -> Media and Content -> Content Editor -> Script Editor.
Next upload a copy of jquery.min.js to the Site Assets library.
Then add the following code to the Script Editor using Edit Snippet:
<script src="/SiteAssets/jquery.min.js" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
$(document).ready(function() {
if (location.search.indexOf('replyMode=1') != -1)
{
openReplyPane();
}
});
function openReplyPane()
{
var mouseEvent = new MouseEvent("click", {
'bubbles': true,
'cancelable': true,
'view': window,
'detail': 0,
'screenX': 0,
'screenY': 0,
'clientX': 0,
'clientY': 0,
'ctrlKey': false,
'altKey': false,
'shiftKey': false,
'metaKey': false,
'button': 0,
'relatedTarget': null,
'currentTarget': 'form#aspnetForm',
'srcElement': 'a#commandBar0-reply-Link.ms-secondaryCommandLink',
'target':'a#commandBar0-reply-Link.ms-secondaryCommandLink',
'timeStamp':1425842811416,
'toElement':'a#commandBar0-reply-Link.ms-secondaryCommandLink'
});
var replyLink = document.getElementById('commandBar0-reply-Link');
replyLink.dispatchEvent(mouseEvent);
}
</script>
Save your changes.
Now if you add the string "&replyMode=1" to the end of the URL for the discussion item, you can navigate to the post, and the Reply pane will be automatically opened for the user.
Related
I have an IG on my page with a custom toolbar button that opens a Modal Dialog page. Because of how the modal dialog is opened, ther eisn't a way for me to capture its closure using native Dialog Close.
The javascript I use in my IG to open Modla Dialog is:
apex.server.process(
'GenerateURL',
{x01: l_url},
{success: function (pData) {
console.log(pData);
// Call Modal Dialog Page
apex.navigation.redirect(pData);
},
dataType: "text"
});
The issue is that after the modal dialog is closed I need to refresh my IG. How can I capture modal dialog closure from the parent page?
Modal dialogs should be opened with apex.navigation.dialog. When one calls apex_util.prepare_url for a modal page, it generates the correct JavaScript code that takes into account the settings for the destination page.
There's an option, p_plain_url, that can be used to get just the URL, but don't enable that in GenerateURL as the rest is important. Another parameter, p_triggering_element, allows you to specify the element for a Dynamic Action (that's not an option with apex_page.get_url, which works similarly).
Let's say GenerateURL looked like this (note that I'm passing document as the triggeringElement):
declare
l_url varchar2(512);
begin
l_url := apex_util.prepare_url(
p_url => 'f?p=' || :APP_ID || ':51:' || :APP_SESSION || ':::::P51_ID:' || apex_application.g_x01,
p_triggering_element => 'document'
);
apex_json.open_object();
apex_json.write('url', l_url);
apex_json.close_object();
end;
Then the JavaScript code could be modified to this:
apex.server.process(
'GenerateURL',
{x01: idForURL},
{success: function (pData) {
var funcBody = pData.url.replace(/^"javascript:/, '').replace(/\"$/,'');
new Function(funcBody).call(window);
}
});
Note that the JavaScript is passing an ID to the process that generates the URL, not the whole URL. This makes the use of the process somewhat limited which helps prevent users from abusing it. You could even add a check that verifies the user is able to view the ID value passed in.
With that in place, you can add a Dynamic Action listening for the Dialog Closed event on the document (JavaScript Expression = document). Note that the event will not fire if the dialog is closed via the close or cancel buttons.
When I copy the contents of a properly formatted word document, meaning it has H1 tags, 3 paragraphs, a URL link, and an email link, some bolded and some italicized words - basically a very basic document, the formatting isn't retained. Below is my init file.
tinyMCE.init({
// General options
mode : "exact",
elements : "content",
theme: "advanced",
//plugins : "safari,pagebreak,advhr,advimage,advlink,iespell,insertdatetime,preview,paste,fullscreen",
plugins : "pagebreak,style,advlink,iespell,insertdatetime,preview,print,contextmenu,paste,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,inlinepopups",
plugin_preview_width : "500",
plugin_preview_height : "600",
// Theme options
theme_advanced_buttons1:"cut,copy,paste,pasteword,|,undo,redo,|,bold,italic,underline,|,forecolor,backcolor|,justifyleft,justifycenter,justifyright,|,bullist,numlist,|fullscreen,code,iespell,imageButton,preview",
theme_advanced_disable : "help,removeformat,sub,sup,anchor,link,unlink,image,|,insertdate,inserttime,advhr,print",
theme_advanced_buttons2 : "",
theme_advanced_buttons3 : "",
paste_auto_cleanup_on_paste: false,
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "center",
valid_elements : "*[*]",
convert_urls:true,
cleanup : false
});
When I run the following console commands, I do see the "html" code IS there. Also, when I click on the HTML icon in the toolbar, I see the HTML code there, too (though all the H1 tags are removed except for the first one).
// Get the HTML contents of the currently active editor
console.debug(tinyMCE.activeEditor.getContent());
// Get the raw contents of the currently active editor
tinyMCE.activeEditor.getContent({format : 'raw'});
// Get content of a specific editor:
tinyMCE.get('content').getContent()
When I click the submit button, all I have on my action page is a simple cfdump and there, it is just plain text and a giant since paragraph. There are no P tags, not H1 tags, just plain text.
<cfdump var="#form.content#">
<cfoutput>
#form.content#
<textarea>#form.content#</textarea>
</cfoutput>
Just for grins, on the action page, I inserted the form.content into my MSSQL database with a datatype of nvarchar(2000) just to see if maybe the browser was playing games and the database only shows plain text, too. Here is another abnormality is that when I run my test page in Chrome, only plain text is saved. When I run the test page in FireFox, the Microsoft XML data is saved.
I only need one browser to work. Can someone provide any guidance on this?
Gotta love spaghetti code.
There was some logic that I missed that was doing a check for browsers that I missed so the issue was really with fckeditor and not tinymce.
/Start Snippet from: http://ckeditor.com/forums/Support/FCK-Link-picker-errors-FF-3
I got the same problem with FCK 2.3.2. The best solution is to change function CreateLink in fckeditorcode_gecko.js:
Old code I had:
FCK.CreateLink=function(A){FCK.ExecuteNamedCommand('Unlink');if (A.length>0){var B='javascript:void(0);/*'+(new Date().getTime())+'*/';FCK.ExecuteNamedCommand('CreateLink',B);var C=document.evaluate("//a[#href='"+B+"']",this.EditorDocument.body,null,9,null).singleNodeValue;if (C){C.href=A;return C;}}};
New code:
FCK.CreateLink=function(A){FCK.ExecuteNamedCommand('Unlink');if (A.length>0){var B='javascript:void(0);/*'+(new Date().getTime())+'*/';FCK.ExecuteNamedCommand('CreateLink',B);var C=this.EditorDocument.evaluate("//a[#href='"+B+"']",this.EditorDocument.body,null,9,null).singleNodeValue;if (C){C.href=A;return C;}}};
In fact, I only replaced document.evaluate with this.EditorDocument.evaluate
/end snippet
I am trying to solve an issue with modals. What I want to do is allow the user to click the browser's back button to dismiss a modal and return to the original state of the page, this is: without modal. For such purpose I thought about using HTML 5 history API.
I started trying to append a querystring parameter to the URL, such as http://...page.html?show_modal=[yes|no] but I ended leaving this approach because I couldn't handle all the stuff involving popstate event, pageshow event, etc. I couldn't make it work and it overwhelmed me.
Then I tried with a more simple approach involving a hash appended to the URL, such as http://...page.html#modal, and the hashchange event. This approach is working better for me and I almost have it.
When the user clicks the button to show the modal, he or she can click the browser's back button and it will dismiss the modal. Furthermore, after that, the user can click the browser's forward button and it will show the modal again. Very nice! The user can also navigate directly to the URL with the hash to access directly this state of the page, as well as he or she can bookmark such state of the page. It's working pretty neat and I'm rather happy with the results.
The problem is that it is not working totally perfect. When the user dismiss the modal by clicking the background, the ESC key or the X in the upper right corner, the history starts to mess up. Try it: open the modal by clicking on the button, then click the background to dismiss it (look a the URL in the address bar, first problem here is that the hash isn't removed), then click your browser back button and you will see it isn't working correctly. You will end with a duplicate in your history and you have to click the back button twice in order to go to the previous page. This is not desirable from an UX viewpoint. Does anyone know a solution to this?
I provide my code in this CodePen and at the end of this question. I suggest trying it in your own machine and NOT IN Codepen, so you can view the hash in the URL, etc. Also, it doesn't work in Codepen Full mode, I don't know why.
Thanks!!
I am using Foundation 5.2.1
HTML
<div class="row">
<div class="small-12 columns">
<h1>Reveal Modal</h1>
<h2>Manipulation of the browser history for a better UX</h2>
<a class="button radius" href="#" data-reveal-id="sampleModal" id="button">Show Modal...</a>
</div>
</div>
<!-- ############# -->
<!-- MODAL -->
<!-- ############# -->
<div id="sampleModal" class="reveal-modal medium" data-reveal>
<h2>Hi!</h2>
<p>You may think you are on a new page now, but you aren't. Try to click your browser <kbd>Back</kbd> button to dismiss this modal and return to the the page you were viewing.</p>
<a class="close-reveal-modal">×</a>
</div>
JavaScript
function setModalHash(url, present) {
var a = $('<a>', { href:url } )[0]; // http://tutorialzine.com/2013/07/quick-tip-parse-urls/
var newHash = "";
if (present === true) {
newHash = "#modal";
}
// Build the resulting URL
result = a.protocol + "//" + a.hostname + ":" + a.port + a.pathname + a.search + newHash;
return result;
}
$("#button").on('click', function() {
history.pushState(null, null, setModalHash(document.URL, true));
});
$(window).on("hashchange load",function(e) {
// Handling also the load event allows navigation directly to http://host/path/to/file#modal and bookmarking it
if (document.location.hash == "#modal") {
$("#sampleModal").foundation("reveal","open");
}
else {
$("#sampleModal").foundation("reveal","close");
}
});
I've been messing with the history api/History.js in combination with session storage to maintain modal state, and open/close based upon user navigation. I've finally achieved about 90% of my goal, but history is implemented very poorly in Safari and iOS Safari so remove the features for these browsers.
Some of the problems you may be running into with the hash approach is that when you use the # with pushstate it actually doesn't push a new object into the history state. It sometimes seems to push history onto the stack and you could use history.back() to fire a popstate, but if you were to say refresh the page with your hashurl and do some sort of check for hash on page initiation, there doesn't seem to be a new history pushed onto the stack, and therefore on backwards navigation the user will leave the site rather than closing the modal.
Here is my implementation working for all browsers except for where it falls back to normal behavior is Safari:
http://dtothefp.github.io/hosted_modal_history_sample/
https://github.com/dtothefp/html5history_express_modal_toggle
Like I said I use History.js in combination with sessionstorage because annoyingly enough, in the popstate for closing the modal the history object is removed, which is exactly when I would need it. In all a very poorly implemented API.
I don't change the URL because this project does not have a backend, so if I change the URL with no hash, on page refresh the page would not be found. An alternate implementation would be a query string, which will properly update history when used in the pushstate, but ends up being bad UX because if the user closes the modal not using the backwards navigation (i.e. hitting the cancel button or clicking off), removing the query string would result in a page refresh.
I have a "Product Page",Product page maps to "ProductPage" Sitecore item. Website/Pages/ProductPage.
I have a text area in that page with page editor, which loads text from "Product Example Text" Sitecore item's "Description" text from Web database. (Sitecore.../CommonText/Product Example Text)
In my ascx file, mark up is pretty straigh forwad,
<sc:FieldRenderer ID="FieldRenderer1" runat="server" />
Codebehind,
FieldRenderer1.Item = //"Product Example Text" Sitecore item
FieldRenderer1.FieldName = "Description";
When I open the page in Page Editor(as a system admin), it allows me to change the "Product Example Text", and when I save using the "Save" button on the Page Editor it get saved to the master database. "Product Example Text" item get saved.
Now, when I try to publish the item using the "Publish" item in the Page Editor ribbon, these changes do not get reflected,reason is "Product Example Text" item does not get published.
When I save the page, somehow Sitecore understands the "Product Example Text" item has to be saved. But why does not it get published?
Am I doing anything wrong.... How can I solve this issue?
While saving an item in Page Editor, Sitecore saves all the field renderers which are displayed on the page, so if you set the Item property of a FieldRenderer1 to "Product Example Test" Sitecore Item, Page Editor know which item should be saved.
The problem with publishing is that you enqueue the current item in the publishing queue, but this item has no link to the "Product Example Test" Sitecore Item in any of its properties cause you're setting the Item property of the field renderer dynamically in the code.
The option would be to add another button to Page Editor next to Edit Related Item button and create a command that will Publish Related Item. The complete description how to add such a command can be found in the answer Sitecore page editor - how to extend page editor item editing panel
Another approach would be to create the "Product Example Test" content item under the "ProductPage" as a sub item. In publish options you can use publish sub items, which will publish all content you want.
But the problem is, if you want a particular content to be shared in several places, this won't work.
Maras's answer is a better solution.
I have a view that can take several seconds to process a GET request and render the results. I'd like to put up a temporary page that says "Processing..." while the view is doing its stuff. How can I do this?
UPDATE
I don't have any control over the link to my page. It is a link to me a third party has on their page. When they click it I run some stuff and display the results. I don't want them to have to click anything on the pages I display.
Ideally, I would like the following:
A user clicks a link to my website that is on a 3rd party website
My websites displays a "processing request" message - the user doesn't have to click anything, just wait.
After a few seconds the results are displayed.
All the user had to do was click a link once and wait for the results.
Some example code would be greatly appreciated as I am quite new to things like jQuery - if that's what I need.
Use jQuery to display the message while waiting for the view to return the result.
Place a hidden div-tag in the page containing the processing message/image.
If you submit the GET request by clicking a button you put an onclick event on the button to display the div-tag. When the view is done processing, the page will be reloaded and the target page will be displayed.
If the view is called using AJAX you can place the show/hide of the div in the ajaxStart and ajaxComplete events.
EDIT: OK since the page will be called from by a 3rd party it will complicate things a bit. I would suggest that you load the page without the data and once the page is loaded you do an AJAX GET request to retrieve the data.
You could do as follows:
Add a hidden div-tag to the page with the Progress message/image.
<div id="progress">Please wait while the page is loading.</div>
Then add the ajax GET call to the page:
$(document).ready(function () {
//Attach the ajaxStart and ajaxComplete event to the div
$('#progress').ajaxStart(function() {
$(this).show();
});
$('#progress').ajaxComplete(function() {
$(this).hide();
});
//Perform the AJAX get
$.get('/your_view/', function(data) {
//Do whatever you want with the data here
});
});
The above code has not been tested but it will give you an idea.
UPDATE
I would suggest that you return a JSON object or similar from your view:
companies = Company.objects.filter(name__istartswith=companyname)
results = [{'value': company.name, 'id':company.id} for company in companies ]
json = simplejson.dumps(results)
return HttpResponse(json, mimetype='application/json')
You can also use the getJSON() method instead of get() in jQuery.
very simple example:
<script>
showProcessingMessage = function() {
$("body").append('<div id="style_me_as_message">processing request</div>');
}
$("body").on('click', "a.slow", showProcessingMessage);
</script>
<a class="slow" href="/slow-response-page/">show slow page</a>