Search code examples
javascriptliferayliferay-7

Change liferay-ui:input-localized XML with javascript


I have the following tag in my view.jsp:

<liferay-ui:input-localized id="message" name="message" xml="" />

And I know that I can set a XML and have a default value on my input localized. My problem is that I want to change this attribute with javascript. I am listening for some changes and call the function "update()" to update my information:

function update(index) {
    var localizedInput= document.getElementById('message');
    localizedInput.value = 'myXMLString';
}

Changing the value is only updating the currently selected language input (with the whole XML String). The XML String is correct, but I am not sure on how to update the XML for the input with javascript.

Is this possible?

PS: I have posted this in the Liferay Dev forum to try and reach more people.


Solution

  • After a week of studying the case and some tests, I think that I found a workaround for this. Not sure if this is the correct approach, but it is working for me so I will post my current solution for future reference.

    After inspecting the HTML, I noticed that the Liferay-UI:input-localized tag creates an input tag by default, and then one more input tag for each language, each time you select a new language. Knowing that I created some functions with Javascript to help me update the inputs created from my liferay-ui:input-localized. Here is the relevant code:

    function updateAnnouncementInformation(index) {
        var announcement = announcements[index];
    
        // the announcement['message'] is a XML String
        updateInputLocalized('message', announcement['message']);
    }
    
    function updateInputLocalized(input, message) {
        var inputId = '<portlet:namespace/>' + input;
        var xml = $.parseXML(message);
        
        var inputCurrent = document.getElementById(inputId);
        var selectedLanguage = getSelectedLanguage(inputId);
        
        var inputPT = document.getElementById(inputId + '_pt_PT');
        inputPT.value = $(xml).find("Title[language-id='pt_PT']").text();
        
        var inputEN = document.getElementById(inputId + '_en_US');
        if (inputEN !== null) inputEN.value = $(xml).find("Title[language-id='en_US']").text();
        else waitForElement(inputId + '_en_US', inputCurrent, inputId, xml);
        
        var inputLabel = getInputLabel(inputId);
        if (selectedLanguage == 'pt-PT') inputLabel.innerHTML = '';
        else inputLabel.innerHTML = inputPT.value;
        
        if (selectedLanguage == 'pt-PT') inputCurrent.value = inputPT.value;
        else if (inputEN !== null) inputCurrent.value = inputEN.value;
        else waitForElement(inputId + '_en_US', inputCurrent, inputId, xml);
    }
    
    function getSelectedLanguage(inputId) {
        var languageContainer = document.getElementById('<portlet:namespace/>' + inputId + 'Menu');
        return languageContainer.getElementsByClassName('btn-section')[0].innerHTML;
    }
    
    function getInputLabel(inputId) {
        var boundingBoxContainer = document.getElementById(inputId + 'BoundingBox').parentElement;
        return boundingBoxContainer.getElementsByClassName('form-text')[0];
    }
    
    function waitForElement(elementId, inputCurrent, inputId, xml) {
        window.setTimeout(function() {
            var element = document.getElementById(elementId);
            if (element) elementCreated(element, inputCurrent, inputId, xml);
            else waitForElement(elementId, inputCurrent, inputId, xml);
        }, 500);
    }
    
    function elementCreated(inputEN, inputCurrent, inputId, xml) {
        inputEN.value = $(xml).find("Title[language-id='en_US']").text();
        
        var selectedLanguage = getSelectedLanguage(inputId);
        if (selectedLanguage == 'en-US') inputCurrent.value = inputEN.value;
    }
    

    With this I am able to update the liferay-ui:input-localized inputs according to a pre-built XML String. I hope that someone finds this useful and if you have anything to add, please let me know!