From 97065c0377e268af866c81149a942cdebdea6adc Mon Sep 17 00:00:00 2001 From: "Lasse S. Haslev" Date: Sun, 25 Oct 2020 18:34:21 +0100 Subject: [PATCH] First commit. --- .gitignore | 10 + composer.json | 29 + dist/css/field.css | 0 dist/images/vendor/leaflet/dist/layers-2x.png | Bin 0 -> 1259 bytes dist/images/vendor/leaflet/dist/layers.png | Bin 0 -> 696 bytes .../vendor/leaflet/dist/marker-icon.png | Bin 0 -> 1466 bytes dist/js/field.js | 25553 ++++++++++++++++ dist/mix-manifest.json | 4 + package.json | 21 + resources/js/components/DetailField.vue | 15 + resources/js/components/FieldMap.vue | 59 + resources/js/components/FormField.vue | 40 + resources/js/components/IndexField.vue | 9 + resources/js/components/fields/Marker.vue | 80 + resources/js/components/fields/Polyline.vue | 87 + resources/js/field.js | 12 + resources/sass/field.scss | 1 + src/FieldServiceProvider.php | 28 + src/MapField.php | 109 + src/Marker.php | 85 + src/Polyline.php | 39 + webpack.mix.js | 5 + 22 files changed, 26186 insertions(+) create mode 100755 .gitignore create mode 100755 composer.json create mode 100755 dist/css/field.css create mode 100755 dist/images/vendor/leaflet/dist/layers-2x.png create mode 100755 dist/images/vendor/leaflet/dist/layers.png create mode 100755 dist/images/vendor/leaflet/dist/marker-icon.png create mode 100755 dist/js/field.js create mode 100755 dist/mix-manifest.json create mode 100755 package.json create mode 100755 resources/js/components/DetailField.vue create mode 100755 resources/js/components/FieldMap.vue create mode 100755 resources/js/components/FormField.vue create mode 100755 resources/js/components/IndexField.vue create mode 100755 resources/js/components/fields/Marker.vue create mode 100755 resources/js/components/fields/Polyline.vue create mode 100755 resources/js/field.js create mode 100755 resources/sass/field.scss create mode 100755 src/FieldServiceProvider.php create mode 100755 src/MapField.php create mode 100755 src/Marker.php create mode 100755 src/Polyline.php create mode 100755 webpack.mix.js diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..b817577 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +/.idea +/vendor +/node_modules +package-lock.json +composer.phar +composer.lock +phpunit.xml +.phpunit.result.cache +.DS_Store +Thumbs.db diff --git a/composer.json b/composer.json new file mode 100755 index 0000000..dfc0768 --- /dev/null +++ b/composer.json @@ -0,0 +1,29 @@ +{ + "name": "lassehaslev/nova-map-fields", + "description": "A Laravel Nova field.", + "keywords": [ + "laravel", + "nova" + ], + "license": "MIT", + "require": { + "php": ">=7.1.0" + }, + "autoload": { + "psr-4": { + "Lassehaslev\\NovaMapFields\\": "src/" + } + }, + "extra": { + "laravel": { + "providers": [ + "Lassehaslev\\NovaMapFields\\FieldServiceProvider" + ] + } + }, + "config": { + "sort-packages": true + }, + "minimum-stability": "dev", + "prefer-stable": true +} diff --git a/dist/css/field.css b/dist/css/field.css new file mode 100755 index 0000000..e69de29 diff --git a/dist/images/vendor/leaflet/dist/layers-2x.png b/dist/images/vendor/leaflet/dist/layers-2x.png new file mode 100755 index 0000000000000000000000000000000000000000..200c333dca9652ac4cba004d609e5af4eee168c1 GIT binary patch literal 1259 zcmVFhCYNy;#0irRPomHqW|G1C*;4?@4#E?jH>?v@U%cy?3dQAc-DchXVErpOh~ z-jbon+tNbnl6hoEb;)TVk+%hTDDi_G%i3*RZ&15!$Fjr^f;Ke&A@|?=`2&+{zr+3a z{D*=t(`AXyS%X7N z%a#RZw6vD^t_rnM`L4E>m=U&R!A-&}nZIi$BOPvkhrCuUe@BN~-lRD)f44;J%TwgE zcze8u!PQ_NR7?o(NylLXVTfDO zxs5=@|GsYEsNo4M#nT%N!UE(?dnS)t2+{ELYAFp*3=iF=|EQnTp`#vlSXuGVraYo? z+RCzXo6h3qA8{KG?S4nE(lM+;Eb4nT3XV;7gcAxUi5m)`k5tv}cPy()8ZR3TLW3I- zAS^}cq-IJvL7a4RgR!yk@~RT%$lA7{L5ES*hyx)M4(yxI$Ub(4f)K|^v1>zvwQY!_ zIrWw8q9GS^!Dp~}+?mbnB6jDF8mVlbQ!jFKDY;w=7;XO{9bq7>LXGK24WA`;rL)_Z z)&j}pbV(;6gY;VMhbxgvn`X;6x}VUEE-7 z%)7j-%t8S=ZL3yc)HbXDAqJZvBTPoiW_A-+a8m3_Z?v{DN7Tnr#O_VUMT0UBt$;p` zDh6JbGHN8JJ*JN%y2%msb97@_S>9!%Egwk;?PEkU9ntz&3uR}%Fj5d$JHQbQb3}a{ zSzFT^#n=VInPpcAS}CNxj?_ zVscANk5Cfz(51EI1pz};AWWb|kgbYNb4wCEGUn3+eMUMV?1-{=I4TlmLJMot@rd07 zZuo2hk1ccu{YmGkcYdWAVdk{Z4Nm?^cTD&}jGm+Q1SYIXMwmG*oO*83&#>l%nbR`G zhh=lZ%xIb7kU3#;TBbfECrnC9P=-XpL|TG2BoZdj61*XiFbW8?1Z_wp%#;>${SUIy V$8qr;L*)Pf002ovPDHLkV1hYLS~36t literal 0 HcmV?d00001 diff --git a/dist/images/vendor/leaflet/dist/layers.png b/dist/images/vendor/leaflet/dist/layers.png new file mode 100755 index 0000000000000000000000000000000000000000..1a72e5784b2b456eac5d7670738db80697af3377 GIT binary patch literal 696 zcmV;p0!RIcP)*@&l2<6p=!C&s@#ZL+%BQvF&b?w6S%wp=I>1QHj7AP5C)IWy#b znXXB;g;j=$a-tW89K%FbDceHVq&unY*Wx3L#=EGWH=rjqnp|4c_Ulec!ql3#G-5ZF zVlbBA@XP=)C8U&+Lrc)S4O5%1$&{(;7R^K(CSnvSr$v;+B$8q&7Bf|h$#PARo1^%M zf1H^nG-EiXVXr07OH(*8R)xa|FD;lXUlg_-%)~ZGsL2cX0NXaAzN2q%jqLRR6ruVk8`Jb7n#{`T;o@`F= z#3YcynIR^s83UNF3D!f5m#Mg)NJ24&Qfrqb&_z=yF;=B)#9Iq7u-@^O!(mW{D;qvr zPc)gVb%aowtS8m@ElL4A9G>w#ffQ~q{i&_i)*6f^)Sz|C?C>zb4Uo?H<-&Hz@a?J; z$ml@zGygWofb9$ZBj6aLjpLhsT2AzjOu=-*u_gSCUP001cn1^@s6z>|W`000GnNklGNuHDcIX17Zdjl&3`L?0sTjIws<{((Dh&g-s0<@jYQyl?D*X^?%13;ml^gy> ziMrY_^1WI=(g@LMizu=zCoA>C`6|QEq1eV92k*7m>G65*&@&6)aC&e}G zI)pf-Za|N`DT&Cn1J|o`19mumxW~hiKiKyc-P`S@q)rdTo84@QI@;0yXrG%9uhI>A zG5QHb6s4=<6xy{1 z@NMxEkryp{LS44%z$3lP^cX!9+2-;CTt3wM4(k*#C{aiIiLuB>jJj;KPhPzIC00bL zU3a#;aJld94lCW=`4&aAy8M7PY=HQ>O%$YEP4c4UY#CRxfgbE~(|uiI=YS8q;O9y6 zmIkXzR`}p7ti|PrM3a}WMnR=3NVnWdAAR>b9X@)DKL6=YsvmH%?I24wdq?Gh54_;# z$?_LvgjEdspdQlft#4CQ z`2Zyvy?*)N1Ftw|{_hakhG9WjS?Az@I@+IZ8JbWewR!XUK4&6346+d#~gsE0SY(LX8&JfY>Aj)RxGy96nwhs2rv zzW6pTnMpFkDSkT*a*6Dx|u@ds6ISVn0@^RmIsKZ5Y;bazbc;tTSq(kg(=481ODrPyNB6n z-$+U}(w$m6U6H$w17Bw+wDaFIe~GvNMYvnw31MpY0eQKT9l>SU``8k7w4)z!GZKMI z#_cEKq7k~i%nlK@6c-K?+R;B#5$?T#YpKD`t_4bAs^#E+@5QW$@OX3*`;(#{U^d-vY)&xEE>n5lYl&T?Amu;)i(a,n=e[u++])&&(~o(c,n)||c.push(n));return c}},function(t,e,n){var i=n(43);t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==i(t)?t.split(""):Object(t)}},function(t,e){var n={}.toString;t.exports=function(t){return n.call(t).slice(8,-1)}},function(t,e){var n=Math.ceil,i=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?i:n)(t)}},function(t,e,n){var i=n(30)("keys"),r=n(19);t.exports=function(t){return i[t]||(i[t]=r(t))}},function(t,e,n){t.exports=!n(12)&&!n(13)(function(){return 7!=Object.defineProperty(n(47)("div"),"a",{get:function(){return 7}}).a})},function(t,e,n){var i=n(18),r=n(9).document,o=i(r)&&i(r.createElement);t.exports=function(t){return o?r.createElement(t):{}}},function(t,e,n){e.f=n(36)},function(t,e){t.exports=!0},function(t,e,n){var i=n(41),r=n(31).concat("length","prototype");e.f=Object.getOwnPropertyNames||function(t){return i(t,r)}},function(t,e,n){t.exports={default:n(54),__esModule:!0}},function(t,e,n){t.exports={default:n(62),__esModule:!0}},function(t,e,n){e.L=n(6),e.findRealParent=n(3).default,e.propsBinder=n(0).default,e.LCircle=n(96).default,e.LCircleMarker=n(94).default,e.LControl=n(93).default,e.LControlAttribution=n(101).default,e.LControlLayers=n(103).default,e.LControlScale=n(105).default,e.LControlZoom=n(104).default,e.LFeatureGroup=n(87).default,e.LGeoJson=n(100).default,e.LIcon=n(90).default,e.LIconDefault=n(102).default,e.LImageOverlay=n(85).default,e.LLayerGroup=n(84).default,e.LMap=n(95).default,e.LMarker=n(98).default,e.LPolygon=n(92).default,e.LPolyline=n(91).default,e.LPopup=n(99).default,e.LRectangle=n(89).default,e.LTileLayer=n(88).default,e.LTooltip=n(97).default,e.LWMSTileLayer=n(86).default},function(t,e,n){n(55),t.exports=n(10).Object.keys},function(t,e,n){var i=n(39),r=n(15);n(59)("keys",function(){return function(t){return r(i(t))}})},function(t,e,n){var i=n(17),r=n(57),o=n(58);t.exports=function(t){return function(e,n,s){var a,u=i(e),c=r(u.length),l=o(s,c);if(t&&n!=n){for(;c>l;)if((a=u[l++])!=a)return!0}else for(;c>l;l++)if((t||l in u)&&u[l]===n)return t||l||0;return!t&&-1}}},function(t,e,n){var i=n(44),r=Math.min;t.exports=function(t){return t>0?r(i(t),9007199254740991):0}},function(t,e,n){var i=n(44),r=Math.max,o=Math.min;t.exports=function(t,e){return(t=i(t))<0?r(t+e,0):o(t,e)}},function(t,e,n){var i=n(32),r=n(10),o=n(13);t.exports=function(t,e){var n=(r.Object||{})[t]||Object[t],s={};s[t]=e(n),i(i.S+i.F*o(function(){n(1)}),"Object",s)}},function(t,e,n){var i=n(61);t.exports=function(t,e,n){if(i(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,i){return t.call(e,n,i)};case 3:return function(n,i,r){return t.call(e,n,i,r)}}return function(){return t.apply(e,arguments)}}},function(t,e){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},function(t,e,n){n(63),n(74),n(75),n(76),t.exports=n(10).Symbol},function(t,e,n){"use strict";var i=n(9),r=n(16),o=n(12),s=n(32),a=n(64),u=n(65).KEY,c=n(13),l=n(30),p=n(66),f=n(19),h=n(36),d=n(48),m=n(37),y=n(67),b=n(68),O=n(20),v=n(18),j=n(17),g=n(34),L=n(35),S=n(69),C=n(72),x=n(73),_=n(11),$=n(15),w=x.f,A=_.f,E=C.f,T=i.Symbol,I=i.JSON,B=I&&I.stringify,N=h("_hidden"),P=h("toPrimitive"),M={}.propertyIsEnumerable,D=l("symbol-registry"),R=l("symbols"),U=l("op-symbols"),z=Object.prototype,F="function"==typeof T,k=i.QObject,W=!k||!k.prototype||!k.prototype.findChild,G=o&&c(function(){return 7!=S(A({},"a",{get:function(){return A(this,"a",{value:7}).a}})).a})?function(t,e,n){var i=w(z,e);i&&delete z[e],A(t,e,n),i&&t!==z&&A(z,e,i)}:A,J=function(t){var e=R[t]=S(T.prototype);return e._k=t,e},Z=F&&"symbol"==typeof T.iterator?function(t){return"symbol"==typeof t}:function(t){return t instanceof T},H=function(t,e,n){return t===z&&H(U,e,n),O(t),e=g(e,!0),O(n),r(R,e)?(n.enumerable?(r(t,N)&&t[N][e]&&(t[N][e]=!1),n=S(n,{enumerable:L(0,!1)})):(r(t,N)||A(t,N,L(1,{})),t[N][e]=!0),G(t,e,n)):A(t,e,n)},V=function(t,e){O(t);for(var n,i=y(e=j(e)),r=0,o=i.length;o>r;)H(t,n=i[r++],e[n]);return t},q=function(t){var e=M.call(this,t=g(t,!0));return!(this===z&&r(R,t)&&!r(U,t))&&(!(e||!r(this,t)||!r(R,t)||r(this,N)&&this[N][t])||e)},K=function(t,e){if(t=j(t),e=g(e,!0),t!==z||!r(R,e)||r(U,e)){var n=w(t,e);return!n||!r(R,e)||r(t,N)&&t[N][e]||(n.enumerable=!0),n}},X=function(t){for(var e,n=E(j(t)),i=[],o=0;n.length>o;)r(R,e=n[o++])||e==N||e==u||i.push(e);return i},Y=function(t){for(var e,n=t===z,i=E(n?U:j(t)),o=[],s=0;i.length>s;)!r(R,e=i[s++])||n&&!r(z,e)||o.push(R[e]);return o};F||(a((T=function(){if(this instanceof T)throw TypeError("Symbol is not a constructor!");var t=f(arguments.length>0?arguments[0]:void 0),e=function(n){this===z&&e.call(U,n),r(this,N)&&r(this[N],t)&&(this[N][t]=!1),G(this,t,L(1,n))};return o&&W&&G(z,t,{configurable:!0,set:e}),J(t)}).prototype,"toString",function(){return this._k}),x.f=K,_.f=H,n(50).f=C.f=X,n(21).f=q,n(38).f=Y,o&&!n(49)&&a(z,"propertyIsEnumerable",q,!0),d.f=function(t){return J(h(t))}),s(s.G+s.W+s.F*!F,{Symbol:T});for(var Q="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),tt=0;Q.length>tt;)h(Q[tt++]);for(var et=$(h.store),nt=0;et.length>nt;)m(et[nt++]);s(s.S+s.F*!F,"Symbol",{for:function(t){return r(D,t+="")?D[t]:D[t]=T(t)},keyFor:function(t){if(!Z(t))throw TypeError(t+" is not a symbol!");for(var e in D)if(D[e]===t)return e},useSetter:function(){W=!0},useSimple:function(){W=!1}}),s(s.S+s.F*!F,"Object",{create:function(t,e){return void 0===e?S(t):V(S(t),e)},defineProperty:H,defineProperties:V,getOwnPropertyDescriptor:K,getOwnPropertyNames:X,getOwnPropertySymbols:Y}),I&&s(s.S+s.F*(!F||c(function(){var t=T();return"[null]"!=B([t])||"{}"!=B({a:t})||"{}"!=B(Object(t))})),"JSON",{stringify:function(t){for(var e,n,i=[t],r=1;arguments.length>r;)i.push(arguments[r++]);if(n=e=i[1],(v(e)||void 0!==t)&&!Z(t))return b(e)||(e=function(t,e){if("function"==typeof n&&(e=n.call(this,t,e)),!Z(e))return e}),i[1]=e,B.apply(I,i)}}),T.prototype[P]||n(33)(T.prototype,P,T.prototype.valueOf),p(T,"Symbol"),p(Math,"Math",!0),p(i.JSON,"JSON",!0)},function(t,e,n){t.exports=n(33)},function(t,e,n){var i=n(19)("meta"),r=n(18),o=n(16),s=n(11).f,a=0,u=Object.isExtensible||function(){return!0},c=!n(13)(function(){return u(Object.preventExtensions({}))}),l=function(t){s(t,i,{value:{i:"O"+ ++a,w:{}}})},p=t.exports={KEY:i,NEED:!1,fastKey:function(t,e){if(!r(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!o(t,i)){if(!u(t))return"F";if(!e)return"E";l(t)}return t[i].i},getWeak:function(t,e){if(!o(t,i)){if(!u(t))return!0;if(!e)return!1;l(t)}return t[i].w},onFreeze:function(t){return c&&p.NEED&&u(t)&&!o(t,i)&&l(t),t}}},function(t,e,n){var i=n(11).f,r=n(16),o=n(36)("toStringTag");t.exports=function(t,e,n){t&&!r(t=n?t:t.prototype,o)&&i(t,o,{configurable:!0,value:e})}},function(t,e,n){var i=n(15),r=n(38),o=n(21);t.exports=function(t){var e=i(t),n=r.f;if(n)for(var s,a=n(t),u=o.f,c=0;a.length>c;)u.call(t,s=a[c++])&&e.push(s);return e}},function(t,e,n){var i=n(43);t.exports=Array.isArray||function(t){return"Array"==i(t)}},function(t,e,n){var i=n(20),r=n(70),o=n(31),s=n(45)("IE_PROTO"),a=function(){},u=function(){var t,e=n(47)("iframe"),i=o.length;for(e.style.display="none",n(71).appendChild(e),e.src="javascript:",(t=e.contentWindow.document).open(),t.write(" diff --git a/resources/js/components/FieldMap.vue b/resources/js/components/FieldMap.vue new file mode 100755 index 0000000..a15894a --- /dev/null +++ b/resources/js/components/FieldMap.vue @@ -0,0 +1,59 @@ + + + + + diff --git a/resources/js/components/FormField.vue b/resources/js/components/FormField.vue new file mode 100755 index 0000000..0d5b1fc --- /dev/null +++ b/resources/js/components/FormField.vue @@ -0,0 +1,40 @@ + + + diff --git a/resources/js/components/IndexField.vue b/resources/js/components/IndexField.vue new file mode 100755 index 0000000..5a07928 --- /dev/null +++ b/resources/js/components/IndexField.vue @@ -0,0 +1,9 @@ + + + diff --git a/resources/js/components/fields/Marker.vue b/resources/js/components/fields/Marker.vue new file mode 100755 index 0000000..4d4fd09 --- /dev/null +++ b/resources/js/components/fields/Marker.vue @@ -0,0 +1,80 @@ + + + diff --git a/resources/js/components/fields/Polyline.vue b/resources/js/components/fields/Polyline.vue new file mode 100755 index 0000000..a61406b --- /dev/null +++ b/resources/js/components/fields/Polyline.vue @@ -0,0 +1,87 @@ + + + diff --git a/resources/js/field.js b/resources/js/field.js new file mode 100755 index 0000000..b79122e --- /dev/null +++ b/resources/js/field.js @@ -0,0 +1,12 @@ +Nova.booting((Vue, router) => { + Vue.component('index-nova-map-fields', require('./components/IndexField')); + Vue.component('detail-nova-map-fields', require('./components/DetailField')); + Vue.component('form-nova-map-fields', require('./components/FormField')); + + Vue.component('field-map', require('./components/FieldMap')); + Vue.component('field-marker', require('./components/fields/Marker')); + Vue.component('field-polyline', require('./components/fields/Polyline')); + + // Config leaflet images to load images from CDN + L.Icon.Default.imagePath = 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.4/images/'; +}) diff --git a/resources/sass/field.scss b/resources/sass/field.scss new file mode 100755 index 0000000..f85ad40 --- /dev/null +++ b/resources/sass/field.scss @@ -0,0 +1 @@ +// Nova Tool CSS diff --git a/src/FieldServiceProvider.php b/src/FieldServiceProvider.php new file mode 100755 index 0000000..2e0137d --- /dev/null +++ b/src/FieldServiceProvider.php @@ -0,0 +1,28 @@ +setHeight('250px'); + $this->setCenter(0, 0); + $this->setZoom(13); + + $this->withMapMeta('type', $this->getMapFieldType()); + + parent::__construct($name, $attribute = null, $resolveCallback); + } + + /** + * Set the height for the map. + * + * @param mixed $height + * + * @return $this + */ + public function setHeight($height) + { + return $this->withMapMeta('height', $height); + } + + /** + * Set the zoom for the map. + * + * @param mixed $level + * + * @return $this + */ + public function setZoom($level) + { + return $this->withMapMeta('zoom', $level); + } + + /** + * Set the position for the map. + * + * @param mixed $latitude + * @param mixed $longitude + * + * @return $this + */ + public function setCenter($latitude, $longitude) + { + return $this->withMapMeta('center', [ + 'latitude' => $latitude, + 'longitude' => $longitude, + ]); + } + + /** + * Add meta data for the map. + * + * @param mixed $key + * @param mixed $value + */ + protected function withMapMeta($key, $value) + { + $existingMapMeta = $this->meta['map'] ?? []; + + return $this->withMeta([ + 'map' => array_merge($existingMapMeta, [ + $key => $value, + ]), + ]); + } + + /** + * Get component name. + * + * @return string + */ + public function getMapFieldType() + { + return Str::kebab(class_basename($this)); + } +} diff --git a/src/Marker.php b/src/Marker.php new file mode 100755 index 0000000..4d1ffb5 --- /dev/null +++ b/src/Marker.php @@ -0,0 +1,85 @@ +help('Drag the marker to change the point.'); + + parent::__construct($name, $attribute = null, $resolveCallback); + } + + /** + * Set the latutude field. + * + * @param mixed $fieldName + * + * @return $this + */ + public function setLatitude($fieldName) + { + return $this->withMeta([ + 'latitudeField' => $fieldName, + ]); + } + + /** + * Set the longitude field. + * + * @param mixed $fieldName + * + * @return $this + */ + public function setLongitude($fieldName) + { + return $this->withMeta([ + 'longitudeField' => $fieldName, + ]); + } + + /** + * Resolve the attribute before sending to frontend. + * + * @param mixed $resource + * @param mixed|null $attribute + * + * @return array + */ + public function resolveAttribute($resource, $attribute = null) + { + return [ + 'lat' => $resource->{$this->meta['latitudeField']}, + 'lng' => $resource->{$this->meta['longitudeField']}, + ]; + } + + /** + * Hydrate the given attribute on the model based on the incoming request. + * + * @param \Laravel\Nova\Http\Requests\NovaRequest $request + * @param string $requestAttribute + * @param object $model + * @param string $attribute + */ + protected function fillAttributeFromRequest(NovaRequest $request, $requestAttribute, $model, $attribute) + { + if ($request->exists($requestAttribute)) { + $latLng = json_decode($request[$requestAttribute]); + + $model->{$this->meta['latitudeField']} = $latLng->lat; + $model->{$this->meta['longitudeField']} = $latLng->lng; + } + } +} diff --git a/src/Polyline.php b/src/Polyline.php new file mode 100755 index 0000000..388d3c1 --- /dev/null +++ b/src/Polyline.php @@ -0,0 +1,39 @@ +help('Click on the map to create a new point. Drag a marker to change the point. When the map is selected, you can press [backspace] to remove markers.'); + + parent::__construct($name, $attribute = null, $resolveCallback); + } + + /** + * Resolve the attribute before sending to frontend. + * + * @param mixed $resource + * @param mixed|null $attribute + * + * @return array + */ + public function resolveAttribute($resource, $attribute = null) + { + return json_decode($resource->{$attribute}); + + return [ + 'lat' => $resource->{$this->meta['latitudeField']}, + 'lng' => $resource->{$this->meta['longitudeField']}, + ]; + } +} diff --git a/webpack.mix.js b/webpack.mix.js new file mode 100755 index 0000000..b96c97e --- /dev/null +++ b/webpack.mix.js @@ -0,0 +1,5 @@ +let mix = require('laravel-mix') + +mix.setPublicPath('dist') + .js('resources/js/field.js', 'js') + .sass('resources/sass/field.scss', 'css')