! 제품 버전을 정확하게 입력해 주세요.
제품 버전이 정확하게 기재되어 있지 않은 경우,
최신 버전을 기준으로 안내 드리므로
더욱 빠르고 명확한 안내를 위해
제품 버전을 정확하게 입력해 주세요!

SpreadJS V13 새로운 기능으로 복잡한 양식 구현 > 블로그 & Tips

본문 바로가기

SpreadJS

블로그 & Tips

SpreadJS V13 새로운 기능으로 복잡한 양식 구현

페이지 정보

작성자 GrapeCity 작성일 2019-11-12 00:00 조회 3,560회 댓글 0건

본문

첨부파일

SpreadJS V13에서는 복잡한 형태의 양삭을 만드는데 도움을 줄 수 있는 새로운 기능을 추가했습니다. 주요 기능은 셀 드롭 다운으로, 시트의 셀 내에서 스타일로 구현할 수있는 내장 메뉴입니다. 또한 셀 버튼과 상태를 추가하여 사용자가 양식과 상호 작용하는 방식을 제어할 수 있습니다.

여기에서는 셀 패딩 및 레이블 외에도 이러한 모든 기능을 사용하여, 제품 이휴에 대한 제출을 위한 양식을 만드어 보겠스니다.


JavaScript 스프레드시트를 위한 템플릿 만들기


Spread 샘플 템플릿을 "SpreadJS Designer"를 통해 만들었습니다: 사용자가 제출한 문제를 나열하는 시트 한 장과, 이슈를 작성하거나 편집할 때 사용자가 작성할 양식이 들어있는 시트입니다. 


"Issues"시트의 경우, 코드가 있는 데이터 바운드 테이블을 추가 할 예정이므로 비워 두었습니다. 


"Issue Details"시트의 경우, 몇 개의 셀을 병합하고 배경색과 테두리를 설정했습니다. 추가적으로 시트의 기본 격자선과 머리글을 제거하였습니다. 이 SSJSON을 저장 한 다음 JavaScript 파일로 내 보내면 응용 프로그램에서이 파일을 참조 할 수 있습니다.


응용 프로그램 만들기





이 데모에서 해당 응용 프로그램은 JavaScript 파일에 대한 참조가 있는 간단한 HTML 페이지가 될 것입니다. 계속해서 HTML 페이지를 작성하고, SpreadJS 파일과 새로 작성된 템플리트를 참조합니다.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta charset="utf-8" /> 
  <title>Spread JS Cell Drop Downs</title> 
  <link href="./gc.spread.sheets.excel2013white.13.0.0.css" rel="stylesheet" type="text/css"> 
  <script type="text/javascript" src=".gc.spread.sheets.all.13.0.0.min.js"></script>
  <script type='text/javascript" src=./CellDropDownsTemplate.js"></script>
</head>
<body>
  <div id="spreadSheet" style="width: 1450px; height: 200 px; border: 1px solid gray"></div>
</body>
</html>


Spread 인스턴스를 초기화하고 몇 가지 예비 옵션을 설정합니다. 이후 Spread 인스턴스를 템플릿에 바인딩 해줍니다.

window.onload = function () { 
  var spread = new GC.Spread.Sheets.Workbook(document.getElementById("spreadSheet"), { sheetCount: 1 }); 
  spread.fromJSON(CellDropDownsTemplate); spread.options.newTabVisible = false; 
  var activeSheet = spread.getSheet(1); 

  var source = new GC.Spread.Sheets.Bindings.CellBindingSource(data); 

  spread.suspendPaint(); 

  // Set these options to lock the sheet for certain cells var options = { 
      allowSelectLockedCells: false, allowSelectUnlockedCells: true, 
      allowResizeRows: false, 
      allowResizeColumns: false, 
      allowEditObjects: true 
  }; 
  activeSheet.options.protectionOptions = options; activeSheet.options.isProtected = true; spread.getSheet(1).visible(false); 

  spread.resumePaint(); 
} 


이슈 목록 초기화


다음 단계는 JavaScript 객체 배열을 데이터 소스로 사용하여 테이블을 만드는 것입니다. 


이 배열은 최신 상태로 유지됩니다. 사용자는 배열에 이슈(issue)를 추가하거나, 이미 목록에있는 이슈(issue)를 편집할 수 있습니다. 테이블을 설정하려면 데이터 소스를 설정하고 열(column)을 바인딩하십시오.

// Set up the intial data binding and table in the Spread instance for the list of issues 
function initializeIssueList(data, source, spread) {      var sheet = spread.getActiveSheet(); 
  var tableColumns = [], 
      names = ['uid', 'status', 'title', 'product', 'assignedTo', 'priority', 'submissionDate', 'estimatedHours', 'tags', 'description'], 
      labels = ['ID', 'Status', 'Title', 'Product', 'Assigned To', 'Priority', 'Sub. Date', 'Est. Hours', 'Tags', 'Description']; 
  var table = sheet.tables.add('tableIssues', 0, 1, 1, 10); 
  table.autoGenerateColumns(false); 
  names.forEach(function (name, index) { 
      var tableColumn = new GC.Spread.Sheets.Tables.TableColumn(); tableColumn.name(labels[index]); tableColumn.dataField(name); 
      tableColumns.push(tableColumn); 
  }); 



  table.bindColumns(tableColumns); 
  table.bindingPath('issueList'); 
  sheet.setDataSource(source); 
  sheet.setColumnWidth(0, 58); 
  sheet.setColumnWidth(1, 40); 
  sheet.setColumnWidth(2, 100); 
  sheet.setColumnWidth(3, 200); 
  sheet.setColumnWidth(4, 100); 
  sheet.setColumnWidth(5, 100); 
  sheet.setColumnWidth(6, 70); 
  sheet.setColumnWidth(7, 100); 
  sheet.setColumnWidth(8, 100); 
  sheet.setColumnWidth(9, 100); 
  sheet.setColumnWidth(10, 400); 
} 




셀 버튼 추가


이 샘플에는 네 가지 종류의 버튼이 있습니다. 이슈 목록에서 새 이슈를 제출하기위한 "추가 버튼", 이미 목록에있는 이슈를 변경하는 "편집 버튼", 새로운 이슈를 제출하기 위한 "제출 버튼", 또는 기존 이슈의 변경을 취고하거나 새로운 이슈의 생성을 취소하기위한 "취소 버튼"이 있습니다.


새로운 셀(cell) 버튼 구현에서는 이러한 버튼이 스타일(style)로 생성된 다음, 시트의 셀에 설정됩니다. 이 4 개의 버튼은 서로 다른 기능을 수행하며, 서로 다르게 보일 수 있으므로 각 버튼마다 새로운 스타일을 만들어야합니다.

// Set the style for the cell buttons 
function setButtonStyles(data, source, spread) { 
  var issuesSheet = spread.getSheet(0); 
  var newIssueButtonStyle = new GC.Spread.Sheets.Style(); 
  newIssueButtonStyle.cellButtons = [ 
      { 

          caption: "Add", 
          width: 60, 
          position: GC.Spread.Sheets.ButtonPosition.center, 
          // Execute this command when the Add button is clicked 
          // Adds a new issue 
          command: (sheet, row, col, option) => {           clearAddIssue(spread);                        newIssueSheet.setValue(0, 4, issueUID);       newIssueSheet.setText(0, 6, "New");           switchHideSheet(spread); 
          } 
        } 
      ]; 
      newIssueButtonStyle.locked = false; issuesSheet.setStyle(0, 0, newIssueButtonStyle);

      var editButtonStyle = new GC.Spread.Sheets.Style(); 
      editButtonStyle.cellButtons = [ 
            { 
                caption: "Edit", 
                width: 60, 
                position: GC.Spread.Sheets.ButtonPosition.center, // Execute this command when the Edit button is clicked 
                // Edit an existing issue 
                command: (sheet, row, col, option) => {   newIssueSheet.setValue(0, 4,            issuesSheet.getValue(row, 1));          newIssueSheet.setText(0, 6,             issuesSheet.getText(row, 2));           newIssueSheet.setText(1, 0,             issuesSheet.getText(row, 3));           newIssueSheet.setText(2, 0,             issuesSheet.getText(row, 4));           newIssueSheet.setText(2, 4,             issuesSheet.getText(row, 5));           newIssueSheet.setValue(3, 0,            issuesSheet.getValue(row, 6));           newIssueSheet.setText(3, 1,            issuesSheet.getText(row, 7));           newIssueSheet.setValue(3, 3,            issuesSheet.getValue(row, 8));          newIssueSheet.setText(3, 6,             issuesSheet.getText(row, 9));           newIssueSheet.setText(4, 0,             issuesSheet.getText(row, 10)); 

                  switchHideSheet(spread); 
                } 
              } 
            ]; 
            editButtonStyle.locked = false; 
            // Add the Edit button to the right of all existing issues in the table 
            for (var i = 0;i < data.issueList.length; i++){               
                issuesSheet.setStyle(i+1, 0, editButtonStyle); 
            } 

            var newIssueSheet = spread.getSheet(1); 
            var submitButtonStyle = new GC.Spread.Sheets.Style(); submitButtonStyle.cellButtons = [ 
              { 
                caption: "Submit Issue", 
                width: 125, 
                position: GC.Spread.Sheets.ButtonPosition.left, 
                // Execute this command when the Submit button is clicked 
                // Submit the new issue or changes to an existing issue 
                command: (sheet, row, col, option) => {    var issueData = { 
                        uid: sheet.getValue(0, 4), status: sheet.getText(0, 6), title: sheet.getText(1, 0), product: sheet.getText(2, 0), assignedTo: sheet.getText(2, 4),priority: sheet.getValue(3, 0), submissionDate: sheet.getText(3,1), 
                        estimatedHours: sheet.getValue(3, 3), 
                        tags: sheet.getText(3, 6), description: sheet.getText(4, 
                } 

                // Test if the issue already exists 
                if (data.issueList.some(issue => issue.uid === issueData.uid)) { 
                    var issueIndex = data.issueList.findIndex(issue => issue.uid === issueData.uid); data.issueList[issueIndex] = issueData; 
                } // Add the new issue if it doesn't exist 
                else { 
                  data.issueList.push(issueData); source = new GC.Spread.Sheets.Bindings.CellBindingSource(data); issuesSheet.setDataSource(source); issuesSheet.setStyle(data.issueList.length, 0, editButtonStyle); 
                  issueUID++; 
                } 
                source = new GC.Spread.Sheets.Bindings.CellBindingSource(data); 
                issuesSheet.setDataSource(source); 

                switchHideSheet(spread); 
            } 
        } 
      ]; 
      submitButtonStyle.locked = false; newIssueSheet.setStyle(6, 2, submitButtonStyle); 

      var cancelButtonStyle = new GC.Spread.Sheets.Style(); 
      cancelButtonStyle.cellButtons = [ 
          { 
                caption: "Cancel", 
                width: 125, 
                position: GC.Spread.Sheets.ButtonPosition.left, 
                // Execute this command when the Cancel button is clicked command: (sheet, row, col, option) => { 
                      switchHideSheet(spread); 
                  } 
                } 
              ]; cancelButtonStyle.locked = false; newIssueSheet.setStyle(6, 4, cancelButtonStyle); 
} 


"추가"버튼의 경우, 다음과 같은 형식으로 새 값을 입력 할 수 있도록, 시트 값을 초기화하는 기능을 구현하려고 합니다.

// Prep the new issue sheet by clearing the data function clearAddIssue(spread) { 
    spread.getSheet(1).clear(1, 0, 4, 9, GC.Spread.Sheets.SheetArea.viewport, GC.Spread.Sheets.StorageType.data); 
} 


모든 버튼에 대해서, 다른 시트로 전환하고 현재 시트를 숨김으로서 사용자가 한 번에 한 시트만 볼 수 있도록 만들어 줍니다. 간단하게 visible 속성을 사용하여 구현하고, 이 경우 Spread 인스턴스의 크기도 변경해줍니다.

// Switch sheets and hide the inactive sheet 
function switchHideSheet(spread) { 
    var originalSheet = spread.getActiveSheet(); 
    if (originalSheet.name() == "Issues") {               spread.setActiveSheet(1); 
      spread.getSheet(1).visible(true); document.getElementById("spreadSheet").style.width = "620px"; 
      document.getElementById("spreadSheet").style.height = "500px"; 
    } else { 
        spread.setActiveSheet(0); 
        spread.getSheet(0).visible(true); document.getElementById("spreadSheet").style.width = "1450px"; 
        document.getElementById("spreadSheet").style.height = "200px"; 
    } 
    originalSheet.visible(false); 
} 


드롭 다운 구현


버튼과 마찬가지로 드롭 다운(drop-downs)은 스타일 형식으로 구현할 수 있습니다. 먼저 이슈에 대한 상태를 위한 워크플로우(workflow) 목록을 구현함으로써 시작할 수 있습니다. 이는 드롭다운(drop-down)이 스위치 될 수 있는 각기 다른 변화를 가지고 있습니다.

// Set the style for the "Status" drop-down 
function setWorkflowDropDown(sheet) { 
    var workflowStyle = new GC.Spread.Sheets.Style(); workflowStyle.cellButtons = [ 
        { 
            imageType: GC.Spread.Sheets.ButtonImageType.dropdown, command: "openWorkflowList", useButtonStyle: true 
        } 
    ]; 
    workflowStyle.dropDowns = [ 
        { 
            type: GC.Spread.Sheets.DropDownType.workflowList, option: { 
                items: [ 
                    { value: "New", transitions: [1] }, { value: "Open",transitions: [0, 2, 3, 5] }, 
                    { value: "In Progress", transitions: [1, 3, 5] }, 
                    { value: "Resolved", transitions: [5, 4] }, 
                    { value: "Reopened",transitions: [5, 3, 2] }, 
                    { value: "Closed", transitions: [4] } 
                ] 
              } 
          } 
      ]; 
      workflowStyle.backColor = 'lightGray'; workflowStyle.locked = false; 

      sheet.setStyle(0, 6, workflowStyle); sheet.getRange(0, 6, 1, 3).borderBottom(new GC.Spread.Sheets.LineBorder("black", GC.Spread.Sheets.LineStyle.thick)); 
} 


"Product" 드롭 다운은 계단식 목록으로, 기본적으로 지정한 목록 항목에 대한, 보조 옵션을 가질 수 있습니다. 이 경우 주요 제품군의 다른 하위 제품을 선택할때 유용합니다.

// Set the style for the "Product" drop-down 
function setVerticalCascadeGroupList(sheet) { 
  var cascadeListData= { 
      items: [ 
          { 
              text: 'Spread', 
              value: 'Spread', 
              layout: {displayAs: GC.Spread.Sheets.LayoutDisplayAs.popup}, items: [ 
                  { 
                      text: 'SpreadJS', 
                      value: 'SpreadJS' 
                  }, 
                  { 
                      text: 'Spread .NET', 
                      value: 'Spread .NET' 
                  } 
                ] 
              }, 
              { 
                text: 'ActiveReports', 
                value: 'ActiveReports', 
                layout: {displayAs: GC.Spread.Sheets.LayoutDisplayAs.popup},items: [ 
                    { 
                        text: 'ActiveReportsJS', 
                        value: 'ActiveReportsJS' 
                    }, 
                    { 
                        text: 'ActiveReports Professional', 
                        value: 'ActiveReports Professional' 
                    } 
                  ] 
                }, 
                { 
                        text: 'DataViewsJS', 
                        value: 'DataViewsJS', 
                    }, 
                    { 
                      text: 'Wijmo', 
                      value: 'Wijmo', 
                    } 
                  ] 
                }; 
                var verticalCascadeListStyle = new GC.Spread.Sheets.Style(); verticalCascadeListStyle.cellButtons = [ 
                  { 
                        imageType: GC.Spread.Sheets.ButtonImageType.dropdown, 
                        command: "openList", useButtonStyle: true, 
                  } 
                ]; 
                verticalCascadeListStyle.dropDowns =[ 
                  { 
                        type: GC.Spread.Sheets.DropDownType.list, 
                        option: cascadeListData 
                  } 
                ]; 
                verticalCascadeListStyle.backColor = 'lightGray'; verticalCascadeListStyle.locked = false; 
                sheet.setStyle(2, 0, verticalCascadeListStyle); sheet.getRange(2, 0, 1, 4).borderBottom(new GC.Spread.Sheets.LineBorder("black", GC.Spread.Sheets.LineStyle.thin)); 
}


'Priority(우선 순위)' 드롭 다운 메뉴는 1에서 6 사이의 값을 설청하여 슬라이더를 만들 수 있습니다.

// Set the style for the "Priority" drop-down 
function setSliderDropDown(sheet) { 
  var sliderStyle = new GC.Spread.Sheets.Style(); 


  sliderStyle.cellButtons = [ 
      { 
          imageType: GC.Spread.Sheets.ButtonImageType.dropdown, command: "openSlider", 
          useButtonStyle: true 
      } 
  ]; 

  sliderStyle.dropDowns = [ 
      { 
          type: GC.Spread.Sheets.DropDownType.slider, option: { 
              max: 6, 
              min: 1, 
              marks: [1,2,3,4,5,6], 
              step: 1, 
              direction: GC.Spread.Sheets.LayoutDirection.horizontal 
          } 
      } 
  ]; 

  sliderStyle.backColor = 'lightGray'; sliderStyle.locked = false; 

  sheet.setStyle(3, 0, sliderStyle); 
  sheet.getCell(3, 0).borderBottom(new GC.Spread.Sheets.LineBorder("black", GC.Spread.Sheets.LineStyle.thin)); 
  sheet.getCell(3, 0).borderRight(new GC.Spread.Sheets.LineBorder("black", GC.Spread.Sheets.LineStyle.thin)); 
} 


"Submission Date(제출 날짜)"를 설정하기 위해, DateTimePicker 드롭 다운을 사용할 수 있습니다.

// Set the style for the "Submission Date" drop-down function setDateTimeDropDown(sheet) { 
    var dateTimeStyle = new GC.Spread.Sheets.Style(); dateTimeStyle.cellButtons = [ 
        { 
              imageType: GC.Spread.Sheets.ButtonImageType.dropdown,command: "openDateTimePicker", useButtonStyle: true 
        } 
    ]; 
    dateTimeStyle.dropDowns=[ 
        { 

            type: GC.Spread.Sheets.DropDownType.dateTimePicker, 
            option: { 
                showTime:false 
            } 
        } 
    ]; 
    dateTimeStyle.backColor = 'lightGray'; dateTimeStyle.locked = false; 

    sheet.setStyle(3, 1, dateTimeStyle); 
    sheet.getRange(3, 1, 1, 2).borderBottom(new GC.Spread.Sheets.LineBorder("black", GC.Spread.Sheets.LineStyle.thin)); 
} 


우리가 사용할 수 있는 마지막 유형의 드롭 다운은 계산기(calculator)이며, "Estimated Hours(예상 시간)" 필드 계산을 위해 사용됩니다.

// Set the style for the "Estimated Hours" drop-down function setCalculatorDropDown(sheet) { 
    var calculatorStyle = new GC.Spread.Sheets.Style(); calculatorStyle.cellButtons = [ 
        { 
              imageType: GC.Spread.Sheets.ButtonImageType.dropdown,command: "openCalculator", useButtonStyle: true 
        } 
    ]; 


    calculatorStyle.backColor = 'lightGray'; calculatorStyle.locked = false; 

    sheet.setStyle(3, 3, calculatorStyle); sheet.getRange(3, 3, 1, 3).borderBottom(new GC.Spread.Sheets.LineBorder("black", GC.Spread.Sheets.LineStyle.thin)); 
} 





JavaScript 스프레드 시트에 셀 상태 추가


양식 시트의 경우, 사용자가 편집할 수있는 셀을 알기를 원합니다. 마우스 커서를 가리킬 때 ,셀 스타일을 변경할 수 있는 "hover" 셀 상태를 통해, 이를 표시 할 수 있습니다. 마우스를 올릴 때 셀 스타일을 지정하고, 해당 상태를 특정 범위에 추가해야합니다.

// Set the style when cells are hovered over with the cursor 
function setHoverStyles(sheet) { 
    var hoverStyle = new GC.Spread.Sheets.Style(); hoverStyle.backColor = 'white'; 

    var range = sheet.getRange(0, 6, 1, 3); sheet.cellStates.add(range, GC.Spread.Sheets.CellStatesType.hover, hoverStyle); 

    range = sheet.getRange(1, 0, 4, 9); sheet.cellStates.add(range, GC.Spread.Sheets.CellStatesType.hover, hoverStyle);
} 


라벨(Labels) 추가


라벨을 위한 별도의 셀을 추가하여, 편집 가능한 필드를 사용자에게 알리는 대신, 동일한 셀 내에서 셀 패딩(Cell Padding) 및 셀 라벨(Cell Label)을 사용할 수 있습니다.

// Set the labels for all of the data entry fields function setLabels(sheet) { 
    var labelOptions = { 
        visibility: 0, 
        font: '11px Arial', 
        margin: '0 0 0 0' 
    } 
    sheet 
    .getCell(0, 6) 
    .watermark('STATUS') 
    .cellPadding('25 0 0 0') 
    .labelOptions(labelOptions); 

    sheet 
    .getCell(1, 0) 
    .watermark('ISSUE TITLE') 
    .cellPadding('25 0 0 0') 
    .labelOptions(labelOptions); 

    sheet 
    .getCell(2, 0) 
    .watermark('PRODUCT') 
    .cellPadding('25 0 0 0') 
    .labelOptions(labelOptions); 

    sheet 
    .getCell(2, 4) 
    .watermark('ASSIGNED TO') 
    .cellPadding('25 0 0 0') 
    .labelOptions(labelOptions); 

    sheet 
    .getCell(3, 0) 
    .watermark('PRIORITY') 
    .cellPadding('25 0 0 0') 
    .labelOptions(labelOptions); 

    sheet 
    .getCell(3, 1) 
    .watermark('SUBMISSION DATE') 
    .cellPadding('25 0 0 0') 
    .labelOptions(labelOptions); 

    sheet 
    .getCell(3, 3) 
    .watermark('ESTIMATED HOURS') 
    .cellPadding('25 0 0 0') 
    .labelOptions(labelOptions); 

    sheet 
    .getCell(3, 6) 
    .watermark('TAGS') 
    .cellPadding('25 0 0 0') 
    .labelOptions(labelOptions); 

    sheet 
    .getCell(4, 0) 
    .watermark('ISSUE DESCRIPTION') 
    .cellPadding('25 0 0 0') 
    .labelOptions(labelOptions); 
} 


양식 셀 설정


드롭다운(drop-down) 또는 버튼이 아닌, 다른 셀의 경우, 해당 셀의 스타일과 테두리를 아래와 같이 다르게 설정하고자 합니다.

function newFormStyle(){ 
    var formStyle = new GC.Spread.Sheets.Style(); formStyle.backColor = 'lightGray'; 
    formStyle.locked = false; 
    return formStyle; 
} 

// Set the style for the cells for simple data entry function setFormCells(sheet) { 
    sheet.setStyle(1, 0, newFormStyle()); 
    sheet.setStyle(2, 4, newFormStyle()); 
    sheet.setStyle(3, 6, newFormStyle()); 
    sheet.setStyle(4, 0, newFormStyle()); 

    var bottomBorder = new GC.Spread.Sheets.LineBorder("black", GC.Spread.Sheets.LineStyle.thin) sheet.getRange(1, 0, 1, 9).borderBottom(bottomBorder); 
    sheet.getRange(2, 4, 1, 5).borderBottom(bottomBorder); 
    sheet.getRange(3, 6, 1, 3).borderBottom(bottomBorder); 
    sheet.getRange(4, 0, 1, 9).borderBottom(bottomBorder); 
} 




이것이 SpreadJS v13의 새로운 드롭 다운 및 버튼 기능을 사용하여 사용자 정의 양식을 작성하는 데 필요한 전부입니다! 

  • 페이스북으로 공유
  • 트위터로  공유
  • 링크 복사
  • 카카오톡으로 보내기

댓글목록

등록된 댓글이 없습니다.

메시어스 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기

태그1

인기글

더보기
  • 인기 게시물이 없습니다.
메시어스 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기
이메일 : sales-kor@mescius.com | 전화 : 1670-0583 | 경기도 과천시 과천대로 7길 33, 디테크타워 B동 1107호 메시어스(주) 대표자 : 허경명 | 사업자등록번호 : 123-84-00981 | 통신판매업신고번호 : 2013-경기안양-00331 ⓒ 2024 MESCIUS inc. All rights reserved.