I'm writing an extension to the "Save" Command, where basically I want to validate certain fields and present a popup allowing the editor to select a given keyword or other values based on current date, a Release # and some other attributes.
I thought I was doing good progress until I finally figured out that $display.getItem()
is returning the item as is stored in CM, not the current values that the editor may have changed.
Is there a built-in method to get me this information? Or do I need to parse the DOM to figure it out?
This is the code I currently have
var item = $display.getItem();
if (item.getItemType() == "tcm:16") {
if (item.getSchema().getStaticTitle() == "Test Schema") {
var content = $xml.getNewXmlDocument(item.getContent());
var fieldXml = $xml.getInnerText(content, "//*[local-name()='NewField']");
alert(fieldXml);
}
}
It is working - I get the value of "NewField" - but this is the value the item had when it was loaded, not the current value.
Interestingly, item.getTitle()
shows the current value of the Title field, so I hope there may be a way to achieve this for custom fields too.
I don't know if this is the proper way to do it, but you could fire the "collectdata" event on the item - which will update it's data with what has been entered on the editing screen so far.
var item = $display.getView().getItem();
item.fireEvent("collectdata");
$log.message(item.getXml());
Peter's approach copies the values from the controls in the HTML into the item's XML. This is a great approach if you don't mind the item being updated, since it allows you to simply manipulate the XML instead of the HTML.
But if you don't want the item to be updated yet, you have no choice but to find the correct control(s) in the HTML and read the value from there.
I wrote up this little helper function for it:
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);
}
}
With this function in place you can simply look up the control for a field given its name. When you have the control you can get the values from it easily.
var fieldControl = getControlForFieldName('Body');
if (fieldControl)
{
var values = fieldControl.getValues();
// values is an array, since it caters for multi-value fields
// if this is a single-value field, get the value from values[0]
}
Note that my approach requires way more code than Peter's and touches quite a few non-public APIs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With