icon select form
@param  string $name
@param  string $value
@param  array  $settings
@return string
432399
static public function icon($name, $value=null, $settings=[])
    {
        $settings['media_type'] = 'icon';
        $settings['with_input'] = 'hidden';
        if (!isset($settings['readonly'])) $settings['readonly'] = "readonly";
        if (!isset($settings['modal_url'])) $settings['modal_url'] = Ioc::url('common/data/select/icon');
        return static::select($name, $value, $settings);
    }
1118280
static public function fieldForm($field, $name, $value=null, $settings=[])
    {
        // format field
        $field = \Wslim\Cms\FieldHelper::formatField($field);
        
        if (!$name) {
            $name  = 'row[' . $field['field_name'] . ']';
        }
        
        // value 此处进行数据解码和反转义，当值不为空
        
        // settings 处理，合并加入 field 的一些选项
        foreach ($field as $k => $v) {
            if (strpos($k, 'form_') === 0) {
                $sk = $k == 'form_type' ? $k : str_replace('form_', '', $k);
                if (!isset($settings[$sk])) $settings[$sk] = $v;
            }
        }
        
        return static::auto($name, $value, $settings);
    }
248061
protected function typeByCssSelector($value, $name, $clear = false)
    {
        return $this->typeBySelectorType('cssSelector', $value, $name, $clear);
    }
256765
public function setSetting($name, $value = null)
    {
        $oldValue = $this->getSetting($name);
        if ($value != $oldValue) {
            if (!empty($value)) {
                $this->settings[$name] = $value;
            } else {
                unset($this->settings[$name]);
            }
            $this->settingsChanged = true;
        }
    }
640904
public function set($name, $value) {
        $setting = &$this->settings;
        $names   = explode('.', $name);
        $lname   = array_pop($names);
        if ($names) {
            foreach ($names as $n) {
                if (!isset($setting[ $n ])) {
                    $setting[ $n ] = [];
                }
                $setting = &$setting[ $n ];
            }
        }
        $setting[ $lname ] = $value;
    }
1371369
public static function cssClassProvider($name, $value)
    {
        switch ($name) {
            case 'table_condensed':
                return $value ? 'table-condensed' : '';
                break;
            case 'collapsed_sidebar':
                return $value ? 'sidebar-collapse' : '';
                break;
            default:
                return parent::cssClassProvider($name, $value);
        }
    }
1256594
public function setSetting( string $name, $value ): self
	{
		if (in_array($name, self::SETTINGS_INIT_ONLY))
			throw new SettingsException("Settings option '$name' can only be set on initialization of the library.");

		$this->settings[$name] = $value;
		return $this;
	}
614820
static public function radio_gender($name, $value=null, $settings=[])
    {
        if (!isset($settings['data_source'])) {
            $settings['data_source'] = Constants::getGenders();
        }
        $settings['class'] = (isset($settings['class']) ? $settings['class'] : '' ) . ' list-inline';
        $value = Constants::getGenderValue($value);
        
        return static::radio_group($name, $value, $settings);
    }
1370749
public static function hidden(string $name, string $value = '', array $attributes = null) : string
    {
        // Set the input type
        $attributes['type'] = 'hidden';

        return Form::input($name, $value, $attributes);
    }
936414
public static function checkboxSmart($name, $checked = false, $options = [])
    {
        $options['checked'] = (boolean)$checked;
        $value = array_key_exists('value', $options) ? $options['value'] : '1';
        if (isset($options['uncheck'])) {
            // add a hidden field so that if the checkbox is not selected, it still submits a value
            $hidden = static::hiddenInput($name, $options['uncheck']);
            unset($options['uncheck']);
        } else {
            $hidden = '';
        }
        if (isset($options['label'])) {
            $label = $options['label'];
            $labelOptions = isset($options['labelOptions']) ? $options['labelOptions'] : [];
            unset($options['label'], $options['labelOptions']);
            $iconOptions = ArrayHelper::remove($options, 'iconOptions', []);
            $iconTag = ArrayHelper::remove($iconOptions, 'tag', 'i');
            $content = static::label(static::input('checkbox', $name, $value, $options) . Html::tag($iconTag, null, $iconOptions) . $label, null, $labelOptions);
            return $hidden . $content;
        } else {
            return $hidden . static::input('checkbox', $name, $value, $options);
        }
    }
1186817
static public function wx_contents_input($form_name, $form_value=null, $settings=null)
    {
        $settings['id']     = isset($settings['id']) ? $settings['id'] : str_replace(array('[', ']'), array('_'), $form_name);
        $index = 0;
        $template = <<<INPUT
<li style="%s" class="%s">
    <img src="%s" class="content-img">
    <div class="content-body">
        <span class="content-title">%s</span>
        <span class="content-description">%s</span>
        <input type="hidden" name="%s" value="%s" class="content-title-input">
        <input type="hidden" name="%s" value="%s" class="content-description-input">
        <input type="hidden" name="%s" value="%s" class="content-pic-url-input">
        <input type="hidden" name="%s" value="%s" class="content-url-input">
        <input type="hidden" name="%s" value="%s" class="content-id-input">
    </div>
    <div class="content-op">
        <input type="button" class="btn btn-primary btn-sm edit-content" value="编辑">
        <input type="button" class="btn btn-primary btn-sm delete-content" value="删除">
    </div>
</li>
INPUT;
        $str = '<ul class="list-unstyled contents-wrap">' . PHP_EOL;
        if (isset($form_value) && is_array($form_value)) foreach ($form_value as $k => $v) {
            $img_src = isset($v['pic_url']) ? $v['pic_url'] : '';
            $title = isset($v['title']) ? $v['title'] : '';
            $description = isset($v['description']) ? $v['description'] : '';
            $url = isset($v['url']) ? $v['url'] : '';
            $id  = isset($v['id']) ? $v['id'] : 0;
            $str .= sprintf($template
                , '', $settings['id'] . '-content-wrap-' . $index
                , $img_src, $title, $description
                , $settings['id'] . '['. $index . '][title]', $title
                , $settings['id'] . '['. $index . '][description]', $description
                , $settings['id'] . '['. $index . '][pic_url]', $img_src
                , $settings['id'] . '['. $index . '][url]', $url
                , $settings['id'] . '['. $index . '][id]', $id
            );
            $index += 1;
        }
        $str .= sprintf($template
            , 'display:none;', $settings['id'] . '-content-wrap-' . 'x'
            , '', '', ''
            , $settings['id'] . '['. 'x' . '][title]', ''
            , $settings['id'] . '['. 'x' . '][description]', ''
            , $settings['id'] . '['. 'x' . '][pic_url]', ''
            , $settings['id'] . '['. 'x' . '][url]', ''
            , $settings['id'] . '['. 'x' . '][id]', 0
        );
        $str .= '</ul>' . PHP_EOL;
        
        $str .= '<div style="margin-top:15px;">'. PHP_EOL;
        $str .= '    <input type="button" class="btn btn-warning btn-sm select-content" data-id="' . $settings['id'] . '" value="选择图文列表">';
        $str .= '    <input type="button" class="btn btn-warning btn-sm add-content" data-id="' . $settings['id'] . '" value="自定义图文列表">';
        $str .= '</div>'. PHP_EOL;
        
        //if (!static::$isLoadedImageText) {
        $select_url = isset($settings['modal_url']) ? $settings['modal_url'] : Ioc::url('common/data/select_content');
            $innerJs = <<<EOF
                <script>
                require(["util"], function(){
                    var index = "{$index}";
                	$(".contents-wrap").on("click", ".delete-content", function() {
                	    //console.log($(this));
                        $(this).parent().parent("li").remove();
                        return false;
                    });
                    $(".select-content").on("click", function() {
                        var tid = $(this).attr('data-id');
                        
                        var dlg = util.dialog.show({
                            width: '800px',
                    		title: '选择图文内容',
                    		url: "{$select_url}",
                    		okValue: '确 定',
                    		ok: false,
                    		cancelValue: '取消',
                    		cancel: null,
                    		cancelDisplay: true
                    	});
                    	
                        dlg.addEventListener('close', function () {
                            if (dlg.returnValue.data) {
                                console.log(dlg.returnValue);
                                data = dlg.returnValue.data;
                                if (data.length > 0) {
                    		        for (dindex in data) {
                    		            var item_index = Number(dindex) + Number(index);
                                        var tpl_ele = $("." + tid + '-content-wrap-x');
                                        var html = tpl_ele.html().replace(/\[x\]/g, '[' + item_index + ']');
                                        $('<li style="text-align:center;" class="' + tid + '-content-wrap-' + item_index + '">').insertBefore(tpl_ele).html(html);
                                        var ele = $("." + tid + '-content-wrap-' + item_index);
                                        ele.find(".content-img").attr('src', data[dindex]["pic_url"]).show();
                    		            ele.find(".content-title").html(data[dindex]["title"]);
                    		            ele.find(".content-description").html(data[dindex]["description"]);
                    		    
                                        ele.find(".content-title-input").val(data[dindex]["title"]);
                    		            ele.find(".content-description-input").val(data[dindex]["description"]);
                    		            ele.find(".content-pic-url-input").val(data[dindex]["pic_url"]);
                    		            ele.find(".content-url-input").val(data[dindex]["url"]);
                                    }
                    		        index = Number(index) + data.length;
                                }
                            }
                    	});
                        
                    });
                });
                </script>
EOF;
            $str .= $innerJs;
            // 动态的添加该输入框时脚本不能作用，暂时先重复脚本生成
            //static::$isLoadedImageText = true;
        //}
        return $str;
    }
292546
public static function url($name, $value = null, array $options = [])
    {
        self::exclure($options);

        return self::input('url', $name, $value, $options);
    }
713369
static public function multi($name, $value=null, $settings=[])
    {
        // settings 处理
        !isset($settings['form_type']) && $settings['form_type'] = 'text';
        unset($settings['with_multi']);
        $settings['no_wrap'] = 1; // 不让子调用项包裹div
        
        $value      = static::formatValueToArray($value);
        $count      = isset($settings['count']) ? intval($settings['count']) : (count($value) > 4 ? 4 : 4);
        $form_id    = isset($settings['id']) ? $settings['id'] : static::formatId($name);
        if (substr($name, strlen($name) - 2) == '[]') {
            $name = substr($name, 0, strlen($name) - 2);
        }
        
        // 是否带文字描述输入，注意此种情况保存数据时应该为 json
        $with_desc = isset($settings['with_desc']) && $settings['with_desc'] ? true : false;
        $str = '<div class="width:100%;overflow:hidden;">' . PHP_EOL;
        for ($i=0; $i<$count; $i++) {
            $settings['id'] = $form_id . '_' . $i;
            $str .= '<div class="form-inline" style="margin-top:10px;">' . PHP_EOL;
            $item_name = $name . '[' . $i . ']';
            if ($with_desc) {
                $item_value = isset($value[$i]['description']) ? $value[$i]['description'] : '';
                $str .= '描述: ' . static::text($item_name . '[description]', $item_value);
                
                $item_name = $item_name . '[value]';
                $item_value = isset($value[$i]['value']) ? $value[$i]['value'] : '';    // 如value 可能为pic_url
            } else {
                $item_value = isset($value[$i]) ? $value[$i] : '';
            }
            
            $str .= static::$form_type($item_name, $item_value, $settings);
            
            $str .= '</div>' . PHP_EOL;
        }
        $str .= '</div>';
        return $str;
    }
1173613
public function submit($name, $value = null, $attributes = null)
    {
        return '<input type="submit" name="'.$name.'" '.(($attributes !== null) ? $this->attributes($attributes) : "").' value="'.$this->getValue($name, $value).'" />';
    }
1218730
public function button($value, $name = null, $attributes = array())
    {
        $name = pick($name, $value);

        return $this->tag('button', $value)
                    ->set(array('id' => $name, 'name' => $name))
                    ->set($attributes);
    }
37183
static public function simditor($name, $value=null, $settings=[])
    {
        $settings = static::formatSettings($settings);
        $form_id    = isset($settings['id']) ? static::formatId($settings['id']) : static::formatId($name);
        $web_url = Config::getRootUrl() . '/lib';
        if(empty($value)) {
            $value = '<p>Thanks for Simditor.</p>';
        }

        // 此处动态加载有问题，不能直接运行脚本
        if (!static::$isLoaded['simditor']) {
            $inner .= <<<EOF
                <link rel="stylesheet" href="${web_url}/simditor-2.3.6/assets/simditor.css" />
                <script type="text/javascript" src="${web_url}/simditor-2.3.6/assets/simditor-2.3.6.full.js"></script>
EOF;
            static::$isLoaded['simditor'] = true;
        }
    
        $inner .= <<<EOF
            <section id="${form_id}wrap">
                <textarea id="${form_id}" name="${name}" data-autosave="${form_id}-content" autofocus required>
                    ${value}
                </textarea>
            </section>
EOF;
        $innerJs = <<<EOF
        <script>
            (function() {
    
                $(function() {
                    var preview, editor, mobileToolbar, toolbar;
                    Simditor.locale = 'zh-CN';	// en-US
                    toolbar = ['title', 'bold', 'italic', 'underline', 'strikethrough', 'fontScale', 'color', '|', 'ol', 'ul', 'blockquote', 'code', 'table', '|', 'link', 'image', 'hr', '|', 'indent', 'outdent', 'alignment'];
                    mobileToolbar = ["bold", "underline", "strikethrough", "color", "ul", "ol"];
                    if (mobilecheck()) {
                      toolbar = mobileToolbar;
                    }
                    editor = new Simditor({
                      textarea: $('#${form_id}'),
                      placeholder: '这里输入文字...',
                      toolbar: toolbar,
                      pasteImage: true,
                      defaultImage: '${web_url}/simditor-2.3.6/assets/images/image.png',
                      upload: location.search === '?upload' ? {
                        url: '/upload'
                      } : false
                    });
                    preview = $('#preview');
                    if (preview.length > 0) {
                      return editor.on('valuechanged', function(e) {
                        return preview.html(editor.getValue());
                      });
                    }
                });
            }).call(this);
        </script>
EOF;
        return $inner . PHP_EOL . $innerJs;
    }
272814
public static function select($name, $list = [], $selected = null, $options = [])
    {
        self::exclure($options, ['name']);
        //
        $options['name'] = $name;
        //
        $sub = '';
        //
        if (!empty($list)) {
            foreach ($list as $value) {
                $sub .= self::option($value, (!is_null($selected) && $value == $selected));
            }
        }
        //
        $options = Html::attributes($options);
        //
        return '<select'.$options.">\n".$sub."</select>\n";
    }