github.com/kotovmak/go-admin@v1.1.1/template/types/action/popup.go (about)

     1  package action
     2  
     3  import (
     4  	"fmt"
     5  	"html/template"
     6  	"regexp"
     7  	"strings"
     8  
     9  	"github.com/kotovmak/go-admin/context"
    10  	"github.com/kotovmak/go-admin/modules/config"
    11  	"github.com/kotovmak/go-admin/modules/constant"
    12  	"github.com/kotovmak/go-admin/modules/language"
    13  	"github.com/kotovmak/go-admin/modules/utils"
    14  	template2 "github.com/kotovmak/go-admin/template"
    15  	"github.com/kotovmak/go-admin/template/icon"
    16  	"github.com/kotovmak/go-admin/template/types"
    17  )
    18  
    19  type PopUpAction struct {
    20  	BaseAction
    21  	Url         string
    22  	Method      string
    23  	Id          string
    24  	Title       string
    25  	Draggable   bool
    26  	Width       string
    27  	Height      string
    28  	HasIframe   bool
    29  	HideFooter  bool
    30  	BtnTitle    template.HTML
    31  	ParameterJS template.JS
    32  	Data        AjaxData
    33  	Handlers    []context.Handler
    34  	Event       Event
    35  }
    36  
    37  func PopUp(id, title string, handler types.Handler) *PopUpAction {
    38  	if id == "" {
    39  		panic("wrong popup action parameter, empty id")
    40  	}
    41  	return &PopUpAction{
    42  		Url:      URL(id),
    43  		Title:    title,
    44  		Method:   "post",
    45  		BtnTitle: "",
    46  		Data:     NewAjaxData(),
    47  		Id:       "info-popup-model-" + utils.Uuid(10),
    48  		Handlers: context.Handlers{handler.Wrap()},
    49  		Event:    EventClick,
    50  	}
    51  }
    52  
    53  func (pop *PopUpAction) SetData(data map[string]interface{}) *PopUpAction {
    54  	pop.Data = pop.Data.Add(data)
    55  	return pop
    56  }
    57  
    58  func (pop *PopUpAction) SetDraggable() *PopUpAction {
    59  	pop.Draggable = true
    60  	return pop
    61  }
    62  
    63  func (pop *PopUpAction) SetWidth(width string) *PopUpAction {
    64  	pop.Width = width
    65  	return pop
    66  }
    67  
    68  func (pop *PopUpAction) SetHeight(height string) *PopUpAction {
    69  	pop.Height = height
    70  	return pop
    71  }
    72  
    73  func (pop *PopUpAction) SetParameterJS(parameterJS template.JS) *PopUpAction {
    74  	pop.ParameterJS += parameterJS
    75  	return pop
    76  }
    77  
    78  func (pop *PopUpAction) SetUrl(url string) *PopUpAction {
    79  	pop.Url = url
    80  	return pop
    81  }
    82  
    83  type IframeData struct {
    84  	Width          string
    85  	Height         string
    86  	Src            string
    87  	AddParameterFn func(ctx *context.Context) string
    88  }
    89  
    90  func PopUpWithIframe(id, title string, data IframeData, width, height string) *PopUpAction {
    91  	if id == "" {
    92  		panic("wrong popup action parameter, empty id")
    93  	}
    94  	if data.Width == "" {
    95  		data.Width = "100%"
    96  	}
    97  	if data.Height == "" {
    98  		data.Height = "100%"
    99  	}
   100  	if strings.Contains(data.Src, "?") {
   101  		data.Src = data.Src + "&"
   102  	} else {
   103  		data.Src = data.Src + "?"
   104  	}
   105  	modalID := "info-popup-model-" + utils.Uuid(10)
   106  	var handler types.Handler = func(ctx *context.Context) (success bool, msg string, res interface{}) {
   107  		param := ""
   108  		if data.AddParameterFn != nil {
   109  			param = data.AddParameterFn(ctx)
   110  		}
   111  		return true, "ok", fmt.Sprintf(`<iframe style="width:%s;height:%s;" 
   112  			scrolling="auto" 
   113  			allowtransparency="true" 
   114  			frameborder="0"
   115  			src="%s__goadmin_iframe=true&__go_admin_no_animation_=true&__goadmin_iframe_id=%s`+param+`"><iframe>`,
   116  			data.Width, data.Height, data.Src, modalID)
   117  	}
   118  	return &PopUpAction{
   119  		Url:        URL(id),
   120  		Title:      title,
   121  		Method:     "post",
   122  		BtnTitle:   "",
   123  		Height:     height,
   124  		HasIframe:  true,
   125  		HideFooter: isFormURL(data.Src),
   126  		Width:      width,
   127  		Draggable:  true,
   128  		Data:       NewAjaxData(),
   129  		Id:         modalID,
   130  		Handlers:   context.Handlers{handler.Wrap()},
   131  		Event:      EventClick,
   132  	}
   133  }
   134  
   135  type PopUpData struct {
   136  	Id     string
   137  	Title  string
   138  	Width  string
   139  	Height string
   140  }
   141  
   142  type GetForm func(panel *types.FormPanel) *types.FormPanel
   143  type GetCtxForm func(ctx *context.Context, panel *types.FormPanel) *types.FormPanel
   144  
   145  var operationHandlerSetter context.NodeProcessor
   146  
   147  func InitOperationHandlerSetter(p context.NodeProcessor) {
   148  	operationHandlerSetter = p
   149  }
   150  
   151  func PopUpWithForm(data PopUpData, fn GetForm, url string) *PopUpAction {
   152  	if data.Id == "" {
   153  		panic("wrong popup action parameter, empty id")
   154  	}
   155  	modalID := "info-popup-model-" + utils.Uuid(10)
   156  
   157  	var handler types.Handler = func(ctx *context.Context) (success bool, msg string, res interface{}) {
   158  		col1 := template2.Default().Col().GetContent()
   159  		btn1 := template2.Default().Button().SetType("submit").
   160  			SetContent(language.GetFromHtml("Save")).
   161  			SetThemePrimary().
   162  			SetOrientationRight().
   163  			SetLoadingText(icon.Icon("fa-spinner fa-spin", 2) + language.GetFromHtml("Save")).
   164  			GetContent()
   165  		btn2 := template2.Default().Button().SetType("reset").
   166  			SetContent(language.GetFromHtml("Reset")).
   167  			SetThemeWarning().
   168  			SetOrientationLeft().
   169  			GetContent()
   170  		col2 := template2.Default().Col().SetSize(types.SizeMD(8)).
   171  			SetContent(btn1 + btn2).GetContent()
   172  		panel := fn(types.NewFormPanel())
   173  
   174  		operationHandlerSetter(panel.Callbacks...)
   175  
   176  		fields, tabFields, tabHeaders := panel.GetNewFormFields()
   177  
   178  		return true, "ok", template2.Default().Box().
   179  			SetHeader("").
   180  			SetBody(template2.Default().Form().
   181  				SetContent(fields).
   182  				SetTabHeaders(tabHeaders).
   183  				SetTabContents(tabFields).
   184  				SetAjax(panel.AjaxSuccessJS, panel.AjaxErrorJS).
   185  				SetPrefix(config.PrefixFixSlash()).
   186  				SetUrl(url).
   187  				SetOperationFooter(col1 + col2).GetContent()).
   188  			SetStyle(template.HTMLAttr(`overflow-x: hidden;overflow-y: hidden;`)).
   189  			GetContent()
   190  	}
   191  	return &PopUpAction{
   192  		Url:        URL(data.Id),
   193  		Title:      data.Title,
   194  		Method:     "post",
   195  		BtnTitle:   "",
   196  		HideFooter: true,
   197  		Height:     data.Height,
   198  		Width:      data.Width,
   199  		Draggable:  true,
   200  		Data:       NewAjaxData(),
   201  		Id:         modalID,
   202  		Handlers:   context.Handlers{handler.Wrap()},
   203  		Event:      EventClick,
   204  	}
   205  }
   206  
   207  func PopUpWithCtxForm(data PopUpData, fn GetCtxForm, url string) *PopUpAction {
   208  	if data.Id == "" {
   209  		panic("wrong popup action parameter, empty id")
   210  	}
   211  	modalID := "info-popup-model-" + utils.Uuid(10)
   212  
   213  	var handler types.Handler = func(ctx *context.Context) (success bool, msg string, res interface{}) {
   214  		col1 := template2.Default().Col().GetContent()
   215  		btn1 := template2.Default().Button().SetType("submit").
   216  			SetContent(language.GetFromHtml("Save")).
   217  			SetThemePrimary().
   218  			SetOrientationRight().
   219  			SetLoadingText(icon.Icon("fa-spinner fa-spin", 2) + language.GetFromHtml("Save")).
   220  			GetContent()
   221  		btn2 := template2.Default().Button().SetType("reset").
   222  			SetContent(language.GetFromHtml("Reset")).
   223  			SetThemeWarning().
   224  			SetOrientationLeft().
   225  			GetContent()
   226  		col2 := template2.Default().Col().SetSize(types.SizeMD(8)).
   227  			SetContent(btn1 + btn2).GetContent()
   228  		panel := fn(ctx, types.NewFormPanel())
   229  
   230  		operationHandlerSetter(panel.Callbacks...)
   231  
   232  		fields, tabFields, tabHeaders := panel.GetNewFormFields()
   233  
   234  		return true, "ok", template2.Default().Box().
   235  			SetHeader("").
   236  			SetBody(template2.Default().Form().
   237  				SetContent(fields).
   238  				SetTabHeaders(tabHeaders).
   239  				SetTabContents(tabFields).
   240  				SetAjax(panel.AjaxSuccessJS, panel.AjaxErrorJS).
   241  				SetPrefix(config.PrefixFixSlash()).
   242  				SetUrl(url).
   243  				SetOperationFooter(col1 + col2).GetContent()).
   244  			GetContent()
   245  	}
   246  	return &PopUpAction{
   247  		Url:        URL(data.Id),
   248  		Title:      data.Title,
   249  		Method:     "post",
   250  		BtnTitle:   "",
   251  		HideFooter: true,
   252  		Height:     data.Height,
   253  		Width:      data.Width,
   254  		Draggable:  true,
   255  		Data:       NewAjaxData(),
   256  		Id:         modalID,
   257  		Handlers:   context.Handlers{handler.Wrap()},
   258  		Event:      EventClick,
   259  	}
   260  }
   261  
   262  func (pop *PopUpAction) SetBtnTitle(title template.HTML) *PopUpAction {
   263  	pop.BtnTitle = title
   264  	return pop
   265  }
   266  
   267  func (pop *PopUpAction) SetEvent(event Event) *PopUpAction {
   268  	pop.Event = event
   269  	return pop
   270  }
   271  
   272  func (pop *PopUpAction) SetMethod(method string) *PopUpAction {
   273  	pop.Method = method
   274  	return pop
   275  }
   276  
   277  func (pop *PopUpAction) GetCallbacks() context.Node {
   278  	return context.Node{
   279  		Path:     pop.Url,
   280  		Method:   pop.Method,
   281  		Handlers: pop.Handlers,
   282  		Value:    map[string]interface{}{constant.ContextNodeNeedAuth: 1},
   283  	}
   284  }
   285  
   286  func (pop *PopUpAction) Js() template.JS {
   287  	return template.JS(`$('`+pop.BtnId+`').on('`+string(pop.Event)+`', function (event) {
   288  						let data = `+pop.Data.JSON()+`;
   289  						`) + pop.ParameterJS + template.JS(`
   290  						let id = $(this).attr("data-id");
   291  						if (id && id !== "") {
   292  							data["id"] = id;
   293  						}
   294  						data['popup_id'] = "`+pop.Id+`"
   295  						$.ajax({
   296                              method: '`+pop.Method+`',
   297                              url: "`+pop.Url+`",
   298                              data: data,
   299                              success: function (data) {
   300                                  if (typeof (data) === "string") {
   301                                      data = JSON.parse(data);
   302                                  }
   303                                  if (data.code === 0) {
   304                                      $('#`+pop.Id+` .modal-body').html(data.data);
   305                                  } else {
   306                                      swal(data.msg, '', 'error');
   307                                  }
   308                              },
   309  							error: function (data) {
   310  								if (data.responseText !== "") {
   311  									swal(data.responseJSON.msg, '', 'error');								
   312  								} else {
   313  									swal('error', '', 'error');
   314  								}
   315  								setTimeout(function() {
   316  									$('#`+pop.Id+`').hide();
   317  									$('.modal-backdrop.fade.in').hide();
   318  								}, 500)
   319  							},
   320                          });
   321              		});`)
   322  }
   323  
   324  func (pop *PopUpAction) BtnAttribute() template.HTML {
   325  	return template.HTML(`data-toggle="modal" data-target="#` + pop.Id + ` " data-id="{{.Id}}" style="cursor: pointer;"`)
   326  }
   327  
   328  func (pop *PopUpAction) FooterContent() template.HTML {
   329  	up := template2.Default().Popup().SetID(pop.Id).
   330  		SetTitle(template.HTML(pop.Title)).
   331  		SetFooter(pop.BtnTitle).
   332  		SetWidth(pop.Width).
   333  		SetHeight(pop.Height).
   334  		SetBody(template.HTML(``))
   335  
   336  	if pop.Draggable {
   337  		if pop.HideFooter {
   338  			up = up.SetHideFooter()
   339  		}
   340  		return up.SetDraggable().GetContent()
   341  	}
   342  
   343  	return up.GetContent()
   344  }
   345  
   346  func isFormURL(s string) bool {
   347  	reg, _ := regexp.Compile("(.*)info/(.*)/(new|edit)(.*?)")
   348  	return reg.MatchString(s)
   349  }