How to pass data from controller to smarty template?

I have created a small module that would just on button click would download some data from DB in CSV format. The main functionality is working absolutely fine.

But what i want to do further is that if the data is returning an empty array, i should assign some status variable and upon that in the template file under if block, it shows that “There is no data to export” or something like it.

What i did so far:

In my controller:

public function createCSV()
    {
        try {
            $resultSet = DatabaseProvider::getDb()->getAll(self::$_Sql['actSql']['expQuery'][0]);
            if (empty($resultSet[1])) {
                // $this->_aViewData['status'] = 0;
                $this->addTplParam('status', 0);
                die();
            }
            $oUtils = Registry::getUtils();
            $oUtils->setHeader("Content-type: text/csv");
            $oUtils->setHeader("Content-Disposition: attachment; filename=" . date("Y_m_d") . "_current_stock.csv");

            $this->outputCSV($resultSet);
            exit();
        } catch (\Exception $ex) {
            Registry::getUtilsView()->addErrorToDisplay(new StandardException($ex->getMessage()));
        }
    }

In my template file:

[{include file="headitem.tpl"}]

<form name="exportCSVForm" id="exportCSVForm" action="[{$oViewConf->getSelfLink()}]" method="post">
  
    [{$oViewConf->getHiddenSid()}]
    <input type="hidden" name="cl" value="zp_export">
    <input type="hidden" name="fnc" value="createCSV">

    <p>Here you can export the details about current stock (of 1 month)</p>
    <input type="submit" value="Export Articles" class="edittext">
    <p>[{$status}]</p>
    [{*[{if {$oViewConf['status']} == 0}]
        <p> There is no data to export </p>
    [{/if}]*}]
</form>

What i want to know is what is correct approach of achieving my desired result.

1 Like

In the controller that renders the form where the button is located (which is probably not the one that outputs the csv) you can place a method that does not output the file but only checks whether data is available. You can call this method from template and check its return value, e.g.

[{ if $oView->isDataAvailable() }]
    form with export button
[{ else }]
    no data!
[{ /if }]
1 Like

Yes i am pretty aware with MVC architecture. I am coming from Laravel background, So oxid is quite new to me. What i wanted to achieve was that when the button is pressed “Export Products” it will send the request to controller and then controller decide if there is no data, then it will show some alert below/above the button :slight_smile:

This is another good solution considering how template works in oxid. I’ll try this. Thankyou :slight_smile:

no, wait, that was not an actual reply to your question,
its a link to another topic with similar question. Click on the red text “Which variables are available in the theme?” and it will get you to this another topic.

Yes it is i know, i have read that topic before i posted my original question :slight_smile:
What i am looking for is upon the clicking of button controller decides what to return, and then it shows alert (below or above the the button meaning re-render the same template with just alert in it.) or simply download the CSV. That’s all. :slight_smile:

And the approach which @leofonic suggested i have tried and it will work, just show/hide the button on data availability. But i want to know if i can achieve it the way i am wanting it to be? What could be the flow?

You need a separate request with no output to download the file. For example, you could open a new window with javascript after the buttonclick and display an error message there or download the file. Or you could load the same page again (the one with the form), and in case there is something to download open a new window with javascript to download the file, otherwise display a message. Something like that, but there might be some problems with popup blockers when you open a window without user action.

1 Like

you could submit a form into hidden iframe and then either stream file to browser for downloading it or return html document with js alert. Similar to invoice generation in admin interface in order management.

1 Like

Alright @vanilla_thunder, @leofonic thanks for suggesting some approaches. I’ll see what i can do now. Right now it seems like an “extra” kind of work but lets see what i am able to achieve with this discussion.

Thank you! guys for your time :slight_smile: