איסוף נתונים באמצעות משתנה קלט

במאמר הזה נסביר איך ליצור משתנה קלט.

כדי להפעיל שלבים, צריך לספק פרטים מסוימים. לדוגמה, כדי לשלוח אימייל צריך כתובת אימייל. כדי לספק את המידע הנדרש הזה, צריך להגדיר משתני קלט. אחרי שמגדירים משתני קלט, בדרך כלל המשתמש מגדיר אותם בכרטיס ההגדרות של השלב בזמן שהוא מגדיר את השלב.

מגדירים את משתנה הקלט בשני מקומות: בקובץ המניפסט של התוסף ובקוד עם כרטיס הגדרות שבו המשתמשים יכולים להזין ערכים למשתני הקלט.

הגדרת משתנה הקלט בקובץ המניפסט

בתוך קובץ המניפסט, מציינים משתני קלט באמצעות המערך inputs[]. כל פריט במערך inputs[] כולל את המאפיינים הבאים:

  • id: מזהה ייחודי של משתנה קלט. כדי לאפשר לתהליך לשייך רכיב קלט של כרטיס הגדרות למשתנה הקלט הזה, השם צריך להיות זהה לשם של רכיב הכרטיס המתאים.
  • description: תיאור של משתנה הקלט שיוצג למשתמשי הקצה.
  • cardinality: כמה ערכים מותרים. הערכים האפשריים הם:
    • SINGLE: מותר להשתמש רק בערך אחד.
  • dataType: סוג הערכים הקבילים. ל-dataType יש את המאפיין basicType שמגדיר את סוג הנתונים. הערכים התקינים כוללים:
    • STRING: מחרוזת אלפאנומרית.
    • INTEGER: מספר.
    • TIMESTAMP: חותמת זמן בפורמט 'אלפיות השנייה מאז ראשית זמן יוניקס'. לדוגמה, התאריך 27 בנובמבר 2025 בשעה 16:49:02 (שעון UTC) מיוצג כ-1764262142988.
    • BOOLEAN: הערך יכול להיות True או False.
    • EMAIL_ADDRESS: כתובת אימייל בפורמט dana@example.com.

בדוגמה הבאה מוגדרים שלושה משתני קלט לשלב של מחשבון. שני משתני הקלט הראשונים הם מספרים שלמים, והשלישי הוא פעולה אריתמטית.

JSON

{
  "timeZone": "America/Los_Angeles",
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "addOns": {
    "common": {
      "name": "Calculator",
      "logoUrl": "https://www.gstatic.com/images/branding/productlogos/calculator_search/v1/web-24dp/logo_calculator_search_color_1x_web_24dp.png",
      "useLocaleFromApp": true
    },
    "flows": {
      "workflowElements": [
        {
          "id": "calculatorDemo",
          "state": "ACTIVE",
          "name": "Calculate",
          "description": "Asks the user for two values and a math operation, then performs the math operation on the values and outputs the result.",
          "workflowAction": {
            "inputs": [
              {
                "id": "value1",
                "description": "value1",
                "cardinality": "SINGLE",
                "dataType": {
                  "basicType": "INTEGER"
                }
              },
              {
                "id": "value2",
                "description": "value2",
                "cardinality": "SINGLE",
                "dataType": {
                  "basicType": "INTEGER"
                }
              },
              {
                "id": "operation",
                "description": "operation",
                "cardinality": "SINGLE",
                "dataType": {
                  "basicType": "STRING"
                }
              }
            ],
            "outputs": [
              {
                "id": "result",
                "description": "Calculated result",
                "cardinality": "SINGLE",
                "dataType": {
                  "basicType": "INTEGER"
                }
              }
            ],
            "onConfigFunction": "onConfigCalculate",
            "onExecuteFunction": "onExecuteCalculate"
          }
        }
      ]
    }
  }
}

הגדרת משתנה הקלט בקוד

הקוד של השלב כולל פונקציה בשם onConfigFunction() שמחזירה כרטיס הגדרה שמגדיר ווידג'ט של כרטיס קלט אחד לכל משתנה קלט שמוגדר במערך inputs[] של קובץ המניפסט.

לווידג'טים של שדות ההזנה שמוגדרים בכרטיס ההגדרות יש את הדרישות הבאות:

  • הערך name של כל ווידג'ט קלט צריך להיות זהה לערך id של משתנה הקלט התואם בקובץ המניפסט.
  • הקרדינליות של ווידג'ט הקלט צריכה להתאים לקרדינליות של משתנה הקלט cardinality בקובץ המניפסט.
  • טיפוס הנתונים של הווידג'ט של הקלט חייב להיות זהה לטיפוס הנתונים של משתנה הקלט dataType בקובץ המניפסט. אם למשתנה הקלט יש dataType של מספר שלם, הוא לא יכול להכיל מחרוזת.

כדי לקבל עזרה ביצירת ממשקי כרטיסים, אפשר לעיין באחת מהאפשרויות הבאות:

בדוגמה הבאה מוחזר כרטיס הגדרה לכל ווידג'ט קלט שהוגדר בקטע הגדרת משתנה הקלט בקובץ המניפסט.

Apps Script

/**
* Generates and displays a configuration card for the sample calculation step.
*
* This function creates a card with input fields for two values and a drop-down
* for selecting an arithmetic operation.
*
* The input fields are configured to let the user select outputs from previous
* workflow steps as input values using the `hostAppDataSource` property.
*/
function onConfigCalculate() {
  const firstInput = CardService.newTextInput()
    .setFieldName("value1") // "FieldName" must match an "id" in the manifest file's inputs[] array.
    .setTitle("First Value")
    .setHostAppDataSource(
      CardService.newHostAppDataSource()
        .setWorkflowDataSource(
          CardService.newWorkflowDataSource()
            .setIncludeVariables(true)
        )
    );

  const secondInput = CardService.newTextInput()
    .setFieldName("value2") // "FieldName" must match an "id" in the manifest file's inputs[] array.
    .setTitle("Second Value")
    .setHostAppDataSource(
      CardService.newHostAppDataSource()
        .setWorkflowDataSource(
          CardService.newWorkflowDataSource()
            .setIncludeVariables(true)
        )
    );

  const selectionInput = CardService.newSelectionInput()
    .setTitle("operation")
    .setFieldName("operation") // "FieldName" must match an "id" in the manifest file's inputs[] array.
    .setType(CardService.SelectionInputType.DROPDOWN)
    .addItem("+", "+", false)
    .addItem("-", "-", true)
    .addItem("x", "x", false)
    .addItem("/", "/", false);

  const sections = CardService.newCardSection()
    .setHeader("Action_sample: Calculate")
    .setId("section_1")
    .addWidget(firstInput)
    .addWidget(selectionInput)
    .addWidget(secondInput)

  let card = CardService.newCardBuilder()
    .addSection(sections)
    .build();

  return card;
}

שימוש במשתני פלט משלבים קודמים

אפשר להגדיר משתני קלט כדי לקבל משתני פלט משלבים קודמים בתהליך העבודה.

הפעלת בחירת משתנים

כדי לאפשר למשתמשים לבחור משתנים משלבים קודמים, משתמשים במאפיין includeVariables בווידג'טים TextInput ו-SelectionInput.

לווידג'טים TextInput ו-SelectionInput יש את התכונות הבאות שספציפיות ל-Workspace Studio:

  • includeVariables: מאפיין בוליאני שמאפשר למשתמשים לבחור משתנים משלבים קודמים. כדי שכלי בחירת המשתנים יוצג בשלבים הבאים, צריך למפות את משתנה הפלט המתאים למשתנה, וגם את אירוע ההתחלה.
  • type: ערך ממוספר שמשלים אוטומטית הצעות. הערכים הנתמכים כוללים:
    • USER: מספק הצעות להשלמה אוטומטית של אנשים שנמצאים ברשימת אנשי הקשר של המשתמש.
    • SPACE: מספק הצעות להשלמה אוטומטית של מרחבים ב-Google Chat שהמשתמש חבר בהם.

אם גם includeVariables וגם type מוגדרים, שדה הקלט משלב את החוויות שלהם. המשתמשים יכולים לבחור משתנה של ההתאמה type מתוך תפריט נפתח, ולראות הצעות להשלמה אוטומטית שלו.

  • השלמה אוטומטית של הצעות למרחב ב-Google Chat.
    איור 4: משתמש בודק את ההצעות להשלמה אוטומטית כשבוחרים מרחב.
  • בתפריט המשתנים, המשתמשים יכולים לבחור משתני פלט משלבים קודמים.
    איור 5: משתמש בוחר את משתנה הפלט של שלב קודם מהתפריט הנפתח ➕Variables (משתנים).

בחירת משתנה פלט אחד בלבד באמצעות תפריט אפשרויות נוספות

אתם יכולים להגדיר את הווידג'ט SelectionInput כדי לאפשר למשתמשים לבחור משתנה פלט אחד משלב קודם באמצעות תפריט האפשרויות הנוספות.

כשמגדירים את SelectionInputType ל-OVERFLOW_MENU, הווידג'ט משמש ככלי ייעודי לבחירת משתנים. בשונה משימוש ב-includeVariables עם TextInput, שממיר ערכי משתנים למחרוזות, OVERFLOW_MENU שומר על סוג הנתונים המקורי של המשתנה שנבחר.

Apps Script

const selectionInput = CardService.newSelectionInput()
  .setFieldName("variable_picker_1")
  .setTitle("Variable Picker")
  .setType(
    CardService.SelectionInputType.OVERFLOW_MENU
  );

איך מאפשרים למשתמשים לשלב בין טקסט ומשתני פלט

אפשר להגדיר את הווידג'טים של TextInput כדי לשלוט באינטראקציה של המשתמשים עם הטקסט ועם משתני הפלט באמצעות setInputMode().

  • RICH_TEXT: מאפשר למשתמשים לשלב טקסט ומשתני פלט. התוצאה היא מחרוזת אחת משורשרת.
  • PLAIN_TEXT: הגבלת הקלט. המשתמשים יכולים להקליד טקסט או לבחור משתנה פלט יחיד. בחירת משתנה מחליפה את הטקסט הקיים. משתמשים במצב הזה כדי לאכוף סוגי נתונים ספציפיים שמוגדרים בקובץ המניפסט.

בתמונה הבאה מוצגים שני ווידג'טים של TextInput. הראשון מוגדר כ-RICH_TEXT וכולל טקסט ומשתנה פלט. השני מוגדר כ-PLAIN_TEXT ומאפשר רק משתנה פלט.

  • ווידג'טים של קלט טקסט שהוגדרו כ-RICH_TEXT ו-PLAIN_TEXT
    איור 3: ווידג'טים של הזנת טקסט שהוגדרו כ-RICH_TEXT וPLAIN_TEXT.

מומלץ להגדיר במפורש את מצב הקלט לכל הווידג'טים של TextInput.

קובץ המניפסט להגדרת ווידג'טים של TextInput עם מצבי קלט שונים:

JSON

{
  "timeZone": "America/Toronto",
  "dependencies": {},
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "addOns": {
    "common": {
      "name": "Text and output variable demo",
      "logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/pets_black_48dp.png",
      "useLocaleFromApp": true
    },
    "flows": {
      "workflowElements": [
        {
          "id": "richTextDemo",
          "state": "ACTIVE",
          "name": "Rich Text Demo",
          "description": "Show the difference between rich text and plain text TextInput widgets",
          "workflowAction": {
            "inputs": [
              {
                "id": "value1",
                "description": "First user input",
                "cardinality": "SINGLE",
                "dataType": {
                  "basicType": "STRING"
                }
              },
              {
                "id": "value2",
                "description": "Second user input",
                "cardinality": "SINGLE",
                "dataType": {
                  "basicType": "STRING"
                }
              }
            ],
            "onConfigFunction": "onConfiguration",
            "onExecuteFunction": "onExecution"
          }
        }
      ]
    }
  }
}

הנה הקוד להגדרת ווידג'טים של TextInput עם מצבי קלט שונים:

Apps Script

function onConfiguration() {
  const input1 = CardService.newTextInput()
    .setFieldName("value1")
    .setId("value1")
    .setTitle("Rich Text")
    .setHostAppDataSource(
      CardService.newHostAppDataSource()
        .setWorkflowDataSource(
          CardService.newWorkflowDataSource()
            .setIncludeVariables(true)
        )
    )
    // Set input mode to RICH_TEXT to allow mixed text and variables.
    .setInputMode(CardService.TextInputMode.RICH_TEXT);

  const input2 = CardService.newTextInput()
    .setFieldName("value2")
    .setId("value2")
    .setTitle("Plain text")
    .setHostAppDataSource(
      CardService.newHostAppDataSource()
        .setWorkflowDataSource(
          CardService.newWorkflowDataSource()
            .setIncludeVariables(true)
        )
    )
    // Set input mode to PLAIN_TEXT to enforce single variable selection.
    .setInputMode(CardService.TextInputMode.PLAIN_TEXT);

  const section = CardService.newCardSection()
    .addWidget(input1)
    .addWidget(input2);

  const card = CardService.newCardBuilder()
    .addSection(section)
    .build();

  return card;
}

function onExecution(e) {
}

התאמה אישית של לחצני בחירת משתנים

אתם יכולים להתאים אישית את הלחצן של בורר המשתנים על ידי הגדרת הגודל והתווית של הלחצן.

גודל כפתור

כדי להגדיר את גודל הלחצן, משתמשים ב-setVariableButtonSize() עם אחת מהאפשרויות הבאות של VariableButtonSize enum:

  • UNSPECIFIED: ברירת המחדל. הכפתור מוצג בצורה קומפקטית בחלונית הצדדית ובגודל מלא בהקשרים אחרים.
  • COMPACT: בכפתור מוצג רק סימן הפלוס (+).
  • FULL_SIZE: הכפתור מציג את התווית המלאה.

תווית הכפתור

כדי להגדיר את הטקסט של הכפתור, משתמשים בתג setVariableButtonLabel().

דוגמה: התאמה אישית של כלי לבחירת משתנים

בדוגמה הבאה מוצגות הגדרות של ווידג'טים מסוג TextInput עם גדלים שונים של לחצני בחירת משתנים ותווית בהתאמה אישית.

  • התאמה אישית של לחצן הבחירה של משתנים באינטרנט.
    איור 1: התאמה אישית של לחצן לבחירת משתנים באינטרנט.
  • התאמה אישית של לחצן לבחירת משתנים בחלונית צדדית של תוסף.
    איור 2: התאמה אישית של לחצן לבחירת משתנים בחלונית צדדית של תוסף.

קובץ המניפסט להתאמה אישית של לחצני בורר המשתנים:

JSON

{
  "timeZone": "America/Los_Angeles",
  "dependencies": {},
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "oauthScopes": [
    "https://www.googleapis.com/auth/script.locale"
  ],
  "addOns": {
    "common": {
      "name": "Variable button customization",
      "logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/pets_black_48dp.png",
      "useLocaleFromApp": true
    },
    "flows": {
      "workflowElements": [
        {
          "id": "variable_picker_customization",
          "state": "ACTIVE",
          "name": "Variable Picker demo",
          "description": "List all possible variable picker customization options",
          "workflowAction": {
            "onConfigFunction": "onUpdateCardConfigFunction",
            "onExecuteFunction": "onUpdateCardExecuteFunction"
          }
        }
      ]
    }
  }
}

הנה הקוד להתאמה אישית של לחצני בורר המשתנים:

Apps Script

function onUpdateCardConfigFunction(event) {
  const textInput1 = CardService.newTextInput()
    .setFieldName("value1")
    .setTitle("Regular variable picker button")
    .setHostAppDataSource(
      CardService.newHostAppDataSource().setWorkflowDataSource(
        CardService.newWorkflowDataSource()
          .setIncludeVariables(true)
          .setVariableButtonSize(CardService.VariableButtonSize.UNSPECIFIED)
      )
    );

  const textInput2 = CardService.newTextInput()
    .setFieldName("value2")
    .setTitle("Size: Unspecified")
    .setHostAppDataSource(
      CardService.newHostAppDataSource().setWorkflowDataSource(
        CardService.newWorkflowDataSource()
          .setIncludeVariables(true)
          .setVariableButtonSize(CardService.VariableButtonSize.UNSPECIFIED)
      )
    );

  const textInput3 = CardService.newTextInput()
    .setFieldName("value3")
    .setTitle("Size: Full size")
    .setHostAppDataSource(
      CardService.newHostAppDataSource().setWorkflowDataSource(
        CardService.newWorkflowDataSource()
          .setIncludeVariables(true)
          .setVariableButtonSize(CardService.VariableButtonSize.FULL_SIZE)
      )
    );

  const textInput4 = CardService.newTextInput()
    .setFieldName("value4")
    .setTitle("Size: Compact")
    .setHostAppDataSource(
      CardService.newHostAppDataSource().setWorkflowDataSource(
        CardService.newWorkflowDataSource()
          .setIncludeVariables(true)
          .setVariableButtonSize(CardService.VariableButtonSize.COMPACT)
      )
    );

  const textInput5 = CardService.newTextInput()
    .setFieldName("value5")
    .setTitle("Custom button label")
    .setHostAppDataSource(
      CardService.newHostAppDataSource().setWorkflowDataSource(
        CardService.newWorkflowDataSource()
          .setIncludeVariables(true)
          .setVariableButtonLabel("New button label!")
      )
    );

  var cardSection = CardService.newCardSection()
    .addWidget(textInput1)
    .addWidget(textInput2)
    .addWidget(textInput3)
    .addWidget(textInput4)
    .addWidget(textInput5)
    .setId("section_1");

  var card = CardService.newCardBuilder().addSection(cardSection).build();

  return card;
}

function onUpdateCardExecuteFunction(event) {
}

הגדרת השלמה אוטומטית של נתונים ב-Google Workspace

אפשר גם לאכלס הצעות להשלמה אוטומטית מנתונים בסביבת Google Workspace של המשתמש:

  • משתמשי Google Workspace: מאכלסים משתמשים באותו ארגון Google Workspace.
  • מרחבים ב-Google Chat: מאכלסים את המרחבים ב-Google Chat שהמשתמש חבר בהם.

כדי להגדיר את זה, צריך להגדיר את התג PlatformDataSource בווידג'ט SelectionInput, ולציין את הערך של WorkflowDataSourceType כ-USER או כ-SPACE.

Apps Script

// User Autocomplete
var multiSelect2 =
  CardService.newSelectionInput()
    .setFieldName("value2")
    .setTitle("User Autocomplete")
    .setType(CardService.SelectionInputType.MULTI_SELECT)
    .setMultiSelectMaxSelectedItems(3)
    .setPlatformDataSource(
      CardService.newPlatformDataSource()
        .setHostAppDataSource(
          CardService.newHostAppDataSource()
            .setWorkflowDataSource(
              CardService.newWorkflowDataSource()
                .setIncludeVariables(true)
                .setType(CardService.WorkflowDataSourceType.USER)
            ))
    );

// Chat Space Autocomplete
var multiSelect3 =
  CardService.newSelectionInput()
    .setFieldName("value3")
    .setTitle("Chat Space Autocomplete")
    .setType(CardService.SelectionInputType.MULTI_SELECT)
    .setMultiSelectMaxSelectedItems(3)
    .setPlatformDataSource(
      CardService.newPlatformDataSource()
        .setHostAppDataSource(
          CardService.newHostAppDataSource()
            .setWorkflowDataSource(
              CardService.newWorkflowDataSource()
                .setIncludeVariables(true)
                .setType(CardService.WorkflowDataSourceType.SPACE)
            ))
    );

דוגמה: שילוב של סוגי השלמה אוטומטית

בדוגמה הבאה מוצגת פונקציה onConfig שיוצרת כרטיס עם שלושה ווידג'טים של SelectionInput, שממחישה השלמה אוטומטית של שרת, משתמש ומרחב:

JSON

{
  "timeZone": "America/Los_Angeles",
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "addOns": {
    "common": {
      "name": "Autocomplete Demo",
      "logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/pets_black_48dp.png",
      "useLocaleFromApp": true
    },
    "flows": {
      "workflowElements": [
        {
          "id": "autocomplete_demo",
          "state": "ACTIVE",
          "name": "Autocomplete Demo",
          "description": "Provide autocompletion in input fields",
          "workflowAction": {
            "inputs": [
              {
                "id": "value1",
                "description": "A multi-select field with autocompletion",
                "cardinality": "SINGLE",
                "dataType": {
                  "basicType": "STRING"
                }
              }
            ],
            "onConfigFunction": "onConfigAutocomplete",
            "onExecuteFunction": "onExecuteAutocomplete"
          }
        }
      ]
    }
  }
}

Apps Script

function onConfigAutocompleteTest(event) {
  // Handle autocomplete request
  if (event.workflow && event.workflow.elementUiAutocomplete) {
    return handleAutocompleteRequest(event);
  }

  // Server-side autocomplete widget
  var multiSelect1 =
    CardService.newSelectionInput()
      .setFieldName("value1")
      .setTitle("Server Autocomplete")
      .setType(CardService.SelectionInputType.MULTI_SELECT)
      .setMultiSelectMaxSelectedItems(3)
      .addDataSourceConfig(
        CardService.newDataSourceConfig()
          .setRemoteDataSource(
            CardService.newAction().setFunctionName('getAutocompleteResults')
          )
      )
      .addDataSourceConfig(
        CardService.newDataSourceConfig()
          .setPlatformDataSource(
            CardService.newPlatformDataSource()
              .setHostAppDataSource(
                CardService.newHostAppDataSource()
                  .setWorkflowDataSource(
                    CardService.newWorkflowDataSource()
                      .setIncludeVariables(true)
                  ))
          )
      );

  // User autocomplete widget
  var multiSelect2 =
    CardService.newSelectionInput()
      .setFieldName("value2")
      .setTitle("User Autocomplete")
      .setType(CardService.SelectionInputType.MULTI_SELECT)
      .setMultiSelectMaxSelectedItems(3)
      .setPlatformDataSource(
        CardService.newPlatformDataSource()
          .setHostAppDataSource(
            CardService.newHostAppDataSource()
              .setWorkflowDataSource(
                CardService.newWorkflowDataSource()
                  .setIncludeVariables(true)
                  .setType(CardService.WorkflowDataSourceType.USER)
              ))
      );

  // Space autocomplete widget
  var multiSelect3 =
    CardService.newSelectionInput()
      .setFieldName("value3")
      .setTitle("Chat Space Autocomplete")
      .setType(CardService.SelectionInputType.MULTI_SELECT)
      .setMultiSelectMaxSelectedItems(3)
      .setPlatformDataSource(
        CardService.newPlatformDataSource()
          .setHostAppDataSource(
            CardService.newHostAppDataSource()
              .setWorkflowDataSource(
                CardService.newWorkflowDataSource()
                  .setIncludeVariables(true)
                  .setType(CardService.WorkflowDataSourceType.SPACE)
              ))
      );

  var sectionBuilder =
    CardService.newCardSection()
      .addWidget(multiSelect1)
      .addWidget(multiSelect2)
      .addWidget(multiSelect3);

  var card =
    CardService.newCardBuilder()
      .addSection(sectionBuilder)
      .build();
  return card;
}

function handleAutocompleteRequest(event) {
  var invokedFunction = event.workflow.elementUiAutocomplete.invokedFunction;
  var query = event.workflow.elementUiAutocomplete.query;

  if (invokedFunction != "getAutocompleteResults" || query == undefined || query == "") {
    return {};
  }

  // Query your data source to get results
  let autocompleteResponse = AddOnsResponseService.newUpdateWidget()
    .addSuggestion(
      query + " option 1",
      query + "_option1",
      false,
      "https://developers.google.com/workspace/add-ons/images/person-icon.png",
      "option 1 bottom text"
    )
    .addSuggestion(
      query + " option 2",
      query + "_option2",
      false,
      "https://developers.google.com/workspace/add-ons/images/person-icon.png",
      "option 2 bottom text"
    ).addSuggestion(
      query + " option 3",
      query + "_option3",
      false,
      "https://developers.google.com/workspace/add-ons/images/person-icon.png",
      "option 3 bottom text"
    );

  const modifyAction = AddOnsResponseService.newAction()
    .addModifyCard(
      AddOnsResponseService.newModifyCard()
        .setUpdateWidget(autocompleteResponse)
    );

  return AddOnsResponseService.newRenderActionBuilder()
    .setAction(modifyAction)
    .build();
}

אימות משתנה הקלט

מומלץ לוודא שהמשתמש מזין ערך מתאים. איך מאמתים משתנה קלט