Input Field String Check With Pattern

403 views
Skip to first unread message

ugur gelisken

unread,
Feb 15, 2019, 8:28:24 AM2/15/19
to Blockly
Hello...

There is a string fields in a block. I want to check the text entered here with a pattern ("^ [a-zA-Z0-9] + ([]? [A-zA-Z0-9-.:@]+)*$"). If it doesn't match the pattern, I want to show a warning icon next to the text box. How can I do that?

Beka Westberg

unread,
Feb 15, 2019, 10:11:13 AM2/15/19
to Blockly
Hello,

I think what you're looking for is a field validator, this allows you to pass a function to a field that is run whenever the field is editted. Here's an example of what a block definition might look like:

Blockly.Blocks['test_block'] = {
  init
: function() {
   
this.appendDummyInput()
     
// This line is changed. I used bind so that "this" inside the
     
// validator function is the block, rather than the FieldTextInput, you
     
// may not want to do this if you want to access properties of the the field.
     
.appendField(new Blockly.FieldTextInput(
         
"defaultText", this.validator.bind(this)), "INPUT");
   
this.setColour(230);
   
this.setTooltip("");
   
this.setHelpUrl("");
 
},


  validator
: function(inputText) {
   
if (/^ [a-zA-Z0-9] + ([]? [A-zA-Z0-9-.:@]+)*$/.test(inputText)) {
     
// If the text is valid we have to return it, just how validators work.
     
return inputText;
   
} else {
     
// This sets the warning.
     
this.setWarningText("myWarningTextHere");
     
// You may or may not want to return this. You can return different
     
// text so that it displays something different, or you can return
     
// null to negate the user's changes.
     
return inputText;
   
}
 
}
};

Note: Warnings are always displayed at the front of the block, as far as I know there's no way to get them to display at a cetain location :/

I hope that gives you a place to start! If you have any other questions be sure to reply!
Beka

ugur gelisken

unread,
Feb 16, 2019, 5:43:31 PM2/16/19
to Blockly
Thanks Beka. You're great.

Can I show an icon next to this text box? If the condition is negative, you want to show a warning icon.

Beka Westberg

unread,
Feb 16, 2019, 7:05:13 PM2/16/19
to Blockly
Hello,

So as far as I know blockly-icons (where you click on them and a bubble pops out) are always at the front of the block, so there's no way to place them next to a specific text field.

IconsExample.jpg



But if you want to add an image with no bubble, that is doable.

WarningFalse.jpg

WarningTrue.jpg



You're going to want to edit the form of the block rather than just calling setWarning(). Here's an example:

Blockly.Blocks['test_block'] = {
  init
: function() {

   
// Notice how some of these things have names that didn't before.
   
this.appendDummyInput("DUMMY_INPUT")
     
.appendField("descriptive text")
     
.appendField(new Blockly.FieldTextInput(
       
"input text", this.validator.bind(this)), "TEXT_INPUT");

   
this.setColour(230);
   
this.setTooltip("");
   
this.setHelpUrl("");
 
},



  hasWarning
: false,


  validator
: function(inputText) {
   
if (/^ [a-zA-Z0-9] + ([]? [A-zA-Z0-9-.:@]+)*$/.test(inputText) && this.hasWarning) {
     
this.hasWarning = false;
     
this.removeField("WARNING_ICON");
     
return inputText;
   
} else if (!this.hasWarning) {
     
this.hasWarning = true;
     
// Inserts the warning after the descriptive text.
     
this.getInput("DUMMY_INPUT").insertFieldAt(1, new Blockly.FieldImage(
         
"https://www.gstatic.com/codesite/ph/images/star_on.gif",
         
15, 15, "*"), "WARNING_ICON");
     
return inputText;
   
}
 
}
};

The only problem with this is that the warning image won't persist between saving/loading the workspace. If you want the warning to save you'll need to define a mutator, which follows a similar principle to the above.

I hope that helps! Again please reply if you're looking for more/different information!
Beka

ugur gelisken

unread,
Feb 18, 2019, 3:11:09 AM2/18/19
to Blockly
Not working... But i did it with your code..

 Blockly.Blocks.text_reg = {
    init: function() {
        this.appendDummyInput("DUMMY_INPUT")
            .appendField(new Blockly.FieldImage("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAn0lEQVQI1z3OMa5BURSF4f/cQhAKjUQhuQmFNwGJEUi0RKN5rU7FHKhpjEH3TEMtkdBSCY1EIv8r7nFX9e29V7EBAOvu7RPjwmWGH/VuF8CyN9/OAdvqIXYLvtRaNjx9mMTDyo+NjAN1HNcl9ZQ5oQMM3dgDUqDo1l8DzvwmtZN7mnD+PkmLa+4mhrxVA9fRowBWmVBhFy5gYEjKMfz9AylsaRRgGzvZAAAAAElFTkSuQmCC", 12, 12, ""))   
                .appendField(new Blockly.FieldTextInput("", this.validator.bind(this)), "TEXT")
                .appendField(new Blockly.FieldImage("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAqUlEQVQI1z3KvUpCcRiA8ef9E4JNHhI0aFEacm1o0BsI0Slx8wa8gLauoDnoBhq7DcfWhggONDmJJgqCPA7neJ7p934EOOKOnM8Q7PDElo/4x4lFb2DmuUjcUzS3URnGib9qaPNbuXvBO3sGPHJDRG6fGVdMSeWDP2q99FQdFrz26Gu5Tq7dFMzUvbXy8KXeAj57cOklgA+u1B5AoslLtGIHQMaCVnwDnADZIFIrXsoXrgAAAABJRU5ErkJggg==", 12, 12, ""))   
            .appendField(" ✅")
        this.setInputsInline(true);
        this.setOutput(true, 'String');
        this.setColour(120);
    },
    validator: function (inputText) {
        if (/^([a-zA-Z0-9 _-]+)$/.test(inputText)) {
            this.getInput("DUMMY_INPUT").fieldRow[3].setText(" ✔");
        } else {
            this.getInput("DUMMY_INPUT").fieldRow[3].setText(" ✖")
        }
    }
};

Blockly.Arduino.text_reg = function (block) {
    var text_value = block.getFieldValue('TEXT');
    var code = text_value;
    return [code, Blockly.Arduino.ORDER_NONE];
};

Beka Westberg

unread,
Feb 18, 2019, 10:04:12 AM2/18/19
to Blockly
Hello,

Could you give a little bit more detail about how it's breaking? Using your setText() method I got this code to work:

Blockly.Blocks['test_block'] = {

  init
: function() {
   
this.appendDummyInput("DUMMY_INPUT")

     
.appendField("descriptive text")
     
.appendField(new Blockly.FieldTextInput(
       
"input text", this.validator.bind(this)), "TEXT_INPUT")

     
.appendField("✔");

   
this.setColour(230);
   
this.setTooltip("");
   
this.setHelpUrl("");
 
},


  validator
: function(inputText) {

   
if (/^ [a-zA-Z0-9] + ([]? [A-zA-Z0-9-.:@]+)*$/.test(inputText)) {
     
// Mine says fieldRow[2] instead of fieldRow[3] because I only have 3
     
// fields.
     
this.getInput("DUMMY_INPUT").fieldRow[2].setText("✔");
   
} else {
     
this.getInput("DUMMY_INPUT").fieldRow[2].setText("✖");
   
}
 
}
};

If I have just a bit more context I'm sure we can get something figured out : )
-- Beka

ugur gelisken

unread,
Feb 26, 2019, 1:42:44 AM2/26/19
to Blockly
Hi Beka.


I guess that's the old version. I would also revise the codes according to the old version. sometimes it can be difficult.

My solution to this is as follows:

// TEXT INOUT WITH REGEX AND MAX 64 CHAR 
Blockly.Blocks.text_with_regex_check = {
    init: function() {
        this.appendDummyInput("DUMMY_INPUT")
            .appendField(new Blockly.FieldImage("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAn0lEQVQI1z3OMa5BURSF4f/cQhAKjUQhuQmFNwGJEUi0RKN5rU7FHKhpjEH3TEMtkdBSCY1EIv8r7nFX9e29V7EBAOvu7RPjwmWGH/VuF8CyN9/OAdvqIXYLvtRaNjx9mMTDyo+NjAN1HNcl9ZQ5oQMM3dgDUqDo1l8DzvwmtZN7mnD+PkmLa+4mhrxVA9fRowBWmVBhFy5gYEjKMfz9AylsaRRgGzvZAAAAAElFTkSuQmCC", 12, 12, "Geçerli veri."))   
            .appendField(new Blockly.FieldTextInput("", this.validator.bind(this)), "TEXT")
            .appendField(new Blockly.FieldImage("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAqUlEQVQI1z3KvUpCcRiA8ef9E4JNHhI0aFEacm1o0BsI0Slx8wa8gLauoDnoBhq7DcfWhggONDmJJgqCPA7neJ7p934EOOKOnM8Q7PDElo/4x4lFb2DmuUjcUzS3URnGib9qaPNbuXvBO3sGPHJDRG6fGVdMSeWDP2q99FQdFrz26Gu5Tq7dFMzUvbXy8KXeAj57cOklgA+u1B5AoslLtGIHQMaCVnwDnADZIFIrXsoXrgAAAABJRU5ErkJggg==", 12, 12, " Geçersiz veri."))   
            .appendField(" ✅")
        this.setInputsInline(true);
        this.setTooltip("Sadece, İngilizce büyük-küçük harf, rakam, kelime içinde tek boşluk, : ve @ işaretleri geçerlidir. Azami karakter sayısı 64.");
        this.setOutput(!0, "String");
        this.setColour(120);
    },
    validator: function (inputText) {
        if (/^[a-zA-Z0-9]+([ ]?[a-zA-Z0-9-.:@]+)*$/.test(inputText) && inputText.length <= 64) {
            this.getInput("DUMMY_INPUT").fieldRow[3].setText(" ✔");
        } else {
            this.getInput("DUMMY_INPUT").fieldRow[3].setText(" ✖")
        }
    }
};
Blockly.Arduino.text_with_regex_check = function (block) {
    var text_value = block.getFieldValue('TEXT');
    var code = text_value;
    return [code, Blockly.Arduino.ORDER_NONE];
};


PS: (Base64 images: left and right double qoutes)

Beka Westberg

unread,
Feb 26, 2019, 9:45:15 AM2/26/19
to Blockly
I'm glad you got it working!
Reply all
Reply to author
Forward
0 new messages