Javascript sum checkboxes for if/else statment - if-statement

So I have a script that will sum the values of checkboxes on my page, but I'm having trouble figuring out how to write an if/else if statement based on the value returned. I think the script would look something like this, but the fine folks on here seem to be pretty knowledgeable so any tips would be great!
Thanks in advance!
$(document).ready(function() {
function updateSum() {
var total = 0;
$(".sum:checked").each(function(i, n) {total += parseInt($(n).val());})
$("#total").val(total);
}
if (total == 0) {
"<input type="text" value="Great Job">";
else if (total == 3) {
"<input type="text" value="Good">";
else
"<input type="text" value="Ok">";
}
// run the update on every checkbox change and on startup
$("input.sum").change(updateSum);
updateSum();
})

Related

How to listen the state changes in svelte like useEffect

I have read some article about state change listener, As I am a very beginner to the svelte environment I can't figure out what is the most efficient way to listen to the state change.
Let us take state variable as X and Y
Method 1:
$: if (X||Y) {
console.log("yes");
}
Method 2:
Use a combination of afterUpdate and onDestroy
REPL: https://svelte.dev/repl/300c16ee38af49e98261eef02a9b04a8?version=3.38.2
import { afterUpdate, onDestroy } from 'svelte';
export function useEffect(cb, deps) {
let cleanup;
function apply() {
if (cleanup) cleanup();
cleanup = cb();
}
if (deps) {
let values = [];
afterUpdate(() => {
const new_values = deps();
if (new_values.some((value, i) => value !== values[i])) {
apply();
values = new_values;
}
});
} else {
// no deps = always run
afterUpdate(apply);
}
onDestroy(() => {
if (cleanup) cleanup();
});
}
Method 3:
Use writable and subscribe
<script>
import { writable } from 'svelte/store';
const X = writable(0);
const Y = writable(0);
X.subscribe(value => {
console.log("X was changed", value);
});
Y.subscribe(value => {
console.log("Y was changed", value);
});
</script>
<button on:click={(e)=>{
X.update((val)=>val++)
}}>Change X</button>
<button on:click={(e)=>{
Y.update((val)=>val++)
}}>Change Y</button>
Reactive statements
Svelte does not have an equivalent of useEffect. Instead, Svelte has reactive statements.
// Svelte
// doubled will always be twice of single. If single updates, doubled will run again.
$: doubled = single * 2
// equivalent to this React
let single = 0
const [doubled, setDoubled] = useState(single * 2)
useEffect(() => {
setDoubled(single * 2)
}, [single])
This may seem like magic, since you don't define dependencies or teardown functions, but Svelte takes care of all that under the hood. Svelte is smart enough to figure out the dependencies and only run each reactive statement as needed.
So if you want to run a callback every time a value updates, you can simply do this.
<script>
let value = ''
$: console.log(value)
</script>
<input type='text' name='name' bind:value />
In short, this will console log the value of the input every time the input's value changes.
Recreating your suggestions
Method 1
That's about as concise as you can go, and is my go-to means of listening to state changes unless I need something more complex.
$: if(x || y) console.log('yes')
Though note that there may be a subtle bug here. If x or y were both truthy then turn falsy (e.g., they both became empty strings), this statement will not run.
Method 2
Here, you basically recreated React's useEffect. This works, but you can simplify the implementation in your REPL a lot using reactive statements.
<script>
let count = 1;
$: console.log(count)
</script>
<input type="number" bind:value={count}>
Method 3
Stores are great for passing data between components without using props or context. Check out this answer for more: https://stackoverflow.com/a/67681054/11506995
In this case, though, we can simplify everything using regular reactive context (again).
<script>
let x = 0
let y = 0
$: console.log('x was changed', x)
$: console.log('y was changed', y)
</script>
<button on:click={() => x++}>Change x</button>
<button on:click={() => y++}>Change x</button>
I also have a detailed answer of comparing React's context/useEffect with Svelte's context/stores/reactive statements in Understanding Context in Svelte (convert from React Context)
https://stackoverflow.com/a/67681054/11506995
How about this?
<script>
let count = 0;
$: doubled = (() => {
return count * 2
})()
function handleClick() {
count += 1;
}
</script>
<button on:click={handleClick}>
Clicked {count} {count === 1 ? 'time' : 'times'}
</button>
<p>{count} doubled is {doubled}</p>

How to make Alexa countdown in seconds

I want to be able to have alexa (audibly) countdown 15 seconds in my skill. I know I can just <break time="15s" /> in SSML. But that isn't audible. I also know I can just do:
15<break time="1s" />
14<break time="1s" />
or better yet (to account for the time it takes to say the number)
15<break time="0.85s" />
14<break time="0.85s" />
But that's going to be a ton of repeated code if I do this many times over. So I'm probably going to write a function that takes in a number and a number of seconds, and produces an SSML countdown in that interval.
Before I do that, however, I was wondering if there's a proper, built-in way of doing this? Or if someone has a function they've already built for this? Thanks!!!
function buildCountdown(seconds, break) {
var countdown = "";
for (var i = seconds; i > 0; i--) {
var count = i.toString + "<break time='" + break.toString() + "s' />\n";
countdown.concat(count);
}
return countdown;
}
And then just provide the outputSpeech property:
"outputSpeech": {
"type": "SSML",
"ssml": buildCountdown(15, 0.85)
}
I'm not sure about any ASK built-ins for building SSML, but writing functions that generate markup is pretty common when working with Javascript frameworks, so it seems appropriate here.
I ended up with the following function (with the help of someone on the Alexa slack):
function countDown(numSeconds, breakTime) {
return Array.apply(null, {length: numSeconds})
.map((n, i) => {return `<say-as interpret-as="cardinal">${numSeconds-i}</say-as>` })
.join(`<break time="${breakTime ? breakTime : 0.85}s" />`) + `<break time="${breakTime ? breakTime : 0.85}s" />`;
}

angular2 - adding 'pattern' for form builder

I have a pattern for a form builder and I have this:
this.userForm = this.formBuilder.group({
'postalCode': ['', Validators.pattern('/[A-Za-z][0-9][A-Za-z] [0-9][A-Za-z][0-9]/i')]
});
I have a ValidationService which I've added a function "getValidatorErrorMessage".
static getValidatorErrorMessage(validatorName: string, validatorValue?: any) {
let config = {
'pattern': 'invalid pattern'
};
return config[validatorName];
}
My template has:
<div>
<label for="postalCode">Postal code (A1A 2J3)</label>
<input formControlName="postalCode" id="postalCode" />
<control-messages [control]="userForm.controls.postalCode"></control-messages>
</div>
But for some odd reason, the validation messages arent displaying if I dont follow the regex code.
You can view the plunkr here.
That's because you set a condition in your ControlMessagesComponent that input field has to be touched in order for error message to be displayed:
get errorMessage() {
for (let propertyName in this.control.errors) {
if (this.control.errors.hasOwnProperty(propertyName) &&
this.control.touched) { // this line
return ValidationService.getValidatorErrorMessage(propertyName, this.control.errors[propertyName]);
}
}
return null;
}
If you remove this.control.touched, validation will be performed as you type. But this also will result in required messages being displayed right away. Combination I prefer most is to display error message in two cases: when user clicks on input field and then clicks somewhere else or when user starts typing which can be achieved with following condition:
if (this.control.errors.hasOwnProperty(propertyName) &&
this.control.dirty ||
this.control.touched)

Drupal7 custom menu code in template adds stray div for no reason

I am hoping someone more knowledgeable here can point out what the problem is.
I am making a custom menu for Drupal7 for a particular theme I am working on, which is using the menu_views module. Everything works pretty nicely until I pass the view menu entry over to menu_views to parse, in which case drupal adds a broken <div class=">...</div> around the parent UL element of the view menu.. I have gone through the code and don't see how this is even happening.. If I comment out the call to the view parsing, then it doesn't add this DIV, but that view parsing shouldnt' be touching the parent UL element?
Here is how the HTML is output:
<ul class="sub-menu collapse" id="parent_">
<div class="> <li class=" first=" " expanded=" " active-trail "=" ">Por nome
<ul class="menu-content collapsed in " id=" ">
<div class="view view-nameofview view-id-nameofview etc ">
<div class="view-content ">
<div class="item-list ">
<ul class="views-summary ">
<li>Á
</li>
</ul>
</div>
</div>
</div>
</ul>
</div>
</ul>
Here is the template code that causes this:
function bstheme_menu_link__main_menu($variables) {
$element = $variables['element'];
// resolve conflict with menu_views module
if (module_exists('menu_views') && $element['#href'] == '<view>') {
return _bstheme_menu_views_menu_link($variables); //<<<< IF I COMMENT OUT THIS THE OUTPUT IS FINE
}
static $item_id = 0;
// Add an ID for easy identifying in jquery and such
$element['#attributes']['id'] = 'menu_'.str_replace(' ', '_',strtolower($element['#title']));
if(!empty($element['#original_link']['menu_name']) && $element['#original_link']['menu_name'] == 'main-menu'){
if($element['#original_link']['has_children'] == 1){
$element['#attributes']['data-target'] = "jquery_updates_this";
$element['#attributes']['data-toggle'] = "collapse";
}
// add class parent and remove leaf
$classes_count = count($element['#attributes']['class']);
for($i=0;$i<$classes_count;++$i){
if($element['#attributes']['class'][$i] == 'expanded'){
//$element['#attributes']['class'][$i] = 'collapse';
}
if($element['#original_link']['plid'] == 0){
if($element['#attributes']['class'][$i] == 'leaf'){
unset($element['#attributes']['class'][$i]);
}
}
else{
if($element['#attributes']['class'][$i] == 'leaf'){
$element['#attributes']['class'][$i] = '';
}
}
}
}
// code to add a span item for the glythicons
$switch = $element['#original_link']['has_children'];
$element['#localized_options']['html'] = TRUE;
if($switch == 1) {
$linktext = $element['#title'] . '<span class="arrow"></span>';
} else {
$linktext = $element['#title'];
}
// if there's a submenu, send the parsing to the custom function instead of the main one to wrap different classes
if ($element['#below']) {
foreach ($element['#below'] as $key => $val) {
if (is_numeric($key)) {
$element['#below'][$key]['#theme'] = 'menu_link__main_menu_inner'; // 2 lavel
}
}
$element['#below']['#theme_wrappers'][0] = 'menu_tree__main_menu_inner'; // 2 lavel
$sub_menu = drupal_render($element['#below']);
$element['#attributes']['class'][] = 'menu-toggle';
}
//$sub_menu = $element['#below'] ? drupal_render($element['#below']) : '';
$output = l($linktext, $element['#href'], $element['#localized_options']);
return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . '</li>'."\n";
}
function _bstheme_menu_views_menu_link(&$variables) {
// Only intercept if this menu link is a view.
$view = _menu_views_replace_menu_item($variables['element']);// <<< MENU VIEWS PARSING
if ($view !== FALSE) {
if (!empty($view)) {
$sub_menu = '';
if ($variables['element']['#below']) {
$sub_menu = render($variables['element']['#below']);
}
return '' . $view . $sub_menu . "\n"; // <<< RETURN PATH
}
return '';
}
return theme('menu_views_menu_link_default', $variables);
}
Any pointers on how to troubleshoot something like this, or if someone has encountered this problem before and has a solution, would be greatly helpful!
From your code, it's apparent you're using Drupal 7.
First things first, you may want to enable theme debug mode. This allows for you to see where the theming function that caused your
You can do so by putting the following line in your settings.php file
$conf['theme_debug'] = TRUE;
Flush your caches after you make this change.
You will now have debug code output to your Drupal HTML source, when you view the site's source. An example of the type of output is shown below:
<!-- THEME DEBUG -->
<!-- CALL: theme('page') -->
<!-- FILE NAME SUGGESTIONS:
x page--front.tpl.php
* page--node.tpl.php
* page.tpl.php
-->
With this debug, you should be able to see exactly which theme functions run, in which order, and by working through them from start to finish, you should be able to determine between which theme is responsible.
At this point, if you want to keep Drupal-best-practices, copy the file name suggestion from the debug output to a folder inside your theme folder. I usually put all template overrides in a sub-directory inside it.
In the case above, if it was page.tpl.php, I'd copy it to /themes/mytheme/templates/, and go hack on it to see whether the offending div is being generated there.
Best of luck, and if you hit a stuck end, I'd be happy to help point you in a direction more specific to your specific user case.
Best,
Karl

angularjs if statements?

So I'm running through the tutorial for AngularJS:
I have an array defined in the controller and i'm returning different points in the array by calling when i'm looping through ng-repeat {{feature.name}} {{feature.description}}
What i don't understand is lets say i have a third point in the array called "importance" and it's a number from 1 to 10. I don't want to display that number in the html but what i do want to do is apply a different color to the feature if that "importance" number in the array is 10 vs 1
so how do i write an if statement to do this:
i.e.
<p style="**insert if statement: {{if feature.importance == 10}} color:red; {{/if}} **">{{feature.description}}</p>
no idea if that's right but that's what i want to do
I do not think there is if statement available.
For your styling purpose, ng-class can be used.
<p ng-class="{important: feature.importance == 10 }">
ng-switch is also convenient.
-- update --
take a look at:
https://stackoverflow.com/a/18021855/1238847
angular1.2.0RC seems to have ng-if support.
Actually there is a ternary operator in Angular 1.2.0.
<p style="{{feature.importance == 10 ? 'color:red' : ''}}">{{feature.description}}</p>
I think the answer needs an update.
Previously you could use ngIf directive from AngularUI project (code here if you still want to download it), bad news is that it's not maintained any more.
The good news is that it has been added to the official AngularJS repo (unstable branch) and soon will be available in the stable one.
<div ng-if="something"> Foo bar </div>
Will not just hide the DIV element, but remove it from DOM as well (when something is falsy).
ng-class is probably the best answer to your issue, but AngularUI has an "if" directive:
http://angular-ui.github.com/
search for:
Remove elements from the DOM completely instead of just hiding it.
I used "ui-if" to decide if I should render a data value as a label or an input, relative to the current month:
<tbody id="allocationTableBody">
<tr ng-repeat="a in data.allocations">
<td>{{a.monthAbrv}}</td>
<td ui-if="$index < currentMonth">{{a.amounts[0]}}</td>
</tr>
</tbody>
In the case where your priority would be a label, you could create a switch filter to use inside of ng-class as shown in a previous SO answer : https://stackoverflow.com/a/8309832/1036025 (for the switch filter code)
<p ng-class="feature.importance|switch:{'Urgent':'red', 'Warning': 'orange', 'Normal': 'green'}">...</p>
You can also try this line of code below
<div class="{{is_foo && foo.bar}}">
which shows foo.bar if is_foo is true.
This first one is a directive that evaluates whether something should be in the DOM only once and adds no watch listeners to the page:
angular.module('setIf',[]).directive('setIf',function () {
return {
transclude: 'element',
priority: 1000,
terminal: true,
restrict: 'A',
compile: function (element, attr, linker) {
return function (scope, iterStartElement, attr) {
if(attr.waitFor) {
var wait = scope.$watch(attr.waitFor,function(nv,ov){
if(nv) {
build();
wait();
}
});
} else {
build();
}
function build() {
iterStartElement[0].doNotMove = true;
var expression = attr.setIf;
var value = scope.$eval(expression);
if (value) {
linker(scope, function (clone) {
iterStartElement.after(clone);
clone.removeAttr('set-if');
clone.removeAttr('wait-for');
});
}
}
};
}
};
});
This second one is a directive that conditionally applies attributes to elements only once without watch listeners:
i.e.
<div set-attr="{ data-id : post.id, data-name : { value : post.name, condition : post.name != 'FOO' } }"></div>
angular.module('setAttr',[]).directive('setAttr', function() {
return {
restrict: 'A',
priority: 100,
link: function(scope,elem,attrs) {
if(attrs.setAttr.indexOf('{') != -1 && attrs.setAttr.indexOf('}') != -1) {
//you could just angular.isObject(scope.$eval(attrs.setAttr)) for the above but I needed it this way
var data = scope.$eval(attrs.setAttr);
angular.forEach(data, function(v,k){
if(angular.isObject(v)) {
if(v.value && v.condition) {
elem.attr(k,v.value);
elem.removeAttr('set-attr');
}
} else {
elem.attr(k,v);
elem.removeAttr('set-attr');
}
});
}
}
}
});
Of course your can use dynamic versions built into angular:
<div ng-class="{ 'myclass' : item.iscool }"></div>
You can also use the new ng-if added by angularjs which basically replaces ui-if created by the angularui team these will conditionally add and remove things from the DOM and add watch listeners to keep evaluating:
<div ng-if="item.iscool"></div>
What also works is:
<span>{{ varWithValue || 'If empty use this string' }}</span>