How to edit list item on another page - javascript

The Situation
In Sharepoint 2010 I can click on an item in a list:
And then the Read/Edit view becomes visible in that page:
My Goal
I have a WebPart on another Page where I show some items coming from this and several other lists and I want to add a read or edit link to each of them.
How can I do that?
I'm searching for a function like EditListItem('ItemId', 'ListId', ...) which will open the edit div window.
What have I tried
The a tag generated by Sharepoint on "Test Item" above is like this:
<a onfocus="OnLink(this)"
href="http://{mysharepointsite}/_layouts/listform.aspx
?PageType=4
&ListId={D0FDB54F-1DDF-4C5E-865B-ABDE55C1125}
&ID=1
&ContentTypeID=0x010800ED5176D13CCEFC4AA8D62A79985DE892"
onclick="EditLink2(this,49);return false;" target="_self">Test Item</a>
So I digged a bit into the Sharepoint JS files and found EditLink2 calling _EditLink2 which calls ShowPopup from the context (the 49) is the context no and seems to be dynamic.
I tried to fake the context but there are billions of variables and I think I can't get that to work stable.

On that page where you need to open dialog just write simple JS function for showing modal dialog, for example:
function openMyItemDialog( itemId ) {
var options = {
url: "http://{mysharepointsite}/_layouts/listform.aspx?PageType=4&ListId={D0FDB54F-1DDF-4C5E-865B-ABDE55C1125}&ID=" + itemId + "&ContentTypeID=0x010800ED5176D13CCEFC4AA8D62A79985DE892&IsDlg=1",
width: 500,
height: 500,
title: "Item view/edit"
};
SP.UI.ModalDialog.showModalDialog( options );
}
Note the &IsDlg=1 param at url
And then modify href link where you display your items.
For example:
Test item
Replace 35 to ID of your item

I know this is an old question, but there's another way to achieve what the OP was trying to do.
In a XSLT ViewWebPart, there is a global parameter named $ViewCounter.
This is the context number required by the _EditLink2 function.
So, in order to add a link to the display form and have it opened in a dialog, wrap the item in an <a> tag like this:
your item
Notice the variables $HttpVDir, $List, $thisNode/#ID and $ViewCounter (no need to hard-code any value).

Related

Options to make jQuery Ajax code more efficient / logical

I have the following HTML to display content pulled from an ajax script (ajax.php):
HTML
<ul class="list-unstyled" id="var_adjectives"><li><a href='#'>Loading...</a></li></ul>
<button id="37" onclick='update_adjectives();'>Refresh</button>
<hr />
<ul class="list-unstyled" id="var_brands"><li><a href='#'>Loading...</a></li></ul>
<button id="37" onclick='update_brands();'>Refresh</button>
<hr />
<ul class="list-unstyled" id="var_clothes"><li><a href='#'>Loading...</a></li></ul>
<button id="37" onclick='update_clothes();'>Refresh</button>
<hr />
When the page first loads, the following JS is used to populate the list items against the relevant <ul> tag (passing in two parameters each time):
Javascript Page Load
$(document).ready(function(){
$.post('ajax.php',{u:37,n:1} ,function(data){ var this_record = data.output; $('#var_adjectives').html(this_record);},'json');
$.post('ajax.php',{u:37,n:33},function(data){ var this_record = data.output; $('#var_brands').html(this_record);},'json');
$.post('ajax.php',{u:37,n:67},function(data){ var this_record = data.output; $('#var_clothes').html(this_record);},'json');
});
The refresh button can be used to refresh the content in the relevant <ul> tag, calling the following relevant JS function, from the onclick event on each of the 3 buttons:
Javascript Refresh Functions
function update_adjectives() {
$.post('ajax.php'
, {u:37,n:1}
, function(data){ var this_record = data.output; $('#var_adjectives').html(this_record); }
, 'json')
};
function update_brands() {
$.post('ajax.php'
, {u:37,n:33}
, function(data){ var this_record = data.output; $('#var_brands').html(this_record); }
, 'json')
};
function update_clothes() {
$.post('ajax.php'
, {u:37,n:67}
, function(data){ var this_record = data.output; $('#var_clothes').html(this_record); }
, 'json')
};
As you can see, there is a lot of overlap in the basic design of the JS.
I have these questions:
I am stuck working out how I can end up with one single line in the block of JS used to populate content when the page first loads.
I'd like to only have 1 function used to refresh content - because in my example above I have 3 blocks, but in my real page I have about 30 blocks.
While the JS is created by the PHP code when the page loads (rather than me writing it long-hand), it still would be nice to have much cleaner code which avoids having e.g. 30 refresh functions and 30 lines of code to populate each of the different <ul> IDs when first loading the page.
In each case, I can see I would need to pass an ID of relevant <ul> but I am tied up in knots working out if I can achieve what I'm trying to do.
Probably there are many things wrong with using the onclick event too!
Any advice would be much appreciated, thank you.
The most likely blocker is your API endpoint design. According to what you posted, you must access one category at a time and that must be done by sending the {u:N,n:N} combo object as the body of the POST request.
It would simplify things greatly if your endpoint accepted a different object. Something like {category:'name'} would allow greater flexibility.
You could use {category: 'all'} for the initial view of all categories and use {category: 'clothes'} for individual categories for the update/refresh.
Extending that to the click of the refresh buttons. You can use a single event handler and event bubbling to deal with every button click.
First you would add the event handler to containing element for all the <ul> elements.
Given this layout:
<div id='container'>
<ul><li><span>loading...</span></li></ul>
<button data-category="adjectives">Refresh</button>
<ul><li><span>loading...</span></li></ul>
<button data-category="brands">Refresh</button>
<ul><li><span>loading...</span></li></ul>
<button data-category="clothes">Refresh</button>
</div>
You can react to all the button clicks like this:
document.getElementById('container').addEventListener('click', update);
The update() event handler can determine which button was clicked by checking out the data- attribute on the button. Then, make the AJAX request and place the data into the correct <ul> by finding the closest or the prev() sibling <ul> element.
function update() {
const category = this.dataset.category;
$.post('ajax.php', {category: category}
, function(data) {
$('button').data(category).prev('ul').html(data.output);
}, 'json')
};

Is there a to change the value of an element using JavaScript

I'm trying to change the value of an element on a third-party web page using a JavaScript Add-on to display a hyperlink
I already have the link on the page i would like to be able to click it
I think I'm on the right track using document.getElementById although I'm not sure how to then change the id into a "a href" and then how to pass it back into the value.
Sorry, this is a bit of a tricky situation so I'll try my best to explain it. On a third-party web-page which we use for our HR related tasks, there is a section titled "File Link" although this isn't a link. When you copy and paste the address into a browser it displays the file. What i am trying to do is create a hyperlink on the "File Link" section to remove the need to copy and paste the link. Because this is a third party website. We have access to the JavaScript on the website and need to change the address into a hyperlink. I'm not entirely sure this is possible.The element id is "__C_cb_file_link" and i would like to insert the link address into the element using a variable then add the link parameters into the variable then reinsert it into the element/value.
function linkIt() {
var intoLink = document.getElementById("__C_cb_file_link");
var hLink = "<a href="+intoLink+"</a>;
intoLink.value = hLink;
}
window.onload = linkIt();
<td><div class="sui-disabled" title="">m-files://view/37FF751C-A23F-4233-BD8B-243834E67731/0-46524?object=C46A7624-D24B-45F3-A301-5117EFC1F674</div>
<input type="hidden" name="__C_cb_file_link" id="__C_cb_file_link" value="m-files://view/37FF751C-A23F-4233-BD8B-243834E67731/0-46524?object=C46A7624-D24B-45F3-A301-5117EFC1F674"/></td></tr>
In below code first we read input value with new link (however we can read this value from other html tags), then we remove this element (and button) and add to parent element (of removed input) the new link
function linkIt() {
let intoLink = __C_cb_file_link.value;
let parent = __C_cb_file_link.parentNode;
__C_cb_file_link.remove();
btn.remove();
parent.innerHTML += `${intoLink}`;
}
<input id="__C_cb_file_link" value="https://example.com">
<button id="btn" onclick="linkIt()">Link It</button>
There are a number of issues with your code:
1) The code snippet in your question doesn't run because of a missing " at the end of the second line of the linkIt() function.
2) intoLink is a hidden field so anything you add to it will not be visible in the page
3) Even if point 2 were not true, setting the value of a form field will not cause HTML to appear on the page (at best you might get some plain text in a textbox).
4) "<a href="+intoLink+"</a>" doesn't work because intoLink is a complex object which represents the entire hidden field element (not just its value property). You can't convert a whole object into a string directly. You need to extract the value of the field.
A better way to do this is by creating a new element for the hyperlink and appending it to the page in a suitable place. Also I recommend not adding your event via onload - when written using this syntax only one onload event can exist in a page at once. Since you're amending another page which isn't under your control you don't want to disable any other load events which might be defined. Use addEventListener instead, which allows multiple handlers to be specified for the same event.
Demo:
function linkIt() {
var intoLink = document.getElementById("__C_cb_file_link");
var hLink = document.createElement("a");
hLink.setAttribute("href", intoLink.value);
hLink.innerHTML = "Click here";
intoLink.insertAdjacentElement('beforebegin', hLink);
}
window.addEventListener('load', linkIt);
<td>
<div class="sui-disabled" title="">m-files://view/37FF751C-A23F-4233-BD8B-243834E67731/0-46524?object=C46A7624-D24B-45F3-A301-5117EFC1F674</div>
<input type="hidden" name="__C_cb_file_link" id="__C_cb_file_link" value="m-files://view/37FF751C-A23F-4233-BD8B-243834E67731/0-46524?object=C46A7624-D24B-45F3-A301-5117EFC1F674" /></td>
</tr>
P.S. m-files:// is not a standard protocol in most browsers, unless some kind of extension has been installed, so even when you turn it into a hyperlink it may not work for everyone.
[UPDATE] I supose that your "__C_cb_file_link" was a paragraph so I get the previous text http://mylink.com and create a link with, is it what you want, right?
function linkIt() {
let fileLink = document.getElementById("__C_cb_file_link");
let hLink = fileLink.textContent;
fileLink.innerHTML = ""+hLink+"";
}
linkIt();
<div>
<p id="__C_cb_file_link">http://myLink.com</p>
</div>

Javascript add ID and hash link to new ID

I "learned" JavaScript a few months ago but quickly picked up Python and spent the past few months writing programs in that language, so I decided it would be a good idea to go back and actually learn JavaScript. Right now I'm making a very simple "blog" with JS that takes the title of the post, generates a hash link from the post, and creates a recent posts section where you can click the link to jump to the post in the page.
For instance, say one of the posts is formatted like this:
<h2 class="post">Another post for you</h2>
<h4>I know you love these</h4>
With multiple posts, and an empty container at the bottom, which will be used to append the recent posts links:
<div id="get-post"></div>
My JS code basically grabs each title with the post class and creates a hash link from the element's title (removing spaces and commas). It then creates and appends a text node consisting of the post title, and then appends the entire link into the get-post container.
var postList = $('#get-post');
var post = $('.post');
function generateRecentPosts() {
post.each(function() {
// Create link from post title that will be used to
// access that post.
var postLink = document.createElement('a');
// Create text node from post title that will be appended
// to the postLink.
var text = document.createTextNode($(this).html());
// Add elements to the DOM.
postLink.href = createLocalLink($(this));
postLink.appendChild(text);
postList.append(postLink);
postList.append('<br />');
});
}
function createLocalLink(elm) {
// Creates the href link that will be used to go to a blog post.
// For example, if the title of the elm parameter is "My Post",
// a link is created called #My-Post that will be used to access
// that post.
elm.id = elm.html().replace(/,/g, '').replace(/\s/g, '-');
console.log(elm.id); // Make sure the ID is added.
return '#' + elm.id;
}
generateRecentPosts();
My problem is that the links it generates to not point to the ID created for each title. When I click on the link, I can see that it successfully created the href hash #My-Post and added it to the anchor tag, but it doesn't take me to the post title.
Example: http://jsfiddle.net/samrap/GQtxL/
I even added a console log function to make sure the ID is being added to the title as I thought that was the problem, but it isn't because the console is printing the correct new ID. I could really use some help in figuring out where exactly the problem is here.
Your h2 tags need to have an id or name attribute that corresponds with the link, that is what makes internal links work. The id is not getting added because you are accessing a jQuery object as if it were a DOM node (elm.id = ...). Modify your createLocalLink function to use jQuery's attr method to set the id property:
elm.attr('id', elm.html().replace(/,/g, '').replace(/\s/g, '-'));
Additionally, since you have jQuery available you could whittle your code down to:
var $this = $(this),
link = createLocalLink($this);
var $postLink = $('a', {
text: $this.text(),
href: link
})
postList.append($postLink).append('<br />');
Here is your fiddle updated: http://jsfiddle.net/GQtxL/1/
This is because your link uses the href = "#My-Post" but none of the posts has the ID "My-Post". It only has a class "post".
This happens because the argument that your are passing to the createLocalLink() function is a DOM Node. But by doing elm.id you are not changing the DOM property but adding another property to the "elm" object. Thus your "elm" object is
x.fn.x.init[1]
0: h2.post
context: h2.post
id: "Another-post-for-you"
length: 1
__proto__: Object[0]
Thus the actual post never gets the attribute ID only "elm" object gets it. Note the empty ID attribute below
draggable: false
firstChild: text
firstElementChild: null
hidden: false
id: ""
innerHTML: "Another post for you"
innerText: "Another post for you"
Thus your document has no element with the ID "My-Post". You can view the source of your HTML to verify this.
For internal links to work there should be an element with the same ID as that used in the href attribute of the link.
For example
<div id="post1">
Your Post Here
</div>
<!--just to show the effect of moving to the post-->
<div style="clear:both; height:900px"></div>
Click Here
This would work because there is an element with the id "post1" and the link uses the href "#post1" which links it to the corresponding element. Hence, add the corresponding id to your post as well (other than your link) for it to work.
In function createLocalLink you are using elm argument as dom node, but actually passing a jQuery wrapped object to it, which don't have id property. To get it work, use elm.get(0).id = ... or elm.attr('id', elm.text().replace(/,/g, '').replace(/\s/g, '-'););

Dynamically change Tweet Button "data-text" contents

This question comes very closely to what I'm after: Replace an Attribute in the Tweet Button with Jquery
However, the suggested solution works just once. That is, I cannot use it in my switch statement like this:
switch(element.id)
{
case "t1":
$(document).ready(function(){
$('a[data-text]').each(function(){
$(this).attr('data-text', Text_Variant_1);
});
$.getScript('http://platform.twitter.com/widgets.js');
});
break;
case "t2":
$(document).ready(function(){
$('a[data-text]').each(function(){
$(this).attr('data-text', Text_Variant_2);
});
$.getScript('http://platform.twitter.com/widgets.js');
});
...
}
What happens is that the data-text attribute is set according to whichever case happens first and doesn't change afterwards.
How can I change data-text attribute of a Tweet Button as many times as I need?
Update: here's the page I'm working on: http://zhilkin.com/socio/en/
The Traits table can be safely ignored. What I want to do with the Sociotypes table is that when you click on a type, the data-text of the Tweet Button below the description on the right should be changed accordingly.
Right now it works like this: if I hover on or click "Don Quixote", then data-text is set to "... Don Quixote ...", and it stays the same if I click "Dumas" later. And vice versa: if I hover on or click "Dumas", then data-text is set to "... Dumas ..." and doesn't change if I click "Don Quixote". (Other types are empty at the moment.)
So, the Tweet Button is only changed the first time I run the script, but I need it to be updated as many times as the type changes.
I struggled with this for a couple of hours this morning, but finally got it working! The problem is essentially that you can only include the twitter widgets.js script once in the page, and that script evaluates the data-text attribute on load. Therefore, in your example, you dynamically set the data-text attribute before loading the script, which will work as expected. However, you can then make no further updates as the script has already run.
I saw this article suggesting you can call twttr.widgets.load() again at runtime to re-evaluate and re-render the buttons, however that didn't work for me. This is because that function re-evaluates <a> tags, not <iframe> tags!
So the solution, as pointed out here, is to completely remove the rendered <iframe> from the DOM, then make a new <a> element with all the appropriate attributes before calling twttr.widgets.load() to finally re-evaluate it and turn it into an <iframe>.
Please see this fiddle for a working example!
You can also use Twitter's createShareButton API call:
function callAsRequired(){
var nodeID = 'YourTwitterNodeID'
//Remove existing share button, if it exists.
var myNode = document.getElementById(nodeID);
while (myNode.firstChild) {
myNode.removeChild(myNode.firstChild);
}
//Create button and customise
twttr.widgets.createShareButton(
'http://your.custom.url.here/',
document.getElementById(nodeID),
{
count: 'none',
text: 'Your custom tweet here'
});
}
since you are using each loop you can use if statements instead:
$(document).ready(function(){
$('a[data-text]').each(function(){
if (theCase == 1) {
$(this).attr('data-text', Text_Variant_1);
}
else if (theCase == 2) { ... }
})
});

How to call Java script method when navigation pane item clicked

I have created one 'sub area' item 'Site Map' of CRM 2011. My requirement is to call .aspx page on click of that item. But I should use javascript to call on click of that item because, I have to pass some query string values along with that URL. I'm using Url="http:////WebResources/SitemapCall.js" attribute in tag. But, how can we call particular 'method' from that JScript file..?
As SubArea is not supporting javascript, we can call html webresource from SubArea tag.
SubArea Id="nav_subArea" Title = "New Sub Area" Url="$webresource:MyPage.htm"/>
And call javascript function on load of html page to call desired URL along with query string.
function onLoadRedirectToURL()
{
var userId = parent.Xrm.Page.context.getUserId();
var baseURL = 'http://www.ServcerName/newPage.aspx';
window.navigate(baseURL + '?userId=' + userId);
}
SubArea is not designed to support javascript. You are able to put your Javascript function into URL of subarea, but you will have difficulties with your page opening. Better way is use Button on Ribbon Bar and it supports Javascript.
<CommandDefinitions>
<CommandDefinition Id="CustomButton">
<EnableRules/>
<DisplayRules/>
<Actions>
<JavaScriptFunction Library=“$webresource:new_CustomAction“ FunctionName=“CustomActionFunction“></JavaScriptFunction>
</Actions>
</CommandDefinition>
</CommandDefinitions>

Categories