Anguilla - Updating a field's value from a popup? - tridion

I have a modal popup that appears whenever an editor tries to save a component with some values (a date field in the past in this case).
In this popup I show the editor a few options (very similar to the default "Open Shared Item" dialog) and an OK/Cancel button combo. On Cancel I fire the "cancel" event and the editor goes back to the editing screen, all good here. On "OK" I want to change the value of the field to match whatever the editor selected, then save.
I tried to use an approach with FieldBuilder and the sample Boris mentioned on this other topic but I can't get to the field from my popup dialog.
Any suggestions on how I can go and modify the xml of the item (could be also a page) from a modal popup?
EDIT: Code used in getControlForFieldName
function getControlForFieldName(name) {
var fieldBuilder = $display.getView().properties.controls.fieldBuilder;
var fieldsContainer = fieldBuilder.properties.input;
var fieldsNode = fieldsContainer.getElement();
var fieldContainer = $dom.getFirstElementChild(fieldsNode);
while (fieldContainer) {
var labelNode = $dom.getFirstElementChild(fieldContainer);
var fieldNode = $dom.getNextElementSibling(labelNode);
var control = fieldNode.control;
if (control.getFieldName() == name) {
return control;
}
fieldContainer = $dom.getNextElementSibling(fieldContainer);
}
}
EDIT #2
After Frank's advice, and some help from Jaime & Frank offline, I got it to work as follows:
The popup is called from a Command Extension (Save & Close in my case)
The command.js specifies an event handler that gets called on "submit" (== OK was pressed)
$evt.addEventHandler(p.dialogPopup, "submit",
this.getDelegate(this._onPopupSubmit));
In my popup I am passing the selected item (it's a keyword ID) to the event handler:
this.fireEvent("submit", { id: select.options[select.selectedIndex].value });
and now back in the event handler _onPopupSubmit(e) I just read e.data.id, load this keyword, get properties like ID & Title, and update the metadata of the item using item.setMetadata("new metadata with updated values").
Simple :)

Your code runs in a popup, so any references you make to global variables will be taken from the popup window.
So when you get the fieldBuilder:
var fieldBuilder = $display.getView().properties.controls.fieldBuilder;
$display is a reference to a global variable. So this actually looks for the FieldBuilder in the popup window (which doesn't have one).
To get the FieldBuilder of the Component window, you can get it from the opener:
var fieldBuilder = opener.$display.getView().properties.controls.fieldBuilder;
You might want to consider actually passing the updated value to either a callback function or with a (custom) event though, since that makes your popup less dependent on opener. trick.

Related

How to attach a callback to a custom confirmation dialog in Google App Maker?

I am creating a custom confirmation dialog in Google App Maker and would like the Confirm button to call a passed-in function. I don't see an "onclick" event in the button widget. Any suggestions on how to do this?
function confirmationDialog(msg, confirmFunction)
{
var desc = app.pageFragments.ConfirmationDialog.descendants;
var label = desc.Label;
var confirmButton = desc.Confirm;
label.text = msg;
confirmButton.onClick = confirmFunction; // does not work
app.showDialog(app.pageFragments.ConfirmationDialog);
}
Thanks
It'd be great if this was a bit easier, but the best bet is to use Custom Properties (https://developers.google.com/appmaker/ui/viewfragments).
You can set up a custom property of type "Dynamic" and call it anything, take "onConfirmCallback", for example. Then you can set the function on that custom property:
Code to invoke dialog:
app.pageFragments.ConfirmationDialog.properties.onConfirmCallback = function(param) {
alert(param);
};
app.showDialog(app.pageFragments.ConfirmationDialog);
And then in the onClick for the close button:
app.pageFragments.ConfirmationDialog.properties.onConfirmCallback("hi");
app.closeDialog();
Also note that there are slightly better ways to set up labels than in your example, also using custom properties.
Create custom properties for any widget properties you want to customize, and then bind those custom properties (#properties.propertyName) to the widget property. For example you might have a confirmText property, with the confirm buttons text property boudn to #properties.confirmText.
Then when you invoke your dialog, you can just set those custom properties. Quick modification of your example code using properties for everything:
function confirmationDialog(msg, confirmFunction)
{
var properties = app.pageFragments.ConfirmationDialog.properties;
properties.text = msg;
properties.confirmCallback = confirmFunction;
app.showDialog(app.pageFragments.ConfirmationDialog);
}
For my confirmation dialogs, I just set the onclick of the OK button before I show the dialog (everything is in one place, which is easier for the dummy (me) who will have to maintain it in six months:
var dialog=app.pages.ConfirmationDialog;
dialog.descendants.message.text='Are you sure...?'
dialog.descendants.btnOk.getElement().onclick=function(){
//do something here
app.closeDialog();
});
};
app.showDialog(dialog);
}

jQuery UI dialog increasingly calling the submit callback

I took the JQuery UI dialog form sample from JQuery UI website.
Since I wanted that, once the dialog is opened and the form is displayed, that pressing the key submits the form, I added the following in the onReady() :
$.extend($.ui.dialog.prototype.options, {
open: function() {
var $this = $(this);
// focus first button and bind enter to it
$this.parent().find('.ui-dialog-buttonpane button:first').focus();
$this.keypress(function(e) {
if( e.keyCode == 13 ) {
$this.parent().find('.ui-dialog-buttonpane button:first').click();
return false;
}
});
}
});
This does perfectly the trick (I mean the click() is triggered when it has to), but the following occurs :
When the form is first submited through a press on the key, the submission is performed once.
If I reopen the dialog, and submit it again with a press on the key, the form is submitted twice.
If I reopen the dialog, and submit it again with a press on the key, the form is submitted three times, and so on...
This can be tested with the following fiddle :
http://jsfiddle.net/fWW2E/
Let me add that doing so by clicking on the dedicated "Submit" button works properly, this fails only when pressing the key is involved.
Any ideas ?
Thank you !
Because since you're assigning this on "open" and your buttons are "closing" the dialog.
When this gets called though:
$('something').dialog('close');
doesn't actually remove the element, it just hides it. So the next time you click to open up a "new" dialog, you're really just showing the first one again. However the "open" event is getting fired again every time it's opened, which is adding a new keypress handler onto it.
Here's the fiddle. I actually write out to the console an array of the current handlers on that element. You'll see everytime you open the dialog that there is another keypress handler.
DEMO

ASP GridView to be updated automatically when ModalDialog is closed

I have a gridView with search and filtering options, it is listing document from SharePoint Library, when i click on the Document name i added a Modal popup to display Documents properties page, if i update Document's title for example and select save, the item is updated but the gridview is still showing the old title, i need to press Search again in order to refresh the values.
the code i use for model popup is:
<script type="text/javascript">
function openModal(url) {
var options = SP.UI.$create_DialogOptions();
options.url = url;
options.dialogReturnValueCallback = Function.createDelegate(null, CloseCallback);
SP.UI.ModalDialog.showModalDialog(options);
}
// Dialog callback
function CloseCallback(result, target) {
if (result === SP.UI.DialogResult.OK) {
SP.UI.ModalDialog.RefreshPage(SP.UI.DialogResult.OK);
}
}
</script>
what should i do to refresh and bid gridview data when the popup is closed?
on the click of save button, make a serverside call to rebind the gridview. i.e
$(document).ready(function(){
$('id_of_save_button').click(function(){
//ajax call of serverside method to rebind the grid.
});
});
However with asp.net these things become little easy if you use modalPopupExtender that ships with asp.net
Hi for handling sharepoint save event using javascript u can use this function
function PreSaveAction()
{
// write your gride view data bind code
}

Jquery toggle should expand after Page reload

I wrote below code for Collapse/Expand some section. It is working fine. Finally If I click "Save" button and I am re-loading page again in asp.net. So then sections are going default Colleapse again. I need them back to expand. How can I do that?
$(function() {
$('tr.subCategory')
.css("cursor", "pointer")
.attr("title", "Click to expand/collapse")
.click(function() {
$(this).siblings('.RegText-' + this.id).toggle();
});
$('tr[#class^=RegText-]').hide().children('td');
})
You can save state using:
URL hash: mysite.com#a=1,b=2 ...or however you want to record your state.
Cookies
Window.name
On reload, check for the recorded state, parse it and re-execute it in your code.
Edit:
When you execute something that changes in the UI you need to record this action somewhere (i.e. Panel A is open), in some sort of code. It could be name, value pairs (ID,STATE|ID,STATE..etc) in a string or whatever you choose. You then need to program a mechanism that takes this "saved state" information and re-initializes the UI back to where it was.
Once you've accomplished a way to represent and re-initialize the state, you have to consider how you'll save and retrieve it.
You can save it is a cookie, if it's not too big. When the page loads, check for the cookie and parse the data and run your re-initialization routine to restore the UI.
Another persistent place to stash data is in window.name, which can hold a string of up to 2mb. Same deal as a cookie.
The third method is to store the state information in the URL: document.location = document.location + "#" + stateData. You can then parse what's in the URL to grab your state data.
The "url/hash" method is becoming the preferred technique as it allows bookmarking and is a new specification to allow search-bots to read ajax-based sites easily.
See: http://code.google.com/intl/sv-SE/web/ajaxcrawling/docs/specification.html
If you are using update panels you can make us of the fact that jQuery's $(document).ready is called only on the initial load and ASP.NET AJAX's pageLoad() is called for every postback. You could collapse your section in $(document).ready so it's initially hidden and then assign the click handler in pageLoad() so users can still collapse it again if they need to after the save.
$(document).ready(function() {{
$('tr[#class^=RegText-]').hide().children('td');
}});
function pageLoad() {
$('tr.subCategory').click(function() {
$(this).siblings('.RegText-' + this.id).toggle();
});
}
you could use an hidden div field, and modify your js to set the hidden text to the id of the expanded field on click. Your function could check the value of the hidden text and show the field that matches the hidden text id.
in your page:
<div class="hidden" style="display:none;" />
in your .js
$(function() {
$('tr.subCategory')
.css("cursor", "pointer")
.attr("title", "Click to expand/collapse")
.click(function() {
$(this).siblings('.RegText-' + this.id).toggle();
$('.hidden').text(this.id); // set the hidden field to the id shown
});
$('tr[#class^=RegText-]').hide().children('td');
$('#' + $('.hidden').text() + ''').show(); // show the id set in hidden field
})

Jquery code on load not firing

I have the following JQuery code in a external JS file linked into a
usercontrol in .Net 1.1 webapp.
The usercontrol is a timesheet.
When the page loads it calls MonthChange and works fine in one page.
But now I want to load the timesheet/usercontrol into aother
webpage that pops up a in a new browser window for printing.
Problem is my MonthChange is not firing.
Any ideas why???
$(function() {
MonthChange();
//TestData();
$('[class^=TSGridTB]').blur(function() {
var day = GetDay($(this).attr('id'));
var date = GetRowDate(day);
var bgcolor = GetInputFieldColor(date, false);
$(this).css("background-color", bgcolor);
$(this).parent().css("background-color", bgcolor);
//CalcHours($(this).get(0));
});
$('[class^=TSGridTB]').focus(function() {
var day = GetDay($(this).attr('id'));
var date = GetRowDate(day);
var bgcolor = GetInputFieldColor(date, true);
$(this).css("background-color", bgcolor);
$(this).parent().css("background-color", bgcolor);
});
$('[id$=lstMonth]').change(function() {
MonthChange();
});
});
without seeing further code, ensure that the selector is correct for the control in the new page.
The problem may be that the DOM has changed for the new page/window and JQuery does not yet know about it.
The change event
fires when a control loses the input
focus and its value has been modified
since gaining focus.
You might want to use the live event:
Binds a handler to an event (like
click) for all current - and future -
matched element.
When you bind a "live" event it will
bind to all current and future
elements on the page (using event
delegation). For example if you bound
a live click to all "li" elements on
the page then added another li at a
later time - that click event would
continue to work for the new element
(this is not the case with bind which
must be re-bound on all new elements).
Did you make sure that the new web page has jQuery script includes?
ensure you're using:
$(document).ready(
);
around your entire code block. The $ alone often does not do the trick.

Resources