Extend Sitecore insert link functionality - javascript

I have an issue which I don't quite know how to approach.
I need to extend the Sitecore Insert link functionality: when I insert a link to a Sitecore Item, a certain icon, based on some logic (I've already created the logic for another user story(*)), needs to appear in the front of the link after "Insert" button is pressed, and of course, finally on the UI.
I was thinking on the following approach: after the item is inserted, the item's ID is sent to the backend via an Ajax call and the response is a mark-up with the values returned by the service I told you above at (*).
The issue is that I don't know where to start on or if my idea is ok.
Any help is welcome.

I found the answer:
In the RichText Commands.js file, I have added the following script which sends the item Sitecore ID to the API:
function scInsertSitecoreLink(sender, returnValue) {
if (!returnValue) {
return;
}
var url = returnValue.url;
var itemId = url.substring(url.indexOf("=") + 1, url.lastIndexOf("&"));
var $ = jQuery.noConflict();
$.ajax({
async: true,
type: "GET",
url: '/sitecore/api/Test/ThisIsTheTestApiCall',
data: JSON.stringify(itemId),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
alert(result);
}
});
[...]
}
First I have added var $ = jQuery.noConflict(); before the ajax call;
More info here: https://api.jquery.com/jquery.noconflict/
Then I've checked if there are any changes over the routes: RegisterHttpRoutes;
Profit.

You might be better to modify the renderField pipeline, because if you ever need to change these icons later, you're going to have to process every single link on your site.
To do that, you'll want to create a processor and have it run before Sitecore.Pipelines.RenderField.ExpandLinks, Sitecore.Kernel in the renderField pipeline so that you can use the dynamic links (which contain IDs) to figure out what icons you need. From there you can use HtmlAgilityPack.HtmlDocument to find and update the markup when the link is rendered.

Related

Ajax call function for each tab

I created responsive tabs just using css. But when I try to implement ajax calls, i am bit confused.
I have a few questions:
What is the best way to make ajax request for each tab?
Is there any shortest way to append response to "tab" div?
How can I call ajax on page load for selected tab?
After first click on tab, do not need to make ajax call again. I need to cache response, but "cache:true" does not work.
Also any other improvements, suggestions and corrections would be helpful.
Example: JSFiddle
if you must use ajax i would run a loop through all the data you need to load do it at once an store the data in a variable (or object in this case)
than the change event will get the id from the tabData which is already populated and you won't need to call the ajax pages again.
now this will solve your cache problem since you won't need it for this scenario
if you want to instant populate the first selected tab when you open the page created an if statement in the ajax success
end result would look something along these lines:
$(document).ready(function() {
//data for the tabs
var tabs = {
1:"tabone",
2:"tabtwo",
3:"tabthree"
}
//empty object for now will be filled with ajax data
var tabData = {};
var activeTabVal=1;
var activeTabID = $('input[name=tabs]:checked', ".tabs").attr('id');
for(key in tabs) {
ajaxCall(key);
}
$('.tabs input').on('change', function() {
var activeTab=$('input[type="radio"]:checked', '.tabs').val();
var tabElement = $('input[name=tabs]:checked', ".tabs").attr('id');
//since we have the data already no need to call ajax here we just get it out of our already loaded data
var data = tabData[activeTab];
replaceData(tabElement, data);
});
function ajaxCall(key){
$.ajax({
type: "POST",
dataType: 'jsonp',
url: 'https://jsonplaceholder.typicode.com/posts/'+key,
async: false,
cache: true,
contentType: "application/json; charset=utf-8",
success: function (msg) {
tabData[key] = msg.body;
//use this to imediatly populate the selected div fo your second point
if(key == activeTabVal) {
replaceData(tabs[key], tabData[key]);
}
}
});
}
function replaceData(tabElement, tabData) {
$('#'+tabElement).next().next().closest('div').append(tabData);
}
});
I would instead of calling it on change I would call it on tab button clicked
Give your tab a data-id and the corresponding container div the same data-id, then when you append you can do something like $('.tab-container[data-id='+$(this).attr('data-id')+']').append('The content');
If you bind it to click you can simply run $('.tab-button .active').trigger('click');
If I were you I would store the data into the data portion of the container div and retrieve it again when they click on it again. So you just check if it was set, if not then do ajax call, if it was just pluck it out and display it. https://api.jquery.com/jquery.data/

Using JSON to store multiple form entries

I'm trying to create a note taking web app that will simply store notes client side using HTML5 local storage. I think JSON is the way to do it but unsure how to go about it.
I have a simple form set up with a Title and textarea. Is there a way I can submit the form and store the details entered with several "notes" then list them back?
I'm new to Javascript and JSON so any help would be appreciated.
there are many ways to use json.
1> u can create a funciton on HTML page and call ajax & post data.
here you have to use $("#txtboxid").val(). get value and post it.
2> use knock out js to bind two way.and call ajax.
here is simple code to call web app. using ajax call.
var params = { "clientID": $("#txtboxid") };
$.ajax({
type: "POST",
url: "http:localhost/Services/LogisticsAppSuite.svc/Json/GetAllLevelSubClients",
contentType: 'application/json',
data: JSON.stringify(params),
dataType: 'json',
async: false,
cache: false,
success: function (response) {
},
error: function (ErrorResponse) {
}
I have written a lib that works just like entity framework. I WILL put it here later, you can follow me there or contact me to get the source code now. Then you can write js code like:
var DemoDbContext = function(){ // define your db
nova.data.DbContext.call(this);
this.notes=new nova.data.Repository(...); // define your table
}
//todo: make DemoDbContext implement nova.data.DbContext
var Notes = function(){
this.id=0; this.name="";
}
//todo: make Note implement nova.data.Entity
How to query data?
var notes = new DemoDbContext().notes.toArray(function(data){});
How to add a note to db?
var db = new DemoDbContext();
db.notes.add(new Note(...));
db.saveChanges(callback);
Depending on the complexity of the information you want to store you may not need JSON.
You can use the setItem() method of localStorage in HTML5 to save a key/value pair on the client-side. You can only store string values with this method but if your notes don't have too complicated a structure, this would probably be the easiest way. Assuming this was some HTML you were using:
<input type="text" id="title"></input>
<textarea id="notes"></textarea>
You could use this simple Javascript code to store the information:
// on trigger (e.g. clicking a save button, or pressing a key)
localStorage.setItem('title', document.getElementById('title').value);
localStorage.setItem('textarea', document.getElementById('notes').value);
You would use localStorage.getItem() to retrieve the values.
Here is a simple JSFiddle I created to show you how the methods work (though not using the exact same code as above; this one relies on a keyup event).
The only reason you might want to use JSON, that I can see, is if you needed a structure with depth to your notes. For example you might want to attach notes with information like the date they were written and put them in a structure like this:
{
'title': {
'text':
'date':
}
'notes': {
'text':
'date':
}
}
That would be JSON. But bear in mind that the localStorage.setItem() method only accepts string values, you would need to turn the object into a string to do that and then convert it back when retrieving it with localStorage.getItem(). The methods JSON.stringify will do the object-to-string transformation and JSON.parse will do the reverse. But as I say this conversion means extra code and is only really worth it if your notes need to be that complicated.

How do I get the counter of a google plus +1 button?

I have added a google +1 button to a website, but I want to get it's counter so i can do some math over it. is it possible to enter the iframe created by the standard method of creating the +1 button or do I need to make some adjustment?
<script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script>
<g:plusone></g:plusone>
I've tried this link:1 , but this is not very accurate
If you can access curl/file_get_contents/readfile/wget or some way to fetch an external URL, this is quite simple.
Load the following URL: https://plusone.google.com/_/+1/fastbutton?url=URLENCODED_URI (UPDATED URL, see note below *)
URLENCODED_URI is the site you wish to know the number of +1's for, e.g. http://www.google.com (http%3A%2F%2Fwww.google.com)
For example, fetch the URI https://plusone.google.com/_/+1/fastbutton?url=http://www.google.com/ (UPDATED URI) and locate the first occurance of window.__SSR = {'c': 32414.0 ,'si'. Preferably use regexp for this, but I'll leave the implementation to you and your chosen programming language (server side or client side).
The float number following 'c' is the number of +1's the site have. For google.com this is 32,414. Don't worry about the float, you can safely convert it to an integer.
* UPDATE: The URL has been updated as the old URL started to 404. Remember, this is expected as this is an unofficial method. There exist no official method (yet).
Could you use a callback function to grab the value of the div that displays the count?
function count() {
var count = $('#aggregateCount').html();
}
<g:plusone callback="count()"></g:plusone>
I'm basing this off the bubble annotation button, I haven't tested it but something like this should work.
A pure client-side solution that works for me to get the Google Plus counter is as follows. It does not need an API key.
var url = "http://www.yoursite-to-be-counted.com";
var data = {
"method":"pos.plusones.get",
"id": url,
"params":{
"nolog":true,
"id": url,
"source":"widget",
"userId":"#viewer",
"groupId":"#self"
},
"jsonrpc":"2.0",
"key":"p",
"apiVersion":"v1"
};
$.ajax({
type: "POST",
url: "https://clients6.google.com/rpc",
processData: true,
contentType: 'application/json',
data: JSON.stringify(data),
success: function(r){
setCount($(".google-plus-count"), r.result.metadata.globalCounts.count);
}
});
var setCount = function($item, count) {
if (count) {
$item.text(count);
}
};
Then I have some html with
<div class="google-plus-count"></div>
Credits here goes to this answer.

Fire asp.net (link button or Button) click event using Jquery

I need to fire asp.net (link button or Button) click event(server side code) using Jquery, the buttons are in an update panel. Kindly help.
Michael's solution is good.
But I think it is safer to call GetPostBackEventReference.
The internal structure of ASP.NET Page may be changed in the future.
Here's the sample Code.
<%= Page.ClientScript.GetPostBackEventReference(lnkButton, "") %>
How about:
__doPostBack("<%= lnkMyButton.UniqueID %>", "");
What you need to do is to define your server side code as [WebMethod] once you do that your classname will be available to client side code for calling.
Then you would go about calling that method using something like this:
jQuery.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: '{}',
dataType: 'json',
url: 'MyPage.aspx/SomePageMethod',
success: function(result){
alert(result);
}
});
I am more of a C# person, but I would imagine if you read this page you are easily able to make it in VB: http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/
Below is how I triggered a click event with a LinkButton within an Update Panel. I couldn't get the ID until run time due to the way I was creating buttons, that is, it kept appending a _0, _1, etc to the end of the button name. For example on the server I would create 2 buttons with ID's say of 111555 & 222666. It would rename the buttons with ID's like:
contentMain_gridviewMessages_111555_0
contentMain_gridviewMessages_222666_1
So the first thing I did was create a unique attribute I could search upon, in my case the message id:
var msgLink = ('a[messageId="' + messageId + '"]');
After that I used a little bit of jQuery to get the auto generated ID:
var id = $(msgLink).attr("ID");
When I got the ID good ole fashion javascript did the rest:
document.getElementById(id).click();
Hope this helps someone out.

how to use JSON for an error class

Hey all. I was fortunate enough to have Paolo help me with a piece of jquery code that would show the end user an error message if data was saved or not saved to a database. I am looking at the code and my imagination is running wild because I am wondering if I could use just that one piece of code and import the selector type into it and then include that whole json script into my document. This would save me from having to include the json script into 10 different documents. Hope I'm making sense here.
$('#add_customer_form').submit(function() { // handle form submit
The "add_customer_form" id is what I would like to change on a per page basis. If I could successfully do this, then I could make a class of some sort that would just use the rest of this json script and include it where I needed it. I'm sure someone has already thought of this so I was wondering if someone could give me some pointers.
Thanks!
Well, I hit a wall so to speak. The code below is the code that is already in my form. It is using a datastring datatype but I need json. What should I do? I want to replace the stupid alert box with the nice 100% wide green div where my server says all is ok.
$.ajax({
type: "POST",
url: "body.php?action=admCustomer",
data: dataString,
success: function(){
$('#contact input[type=text]').val('');
alert( "Success! Data Saved");
}
});
Here is the code I used in the last question, minus the comments:
$(function() {
$('#add_customer_form').submit(function() {
var data = $(this).serialize();
var url = $(this).attr('action');
var method = $(this).attr('method');
$.ajax({
url: url,
type: method,
data: data,
dataType: 'json',
success: function(data) {
var $div = $('<div>').attr('id', 'message').html(data.message);
if(data.success == 0) {
$div.addClass('error');
} else {
$div.addClass('success');
}
$('body').append($div);
}
});
return false;
});
});
If I am right, what you are essentially asking is how you can make this piece of code work for multiple forms without having to edit the selector. This is very easy. As long as you have the above code included in every page with a form, you can change the $('#add_customer_form') part to something like $('form.json_response'). With this selector we are basically telling jQuery "any form with a class of json_response should be handled through this submit function" - The specific class I'm using is not relevant here, the point is you use a class and give it to all the forms that should have the functionality. Remember, jQuery works on sets of objects. The way I originally had it the set happened to be 1 element, but every jQuery function is meant to act upon as many elements as it matches. This way, whenever you create a form you want to handle through AJAX (and you know the server will return a JSON response with a success indicator), you can simply add whatever class you choose and the jQuery code will take over and handle it for you.
There is also a cleaner plugin that sort of does this, but the above is fine too.
Based on your question, I think what you want is a jQuery selector that will select the right form on each of your pages. If you gave them all a consistent class you could use the same code on each page:
HTML
<form id="some_form_name" class="AJAX_form"> ... </form>
Selector:
$('form.AJAX_form")

Categories