FANDOM


-- <nowiki>
--|Creates a new html table using the functions and mw.html library
---Variables prefixed with h are mw.html nodes. e.g. hTable is created using mw.html.create('table')
local p = {}
local tableModel = {}
local libraryUtil = require( 'libraryUtil' )
 
-- //Lazy load methods
local createCol,appendRow,appendCol,createRow
 
--% Creates  table model
--@  arrTable (table) A Two dimensional array of the table ,e.g. {{'header','header2'},{"cell1","cell2"}}
--@ sTableDescription (string) Caption of the table (e.g."green")
--@ sStyle (string) Table style ( e.g. sStyle="color:green")
--@ tClass (table)- Table classes (e.g. {"wikitable","sortable"})
--: (table) a tablemodel "class" that allows users to create tables 
function tableModel.new(arrExtData,sTableDescription, sStyle,tClass)
    local  self = {} 
    local checkSelf = libraryUtil.makeCheckSelfFunction( 'tableModel', 'obj', self, 'tableModel object' )
 
    self.tableFormatting = {caption="",class={},style=""}
    self.arrTable =  {}
 
    --% Outputs the attributes of a html table
    --@ iRow (number) Row number
    --@ iCol (number) Column number
    --: (table) attributes for a specific cell (row + col)
    function self:getAttribs(iRow, iCol)
        checkSelf(self,"getAttribs")
        if (self.arrTable[iRow] and self.arrTable[iRow][iCol]) then
            return self.arrTable[iRow][iCol]
        end
    end
    --% Sets an attribute to a cell
    --@ iRow (number) Row number
    --@ iCol (number) Column number
    --@ oCellAttributes (table) Attributes to be set, a single string attribute  or many as a table 
    --@ oAttrVal (string) attribute to be set
    function self:setCellAttr(iRow,iCol, oCellAttributes, oAttrVal)
        checkSelf(self,"setCellAttr")
        if (self.arrTable[iRow] and self.arrTable[iRow][iCol]  ) then
            local oTableData = self:getAttribs(iRow,iCol)
            local sCellVal = oTableData.sValue
 
            if  oCellAttributes and type (oCellAttributes)=="string" then
                oTableData.oFormatting = {[oCellAttributes]=oAttrVal}
            end
 
            if (type(oCellAttributes)=="table" and  next(oCellAttributes)) then
                oTableData.oFormatting = oCellAttributes
            end
        end
    end
    --% Sets a value to a cell	
    --@ sValue (string) Value to be set to a table
    --@ iRow (number) Row number
    --@ iCol (number)  Column number
    --@ formatting (table) Formatting to be set, e.g. {"style"="color:red"}
    --@ header (boolean) Sets this cell to a header  (true to set, false to remove)
    function self:setCell (sValue,iRow,iCol,oFormatting,bHeader)
        checkSelf(self,"setCell")
        if self.arrTable[iRow] and (self.arrTable[iRow][iCol]) then
            local oTableData = self:getAttribs(iRow,iCol)
            oTableData.sValue = sValue
            oTableData.bHeader = bHeader
 
            if (not(self.arrTable[iRow]["rowdata"])) then
                self.arrTable[iRow]["rowdata"]={}
            end
            self:setCellAttr(iRow,iCol,oFormatting)
        end
    end
    --% Imports a lua table, changes it to an html table
    --@ arrInput (table) Table two dimensional (e.g. {{'f','z'}})
    function self:setTable(arrInput)
        checkSelf(self,"setTable")
        local bHeader 
 
        if arrInput and type(arrInput) =="table" then
            for iRow,tCols in pairs(arrInput) do
 
                if type(tCols)=="table" then
                    self.arrTable[iRow] = {}
                    for iCol,sValue in ipairs(tCols) do
                        bHeader = (iRow==1)
                        self.arrTable[iRow][iCol]={}
                        self:setCell (sValue,iRow,iCol,{},bHeader)
                    end
                else
                    bHeader = true
                    self.arrTable[1] = self.arrTable[1] or {}
                    local iCol = #self.arrTable[1]+1
                    self.arrTable[1][iCol] = {}
                    self:setCell (tCols,1,iCol,{},bHeader)
                end
            end
        end
    end
 
    --% Sets data to a cell 
    --@ iRow (number) Row number
    --@ iCol (number) Column number
    --@ sField (string) internal table field to set data
    --@ sNewValue (string) new value
    function self:setData(iRow,iCol,sField, sNewValue)
        checkSelf(self,"setData")
        if (self.arrTable[iRow] and self.arrTable[iRow][iCol]
            and self.arrTable[iRow][iCol][sField]) then
            local arrMetaData = self.arrTable[iRow][iCol]
            arrMetaData[sField] = sNewValue
        end
    end
    --% Gets a cell from a table
    --@ iRow (number) Row number
    --@ iCol (number)  Column number
    --: (table) attributes for a specific cell (row + col)
    function self:getCell(iRow,iCol)
        checkSelf(self,"getCell")
        if self.arrTable[iRow] and self.arrTable[iRow][iCol] then  
            return self.arrTable[iRow][iCol].sValue
        end
    end
    --% Sets the style of a cell
    --@ iRow (number) Row number
    --@ iCol (number)  Column number
    --@ sCellStyle (string) Cell style, e.g. ("color")
    --@ sAttrVal (string) Cell attribute, e.g. ("blue")
    function self:setCellStyle(iRow,iCol,sCellStyle,sAttrVal)
        self:setCellAttr(iRow,iCol,sCellStyle,sAttrVal)
    end
    --% Sets a cell as a header
    --@ iRow (number) Row number
    --@ iCol (number) Column number
    --@ bHeader (boolean) true if header
    function self:setCellHeader(iRow,iCol,bHeader)
        checkSelf(self,"setCellHeader")
        if self.arrTable[iRow] and self.arrTable[iRow][iCol] then
            local oTableData = self:getAttribs(iRow,iCol)
            local sCellVal =  oTableData.sValue      
 
            if (type(bHeader)=="boolean") then
                oTableData["bHeader"] =  bHeader
            end 
        end
    end
 
    --% Creates a row 
    --@ tFormatting (string) Formatting to be set, e.g. {"style"="color:red"}.)
    --: (table) A mw.html node containing a row
    function createRow(tFormatting)
        local hTableRow= mw.html.create('tr')
 
        if(tFormatting and type(tFormatting)=="table" and next(tFormatting)) then
            hTableRow:attr(tFormatting)
            hTableRow:node(sHeadingCol) 
        end
        hTableRow:done()
 
        return hTableRow
    end
 
    --% Appends a row to a table 
    --@ hTable (table) hTable mw.html table node --e.g. mw.html.create('table')) 
    --@ tFormatting (table)  {["style"]="color:green"}
    --: (table) A full mw.html table 
    function appendRow(hTable, hRow,tFormatting)
        if(tFormatting and type(tFormatting)=="table" and next(tFormatting)) then
               hRow:attr(tFormatting)
        end
 
        if (hRow) and  (hTable) then
            hTable:node(hRow)
        else 
           return "Syntax error: Row and table cannot be nil!"  
        end
 
        return hTable:done()
    end 
 
    --% Creates a new column 
    --@ sColValue (string) Value of table column
    --@ tFormatting (table) Formatting to be set, e.g. {"style"="color:red"}.
    --@ bHeader (boolean) Returns true if header
    --: (table) A full mw.html node containing a "td"
    function createCol(sColValue,tFormatting,bHeader)
        local sTagCol = "td"
 
        if (bHeader) then 
            sTagCol ="th"
        end
 
        local hHeadingCol =mw.html.create(sTagCol)
        if  (sColValue and type(sColValue)=="string") or  sColValue =="" or type(sColValue)=="number"  then
            hHeadingCol:wikitext(sColValue)
        end
 
        if (tFormatting and type(tFormatting)=="table") then
            local sAttribute, sValues = next(tFormatting)
             if (type(sAttribute)=="string" and sValues) then 
                hHeadingCol :attr(tFormatting )
             else
                if (sAttribute) then
                    return "Error: Attributes need Key and value ({[key]='value'}), e.g. {['style']='color:blue'}"
                end
             end
        end
 
        hHeadingCol:done()
        return hHeadingCol
    end
    --% Appends a column cell to a row 
    --@ hColumn (table) A mw.html node containing a column (html th)
    --@ hTableRow (table) A mw.html node containing a cell (html td)
    --@ tFormatting (table) Formatting to be set, e.g. {"style"="color:red"}.
    --: (string) An error if the table is invalid or nil if not
    function appendCol(hTableRow,hColumn,tFormatting)
        local sColType = type (hColumn)
 
        if sColType =="string" or  sColType =="number" or  sColType =="boolean" then
            hColumn = createCol(hColumn)
        end
 
        if(tFormatting and type(tFormatting)=="table" and next(tFormatting)) then
            local sAttribute, sValues = next(tFormatting)
            if (type(sAttribute)=="string" and sValues) then 
                hHeadingCol :attr(tFormatting )
            else
                if (sAttribute) then
                    return "Error: Attributes need Key and value ({[key]='value'}), e.g. {['style']='color:blue'}"
                end
            end
        end
 
        if (hTableRow and hColumn and type(hColumn)=="table" ) then
            hTableRow = hTableRow:node(hColumn)
        else 
           return "Syntax error: Table row and table column cannot be nil!"  
        end
    end
    --% Outputs the html table
    --: (table) An mw.html node containing the whole table
    function self:getTable ()
        checkSelf(self,"getTable")
        local hRow,hCell 
        local hTable = mw.html.create("table")
        hTable:tag("caption")
            :wikitext(self.tableFormatting.caption)
        hTable:cssText(self.tableFormatting.style)
 
        for i,sClassName in pairs(self.tableFormatting.class) do
            if type(sClassName) == "string" then
                hTable:addClass(sClassName)
            end
        end
        for iRow,tRow in pairs(self.arrTable) do
            if (self.arrTable[iRow]) then
                tRowFormat = self.arrTable[iRow]["rowdata"] 
            end
            hRow = createRow(tRowFormat)
 
            for iCol,oCell in ipairs(tRow)  do
                if (oCell) then
                    hCell = createCol(oCell.sValue,oCell.oFormatting,oCell.bHeader)
                    appendCol(hRow,hCell)
                end
            end
            appendRow(hTable, hRow)
        end
 
        return hTable:done()
    end
    --% Sets the rows and columns of table
    --iRows (number) Number of rows in the table
    --iColumns (number) Number of columns in the table
    function self:setGrid(iRows,iColumns)
        checkSelf(self,"setGrid")
        local bHeader
 
        for iRowCount=0,iRows  do
            self.arrTable[iRowCount] = {}
            bHeader = false
            for iColCount=0, iColumns do
                bHeader = (iRowCount==1)
                self.arrTable[iRowCount][iColCount] ={["sValue"]= "",["oFormatting"] =  {},["bHeader"] =  bHeader}
            end
        end
    end
    --% Prints out text representation of the table
    --: (string) text representation of the table
    function self:getGrid()
        checkSelf(self,"getGrid")
        local sGrid  = "\tCol1\tCol2\n"
        local sValue 
        for iRow =1,#self.arrTable do
            sGrid = sGrid ..iRow.."\t|"
            for iCol =1, #self.arrTable[iRow] do
                sValue = self:getCell(iRow,iCol) or ""
                sGrid = sGrid .."\t" .. sValue .. "\t|"
            end
            sGrid = sGrid .."\n"
        end
        return sGrid
    end
    --% Sets the styling of a table
    --@ sTableDescription (string) Description or caption of the table
    --@ sStyle (string) the styles (e.g. "color:green")
    --@ tClass  (table) the css classes the table will use (e.g.{"bluetable","greentext"}
    function self:setTableFormat(sTableDescription, sStyle,tClass)
        checkSelf(self,"setTableFormat")
        if sTableDescription and type(sTableDescription)=="string"  then
              self.tableFormatting.caption = sTableDescription
        end
 
        if (tClass) then
            if type(tClass)=="table" and next(tClass) then  
                self.tableFormatting.class= tClass
            end
        end 
 
        if(sStyle and  type(sStyle)=="string" and sStyle~="") then
            self.tableFormatting.style =sStyle
        end
 
    end 
    --% Sets the formatting of a table
    --@ iRow (number) The row to add the styling
    --@ tFormatting (table) Formatting to be set, e.g. {"style"="color:red"}.
    function self:setRowFormat(iRow,tFormatting)
        checkSelf(self,"setRowFormat")
        if (iRow and  self.arrTable[iRow] and self.arrTable[iRow]["rowdata"]) then
            self.arrTable[iRow]["rowdata"] = tFormatting
        end
    end 
    --% Adds a new row to a table
    --@ iRow (number)  The index of the row to add
    function self:addRow(iRow)
        checkSelf(self,"addRow")
        local sValue =""
        local tColumns ={}
        local iRowToAdd = tonumber(iRow) or 1
 
        if iRow and (iRow>=(#self.arrTable +2) or iRow<1) then
            return
        end
 
        if self.arrTable and self.arrTable[1]  then
            iRowToAdd = iRow or #self.arrTable+1
             for i=1,#self.arrTable[1] do
                tColumns[i] = {}
             end
        end
        table.insert(self.arrTable,iRowToAdd,tColumns)
    end
    --% Removes a row from the table	
    --@ iRow (number) The index of the row to remove
    function self:removeRow(iRow)
        checkSelf(self,"removeRow")
        if self.arrTable[iRow] then
            table.remove(self.arrTable,iRow)
        end
    end
    --% Sets the contents of a row
    --@ iRow (number) The index of the row to set
    --@ tTable (table) contents (e.g. {2,3})
    function self:setRow(iRow,tTable)
        checkSelf(self,"setRow")
        if iRow and self.arrTable[iRow] and tTable then
            for iCol,sValue in pairs(tTable) do
                self:setCell(sValue,iRow,iCol)
            end
        end
    end
 
    --% Adds a new column to the table
    --@ sColName(string) Name of the column
    --@ iCol (number) The index of the column to set
    function self:addCol(sColName,iCol)
        checkSelf(self,"addCol")
 
        if iCol and self.arrTable 
            and self.arrTable[1]
            and (iCol>=#self.arrTable[1] +2 or  iCol<1) then
            return
        end
 
        if self.arrTable and self.arrTable[1] and not(iCol) then
            iCol = #self.arrTable[1]+1
        end
 
        if self.arrTable[1] then 
            table.insert(self.arrTable[1],iCol,{})
            self:setCell(sColName,1,iCol,{},true)
        end
    end
 
    --% Removes a new column to the table
    --@ iCol (number) The index of the column to remove
    function self:removeCol(iCol)
        checkSelf(self,"removeCol")
 
        if iCol then
            for i,v in pairs(self.arrTable) do
                if self.arrTable[i] and self.arrTable[i][iCol] then
                    table.remove(self.arrTable[i],iCol)
                end    
            end
        end
    end
    --% Gets number of rows in table
    --: (number) Number of rows
    function self:getRowCount()
        checkSelf(self,"getRowCount")
        return #self.arrTable
    end
    --% Gets number of columns in table
    --: (number) Number of columns
    function self:getColCount(iRow)
        checkSelf(self,"getColCount")
        iRow = iRow or 1
        if self.arrTable[iRow] then
            return #self.arrTable[iRow]
        end
        return 0
    end
    --% Initializes the tablebuilder (internal use)
    function initialize()
        self.setTableFormat(self,sTableDescription, sStyle,tClass)
        self:setTable(arrExtData)
    end
    -- //Constructor 
    initialize()
 
    return self
end
--%  Create a new table builder 
--@ arrExtData (table) A two dimensional array containing a table e.g {{"Girls","Boys"},{"Xena","Hercules"}}
--@ sTableDescription (string) A caption for the table  e.g. "Table of boys and girls
--@ sStyle (string) Basic styling for the table  e.g. "background:green"
--@ tClass (table) CSS classes for the whole table e.g. {"boysandgirls","red"}
function p.new(arrExtData,sTableDescription, sStyle,tClass)
    return tableModel.new(arrExtData,sTableDescription, sStyle,tClass)
end
 
-- Test code
function p.test(frame)
    -- Array consisting of rows and columns
    local tRowData = {
    -- Row Columns
        {"1","2"},
        {"44","3"}, 
        {"6","8"}, 
    }
 
    local c = tableModel.new(tRowData,"Table","",{"wikitable"})
    local row1 = 4
    local col1 = 1
    local celltext = "green"
    local cellFormat = {["style"]="color:green"}
 
    c:addRow()
    c:setCell("7",row1,col1)
    c:setCell("2",row1,2)
 
    local row2 = 1
    local col2 = 1
 
    c:setCell(celltext,row2,col2,cellFormat)
 
    return c:getTable()
end
-- End Test code
return p
Community content is available under CC-BY-SA unless otherwise noted.

Fandom may earn an affiliate commission on sales made from links on this page.

Stream the best stories.

Fandom may earn an affiliate commission on sales made from links on this page.

Get Disney+