Add JS to CRUD view to interact with fields - laravel-backpack

I followed this github pull comments https://github.com/Laravel-Backpack/CRUD/pull/4312
I added to the crud controller
Widget::add()->type('script')->content('/js/hotel.js');
and also this fields
CRUD::field('caption');
CRUD::field('slug');
Created hotel.js with one of the functions in the example mentioned https://gist.githubusercontent.com/tabacitu/248dd59da9b33debc26cb7496f205bb5/raw/2477e2aef02facbc9ffc08cdceff20c82eab493a/product-form.js
function slugify(string) {
const a = 'àáâäæãåāăąçćčđďèéêëēėęěğǵḧîïíīįìıİłḿñńǹňôöòóœøōõőṕŕřßśšşșťțûüùúūǘůűųẃẍÿýžźż·/_,:;'
const b = 'aaaaaaaaaacccddeeeeeeeegghiiiiiiiilmnnnnoooooooooprrsssssttuuuuuuuuuwxyyzzz------'
const p = new RegExp(a.split('').join('|'), 'g')
return string.toString().toLowerCase()
.replace(/\s+/g, '-') // Replace spaces with -
.replace(p, c => b.charAt(a.indexOf(c))) // Replace special characters
.replace(/&/g, '-and-') // Replace & with 'and'
.replace(/[^\w\-]+/g, '') // Remove all non-word characters
.replace(/\-\-+/g, '-') // Replace multiple - with single -
.replace(/^-+/, '') // Trim - from start of text
.replace(/-+$/, '') // Trim - from end of text
}
crud.field('caption').change(function(e, value) {
var slug = slugify(value);
crud.field('slug').input.val(slug);
});
The JS is loaded correctly when I reload the CRUD view, but when I modify the caption field nothing happens I don't get any JS error, but the slug field doesn't change either

I changed the script to
crud.field('caption').onChange(field => {
crud.field('slug').input.value = slugify(field.value);
})
and it's working.

not sure if you are using PRO, if you are, there is already a slug field type, no need to manually create it. CRUD::field('slug')->type('slug').
Cheers

Related

Joi validation with dollar sign in the number text

Is it possible to extend joi to allow for a '$' in the number() validation?
My input is a string like "$12.34". When I attempt to validate this using Joi.number() I receive an error "{Field} must be a number". All I need is to remove the $ and it works fine. Is there any way to do this in the schema definition so that I don't have to scrub my incoming data before calling validate?
const results = Joi.number().validate("$12.34") // fails
const results = Joi.number().validate("12.34") // succeeds
If you are okay with regex then you can use regex to validate the string as follows:
Joi.string().regex(/\$\d+(\.?\d+)?/)
// \$ check for $
// \d+ digit 1 or more
// \.? . one or zero
// (\.?\d+)? match group for 0 or 1 time
As input type is string you can be sure that it contains $ by two ways i.e.
replace $ with empty string.
Joi.number().validate("$12.34".replace("$",""))
splitting string at $ and then checking 2nd part (less secure)
Joi.number().validate("$12.34".split("$")[1])
Last option is to strip of $ every-time and then pass remaining part to check if it's number.
The short answer is to extend number with a custom prepare method.
After trying everything I could think of I looked at the source on github and found this test
it('extends number to support comma delimiter', () => {
const custom = Joi.extend({
type: 'number',
base: Joi.number(),
prepare(value, helpers) {
if (typeof value !== 'string') {
return;
}
return { value: value.replace(',', '.') };
}
});
expect(custom.number().validate(2.0)).to.equal({ value: 2.0 });
expect(custom.number().validate('2.0')).to.equal({ value: 2.0 });
expect(custom.number().validate('2,0')).to.equal({ value: 2.0 });
expect(custom.number().validate('2,0', { convert: false }).error).to.be.an.error('"value" must be a number');
expect(custom.number().validate(undefined).error).to.not.exist();
});
which is basically what I am trying to do so I modified it to fix up '$' instead of ',' and voila
results1 will pass and results2 will error out.

Typoscript: how do I add a parameter to all links in the RTE?

I want to add a parameter to all links entered in the RTE by the user.
My initial idea was to do this:
lib.parseFunc_RTE.tags.link {
typolink.parameter.append = TEXT
typolink.parameter.append.value = ?flavor=lemon
}
So for example:
http://domain.com/mypage.php
becomes
http://domain.com/mypage.php?flavor=lemon
which sounds great -- as long as the link does not already have a query string!
In that case, I obviously end up with two question marks in the URL
So for example:
http://domain.com/prefs.php?id=1234&unit=moon&qty=300
becomes
http://domain.com/prefs.php?id=1234&unit=moon&qty=300?flavor=lemon
Is there any way to add my parameter with the correct syntax, depending on whether the URL already has a query string or not? Thanks!
That would be the solution:
lib.parseFunc_RTE.tags.link {
typolink.additionalParams = &flavor=lemon
}
Note that it has to start with an &, typo3 then generates a valid link. The parameter in the link also will be parsed with realURL if configured accordingly.
Edit: The above solution only works for internal links as described in the documentation https://docs.typo3.org/typo3cms/TyposcriptReference/Functions/Typolink/Index.html
The only solution that works for all links that I see is to use a userFunc
lib.parseFunc_RTE.tags.link {
typolink.userFunc = user_addAdditionalParams
}
Then you need to create a php script and include in your TS with:
includeLibs.rteScript = path/to/yourScript.php
Keep in mind that includeLibs is outdated, so if you are using TYPO3 8.x (and probably 7.3+) you will need to create a custom extension with just a few files
<?php
function user_addAdditionalParams($finalTagParts) {
// modify the url in $finalTagParts['url']
// $finalTagParts['TYPE'] is an indication of link-kind: mailto, url, file, page, you can use it to check if you need to append the new params
switch ($finalTagParts['TYPE']) {
case 'url':
case 'file':
$parts = explode('#', $finalTagParts['url']);
$finalTagParts['url'] = $parts[0]
. (strpos($parts[0], '?') === false ? '?' : '&')
. 'newParam=test&newParam=test2'
. ($parts[1] ? '#' . $parts[1] : '');
break;
}
return '<a href="' . $finalTagParts['url'] . '"' .
$finalTagParts['targetParams'] .
$finalTagParts['aTagParams'] . '>'
}
PS: i have not tested the actual php code, so it can have some errors. If you have troubles, try debugging the $finalTagParts variable
Test whether the "?" character is already in the URL and append either "?" or "&", then append your key-value pair. There's a CASE object available in the TypoScript Reference, with an example you can modify for your purpose.
For anyone interested, here's a solution that worked for me using the replacement function of Typoscript. Hope this helps.
lib.parseFunc_RTE.tags.link {
# Start by "replacing" the whole URL by itself + our string
# For example: http://domain.com/?id=100 becomes http://domain.com/?id=100?flavor=lemon
# For example: http://domain.com/index.html becomes http://domain.com/index.html?flavor=lemon
typolink.parameter.stdWrap.replacement.10 {
#this matches the whole URL
search = #^(.*)$#i
# this replaces it with itself (${1}) + our string
replace =${1}?flavor=lemon
# in this case we want to use regular expressions
useRegExp = 1
}
# After the first replacement is done, we simply replace
# the first '?' by '?' and all others by '&'
# the use of Option Split allow this
typolink.parameter.stdWrap.replacement.20 {
search = ?
replace = ? || & || &
useOptionSplitReplace = 1
}
}

Zend_valdiate_alpha combined with special characters

Zend_valdiate_alpha combined with special characters
Need to combine An alphanumeric character or underscore with string .
for example : need to add control for City name with
not necessary with zend_alpha it can be another way
any suggestions ??
I have exactly the same problem. I need to allow commas, alphas, and whitespaces. The most simple solution, I can think of, is to define callback validation function like this:
$myValidator = new Zend_Validate_Callback(function($value) {
$value = preg_replace('/,/', '', $value);
$alphaValidator = new Zend_Validate_Alpha(array('allowWhiteSpace' => true));
if ($alphaValidator->isValid($value)) return true;
return false;
});
And using it like this:
if ($myValidator->isValid($input)) {
// input valid
} else {
// input invalid
}
I know this is old but perhaps it can help somebody and I would be interested if there is a simpler solution.

How to include field values in the vtypes message text for vtype validation in forms?

I'm working on form validation and I have used Vtypes to check number ranges.
It's all working fine, except I need to include my own allowed values ( field.minValField and field.maxValField) in the 'numberrangeText'. Is there any way to do that ?
Thanks in advance
Ext.apply(Ext.form.VTypes, {
numberrange : function(val, field) {
if(val < field.minValField || val > field.maxValField){
console.log(field);
return false;
}
},
numberrangeText: 'Value Range Should Be: '
});
Arfeen
There is no way to use templates or XTemplates in numberrangeText. Because they(extjs) just take this string without changes as I've found out from file src/widgets/form/TextField.js from the line errors.push(this.vtypeText || vt[this.vtype +'Text']);.
But as you can see you can use field.vtypeText instead.
For example you can write something like this:
field.vtypeText = 'Value Range Should Be: ' + field.minValField + '-' + field.maxValField;
in your numberrange function.
You can see what I'm talking about in this example

jqgrid edittype select load value from data

I am using jqgrid in my new project.
In a specific case I need to use a select element in the grid. No problem.
I define the colModel and the column for example like (from wiki)
colModel : [
...
{name:'myname', edittype:'select', editoptions:{value:{1:'One',2:'Two'}} },
...
]
But now when I load my data I would prefer the column "myname" to contain the value 1.
This won't work for me instead it has to contain the value "One".
The problem with this is that the text-part of the select element is in my case localized in the business layer where the colModel is dynamically generated. Also the datatype for the entity which generates the data via EF 4 may not be a string. Then I have to find the correct localized text and manipulate the data result so that the column "myname" does not containt an integer which is typically the case but a string instead with the localized text.
There is no option you can use so that when the data contains the value which match an option in the select list then the grid finds that option and presents the text.
Now the grid presents the value as a text and first when I click edit it finds the matching option and presents the text. When I undo the edit it returns to present the value again.
I started to think of a solution and this is what I came up with. Please if you know a better solution or if you know there is a built in option don't hesitate to answer.
Otherwise here is what I did:
loadComplete: function (data) {
var colModel = grid.getGridParam('colModel');
$.each(colModel, function (index, col) {
if (col.edittype === 'select') {
$.each(grid.getDataIDs(), function (index, id) {
var row = grid.getRowData(id);
var value = row[col.name];
var editoptions = col.editoptions.value;
var startText = editoptions.indexOf(value + ':') + (value + ':').length;
var endText = editoptions.indexOf(';', startText);
if (endText === -1) { endText = editoptions.length; }
var text = editoptions.substring(startText, endText);
row[col.name] = text;
grid.setRowData(id, row);
});
}
});
}
It works and I will leave it like this if nobody comes up with a better way.
You should just include additional formatter:'select' option in the definition of the column. See the documentation for more details.